From bcc1a9ada5717e19c0cc263c21b0443484d83292 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 28 May 2024 13:24:05 +0200 Subject: [PATCH] Sketch: Refactor SketchAnalysis Refactor detectMissingPointOnPointConstraints --- src/Mod/Sketcher/App/SketchAnalysis.cpp | 214 ++++++++++++++---------- 1 file changed, 124 insertions(+), 90 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchAnalysis.cpp b/src/Mod/Sketcher/App/SketchAnalysis.cpp index 0a5c380fcc..3ac9920150 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.cpp +++ b/src/Mod/Sketcher/App/SketchAnalysis.cpp @@ -142,22 +142,130 @@ struct Edge_EqualTo {} bool operator()(const EdgeIds& x, const EdgeIds& y) const { - if (fabs(x.l - y.l) <= tolerance) { - return true; - } - return false; + return (fabs(x.l - y.l) <= tolerance); } private: double tolerance; }; +struct PointConstraints +{ + explicit PointConstraints(std::vector& vertexIds) + : vertexIds {vertexIds} + {} + + void addGeometry(const Part::Geometry* geo, int index) + { + if (const auto* segm = dynamic_cast(geo)) { + addLineSegment(segm, index); + } + else if (const auto* segm = dynamic_cast(geo)) { + addArcOfCircle(segm, index); + } + else if (const auto* segm = dynamic_cast(geo)) { + addArcOfEllipse(segm, index); + } + else if (const auto* segm = dynamic_cast(geo)) { + addArcOfHyperbola(segm, index); + } + else if (const auto* segm = dynamic_cast(geo)) { + addArcOfParabola(segm, index); + } + else if (const auto* segm = dynamic_cast(geo)) { + addBSplineCurve(segm, index); + } + } + + void addLineSegment(const Part::GeomLineSegment* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + + void addArcOfCircle(const Part::GeomArcOfCircle* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(/*emulateCCW=*/true); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(/*emulateCCW=*/true); + vertexIds.push_back(id); + } + + void addArcOfEllipse(const Part::GeomArcOfEllipse* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(/*emulateCCW=*/true); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(/*emulateCCW=*/true); + vertexIds.push_back(id); + } + + void addArcOfHyperbola(const Part::GeomArcOfHyperbola* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + + void addArcOfParabola(const Part::GeomArcOfParabola* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + + void addBSplineCurve(const Part::GeomBSplineCurve* segm, int index) + { + VertexIds id; + id.GeoId = index; + id.PosId = Sketcher::PointPos::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = index; + id.PosId = Sketcher::PointPos::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + +private: + std::vector& vertexIds; +}; + } // namespace int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool includeconstruction /*=true*/) { std::vector vertexIds; // Holds a list of all vertices in the sketch + PointConstraints pointConstr(vertexIds); // Build the list of sketch vertices const std::vector& geom = sketch->getInternalGeometry(); @@ -168,84 +276,7 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, continue; } - if (gf->getGeometry()->is()) { - const Part::GeomLineSegment* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(); - vertexIds.push_back(id); - } - else if (gf->getGeometry()->is()) { - const Part::GeomArcOfCircle* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(/*emulateCCW=*/true); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(/*emulateCCW=*/true); - vertexIds.push_back(id); - } - else if (gf->getGeometry()->is()) { - const Part::GeomArcOfEllipse* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(/*emulateCCW=*/true); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(/*emulateCCW=*/true); - vertexIds.push_back(id); - } - else if (gf->getGeometry()->is()) { - const Part::GeomArcOfHyperbola* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(); - vertexIds.push_back(id); - } - else if (gf->getGeometry()->is()) { - const Part::GeomArcOfParabola* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(); - vertexIds.push_back(id); - } - else if (gf->getGeometry()->is()) { - const Part::GeomBSplineCurve* segm = - static_cast(gf->getGeometry()); - VertexIds id; - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::start; - id.v = segm->getStartPoint(); - vertexIds.push_back(id); - id.GeoId = (int)i; - id.PosId = Sketcher::PointPos::end; - id.v = segm->getEndPoint(); - vertexIds.push_back(id); - } + pointConstr.addGeometry(gf->getGeometry(), int(i)); // TODO take into account single vertices ? } @@ -257,10 +288,13 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, std::vector coincidences = sketch->Constraints.getValues(); for (auto& constraint : sketch->Constraints.getValues()) { - if (constraint->Type == Sketcher::Coincident || constraint->Type == Sketcher::Tangent - || constraint->Type == Sketcher::Perpendicular) { + // clang-format off + if (constraint->Type == Sketcher::Coincident || + constraint->Type == Sketcher::Tangent || + constraint->Type == Sketcher::Perpendicular) { coincidences.push_back(constraint); } + // clang-format on // TODO optimizing by removing constraints not applying on vertices ? } @@ -295,7 +329,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, // Decompose the group of adjacent vertices into groups of coincident vertices // Going through existent coincidences for (auto& coincidence : coincidences) { - VertexIds v1, v2; + VertexIds v1; + VertexIds v2; v1.GeoId = coincidence->First; v1.PosId = coincidence->FirstPos; v2.GeoId = coincidence->Second; @@ -407,10 +442,8 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision) if (geo1->is() && geo2->is()) { - const Part::GeomLineSegment* segm1 = - static_cast(geo1); - const Part::GeomLineSegment* segm2 = - static_cast(geo2); + const auto* segm1 = static_cast(geo1); + const auto* segm2 = static_cast(geo2); Base::Vector3d dir1 = segm1->getEndPoint() - segm1->getStartPoint(); Base::Vector3d dir2 = segm2->getEndPoint() - segm2->getStartPoint(); @@ -424,7 +457,8 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision) } try { - double u1, u2; + double u1; + double u2; curve1->closestParameter(vc.v, u1); curve2->closestParameter(vc.v, u2);