From abe4babd135ffb1f468505326cf64333180b34a2 Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Fri, 26 Nov 2021 15:19:35 +0100 Subject: [PATCH] [Sketcher] Introduce hack to be able to vertically/horizontally auto-constrain primitives Adds a new type "VERTEX_FOR_PRIMITIVE" that will analyze the direction for vertical/horizontal but not for tangent If defined, makes use of GeoId item of AutoConstraint struct (instead of last geometry) to apply the horizontal/vertical constraint. This allow this constraint to be applied on an arbitrary geometry. --- src/Mod/Sketcher/Gui/DrawSketchHandler.cpp | 21 ++++++++++++++------- src/Mod/Sketcher/Gui/DrawSketchHandler.h | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp b/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp index dc571a673d..2f4ea5e379 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp +++ b/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp @@ -354,11 +354,11 @@ int DrawSketchHandler::seekAutoConstraint(std::vector &suggested constr.Type = Sketcher::None; constr.GeoId = GeoId; constr.PosId = PosId; - if (type == AutoConstraint::VERTEX && PosId != Sketcher::none) + if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY) && PosId != Sketcher::none) constr.Type = Sketcher::Coincident; else if (type == AutoConstraint::CURVE && PosId != Sketcher::none) constr.Type = Sketcher::PointOnObject; - else if (type == AutoConstraint::VERTEX && PosId == Sketcher::none && hitobject->getTypeId() != Part::GeomBSplineCurve::getClassTypeId()) + else if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY) && PosId == Sketcher::none && hitobject->getTypeId() != Part::GeomBSplineCurve::getClassTypeId()) constr.Type = Sketcher::PointOnObject; else if (type == AutoConstraint::CURVE && PosId == Sketcher::none) constr.Type = Sketcher::Tangent; @@ -405,6 +405,9 @@ int DrawSketchHandler::seekAutoConstraint(std::vector &suggested if (constr.Type != Sketcher::None) suggestedConstraints.push_back(constr); + // Do not seek for tangent if we are actually building a primitive + if (type == AutoConstraint::VERTEX_NO_TANGENCY) return suggestedConstraints.size(); + // Find if there are tangent constraints (currently arcs and circles) int tangId = Constraint::GeoUndef; @@ -578,6 +581,8 @@ void DrawSketchHandler::createAutoConstraints(const std::vector // Iterate through constraints std::vector::const_iterator it = autoConstrs.begin(); for (; it != autoConstrs.end(); ++it) { + int geoId2 = it->GeoId; + switch (it->Type) { case Sketcher::Coincident: { @@ -588,7 +593,6 @@ void DrawSketchHandler::createAutoConstraints(const std::vector , geoId1, posId1, it->GeoId, it->PosId); } break; case Sketcher::PointOnObject: { - int geoId2 = it->GeoId; Sketcher::PointPos posId2 = it->PosId; if (posId1 == Sketcher::none) { // Auto constraining an edge so swap parameters @@ -599,11 +603,16 @@ void DrawSketchHandler::createAutoConstraints(const std::vector Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('PointOnObject',%i,%i,%i)) " , geoId1, posId1, geoId2); } 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 case the caller as to set geoId2, then it will be used as target instead of geoId2 case Sketcher::Horizontal: { - Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Horizontal',%i)) ", geoId1); + Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Horizontal',%i)) ", + geoId2 != Constraint::GeoUndef ? geoId2 : geoId1); } break; case Sketcher::Vertical: { - Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Vertical',%i)) ", geoId1); + Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Vertical',%i)) ", + geoId2 != Constraint::GeoUndef ? geoId2 : geoId1); } break; case Sketcher::Tangent: { Sketcher::SketchObject* Obj = static_cast(sketchgui->getObject()); @@ -611,8 +620,6 @@ void DrawSketchHandler::createAutoConstraints(const std::vector const Part::Geometry *geom1 = Obj->getGeometry(geoId1); const Part::Geometry *geom2 = Obj->getGeometry(it->GeoId); - int geoId2 = it->GeoId; - // ellipse tangency support using construction elements (lines) if( geom1 && geom2 && ( geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() || diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandler.h b/src/Mod/Sketcher/Gui/DrawSketchHandler.h index b7cc951ccc..572a1cbe4c 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandler.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandler.h @@ -45,7 +45,8 @@ struct AutoConstraint enum TargetType { VERTEX, - CURVE + CURVE, + VERTEX_NO_TANGENCY }; Sketcher::ConstraintType Type; int GeoId;