From e96ac0b1dbc1c061d5b052eb818ce3ccfedc21cc Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 27 May 2024 15:23:25 +0200 Subject: [PATCH] Sketch: Add test case for degenerated geometry --- src/Mod/Sketcher/App/SketchAnalysis.cpp | 41 +++++++------------ src/Mod/Sketcher/App/SketchAnalysis.h | 7 ++-- .../TestSketchValidateCoincidents.py | 17 ++++++++ 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchAnalysis.cpp b/src/Mod/Sketcher/App/SketchAnalysis.cpp index 5a09e5a7ad..513dd89168 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.cpp +++ b/src/Mod/Sketcher/App/SketchAnalysis.cpp @@ -972,30 +972,7 @@ std::vector SketchAnalysis::getOpenVertices() const return points; } -int SketchAnalysis::detectDegeneratedGeometries(double tolerance) -{ - int countDegenerated = 0; - const std::vector& geom = sketch->getInternalGeometry(); - for (std::size_t i = 0; i < geom.size(); i++) { - auto gf = GeometryFacade::getFacade(geom[i]); - - if (gf->getConstruction()) { - continue; - } - - if (gf->getGeometry()->isDerivedFrom()) { - Part::GeomCurve* curve = static_cast(gf->getGeometry()); - double len = curve->length(curve->getFirstParameter(), curve->getLastParameter()); - if (len < tolerance) { - countDegenerated++; - } - } - } - - return countDegenerated; -} - -int SketchAnalysis::removeDegeneratedGeometries(double tolerance) +std::set SketchAnalysis::getDegeneratedGeometries(double tolerance) const { std::set delInternalGeometries; const std::vector& geom = sketch->getInternalGeometry(); @@ -1006,8 +983,7 @@ int SketchAnalysis::removeDegeneratedGeometries(double tolerance) continue; } - if (gf->getGeometry()->isDerivedFrom()) { - Part::GeomCurve* curve = static_cast(gf->getGeometry()); + if (auto curve = dynamic_cast(gf->getGeometry())) { double len = curve->length(curve->getFirstParameter(), curve->getLastParameter()); if (len < tolerance) { delInternalGeometries.insert(static_cast(i)); @@ -1015,9 +991,20 @@ int SketchAnalysis::removeDegeneratedGeometries(double tolerance) } } + return delInternalGeometries; +} + +int SketchAnalysis::detectDegeneratedGeometries(double tolerance) const +{ + std::set delInternalGeometries = getDegeneratedGeometries(tolerance); + return static_cast(delInternalGeometries.size()); +} + +int SketchAnalysis::removeDegeneratedGeometries(double tolerance) +{ + std::set delInternalGeometries = getDegeneratedGeometries(tolerance); for (auto it = delInternalGeometries.rbegin(); it != delInternalGeometries.rend(); ++it) { sketch->delGeometry(*it); } - return static_cast(delInternalGeometries.size()); } diff --git a/src/Mod/Sketcher/App/SketchAnalysis.h b/src/Mod/Sketcher/App/SketchAnalysis.h index 9f575219c9..07914e2d8b 100644 --- a/src/Mod/Sketcher/App/SketchAnalysis.h +++ b/src/Mod/Sketcher/App/SketchAnalysis.h @@ -142,7 +142,7 @@ public: void makeMissingEquality(bool onebyone = true); /// Detect degenerated geometries - int detectDegeneratedGeometries(double tolerance); + int detectDegeneratedGeometries(double tolerance) const; /// Remove degenerated geometries int removeDegeneratedGeometries(double tolerance); @@ -169,7 +169,7 @@ public: // third type of routines std::vector getOpenVertices() const; -protected: +private: Sketcher::SketchObject* sketch; struct VertexIds; @@ -184,9 +184,10 @@ protected: std::vector lineequalityConstraints; std::vector radiusequalityConstraints; -protected: +private: bool checkHorizontal(Base::Vector3d dir, double angleprecision); bool checkVertical(Base::Vector3d dir, double angleprecision); + std::set getDegeneratedGeometries(double tolerance) const; }; } // namespace Sketcher diff --git a/src/Mod/Sketcher/SketcherTests/TestSketchValidateCoincidents.py b/src/Mod/Sketcher/SketcherTests/TestSketchValidateCoincidents.py index e6cb6186e6..067dc8490d 100644 --- a/src/Mod/Sketcher/SketcherTests/TestSketchValidateCoincidents.py +++ b/src/Mod/Sketcher/SketcherTests/TestSketchValidateCoincidents.py @@ -64,6 +64,23 @@ class TestSketchValidateCoincidents(unittest.TestCase): del geo0, geo1, geo2, geo3 del sketch + def testDegenratedGeometryCase(self): + sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") + v0 = Vector(-47.680691, 18.824165000000004, 0.0) + v1 = Vector(-47.680691, -27.346279, 0.0) + v2 = Vector(-47.680691, -27.34627900001, 0.0) + + geo0 = sketch.addGeometry(Part.LineSegment(v0, v1)) + geo1 = sketch.addGeometry(Part.LineSegment(v1, v2)) + sketch.addConstraint(Sketcher.Constraint("Coincident", geo0, 2, geo1, 1)) + self.Doc.recompute() + tol = 1.0e-8 + self.assertEqual(sketch.ConstraintCount, 1) + self.assertEqual(sketch.detectDegeneratedGeometries(tol), 1) + self.assertEqual(sketch.removeDegeneratedGeometries(tol), 1) + self.assertEqual(sketch.detectDegeneratedGeometries(tol), 0) + self.assertEqual(sketch.ConstraintCount, 0) + def tearDown(self): # closing doc FreeCAD.closeDocument(self.Doc.Name)