diff --git a/src/Mod/Sketcher/App/SketchAnalysis.cpp b/src/Mod/Sketcher/App/SketchAnalysis.cpp index 3ac9920150..ad00af681f 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.cpp +++ b/src/Mod/Sketcher/App/SketchAnalysis.cpp @@ -482,55 +482,79 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision) } } -void SketchAnalysis::makeMissingPointOnPointCoincident(bool onebyone) +Sketcher::Constraint* SketchAnalysis::create(const ConstraintIds& id) +{ + auto c = new Sketcher::Constraint(); + c->Type = id.Type; + c->First = id.First; + c->Second = id.Second; + c->FirstPos = id.FirstPos; + c->SecondPos = id.SecondPos; + return c; +} + +void SketchAnalysis::solveSketch(const char* errorText) +{ + int status {}; + int dofs {}; + solvesketch(status, dofs, true); + + if (status == -2) { // redundant constraints + sketch->autoRemoveRedundants(false); + + solvesketch(status, dofs, false); + } + + if (status) { + THROWMT(Base::RuntimeError, errorText); + } +} + +void SketchAnalysis::makeConstraints(std::vector& ids) { - int status, dofs; std::vector constr; - - for (const auto& it : vertexConstraints) { - Sketcher::Constraint* c = new Sketcher::Constraint(); - c->Type = it.Type; - c->First = it.First; - c->Second = it.Second; - c->FirstPos = it.FirstPos; - c->SecondPos = it.SecondPos; - - if (onebyone) { - // addConstraint() creates a clone - sketch->addConstraint(c); - delete c; - - solvesketch(status, dofs, true); - - if (status == -2) { // redundant constraints - sketch->autoRemoveRedundants(false); - - solvesketch(status, dofs, false); - } - - if (status) { - THROWMT(Base::RuntimeError, - QT_TRANSLATE_NOOP("Exceptions", - "Autoconstrain error: Unsolvable sketch while applying " - "coincident constraints.")); - } - } - else { - constr.push_back(c); - } + constr.reserve(ids.size()); + for (const auto& it : ids) { + auto c = create(it); + constr.push_back(c); } - if (!onebyone) { - sketch->addConstraints(constr); - } - - vertexConstraints.clear(); + sketch->addConstraints(constr); + ids.clear(); for (auto it : constr) { delete it; } } +void SketchAnalysis::makeConstraintsOneByOne(std::vector& ids, const char* errorText) +{ + for (const auto& it : ids) { + auto c = create(it); + + // addConstraint() creates a clone + sketch->addConstraint(c); + delete c; + + solveSketch(errorText); + } + + ids.clear(); +} + +void SketchAnalysis::makeMissingPointOnPointCoincident() +{ + makeConstraints(vertexConstraints); +} + +void SketchAnalysis::makeMissingPointOnPointCoincidentOneByOne() +{ + makeConstraintsOneByOne(vertexConstraints, + QT_TRANSLATE_NOOP("Exceptions", + "Autoconstrain error: Unsolvable sketch while " + "applying coincident constraints.")); +} + int SketchAnalysis::detectMissingVerticalHorizontalConstraints(double angleprecision) { const std::vector& geom = sketch->getInternalGeometry(); diff --git a/src/Mod/Sketcher/App/SketchAnalysis.h b/src/Mod/Sketcher/App/SketchAnalysis.h index 5456060fc6..d06355fc5c 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.h +++ b/src/Mod/Sketcher/App/SketchAnalysis.h @@ -97,9 +97,11 @@ public: vertexConstraints = cl; } /// Point on Point constraint simple routine Make step (see constructor) - /// if onebyone, then the sketch is solved after each individual constraint addition and any + void makeMissingPointOnPointCoincident(); + /// Point on Point constraint simple routine Make step (see constructor) + /// The sketch is solved after each individual constraint addition and any /// redundancy removed. - void makeMissingPointOnPointCoincident(bool onebyone = false); + void makeMissingPointOnPointCoincidentOneByOne(); /// Vertical/Horizontal constraints simple routine Detect step (see constructor) int detectMissingVerticalHorizontalConstraints(double angleprecision = M_PI / 8); @@ -180,7 +182,11 @@ private: private: bool checkHorizontal(Base::Vector3d dir, double angleprecision); bool checkVertical(Base::Vector3d dir, double angleprecision); + void makeConstraints(std::vector&); + void makeConstraintsOneByOne(std::vector&, const char* errorText); std::set getDegeneratedGeometries(double tolerance) const; + void solveSketch(const char* errorText); + static Sketcher::Constraint* create(const ConstraintIds& id); }; } // namespace Sketcher diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 9ff799fe3d..e322b40b9c 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -9825,8 +9825,10 @@ void SketchObject::setMissingPointOnPointConstraints(std::vector& void SketchObject::makeMissingPointOnPointCoincident(bool onebyone) { - if (analyser) - analyser->makeMissingPointOnPointCoincident(onebyone); + if (analyser) { + onebyone ? analyser->makeMissingPointOnPointCoincidentOneByOne() + : analyser->makeMissingPointOnPointCoincident(); + } } void SketchObject::makeMissingVerticalHorizontal(bool onebyone)