Sketcher: Add line mid-point auto-constraint
This commit is contained in:
committed by
Chris Hennes
parent
f9c9870273
commit
64054d13c4
@@ -720,6 +720,17 @@ protected:
|
||||
AutoConstraints.push_back(std::move(c));
|
||||
}
|
||||
} break;
|
||||
case Sketcher::Symmetric: {
|
||||
auto c = std::make_unique<Sketcher::Constraint>();
|
||||
c->Type = Sketcher::Symmetric;
|
||||
c->First = geoId2;
|
||||
c->FirstPos = Sketcher::PointPos::start;
|
||||
c->Second = geoId2;
|
||||
c->SecondPos = Sketcher::PointPos::end;
|
||||
c->Third = geoId1;
|
||||
c->ThirdPos = posId1;
|
||||
AutoConstraints.push_back(std::move(c));
|
||||
} break;
|
||||
// In special case of Horizontal/Vertical constraint, geoId2 is normally unused
|
||||
// and should be 'Constraint::GeoUndef' However it can be used as a way to
|
||||
// require the function to apply these constraints on another geometry In this
|
||||
|
||||
@@ -600,11 +600,9 @@ DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& sugg
|
||||
{
|
||||
std::vector<QPixmap> pixmaps;
|
||||
// Iterate through AutoConstraints types and get their pixmaps
|
||||
std::vector<AutoConstraint>::iterator it = suggestedConstraints.begin();
|
||||
int i = 0;
|
||||
for (; it != suggestedConstraints.end(); ++it, i++) {
|
||||
for (auto& autoCstr : suggestedConstraints) {
|
||||
QString iconType;
|
||||
switch (it->Type) {
|
||||
switch (autoCstr.Type) {
|
||||
case Horizontal:
|
||||
iconType = QString::fromLatin1("Constraint_Horizontal");
|
||||
break;
|
||||
@@ -617,6 +615,9 @@ DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& sugg
|
||||
case PointOnObject:
|
||||
iconType = QString::fromLatin1("Constraint_PointOnObject");
|
||||
break;
|
||||
case Symmetric:
|
||||
iconType = QString::fromLatin1("Constraint_Symmetric");
|
||||
break;
|
||||
case Tangent:
|
||||
iconType = QString::fromLatin1("Constraint_Tangent");
|
||||
break;
|
||||
@@ -644,15 +645,13 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
AutoConstraint::TargetType type)
|
||||
{
|
||||
suggestedConstraints.clear();
|
||||
SketchObject* obj = sketchgui->getSketchObject();
|
||||
|
||||
if (!sketchgui->Autoconstraints.getValue()) {
|
||||
return 0; // If Autoconstraints property is not set quit
|
||||
}
|
||||
|
||||
Base::Vector3d hitShapeDir =
|
||||
Base::Vector3d(0,
|
||||
0,
|
||||
0); // direction of hit shape (if it is a line, the direction of the line)
|
||||
// direction of hit shape (if it is a line, the direction of the line)
|
||||
Base::Vector3d hitShapeDir = Base::Vector3d(0, 0, 0);
|
||||
|
||||
// Get Preselection
|
||||
int preSelPnt = getPreselectPoint();
|
||||
@@ -660,13 +659,13 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
int preSelCrs = getPreselectCross();
|
||||
int GeoId = GeoEnum::GeoUndef;
|
||||
|
||||
Sketcher::PointPos PosId = Sketcher::PointPos::none;
|
||||
PointPos PosId = PointPos::none;
|
||||
|
||||
if (preSelPnt != -1) {
|
||||
sketchgui->getSketchObject()->getGeoVertexIndex(preSelPnt, GeoId, PosId);
|
||||
obj->getGeoVertexIndex(preSelPnt, GeoId, PosId);
|
||||
}
|
||||
else if (preSelCrv != -1) {
|
||||
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(preSelCrv);
|
||||
const Part::Geometry* geom = obj->getGeometry(preSelCrv);
|
||||
|
||||
// ensure geom exists in case object was called before preselection is updated
|
||||
if (geom) {
|
||||
@@ -679,7 +678,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
}
|
||||
else if (preSelCrs == 0) { // root point
|
||||
GeoId = Sketcher::GeoEnum::RtPnt;
|
||||
PosId = Sketcher::PointPos::start;
|
||||
PosId = PointPos::start;
|
||||
}
|
||||
else if (preSelCrs == 1) { // x axis
|
||||
GeoId = Sketcher::GeoEnum::HAxis;
|
||||
@@ -696,18 +695,33 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
constr.Type = Sketcher::None;
|
||||
constr.GeoId = GeoId;
|
||||
constr.PosId = PosId;
|
||||
if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY)
|
||||
&& PosId != Sketcher::PointPos::none) {
|
||||
constr.Type = Sketcher::Coincident;
|
||||
if (type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY) {
|
||||
if (PosId == PointPos::none) {
|
||||
bool lineCenter = false;
|
||||
auto* geo = obj->getGeometry(GeoId);
|
||||
if (geo->is<Part::GeomLineSegment>()) {
|
||||
auto* line = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
|
||||
Base::Vector2d startPoint = toVector2d(line->getStartPoint());
|
||||
Base::Vector2d endPoint = toVector2d(line->getEndPoint());
|
||||
Base::Vector2d midPoint = (startPoint + endPoint) / 2;
|
||||
|
||||
// Check if we are at middle of the line
|
||||
if ((Pos - midPoint).Length() < (endPoint - startPoint).Length() * 0.05) {
|
||||
lineCenter = true;
|
||||
}
|
||||
}
|
||||
|
||||
constr.Type = lineCenter ? Sketcher::Symmetric : Sketcher::PointOnObject;
|
||||
}
|
||||
else {
|
||||
constr.Type = Sketcher::Coincident;
|
||||
}
|
||||
}
|
||||
else if (type == AutoConstraint::CURVE && PosId != Sketcher::PointPos::none) {
|
||||
else if (type == AutoConstraint::CURVE && PosId != PointPos::none) {
|
||||
constr.Type = Sketcher::PointOnObject;
|
||||
}
|
||||
else if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY)
|
||||
&& PosId == Sketcher::PointPos::none) {
|
||||
constr.Type = Sketcher::PointOnObject;
|
||||
}
|
||||
else if (type == AutoConstraint::CURVE && PosId == Sketcher::PointPos::none) {
|
||||
else if (type == AutoConstraint::CURVE && PosId == PointPos::none) {
|
||||
constr.Type = Sketcher::Tangent;
|
||||
}
|
||||
|
||||
@@ -750,7 +764,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
AutoConstraint constr;
|
||||
constr.Type = Sketcher::None;
|
||||
constr.GeoId = GeoEnum::GeoUndef;
|
||||
constr.PosId = Sketcher::PointPos::none;
|
||||
constr.PosId = PointPos::none;
|
||||
double angle = std::abs(atan2(Dir.y, Dir.x));
|
||||
if (angle < angleDevRad || (M_PI - angle) < angleDevRad) {
|
||||
// Suggest horizontal constraint
|
||||
@@ -779,20 +793,18 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
double tangDeviation = 0.1 * sketchgui->getScaleFactor();
|
||||
|
||||
// Get geometry list
|
||||
const std::vector<Part::Geometry*> geomlist =
|
||||
sketchgui->getSketchObject()->getCompleteGeometry();
|
||||
const std::vector<Part::Geometry*> geomlist = obj->getCompleteGeometry();
|
||||
|
||||
Base::Vector3d tmpPos(Pos.x, Pos.y, 0.f); // Current cursor point
|
||||
Base::Vector3d tmpDir(Dir.x, Dir.y, 0.f); // Direction of line
|
||||
Base::Vector3d tmpStart(Pos.x - Dir.x, Pos.y - Dir.y, 0.f); // Start point
|
||||
|
||||
// Iterate through geometry
|
||||
int i = 0;
|
||||
for (std::vector<Part::Geometry*>::const_iterator it = geomlist.begin(); it != geomlist.end();
|
||||
++it, i++) {
|
||||
int i = -1;
|
||||
for (auto* geo : geomlist) {
|
||||
i++;
|
||||
|
||||
if ((*it)->is<Part::GeomCircle>()) {
|
||||
const Part::GeomCircle* circle = static_cast<const Part::GeomCircle*>((*it));
|
||||
if (geo->is<Part::GeomCircle>()) {
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
|
||||
Base::Vector3d center = circle->getCenter();
|
||||
|
||||
@@ -813,9 +825,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
tangDeviation = projDist;
|
||||
}
|
||||
}
|
||||
else if ((*it)->is<Part::GeomEllipse>()) {
|
||||
|
||||
const Part::GeomEllipse* ellipse = static_cast<const Part::GeomEllipse*>((*it));
|
||||
else if (geo->is<Part::GeomEllipse>()) {
|
||||
auto* ellipse = static_cast<const Part::GeomEllipse*>(geo);
|
||||
|
||||
Base::Vector3d center = ellipse->getCenter();
|
||||
|
||||
@@ -832,8 +843,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
|
||||
double distancetoline = norm * (tmpPos - focus1P); // distance focus1 to line
|
||||
|
||||
Base::Vector3d focus1PMirrored =
|
||||
focus1P + 2 * distancetoline * norm; // mirror of focus1 with respect to the line
|
||||
// mirror of focus1 with respect to the line
|
||||
Base::Vector3d focus1PMirrored = focus1P + 2 * distancetoline * norm;
|
||||
|
||||
double error = fabs((focus1PMirrored - focus2P).Length() - 2 * a);
|
||||
|
||||
@@ -842,8 +853,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
tangDeviation = error;
|
||||
}
|
||||
}
|
||||
else if ((*it)->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>((*it));
|
||||
else if (geo->is<Part::GeomArcOfCircle>()) {
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
|
||||
Base::Vector3d center = arc->getCenter();
|
||||
double radius = arc->getRadius();
|
||||
@@ -873,8 +884,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((*it)->is<Part::GeomArcOfEllipse>()) {
|
||||
const Part::GeomArcOfEllipse* aoe = static_cast<const Part::GeomArcOfEllipse*>((*it));
|
||||
else if (geo->is<Part::GeomArcOfEllipse>()) {
|
||||
auto* aoe = static_cast<const Part::GeomArcOfEllipse*>(geo);
|
||||
|
||||
Base::Vector3d center = aoe->getCenter();
|
||||
|
||||
@@ -934,7 +945,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
|
||||
// Suggest vertical constraint
|
||||
constr.Type = Tangent;
|
||||
constr.GeoId = tangId;
|
||||
constr.PosId = Sketcher::PointPos::none;
|
||||
constr.PosId = PointPos::none;
|
||||
suggestedConstraints.push_back(constr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user