From 7bc2b3688ac46e1d6d0a2614616bb40536825740 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Thu, 11 Apr 2024 10:21:32 -0400 Subject: [PATCH 1/2] TopoShape/Part: Bring in FeatureDressup --- src/Mod/PartDesign/App/FeatureDressUp.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureDressUp.cpp b/src/Mod/PartDesign/App/FeatureDressUp.cpp index c77e5c67d8..5e801194f7 100644 --- a/src/Mod/PartDesign/App/FeatureDressUp.cpp +++ b/src/Mod/PartDesign/App/FeatureDressUp.cpp @@ -231,7 +231,11 @@ void DressUp::getAddSubShape(Part::TopoShape &addShape, Part::TopoShape &subShap baseShape.move(base->getLocation().Inverted()); if (base->getAddSubType() == Additive) { if(!baseShape.isNull() && baseShape.hasSubShape(TopAbs_SOLID)) +#ifdef FC_USE_TNP_FIX + shapes.emplace_back(shape.makeElementCut(baseShape.getShape())); +#else shapes.emplace_back(shape.cut(baseShape.getShape())); +#endif else shapes.push_back(shape); } else { @@ -241,22 +245,35 @@ void DressUp::getAddSubShape(Part::TopoShape &addShape, Part::TopoShape &subShap // push an empty compound to indicate null additive shape shapes.emplace_back(comp); if(!baseShape.isNull() && baseShape.hasSubShape(TopAbs_SOLID)) +#ifdef FC_USE_TNP_FIX + shapes.emplace_back(baseShape.makeElementCut(shape.getShape())); +#else shapes.emplace_back(baseShape.cut(shape.getShape())); +#endif else shapes.push_back(shape); } } else { baseShape = getBaseTopoShape(); baseShape.move(getLocation().Inverted()); +#ifdef FC_USE_TNP_FIX + shapes.emplace_back(shape.makeElementCut(baseShape.getShape())); + shapes.emplace_back(baseShape.makeElementCut(shape.getShape())); +#else shapes.emplace_back(shape.cut(baseShape.getShape())); shapes.emplace_back(baseShape.cut(shape.getShape())); +#endif } // Make a compound to contain both additive and subtractive shape, // bceause a dressing (e.g. a fillet) can either be additive or // subtractive. And the dressup feature can contain mixture of both. - AddSubShape.setValue(Part::TopoShape().makeCompound(shapes)); +#ifdef FC_USE_TNP_FIX + AddSubShape.setValue(Part::TopoShape().makeElementCompound(shapes)); +#else + AddSubShape.setValue(Part::TopoShape().makeCompound(shapes)); +#endif } catch (Standard_Failure &e) { FC_THROWM(Base::CADKernelError, "Failed to calculate AddSub shape: " << e.GetMessageString()); @@ -274,12 +291,12 @@ void DressUp::getAddSubShape(Part::TopoShape &addShape, Part::TopoShape &subShap if(!count) throw Part::NullShapeException("Null AddSub shape"); if(count) { - Part::TopoShape s = res.getSubShape(TopAbs_SHAPE, 1); + Part::TopoShape s = res.getSubTopoShape(TopAbs_SHAPE, 1); if(!s.isNull() && s.hasSubShape(TopAbs_SOLID)) addShape = s; } if(count > 1) { - Part::TopoShape s = res.getSubShape(TopAbs_SHAPE, 2); + Part::TopoShape s = res.getSubTopoShape(TopAbs_SHAPE, 2); if(!s.isNull() && s.hasSubShape(TopAbs_SOLID)) subShape = s; } From 5f2c412cfa067561744bb45a4de79ee33ead5f75 Mon Sep 17 00:00:00 2001 From: bgbsww Date: Thu, 11 Apr 2024 10:22:27 -0400 Subject: [PATCH 2/2] Toponaming/Part: Clean and add tests --- src/Mod/PartDesign/App/FeatureTransformed.cpp | 8 ++ .../TestTopologicalNamingProblem.py | 99 ++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index 17856bd8df..5f3dbcce7f 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -273,10 +273,18 @@ App::DocumentObjectExecReturn *Transformed::execute() if (fuseShape.isNull() && cutShape.isNull()) return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Shape of additive/subtractive feature is empty")); gp_Trsf trsf = feature->getLocation().Transformation().Multiplied(trsfInv); +#ifdef FC_USE_TNP_FIX + if (!fuseShape.isNull()) + fuseShape = fuseShape.makeElementTransform(trsf); + if (!cutShape.isNull()) + cutShape = cutShape.makeElementTransform(trsf); +#else if (!fuseShape.isNull()) fuseShape = fuseShape.makeTransform(trsf); if (!cutShape.isNull()) cutShape = cutShape.makeTransform(trsf); + +#endif } else { return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Only additive and subtractive features can be transformed")); diff --git a/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py b/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py index 22ed6d4f98..f31232d5bc 100644 --- a/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py +++ b/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py @@ -532,6 +532,101 @@ class TestTopologicalNamingProblem(unittest.TestCase): def testPartDesignElementMapSubHelix(self): pass # TODO + def testPartDesignElementMapChamfer(self): + """ Test Chamfer ( and FeatureDressup )""" + # Arrange + body = self.Doc.addObject('PartDesign::Body', 'Body') + box = self.Doc.addObject('PartDesign::AdditiveBox', 'Box') + if body.Shape.ElementMapVersion == "": # Skip without element maps. + return + chamfer = self.Doc.addObject('PartDesign::Chamfer', 'Chamfer') + chamfer.Base = (box, ['Edge1', + 'Edge2', + 'Edge3', + 'Edge4', + 'Edge5', + 'Edge6', + 'Edge7', + 'Edge8', + 'Edge9', + 'Edge10', + 'Edge11', + 'Edge12', + ]) + chamfer.Size = 1 + chamfer.UseAllEdges = True + # Act / Assert + body.addObject(box) + body.addObject(chamfer) + self.Doc.recompute() + reverseMap = body.Shape.childShapes()[0].ElementReverseMap + faces = [name for name in reverseMap.keys() if name.startswith("Face")] + edges = [name for name in reverseMap.keys() if name.startswith("Edge")] + vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] + self.assertEqual(len(body.Shape.childShapes()), 1) + self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 98) + self.assertEqual(len(reverseMap),98) + self.assertEqual(len(faces),26) # 6 Faces become 26 ( +8 + 2*6 ) + self.assertEqual(len(edges),48) # 12 Edges become 48 + self.assertEqual(len(vertexes),24) # 8 Vertices become 24 + def testPartDesignElementMapFillet(self): + """ Test Fillet ( and FeatureDressup )""" + # Arrange + body = self.Doc.addObject('PartDesign::Body', 'Body') + box = self.Doc.addObject('PartDesign::AdditiveBox', 'Box') + if body.Shape.ElementMapVersion == "": # Skip without element maps. + return + fillet = self.Doc.addObject('PartDesign::Fillet', 'Fillet') + fillet.Base = (box, ['Edge1', + 'Edge2', + 'Edge3', + 'Edge4', + 'Edge5', + 'Edge6', + 'Edge7', + 'Edge8', + 'Edge9', + 'Edge10', + 'Edge11', + 'Edge12', + ]) + # Act / Assert + body.addObject(box) + body.addObject(fillet) + self.Doc.recompute() + reverseMap = body.Shape.childShapes()[0].ElementReverseMap + faces = [name for name in reverseMap.keys() if name.startswith("Face")] + edges = [name for name in reverseMap.keys() if name.startswith("Edge")] + vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] + self.assertEqual(len(body.Shape.childShapes()), 1) + self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 106) + self.assertEqual(len(reverseMap),106) + self.assertEqual(len(faces),26) # 6 Faces become 26 ( +8 + 2*6 ) + self.assertEqual(len(edges),56) # 12 Edges become 56 Why? + self.assertEqual(len(vertexes),24) # 8 Vertices become 24 + + def testPartDesignElementMapTransform(self): + # Arrange + body = self.Doc.addObject('PartDesign::Body', 'Body') + box = self.Doc.addObject('PartDesign::AdditiveBox', 'Box') + if body.Shape.ElementMapVersion == "": # Skip without element maps. + return + multitransform = self.Doc.addObject('PartDesign::MultiTransform', 'MultiTransform') + scaled = self.Doc.addObject('PartDesign::Scaled', 'Scaled') + scaled.Factor = 2 + scaled.Occurrences = 2 + multitransform.Transformations = scaled + multitransform.Shape = box.Shape + + # Act / Assert + self.Doc.recompute() + body.addObject(box) + body.addObject(multitransform) + self.assertEqual(len(body.Shape.childShapes()), 0) + self.Doc.recompute() + self.assertEqual(len(body.Shape.childShapes()), 1) + self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26) + def testSketchElementMap(self): body = self.Doc.addObject('PartDesign::Body', 'Body') sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch') @@ -543,7 +638,7 @@ class TestTopologicalNamingProblem(unittest.TestCase): pad.Profile = sketch body.addObject(pad) self.Doc.recompute() - if not hasattr(body,"ElementMapVersion"): # Skip without element maps. + if body.Shape.ElementMapVersion == "": # Skip without element maps. return # Assert self.assertEqual(sketch.Shape.ElementMapSize, 12) @@ -562,7 +657,7 @@ class TestTopologicalNamingProblem(unittest.TestCase): pad = self.Doc.addObject('PartDesign::Pad', 'Pad') pad.Profile = plane self.Doc.recompute() - if not hasattr(pad,"ElementMapVersion"): # Skip without element maps. + if pad.Shape.ElementMapVersion == "": # Skip without element maps. return # Assert self.assertEqual(plane.Shape.ElementMapSize, 0)