From a6095da2afd9369d3679175a9c79872b008f37d4 Mon Sep 17 00:00:00 2001 From: bgbsww Date: Mon, 22 Jan 2024 20:00:33 -0500 Subject: [PATCH] Toponaming/Part: Add tests, dependencies, and cleanup --- src/Mod/Part/App/OpenCascadeAll.h | 1 + src/Mod/Part/App/TopoShapeExpansion.cpp | 50 +++----- tests/src/Mod/Part/App/TopoShapeExpansion.cpp | 109 +++++++++++++++--- 3 files changed, 108 insertions(+), 52 deletions(-) diff --git a/src/Mod/Part/App/OpenCascadeAll.h b/src/Mod/Part/App/OpenCascadeAll.h index 627d7fb587..130c89b49d 100644 --- a/src/Mod/Part/App/OpenCascadeAll.h +++ b/src/Mod/Part/App/OpenCascadeAll.h @@ -112,6 +112,7 @@ #include #include +#include #include #include # include diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 53ec8381d0..2eb404b18c 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -42,37 +42,33 @@ #include #include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include #include -#include -#include -#include -#include #endif +#if OCC_VERSION_HEX >= 0x070500 +# include +#endif + #include "TopoShape.h" +#include "TopoShapeOpCode.h" #include "TopoShapeCache.h" #include "TopoShapeMapper.h" #include "FaceMaker.h" -#include "TopoShapeOpCode.h" #include #include -#include FC_LOG_LEVEL_INIT("TopoShape", true, true) // NOLINT @@ -2400,17 +2396,12 @@ TopoShape::makeElementBoolean(const char* maker, const TopoShape& shape, const c } +// TODO: Refactor this so that each OpCode type is a separate method to reduce size TopoShape& TopoShape::makeElementBoolean(const char* maker, const std::vector& shapes, const char* op, double tolerance) { -#if OCC_VERSION_HEX <= 0x060800 - if (tolerance > 0.0) { - Standard_Failure::Raise("Fuzzy Booleans are not supported in this version of OCCT"); - } -#endif - if (!maker) { FC_THROWM(Base::CADKernelError, "no maker"); } @@ -2454,10 +2445,10 @@ TopoShape& TopoShape::makeElementBoolean(const char* maker, if (strcmp(maker, Part::OpCodes::Pipe) == 0) { if (shapes.size() != 2) { - FC_THROWM(Base::CADKernelError, "Not enough input shapes"); + FC_THROWM(Base::CADKernelError, "Sweep needs a spine and a shape"); } if (shapes[0].isNull() || shapes[1].isNull()) { - FC_THROWM(Base::CADKernelError, "Cannot sweep along empty spine"); + FC_THROWM(Base::CADKernelError, "Cannot sweep with empty spine or empty shape"); } if (shapes[0].getShape().ShapeType() != TopAbs_WIRE) { FC_THROWM(Base::CADKernelError, "Spine shape is not a wire"); @@ -2479,7 +2470,7 @@ TopoShape& TopoShape::makeElementBoolean(const char* maker, if (!check.IsValid()) { ShapeUpgrade_ShellSewing sewShell; setShape(sewShell.ApplySewing(shell), false); - // TODO confirm the above won't change OCCT topological naming + // TODO: confirm the above won't change OCCT topological naming } return *this; } @@ -2580,26 +2571,15 @@ TopoShape& TopoShape::makeElementBoolean(const char* maker, } #if OCC_VERSION_HEX >= 0x070500 -// Can't find this threshold value anywhere. Go ahead assuming it is true. -// if (PartParams::getParallelRunThreshold() > 0) { + // -1/22/2024 Removing the parameter. + // if (PartParams::getParallelRunThreshold() > 0) { mk->SetRunParallel(Standard_True); OSD_Parallel::SetUseOcctThreads(Standard_True); -// } + // } #else - // Only run parallel - if (shapeArguments.Size() + shapeTools.Size() > 2) { - mk->SetRunParallel(true); - } - else if (PartParams::getParallelRunThreshold() > 0) { - int total = 0; - for (const auto& shape : inputs) { - total += shape.countSubShapes(TopAbs_FACE); - if (total > PartParams::getParallelRunThreshold()) { - mk->SetRunParallel(true); - break; - } - } - } + // 01/22/2024 This will be an extremely rare case, since we don't + // build against OCCT versions this old. Removing the parameter. + mk->SetRunParallel(true); #endif mk->SetArguments(shapeArguments); diff --git a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp index 341c3192eb..b047f62eb0 100644 --- a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -60,8 +60,7 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundOneShapeReturnsShape) // Act topoShape.makeElementCompound(shapes, "C", - TopoShape::SingleShapeCompoundCreationPolicy:: - returnShape /*Don't force the creation*/); + TopoShape::SingleShapeCompoundCreationPolicy::returnShape); // Assert EXPECT_EQ(edge.ShapeType(), topoShape.getShape().ShapeType()); // NOT a Compound @@ -75,10 +74,9 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundOneShapeForceReturnsCompound) std::vector shapes {topoShape}; // Act - topoShape.makeElementCompound( - shapes, - "C", - TopoShape::SingleShapeCompoundCreationPolicy::forceCompound /*Force the creation*/); + topoShape.makeElementCompound(shapes, + "C", + TopoShape::SingleShapeCompoundCreationPolicy::forceCompound); // Assert EXPECT_NE(edge.ShapeType(), topoShape.getShape().ShapeType()); // No longer the same thing @@ -278,9 +276,7 @@ TEST_F(TopoShapeExpansionTest, MapperMakerGenerated) TEST_F(TopoShapeExpansionTest, makeElementFaceNull) { // Arrange - const float Len = 3; - const float Wid = 2; - const float Rad = 1; + const double Len = 3, Wid = 2, Rad = 1; auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad); TopoShape topoShape {face1}; double area = getArea(face1); @@ -333,8 +329,7 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceParams) double area = getArea(face1); double area1 = getArea(topoShape.getShape()); // Act - TopoShape newFace = - topoShape.makeElementFace(wire1, "Cut", "Part::FaceMakerBullseye", nullptr); + TopoShape newFace = topoShape.makeElementFace(wire1, "Cut", "Part::FaceMakerBullseye", nullptr); double area2 = getArea(newFace.getShape()); double area3 = getArea(topoShape.getShape()); // Assert @@ -358,8 +353,7 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceFromFace) double area = getArea(face1); double area1 = getArea(topoShape.getShape()); // Act - TopoShape newFace = - topoShape.makeElementFace(face1, "Cut", "Part::FaceMakerBullseye", nullptr); + TopoShape newFace = topoShape.makeElementFace(face1, "Cut", "Part::FaceMakerBullseye", nullptr); double area2 = getArea(newFace.getShape()); double area3 = getArea(topoShape.getShape()); // Assert @@ -409,8 +403,7 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceClosedWire) double area = getArea(face1); double area1 = getArea(topoShape.getShape()); // Act - TopoShape newFace = - topoShape.makeElementFace(wire2, "Cut", "Part::FaceMakerBullseye", nullptr); + TopoShape newFace = topoShape.makeElementFace(wire2, "Cut", "Part::FaceMakerBullseye", nullptr); double area2 = getArea(newFace.getShape()); double area3 = getArea(topoShape.getShape()); // Assert @@ -516,8 +509,7 @@ TEST_F(TopoShapeExpansionTest, splitWires) std::vector inner; // Act EXPECT_EQ(topoShape.getShape().Orientation(), TopAbs_FORWARD); - TopoShape wire = - topoShape.splitWires(&inner, TopoShape::SplitWireReorient::ReorientReversed); + TopoShape wire = topoShape.splitWires(&inner, TopoShape::SplitWireReorient::ReorientReversed); // Assert EXPECT_EQ(inner.size(), 1); EXPECT_FLOAT_EQ(getLength(wire.getShape()), 2 + 2 + 3 + 3); @@ -791,5 +783,88 @@ TEST_F(TopoShapeExpansionTest, makeElementShellIntersecting) // { // // Arrange // } +TEST_F(TopoShapeExpansionTest, makeElementBooleanImpossibleCommon) +{ + // Arrange + auto [cube1, cube2] = CreateTwoCubes(); + TopoShape topoShape1 {cube1, 1L}; + TopoShape topoShape2 {cube2, 2L}; + // Act + TopoShape& result = + topoShape1.makeElementBoolean(Part::OpCodes::Common, {topoShape1, topoShape2}); + auto elements = elementMap(result); + // Assert + EXPECT_EQ(elements.size(), 0); + EXPECT_FLOAT_EQ(getVolume(result.getShape()), 0); +} + +TEST_F(TopoShapeExpansionTest, makeElementBooleanCommon) +{ + // Arrange + auto [cube1, cube2] = CreateTwoCubes(); + auto tr {gp_Trsf()}; + tr.SetTranslation(gp_Vec(gp_XYZ(-0.5, -0.5, 0))); + cube2.Move(TopLoc_Location(tr)); + TopoShape topoShape1 {cube1, 1L}; + TopoShape topoShape2 {cube2, 2L}; + // Act + TopoShape& result = + topoShape1.makeElementBoolean(Part::OpCodes::Common, {topoShape1, topoShape2}); + auto elements = elementMap(result); + // Assert + EXPECT_EQ(elements.size(), 26); + EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face3;:M;CMN;:H1:7,F")); + EXPECT_FLOAT_EQ(getVolume(result.getShape()), 0.25); +} + +TEST_F(TopoShapeExpansionTest, makeElementBooleanCut) +{ + // Arrange + auto [cube1, cube2] = CreateTwoCubes(); + auto tr {gp_Trsf()}; + tr.SetTranslation(gp_Vec(gp_XYZ(-0.5, -0.5, 0))); + cube2.Move(TopLoc_Location(tr)); + TopoShape topoShape1 {cube1, 1L}; + TopoShape topoShape2 {cube2, 2L}; + // Act + TopoShape& result = topoShape1.makeElementBoolean(Part::OpCodes::Cut, {topoShape1, topoShape2}); + auto elements = elementMap(result); + // Assert + EXPECT_EQ(elements.size(), 38); + EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); + EXPECT_EQ( + elements[IndexedName("Face", 1)], + MappedName( + "Face3;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E;:L(Face5;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E|Face5;:M;" + "CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V;:L(Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;" + "CUT;:H1:7,V);CUT;:H1:3c,E|Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E);CUT;:H1:cb,F")); + EXPECT_FLOAT_EQ(getVolume(result.getShape()), 0.75); +} + +TEST_F(TopoShapeExpansionTest, makeElementBooleanFuse) +{ + // Arrange + auto [cube1, cube2] = CreateTwoCubes(); + auto tr {gp_Trsf()}; + tr.SetTranslation(gp_Vec(gp_XYZ(-0.5, -0.5, 0))); + cube2.Move(TopLoc_Location(tr)); + TopoShape topoShape1 {cube1, 1L}; + TopoShape topoShape2 {cube2, 2L}; + // Act + TopoShape& result = + topoShape1.makeElementBoolean(Part::OpCodes::Fuse, {topoShape1, topoShape2}); + auto elements = elementMap(result); + // Assert + EXPECT_EQ(elements.size(), 66); + EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); + EXPECT_EQ( + elements[IndexedName("Face", 1)], + MappedName( + "Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;" + "FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;" + "FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F")); + EXPECT_FLOAT_EQ(getVolume(result.getShape()), 1.75); +} // NOLINTEND(readability-magic-numbers,cppcoreguidelines-avoid-magic-numbers)