From 11075c396f4108f11d281c800f4a8ec79d8bea30 Mon Sep 17 00:00:00 2001 From: bgbsww Date: Thu, 15 Feb 2024 07:55:15 -0500 Subject: [PATCH] Toponaming/Part: Add tests for searchSubShape --- src/Mod/Part/App/TopoShape.h | 15 ++- src/Mod/Part/App/TopoShapeExpansion.cpp | 12 +- tests/src/Mod/Part/App/TopoShapeExpansion.cpp | 123 ++++++++++++++++++ 3 files changed, 140 insertions(+), 10 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index ebb6f581bb..285dd06126 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -118,6 +118,12 @@ enum class RefineFail throwException }; +/// Behavior of findSubShapesWithSharedVertex. +enum class CheckGeometry +{ + ignoreGeometry, + checkGeometry +}; /** The representation for a CAD Shape */ class PartExport TopoShape: public Data::ComplexGeoData @@ -703,8 +709,10 @@ public: std::vector findAncestors(const TopoDS_Shape& subshape, TopAbs_ShapeEnum type) const; std::vector findAncestorsShapes(const TopoDS_Shape& subshape, TopAbs_ShapeEnum type) const; - /** Search sub shape + /** Find sub shapes with shared Vertexes. * + * Renamed: searchSubShape -> findSubShapesWithSharedVertex + * * unlike findShape(), the input shape does not have to be an actual * sub-shape of this shape. The sub-shape is searched by shape geometry * Note that subshape must be a Vertex, Edge, or Face. @@ -715,10 +723,9 @@ public: * @param tol: tolerance to check coincident vertices * @param atol: tolerance to check for same angles */ - // TODO: Refactor this method and its tests later in Toponaming Phase 3. - std::vector searchSubShape(const TopoShape &subshape, + std::vector findSubShapesWithSharedVertex(const TopoShape &subshape, std::vector *names=nullptr, - bool checkGeometry=true, + CheckGeometry checkGeometry=CheckGeometry::checkGeometry, double tol=1e-7, double atol=1e-12) const; //@} diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index de0b1b0454..ef4f8e1edc 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -221,9 +221,9 @@ TopoDS_Shape TopoShape::findShape(TopAbs_ShapeEnum type, int idx) const return _cache->findShape(_Shape, type, idx); } -std::vector TopoShape::searchSubShape(const TopoShape& subshape, +std::vector TopoShape::findSubShapesWithSharedVertex(const TopoShape& subshape, std::vector* names, - bool checkGeometry, + CheckGeometry checkGeometry, double tol, double atol) const { @@ -266,7 +266,7 @@ std::vector TopoShape::searchSubShape(const TopoShape& subshape, vertices = subshape.getSubShapes(TopAbs_VERTEX); } - if (vertices.empty() || checkGeometry) { + if (vertices.empty() || checkGeometry == CheckGeometry::checkGeometry) { g = Geometry::fromShape(subshape.getShape()); if (!g) { return res; @@ -330,7 +330,7 @@ std::vector TopoShape::searchSubShape(const TopoShape& subshape, // * Perform geometry comparison of the ancestor and input shape. // * For face, perform addition geometry comparison of each edges. std::unordered_set shapeSet; - for (auto& v : searchSubShape(vertices[0], nullptr, checkGeometry, tol, atol)) { + for (auto& v : findSubShapesWithSharedVertex(vertices[0], nullptr, checkGeometry, tol, atol)) { for (auto idx : findAncestors(v.getShape(), shapeType)) { auto s = getSubTopoShape(shapeType, idx); if (!shapeSet.insert(s).second) { @@ -352,7 +352,7 @@ std::vector TopoShape::searchSubShape(const TopoShape& subshape, if (otherVertices.size() != vertices.size()) { continue; } - if (checkGeometry && !compareGeometry(s, false)) { + if (checkGeometry == CheckGeometry::checkGeometry && !compareGeometry(s, false)) { continue; } unsigned i = 0; @@ -380,7 +380,7 @@ std::vector TopoShape::searchSubShape(const TopoShape& subshape, continue; } - if (shapeType == TopAbs_FACE && checkGeometry) { + if (shapeType == TopAbs_FACE && checkGeometry == CheckGeometry::checkGeometry) { // Is it really necessary to check geometries of each edge of a face? // Right now we only do outer wire check auto otherEdges = otherWire.getSubShapes(TopAbs_EDGE); diff --git a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp index e72288d45e..894be2d2a8 100644 --- a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -746,6 +746,129 @@ TEST_F(TopoShapeExpansionTest, mapSubElementFindAncestors) EXPECT_TRUE(ancestorShapeList.back().IsEqual(topoShape6.getShape())); } +TEST_F(TopoShapeExpansionTest, findSubShapesWithSharedVertexEverything) +{ + // Arrange + auto [box1, box2] = CreateTwoCubes(); + TopoShape box1TS {box1}; + std::vector names; + std::vector names1; + std::vector names2; + double tol {2}; // Silly big tolerance to get everything + double atol {2}; + + TopExp_Explorer exp(box1, TopAbs_FACE); + auto face = exp.Current(); + exp.Init(box1, TopAbs_EDGE); + auto edge = exp.Current(); + exp.Init(box1, TopAbs_VERTEX); + auto vertex = exp.Current(); + // Act + auto shapes = + box1TS.findSubShapesWithSharedVertex(face, &names, CheckGeometry::checkGeometry, tol, atol); + auto shapes1 = box1TS.findSubShapesWithSharedVertex(edge, + &names1, + CheckGeometry::checkGeometry, + tol, + atol); + auto shapes2 = box1TS.findSubShapesWithSharedVertex(vertex, + &names2, + CheckGeometry::checkGeometry, + tol, + atol); + // Assert + EXPECT_EQ(shapes.size(), 6); + EXPECT_EQ(names.size(), 6); + EXPECT_STREQ(names[0].c_str(), "Face1"); + EXPECT_STREQ(names[1].c_str(), "Face3"); + EXPECT_STREQ(names[2].c_str(), "Face6"); + EXPECT_STREQ(names[3].c_str(), "Face5"); + EXPECT_STREQ(names[4].c_str(), "Face4"); + EXPECT_STREQ(names[5].c_str(), "Face2"); + EXPECT_EQ(shapes1.size(), 12); + EXPECT_EQ(names1.size(), 12); + EXPECT_EQ(shapes2.size(), 8); + EXPECT_EQ(names2.size(), 8); +} + +TEST_F(TopoShapeExpansionTest, findSubShapesWithSharedVertexMid) +{ + // Arrange + auto [box1, box2] = CreateTwoCubes(); + TopoShape box1TS {box1}; + std::vector names; + std::vector names1; + std::vector names2; + double tol {1e-0}; + double atol {1e-04}; + + TopExp_Explorer exp(box1, TopAbs_FACE); + auto face = exp.Current(); + exp.Init(box1, TopAbs_EDGE); + auto edge = exp.Current(); + exp.Init(box1, TopAbs_VERTEX); + auto vertex = exp.Current(); + // Act + auto shapes = + box1TS.findSubShapesWithSharedVertex(face, &names, CheckGeometry::checkGeometry, tol, atol); + auto shapes1 = box1TS.findSubShapesWithSharedVertex(edge, + &names1, + CheckGeometry::checkGeometry, + tol, + atol); + auto shapes2 = box1TS.findSubShapesWithSharedVertex(vertex, + &names2, + CheckGeometry::checkGeometry, + tol, + atol); + // Assert + EXPECT_EQ(shapes.size(), 6); + EXPECT_EQ(names.size(), 6); + EXPECT_EQ(shapes1.size(), 7); + EXPECT_EQ(names1.size(), 7); + EXPECT_EQ(shapes2.size(), 4); + EXPECT_EQ(names2.size(), 4); +} + +TEST_F(TopoShapeExpansionTest, findSubShapesWithSharedVertexClose) +{ + // Arrange + auto [box1, box2] = CreateTwoCubes(); + TopoShape box1TS {box1}; + std::vector names; + std::vector names1; + std::vector names2; + double tol {1e-02}; + double atol {1e-04}; + + TopExp_Explorer exp(box1, TopAbs_FACE); + auto face = exp.Current(); + exp.Init(box1, TopAbs_EDGE); + auto edge = exp.Current(); + exp.Init(box1, TopAbs_VERTEX); + auto vertex = exp.Current(); + // Act + auto shapes = + box1TS.findSubShapesWithSharedVertex(face, &names, CheckGeometry::checkGeometry, tol, atol); + auto shapes1 = box1TS.findSubShapesWithSharedVertex(edge, + &names1, + CheckGeometry::checkGeometry, + tol, + atol); + auto shapes2 = box1TS.findSubShapesWithSharedVertex(vertex, + &names2, + CheckGeometry::checkGeometry, + tol, + atol); + // Assert + EXPECT_EQ(shapes.size(), 1); + EXPECT_EQ(names.size(), 1); + EXPECT_EQ(shapes1.size(), 1); + EXPECT_EQ(names1.size(), 1); + EXPECT_EQ(shapes2.size(), 1); + EXPECT_EQ(names2.size(), 1); +} + TEST_F(TopoShapeExpansionTest, makeElementShellInvalid) { // Arrange