diff --git a/src/Mod/Sketcher/App/SketchAnalysis.cpp b/src/Mod/Sketcher/App/SketchAnalysis.cpp index 7dc31c5890..fcd5f64b51 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.cpp +++ b/src/Mod/Sketcher/App/SketchAnalysis.cpp @@ -312,7 +312,7 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision) Base::Vector3d dir1 = segm1->getEndPoint() - segm1->getStartPoint(); Base::Vector3d dir2 = segm2->getEndPoint() - segm2->getStartPoint(); - + if( (checkVertical(dir1,angleprecision) || checkHorizontal(dir1,angleprecision)) && (checkVertical(dir2,angleprecision) || checkHorizontal(dir2,angleprecision)) ) { // this is a job for horizontal/vertical constraints alone @@ -322,26 +322,26 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision) try { double u1, u2; - + curve1->closestParameter(vc.v,u1); curve2->closestParameter(vc.v,u2); Base::Vector3d tgv1 = curve1->firstDerivativeAtParameter(u1).Normalize(); Base::Vector3d tgv2 = curve2->firstDerivativeAtParameter(u2).Normalize(); - + if(fabs(tgv1*tgv2)>fabs(cos(angleprecision))) { vc.Type = Sketcher::Tangent; } else if(fabs(tgv1*tgv2) constr; - + for (std::vector::iterator it = verthorizConstraints.begin(); it != verthorizConstraints.end(); ++it) { Sketcher::Constraint* c = new Sketcher::Constraint(); c->Type = it->Type; @@ -484,7 +484,7 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision) { std::vector lineedgeIds; std::vector radiusedgeIds; - + const std::vector& geom = sketch->getInternalGeometry(); for (std::size_t i=0; i::iterator vt = lineedgeIds.begin(); Edge_EqualTo pred(precision); - + std::list equallines; // Make a list of constraint we expect for coincident vertexes while (vt < lineedgeIds.end()) { @@ -538,14 +538,14 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision) break; } } - + vt = vn; } } - + std::sort(radiusedgeIds.begin(), radiusedgeIds.end(), Edge_Less(precision)); vt = radiusedgeIds.begin(); - + std::list equalradius; // Make a list of constraint we expect for coincident vertexes while (vt < radiusedgeIds.end()) { @@ -568,12 +568,12 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision) break; } } - + vt = vn; } } - - + + // Go through the available 'Coincident', 'Tangent' or 'Perpendicular' constraints // and check which of them is forcing two vertexes to be coincident. // If there is none but two vertexes can be considered equal a coincident constraint is missing. @@ -585,37 +585,37 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision) id.FirstPos = (*it)->FirstPos; id.Second = (*it)->Second; id.SecondPos = (*it)->SecondPos; - + std::list::iterator pos = std::find_if (equallines.begin(), equallines.end(), Constraint_Equal(id)); if (pos != equallines.end()) { equallines.erase(pos); } - + pos = std::find_if (equalradius.begin(), equalradius.end(), Constraint_Equal(id)); - + if (pos != equalradius.end()) { equalradius.erase(pos); } } } - + this->lineequalityConstraints.clear(); this->lineequalityConstraints.reserve(equallines.size()); - + for (std::list::iterator it = equallines.begin(); it != equallines.end(); ++it) { this->lineequalityConstraints.push_back(*it); } - + this->radiusequalityConstraints.clear(); this->radiusequalityConstraints.reserve(equalradius.size()); - + for (std::list::iterator it = equalradius.begin(); it != equalradius.end(); ++it) { this->radiusequalityConstraints.push_back(*it); } - + return this->lineequalityConstraints.size() + this->radiusequalityConstraints.size(); } @@ -678,7 +678,7 @@ void SketchAnalysis::solvesketch(int &status, int &dofs, bool updategeo) if (sketch->getLastHasRedundancies()) { // redundant constraints status = -2; } - + if (dofs < 0) { // over-constrained sketch status = -4; } @@ -795,3 +795,30 @@ int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool return 0; } + + +std::vector SketchAnalysis::getOpenVertices(void) const +{ + std::vector points; + TopoDS_Shape shape = sketch->Shape.getValue(); + + Base::Placement Plm = sketch->Placement.getValue(); + + Base::Placement invPlm = Plm.inverse(); + + // build up map vertex->edge + TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge; + TopExp::MapShapesAndAncestors(shape, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge); + for (int i=1; i<= vertex2Edge.Extent(); ++i) { + const TopTools_ListOfShape& los = vertex2Edge.FindFromIndex(i); + if (los.Extent() != 2) { + const TopoDS_Vertex& vertex = TopoDS::Vertex(vertex2Edge.FindKey(i)); + gp_Pnt pnt = BRep_Tool::Pnt(vertex); + Base::Vector3d pos; + invPlm.multVec(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()),pos); + points.push_back(pos); + } + } + + return points; +} diff --git a/src/Mod/Sketcher/App/SketchAnalysis.h b/src/Mod/Sketcher/App/SketchAnalysis.h index 7a8e1fb9f5..8a7f692e72 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.h +++ b/src/Mod/Sketcher/App/SketchAnalysis.h @@ -62,9 +62,11 @@ public: /// /// A second type of routines, complex routines, are thought for running fully automatic and they Detect, Analyse and Make. /// They may also apply a variaty of types of Constraints. + /// + /// A third type of routines do not relate to autoconstraining at all, and include validation methods for sketches. SketchAnalysis(Sketcher::SketchObject * Obj); ~SketchAnalysis(); - + // Simple routines (see constructor) /// Point on Point constraint simple routine Detect step (see constructor) @@ -103,7 +105,7 @@ public: void makeMissingEquality(bool onebyone = true); // Complex routines (see constructor) - + /// Fully automated multi-constraint autoconstraining /// /// It DELETES all the constraints currently present in the Sketcher. The reason is that it makes assumptions to avoid redundancies. @@ -112,11 +114,14 @@ public: int autoconstraint(double precision = Precision::Confusion() * 1000, double angleprecision = M_PI/8, bool includeconstruction = true); // helper functions, which may be used by more complex methods, and/or called directly by user space (python) methods - - /// solves the sketch and retrieves the error status, and the degrees of freedom. + + /// solves the sketch and retrieves the error status, and the degrees of freedom. /// It enables to solve updating the geometry (so moving the geometry to match the constraints) or preserving the geometry. void solvesketch(int &status, int &dofs, bool updategeo); + // third type of routines + std::vector getOpenVertices(void) const; + protected: Sketcher::SketchObject* sketch; diff --git a/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp b/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp index e0f3c5c984..26a67e773c 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp @@ -168,25 +168,8 @@ void SketcherValidation::on_fixButton_clicked() void SketcherValidation::on_highlightButton_clicked() { std::vector points; - TopoDS_Shape shape = sketch->Shape.getValue(); - Base::Placement Plm = sketch->Placement.getValue(); - - Base::Placement invPlm = Plm.inverse(); - - // build up map vertex->edge - TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge; - TopExp::MapShapesAndAncestors(shape, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge); - for (int i=1; i<= vertex2Edge.Extent(); ++i) { - const TopTools_ListOfShape& los = vertex2Edge.FindFromIndex(i); - if (los.Extent() != 2) { - const TopoDS_Vertex& vertex = TopoDS::Vertex(vertex2Edge.FindKey(i)); - gp_Pnt pnt = BRep_Tool::Pnt(vertex); - Base::Vector3d pos; - invPlm.multVec(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()),pos); - points.push_back(pos); - } - } + points = sketchAnalyser.getOpenVertices(); hidePoints(); if (!points.empty())