diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerSlot.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerSlot.h index 1f8265804a..256a0270ce 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerSlot.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerSlot.h @@ -73,8 +73,6 @@ public: : radius(1.0) , length(0.0) , angle(0.0) - , isHorizontal(false) - , isVertical(false) , firstCurve(0) {} @@ -123,7 +121,6 @@ private: secondPoint = onSketchPos; angle = (secondPoint - startPoint).Angle(); - checkHorizontalVertical(); length = (secondPoint - startPoint).Length(); const double scale = 0.2; radius = length * scale; // radius chosen at 1/5 of length @@ -197,6 +194,22 @@ private: void generateAutoConstraints() override { + // alignment constraints needs to apply to the line not the arc. + bool alignmentCstr = false; + for (auto& ac : sugConstraints[1]) { + if (ac.Type == Sketcher::Horizontal || ac.Type == Sketcher::Vertical + || ac.Type == Sketcher::Perpendicular || ac.Type == Sketcher::Parallel) { + ac.GeoId = firstCurve + 2; + alignmentCstr = true; + } + } + + if (avoidRedundants && alignmentCstr) { + removeRedundantHorizontalVertical(getSketchObject(), + sugConstraints[0], + sugConstraints[1]); + } + // add auto constraints for the center of 1st arc generateAutoConstraintsOnElement(sugConstraints[0], getHighestCurveIndex() - 3, @@ -219,8 +232,6 @@ private: sugConstraints[0].clear(); sugConstraints[1].clear(); - isHorizontal = false; - isVertical = false; } std::string getToolName() const override @@ -321,53 +332,12 @@ private: firstCurve, Sketcher::PointPos::none, firstCurve + 1); - - // Prevent duplicate with Autocontraint - AutoConstraint lastCons = {Sketcher::None, - Sketcher::GeoEnum::GeoUndef, - Sketcher::PointPos::none}; - if (!sugConstraints[1].empty()) { - lastCons = sugConstraints[1].back(); - } - - if (isHorizontal || isVertical) { - addToShapeConstraints(isHorizontal ? Sketcher::Horizontal : Sketcher::Vertical, - firstCurve + 3); - - - if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) { - sugConstraints[1].pop_back(); - } - } - else { - // If horizontal/vertical Autoconstraint suggested, applied it on first line - // (rather than last arc) - if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) { - sugConstraints[1].back().GeoId = firstCurve + 2; - } - } - } - } - - void checkHorizontalVertical() - { - using std::numbers::pi; - - isHorizontal = false; - isVertical = false; - - if (fmod(fabs(angle), pi) < Precision::Confusion()) { - isHorizontal = true; - } - else if (fmod(fabs(angle + pi / 2), pi) < Precision::Confusion()) { - isVertical = true; } } private: Base::Vector2d startPoint, secondPoint; double radius, length, angle; - bool isHorizontal, isVertical; int firstCurve; }; @@ -625,23 +595,16 @@ void DSHSlotController::addConstraints() }; auto constraintAngle = [&]() { - if (!handler->isHorizontal && !handler->isVertical) { + ConstraintType lastType = handler->sugConstraints[1].empty() + ? ConstraintType::None + : handler->sugConstraints[1].back().Type; + if (lastType != Sketcher::Horizontal && lastType != Sketcher::Vertical + && lastType != Sketcher::Perpendicular && lastType != Sketcher::Parallel) { Gui::cmdAppObjectArgs(obj, "addConstraint(Sketcher.Constraint('Angle',%d,%d,%f)) ", Sketcher::GeoEnum::HAxis, firstCurve + 2, handler->angle); - - // Prevent duplicate with Autocontraint - AutoConstraint lastCons = {Sketcher::None, - Sketcher::GeoEnum::GeoUndef, - Sketcher::PointPos::none}; - if (!handler->sugConstraints[1].empty()) { - lastCons = handler->sugConstraints[1].back(); - if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical) { - handler->AutoConstraints.pop_back(); - } - } } }; diff --git a/src/Mod/Sketcher/Gui/Utils.cpp b/src/Mod/Sketcher/Gui/Utils.cpp index 91dfc948fa..ccc62fd6c6 100644 --- a/src/Mod/Sketcher/Gui/Utils.cpp +++ b/src/Mod/Sketcher/Gui/Utils.cpp @@ -601,74 +601,72 @@ void SketcherGui::removeRedundantHorizontalVertical(Sketcher::SketchObject* pske std::vector& sug1, std::vector& sug2) { - if (!sug1.empty() && !sug2.empty()) { + if (sug1.empty() || sug2.empty()) { + return; + } - bool rmvhorvert = false; + bool rmvhorvert = false; - // we look for: - // 1. Coincident to external on both endpoints - // 2. Coincident in one endpoint to origin and pointonobject/tangent to an axis on the other - auto detectredundant = - [psketch](std::vector& sug, bool& ext, bool& orig, bool& axis) { - ext = false; - orig = false; - axis = false; + // we look for: + // 1. Coincident to external on both endpoints + // 2. Coincident in one endpoint to origin and pointonobject/tangent to an axis on the other + auto detectredundant = + [psketch](std::vector& sug, bool& ext, bool& orig, bool& axis) { + ext = false; + orig = false; + axis = false; - for (std::vector::const_iterator it = sug.begin(); it != sug.end(); - ++it) { - if ((*it).Type == Sketcher::Coincident && !ext) { - const std::map coincidents = - psketch->getAllCoincidentPoints((*it).GeoId, (*it).PosId); + for (auto& it : sug) { + if (it.Type == Sketcher::Coincident && !ext) { + const std::map coincidents = + psketch->getAllCoincidentPoints(it.GeoId, it.PosId); - if (!coincidents.empty()) { - // the keys are ordered, so if the first is negative, it is coincident - // with external - ext = coincidents.begin()->first < 0; + if (!coincidents.empty()) { + // the keys are ordered, so if the first is negative, it is coincident + // with external + ext = coincidents.begin()->first < 0; - std::map::const_iterator geoId1iterator; + std::map::const_iterator geoId1iterator; - geoId1iterator = coincidents.find(-1); + geoId1iterator = coincidents.find(-1); - if (geoId1iterator != coincidents.end()) { - if ((*geoId1iterator).second == Sketcher::PointPos::start) { - orig = true; - } + if (geoId1iterator != coincidents.end()) { + if ((*geoId1iterator).second == Sketcher::PointPos::start) { + orig = true; } } - else { // it may be that there is no constraint at all, but there is - // external geometry - ext = (*it).GeoId < 0; - orig = ((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::start); - } } - else if ((*it).Type == Sketcher::PointOnObject && !axis) { - axis = (((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::none) - || ((*it).GeoId == -2 && (*it).PosId == Sketcher::PointPos::none)); + else { // it may be that there is no constraint at all, but there is + // external geometry + ext = it.GeoId < 0; + orig = (it.GeoId == -1 && it.PosId == Sketcher::PointPos::start); } } - }; - - bool firstext = false, secondext = false, firstorig = false, secondorig = false, - firstaxis = false, secondaxis = false; - - detectredundant(sug1, firstext, firstorig, firstaxis); - detectredundant(sug2, secondext, secondorig, secondaxis); - - - rmvhorvert = - ((firstext && secondext) || // coincident with external on both endpoints - (firstorig && secondaxis) || // coincident origin and point on object on other - (secondorig && firstaxis)); - - if (rmvhorvert) { - for (std::vector::reverse_iterator it = sug2.rbegin(); - it != sug2.rend(); - ++it) { - if ((*it).Type == Sketcher::Horizontal || (*it).Type == Sketcher::Vertical) { - sug2.erase(std::next(it).base()); - it = sug2.rbegin(); // erase invalidates the iterator + else if (it.Type == Sketcher::PointOnObject && !axis) { + axis = ((it.GeoId == -1 && it.PosId == Sketcher::PointPos::none) + || (it.GeoId == -2 && it.PosId == Sketcher::PointPos::none)); } } + }; + + bool firstext = false, secondext = false, firstorig = false, secondorig = false, + firstaxis = false, secondaxis = false; + + detectredundant(sug1, firstext, firstorig, firstaxis); + detectredundant(sug2, secondext, secondorig, secondaxis); + + + rmvhorvert = ((firstext && secondext) || // coincident with external on both endpoints + (firstorig && secondaxis) || // coincident origin and point on object on other + (secondorig && firstaxis)); + + if (rmvhorvert) { + for (std::vector::reverse_iterator it = sug2.rbegin(); it != sug2.rend(); + ++it) { + if ((*it).Type == Sketcher::Horizontal || (*it).Type == Sketcher::Vertical) { + sug2.erase(std::next(it).base()); + it = sug2.rbegin(); // erase invalidates the iterator + } } } }