From ae46ea5e7bbb762f4e5b8eed3119deff1ca74fca Mon Sep 17 00:00:00 2001 From: bgbsww Date: Tue, 30 Jul 2024 08:34:34 -0400 Subject: [PATCH 1/6] Toponaming: Refactor refine to its own FeatureRefine class --- src/Mod/PartDesign/App/AppPartDesign.cpp | 2 + src/Mod/PartDesign/App/CMakeLists.txt | 2 + src/Mod/PartDesign/App/FeatureAddSub.cpp | 18 +--- src/Mod/PartDesign/App/FeatureAddSub.h | 6 +- src/Mod/PartDesign/App/FeatureBoolean.cpp | 25 ------ src/Mod/PartDesign/App/FeatureBoolean.h | 6 +- src/Mod/PartDesign/App/FeatureRefine.cpp | 85 +++++++++++++++++++ src/Mod/PartDesign/App/FeatureRefine.h | 51 +++++++++++ src/Mod/PartDesign/App/FeatureTransformed.cpp | 22 +---- src/Mod/PartDesign/App/FeatureTransformed.h | 6 +- src/Mod/PartDesign/App/ShapeBinder.cpp | 4 - src/Mod/PartDesign/App/ShapeBinder.h | 3 +- .../PartDesignTests/TestInvoluteGear.py | 4 +- .../PartDesignTests/TestMultiTransform.py | 55 ++++++------ .../TestTopologicalNamingProblem.py | 6 +- 15 files changed, 185 insertions(+), 110 deletions(-) create mode 100644 src/Mod/PartDesign/App/FeatureRefine.cpp create mode 100644 src/Mod/PartDesign/App/FeatureRefine.h diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp b/src/Mod/PartDesign/App/AppPartDesign.cpp index c9118aa464..92f28e9fdf 100644 --- a/src/Mod/PartDesign/App/AppPartDesign.cpp +++ b/src/Mod/PartDesign/App/AppPartDesign.cpp @@ -88,6 +88,8 @@ PyMOD_INIT_FUNC(_PartDesign) // clang-format off PartDesign::Feature ::init(); PartDesign::FeaturePython ::init(); + PartDesign::FeatureRefine ::init(); + PartDesign::FeatureRefinePython ::init(); PartDesign::Solid ::init(); PartDesign::FeatureAddSub ::init(); PartDesign::FeatureAddSubPython ::init(); diff --git a/src/Mod/PartDesign/App/CMakeLists.txt b/src/Mod/PartDesign/App/CMakeLists.txt index d10d251f51..04cd4fb8b8 100644 --- a/src/Mod/PartDesign/App/CMakeLists.txt +++ b/src/Mod/PartDesign/App/CMakeLists.txt @@ -94,6 +94,8 @@ SET(FeaturesSketchBased_SRCS FeatureRevolution.h FeatureGroove.cpp FeatureGroove.h + FeatureRefine.cpp + FeatureRefine.h FeatureAddSub.cpp FeatureAddSub.h FeatureHole.h diff --git a/src/Mod/PartDesign/App/FeatureAddSub.cpp b/src/Mod/PartDesign/App/FeatureAddSub.cpp index ec5034e228..9603d6d4b3 100644 --- a/src/Mod/PartDesign/App/FeatureAddSub.cpp +++ b/src/Mod/PartDesign/App/FeatureAddSub.cpp @@ -40,16 +40,11 @@ using namespace PartDesign; namespace PartDesign { -PROPERTY_SOURCE(PartDesign::FeatureAddSub, PartDesign::Feature) +PROPERTY_SOURCE(PartDesign::FeatureAddSub, PartDesign::FeatureRefine) FeatureAddSub::FeatureAddSub() { ADD_PROPERTY(AddSubShape,(TopoDS_Shape())); - ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after adding/subtracting"); - //init Refine property - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); - this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } FeatureAddSub::Type FeatureAddSub::getAddSubType() @@ -64,17 +59,6 @@ short FeatureAddSub::mustExecute() const return PartDesign::Feature::mustExecute(); } - -TopoShape FeatureAddSub::refineShapeIfActive(const TopoShape& oldShape) const -{ - if (this->Refine.getValue()) { - TopoShape shape(oldShape); - // this->fixShape(shape); // Todo: Not clear that this is required - return shape.makeElementRefine(); - } - return oldShape; -} - void FeatureAddSub::getAddSubShape(Part::TopoShape &addShape, Part::TopoShape &subShape) { if (addSubType == Additive) diff --git a/src/Mod/PartDesign/App/FeatureAddSub.h b/src/Mod/PartDesign/App/FeatureAddSub.h index 30864a5f41..247950efdd 100644 --- a/src/Mod/PartDesign/App/FeatureAddSub.h +++ b/src/Mod/PartDesign/App/FeatureAddSub.h @@ -24,13 +24,13 @@ #ifndef PARTDESIGN_FeatureAdditive_H #define PARTDESIGN_FeatureAdditive_H -#include "Feature.h" +#include "FeatureRefine.h" /// Base class of all additive features in PartDesign namespace PartDesign { -class PartDesignExport FeatureAddSub : public PartDesign::Feature +class PartDesignExport FeatureAddSub : public PartDesign::FeatureRefine { PROPERTY_HEADER_WITH_OVERRIDE(PartDesign::FeatureAddSub); @@ -49,12 +49,10 @@ public: virtual void getAddSubShape(Part::TopoShape &addShape, Part::TopoShape &subShape); Part::PropertyPartShape AddSubShape; - App::PropertyBool Refine; protected: Type addSubType{Additive}; - TopoShape refineShapeIfActive(const TopoShape&) const; }; using FeatureAddSubPython = App::FeaturePythonT; diff --git a/src/Mod/PartDesign/App/FeatureBoolean.cpp b/src/Mod/PartDesign/App/FeatureBoolean.cpp index 2a0de63fbf..98a7795fd0 100644 --- a/src/Mod/PartDesign/App/FeatureBoolean.cpp +++ b/src/Mod/PartDesign/App/FeatureBoolean.cpp @@ -53,10 +53,6 @@ Boolean::Boolean() ADD_PROPERTY(Type,((long)0)); Type.setEnums(TypeEnums); - ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after adding/subtracting"); - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); - this->Refine.setValue(hGrp->GetBool("RefineModel", true)); ADD_PROPERTY_TYPE(UsePlacement,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Apply the placement of the second ( tool ) object"); this->UsePlacement.setValue(false); @@ -188,25 +184,4 @@ void Boolean::handleChangedPropertyName(Base::XMLReader &reader, const char * Ty } } - -// FIXME: This method ( and the Refine property it depends on ) is redundant with the exact same -// thing in FeatureAddSub, but cannot reasonably be moved up an inheritance level to Feature as -// there are inheritors like FeatureBox for which a refine Property does not make sense. A -// solution like moving Refine and refineShapeIfActive to a new FeatureRefine class that sits -// between Feature and FeatureBoolean / FeatureAddSub is a possibility, or maybe [ew!] hiding the -// property in Feature and only enabling it in the places it is relevant. -TopoShape Boolean::refineShapeIfActive(const TopoShape& oldShape) const -{ - if (this->Refine.getValue()) { - try { - return oldShape.makeElementRefine(); - } - catch (Standard_Failure&) { - return oldShape; - } - } - - return oldShape; -} - } diff --git a/src/Mod/PartDesign/App/FeatureBoolean.h b/src/Mod/PartDesign/App/FeatureBoolean.h index 2810574605..5fcffdac2b 100644 --- a/src/Mod/PartDesign/App/FeatureBoolean.h +++ b/src/Mod/PartDesign/App/FeatureBoolean.h @@ -26,7 +26,7 @@ #include #include -#include "Feature.h" +#include "FeatureRefine.h" namespace PartDesign @@ -36,7 +36,7 @@ namespace PartDesign * Abstract superclass of all features that are created by transformation of another feature * Transformations are translation, rotation and mirroring */ -class PartDesignExport Boolean : public PartDesign::Feature, public App::GeoFeatureGroupExtension +class PartDesignExport Boolean : public PartDesign::FeatureRefine, public App::GeoFeatureGroupExtension { PROPERTY_HEADER_WITH_EXTENSIONS(PartDesign::Boolean); @@ -46,7 +46,6 @@ public: /// The type of the boolean operation App::PropertyEnumeration Type; - App::PropertyBool Refine; App::PropertyBool UsePlacement; /** @name methods override feature */ @@ -63,7 +62,6 @@ public: protected: void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override; - TopoShape refineShapeIfActive(const TopoShape&) const; private: diff --git a/src/Mod/PartDesign/App/FeatureRefine.cpp b/src/Mod/PartDesign/App/FeatureRefine.cpp new file mode 100644 index 0000000000..c023860193 --- /dev/null +++ b/src/Mod/PartDesign/App/FeatureRefine.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (c) 2024 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include +#include +#include +#include + +#include "FeatureRefine.h" +#include "FeaturePy.h" + + +using namespace PartDesign; + +namespace PartDesign +{ +PROPERTY_SOURCE(PartDesign::FeatureRefine, PartDesign::Feature) + +FeatureRefine::FeatureRefine() +{ + ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after operations"); + //init Refine property + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); + this->Refine.setValue(hGrp->GetBool("RefineModel", true)); +} + +TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape) const +{ + if (this->Refine.getValue()) { + TopoShape shape(oldShape); + // Potentially also "fixShape" to repair it ( as a workaround to OCCT bugs? ) + return shape.makeElementRefine(); + } + return oldShape; +} + +} + + +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(PartDesign::FeatureRefinePython, PartDesign::FeatureRefine) +template<> const char* PartDesign::FeatureRefinePython::getViewProviderName() const { + return "PartDesignGui::ViewProviderPython"; +} +template<> PyObject* PartDesign::FeatureRefinePython::getPyObject() { + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new FeaturePythonPyT(this),true); + } + return Py::new_reference_to(PythonObject); +} +/// @endcond + +// explicit template instantiation +template class PartDesignExport FeaturePythonT; +} + + diff --git a/src/Mod/PartDesign/App/FeatureRefine.h b/src/Mod/PartDesign/App/FeatureRefine.h new file mode 100644 index 0000000000..49da26cc1c --- /dev/null +++ b/src/Mod/PartDesign/App/FeatureRefine.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (c) 2024 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef PARTDESIGN_FeatureRefine_H +#define PARTDESIGN_FeatureRefine_H + +#include "Feature.h" + +/// Base class of all features that can be refined PartDesign +namespace PartDesign +{ + +class PartDesignExport FeatureRefine : public PartDesign::Feature +{ + PROPERTY_HEADER_WITH_OVERRIDE(PartDesign::FeatureRefine); + +public: + FeatureRefine(); + + App::PropertyBool Refine; + +protected: + TopoShape refineShapeIfActive(const TopoShape&) const; +}; + +using FeatureRefinePython = App::FeaturePythonT; + +} //namespace PartDesign + + +#endif // PARTDESIGN_FeatureRefine_H diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index df1c3f2954..691b5a203e 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -58,7 +58,7 @@ using namespace PartDesign; namespace PartDesign { -PROPERTY_SOURCE(PartDesign::Transformed, PartDesign::Feature) +PROPERTY_SOURCE(PartDesign::Transformed, PartDesign::FeatureRefine) std::array transformModeEnums = {"Transform tool shapes", "Transform body", @@ -72,17 +72,6 @@ Transformed::Transformed() ADD_PROPERTY(TransformMode, (static_cast(Mode::TransformToolShapes))); TransformMode.setEnums(transformModeEnums.data()); - - ADD_PROPERTY_TYPE(Refine, - (0), - "Part Design", - (App::PropertyType)(App::Prop_None), - "Refine shape (clean up redundant edges) after adding/subtracting"); - - //init Refine property - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); - this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } void Transformed::positionBySupport() @@ -355,15 +344,6 @@ App::DocumentObjectExecReturn* Transformed::execute() return App::DocumentObject::StdReturn; } - -TopoShape Transformed::refineShapeIfActive(const TopoShape& oldShape) const -{ - if (this->Refine.getValue()) { - return oldShape.makeElementRefine(); - } - return oldShape; -} - TopoDS_Shape Transformed::getRemainingSolids(const TopoDS_Shape& shape) { BRep_Builder builder; diff --git a/src/Mod/PartDesign/App/FeatureTransformed.h b/src/Mod/PartDesign/App/FeatureTransformed.h index 81ac61786f..3fe27e8851 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.h +++ b/src/Mod/PartDesign/App/FeatureTransformed.h @@ -27,7 +27,7 @@ #include #include -#include "Feature.h" +#include "FeatureRefine.h" namespace PartDesign @@ -37,7 +37,7 @@ namespace PartDesign * Abstract superclass of all features that are created by transformation of another feature * Transformations are translation, rotation and mirroring */ -class PartDesignExport Transformed: public PartDesign::Feature +class PartDesignExport Transformed: public PartDesign::FeatureRefine { PROPERTY_HEADER_WITH_OVERRIDE(PartDesign::Transformed); @@ -106,8 +106,6 @@ protected: App::Property* prop) override; virtual void positionBySupport(); - TopoShape refineShapeIfActive(const TopoShape&) const; - TopoDS_Shape refineShapeIfActive(const TopoDS_Shape&) const; static TopoDS_Shape getRemainingSolids(const TopoDS_Shape&); private: diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 8908df80ec..20bd8c7471 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -384,10 +384,6 @@ SubShapeBinder::~SubShapeBinder() { void SubShapeBinder::setupObject() { _Version.setValue(2); checkPropertyStatus(); - - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); - this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } App::DocumentObject* SubShapeBinder::getSubObject(const char* subname, PyObject** pyObj, diff --git a/src/Mod/PartDesign/App/ShapeBinder.h b/src/Mod/PartDesign/App/ShapeBinder.h index a32841b3bd..29d2342f39 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.h +++ b/src/Mod/PartDesign/App/ShapeBinder.h @@ -29,6 +29,7 @@ #include #include #include +#include "FeatureRefine.h" namespace PartDesign { @@ -41,7 +42,7 @@ namespace PartDesign */ // TODO Add better documentation (2015-09-11, Fat-Zer) -class PartDesignExport ShapeBinder : public Part::Feature +class PartDesignExport ShapeBinder : public PartDesign::FeatureRefine { PROPERTY_HEADER_WITH_OVERRIDE(PartDesign::ShapeBinder); diff --git a/src/Mod/PartDesign/PartDesignTests/TestInvoluteGear.py b/src/Mod/PartDesign/PartDesignTests/TestInvoluteGear.py index c3e75193af..ba83668bfd 100644 --- a/src/Mod/PartDesign/PartDesignTests/TestInvoluteGear.py +++ b/src/Mod/PartDesign/PartDesignTests/TestInvoluteGear.py @@ -26,7 +26,7 @@ from math import pi, tan, cos, acos import FreeCAD Quantity = FreeCAD.Units.Quantity # FIXME from FreeCAD.Units import Quantity doesn't work from FreeCAD import Vector -from Part import makeCircle, Precision +from Part import makeCircle, Precision, Solid import InvoluteGearFeature FIXTURE_PATH = pathlib.Path(__file__).parent / "Fixtures" @@ -263,7 +263,7 @@ class TestInvoluteGear(unittest.TestCase): pocket.Reversed = True # need to "pocket upwards" into the cylinder pocket.Type = 'ThroughAll' self.assertSuccessfulRecompute() - self.assertSolid(pocket.Shape) + self.assertSolid(Solid(pocket.Shape)) # Can be a compound, make that into a Solid if needed. def testRecomputeExternalGearFromV020(self): FreeCAD.closeDocument(self.Doc.Name) # this was created in setUp(self) diff --git a/src/Mod/PartDesign/PartDesignTests/TestMultiTransform.py b/src/Mod/PartDesign/PartDesignTests/TestMultiTransform.py index 272f708284..fa94affb15 100644 --- a/src/Mod/PartDesign/PartDesignTests/TestMultiTransform.py +++ b/src/Mod/PartDesign/PartDesignTests/TestMultiTransform.py @@ -20,6 +20,7 @@ #*************************************************************************** import unittest +import math import FreeCAD import TestSketcherApp @@ -72,26 +73,14 @@ class TestMultiTransform(unittest.TestCase): # Make first offset cube Pad PadSketch = Doc.addObject('Sketcher::SketchObject', 'SketchPad') Body.addObject(PadSketch) - TestSketcherApp.CreateRectangleSketch(PadSketch, (0, 0), (10, 10)) + xw = yw = zw = 10 + TestSketcherApp.CreateRectangleSketch(PadSketch, (0, 0), (xw, yw)) Doc.recompute() Pad = Doc.addObject("PartDesign::Pad", "Pad") Body.addObject(Pad) Pad.Profile = PadSketch - Pad.Length = 10 + Pad.Length = zw Doc.recompute() - - PadSketch2 = Doc.addObject('Sketcher::SketchObject', 'SketchPad') - PadSketch2.AttachmentSupport = (Pad, ('Face6',)) - Body.addObject(PadSketch2) - TestSketcherApp.CreateRectangleSketch(PadSketch, (9, 9), (1, 1)) - Doc.recompute() - Pad2 = Doc.addObject("PartDesign::Pad", "Pad2") - Body.addObject(Pad2) - Pad2.Profile = PadSketch2 - Pad2.Length = 10 - Doc.recompute() - - MultiTransform = Doc.addObject("PartDesign::MultiTransform","MultiTransform") Doc.recompute() MultiTransform.Originals = [Pad] @@ -100,27 +89,43 @@ class TestMultiTransform(unittest.TestCase): Doc.recompute() Mirrored = Doc.addObject("PartDesign::Mirrored","Mirrored") Mirrored.MirrorPlane = (Doc.getObject('XY_Plane'), ['']) + Mirrored.Refine = True Body.addObject(Mirrored) Mirrored2 = Doc.addObject("PartDesign::Mirrored","Mirrored") Mirrored2.MirrorPlane = (Doc.getObject('XZ_Plane'), [""]) + Mirrored2.Refine = True Body.addObject(Mirrored2) MultiTransform.Transformations = [Mirrored,Mirrored2] + MultiTransform.Refine = True Doc.recompute() Fillet = Doc.addObject("PartDesign::Fillet","Fillet") - Fillet.Base = (MultiTransform, ['Face'+str(i+1) for i in range(2)]) - Fillet.Radius = 3 + Fillet.Base = (MultiTransform, [ "Face1", "Face2" ]) + radius = 3 + Fillet.Radius = radius Body.addObject(Fillet) - # Add a fillet here. - # Now do that copy thing... + # Broken out calculation of volume with two adjacent filleted faces = 5 long edges, 2 short edges, + # 2 fully rounded corners and 4 corners with only 2 fillets meeting + cubeVolume = xw * yw * zw * 2 * 2 # Mirrored and mirrored again. + filletOuter = radius ** 2 * ( xw - radius * 2 ) # Volume of the rect prisms the fillets are in. + filletCorner = radius ** 3 # Volume of the rect prism corners + qRoundArea = math.pi * radius ** 2 / 4 # Area of the quarter round fillet profile + filletPrism = qRoundArea * ( xw - radius * 2 ) # Volume of fillet minus corners + fillet3Corner = math.pi * radius ** 3 * 4 / 3 / 8 # Volume of a fully rounded corner ( Sphere / 8 ) + fillet2Corner = radius ** 2 * 2 # Volume of corner with two fillets intersecting + fillet1Corner = math.pi * radius ** 2 / 4 * radius # Volume of corner with stopped single fillet + extraFillet = qRoundArea * xw # extra fillet in a mirrored direction + filletOuterExt = radius ** 2 * 10 # extra rect prim surrounding fillet + rectBox = cubeVolume - (4 + 3) * (filletOuter + filletCorner ) - 5 * filletOuterExt + filletCorner + fillets = ( 4 + 3 ) * filletPrism + 5 * extraFillet + fillet3Corner * 2 + fillet2Corner * 4 + fillet1Corner * 0 + volume = rectBox + fillets + # Act Link = Doc.addObject('App::Link','Link001') Link.setLink(Doc.Body) Link.Label='Body001' - # Act - # There are properties on those objects with values - # Link.addProperty("App::PropertyInteger","test2","Table2") + Doc.recompute() # Assert - self.assertAlmostEqual(Body.Shape.Volume, 990) - self.assertAlmostEqual(Link.Shape.Volume, 990) + self.assertAlmostEqual(abs(Body.Shape.Volume), volume, 6) + self.assertAlmostEqual(abs(Link.Shape.Volume), volume, 6) def testMultiTransformBody(self): pass @@ -132,5 +137,5 @@ class TestMultiTransform(unittest.TestCase): def tearDown(self): #closing doc FreeCAD.closeDocument("PartDesignTestMultiTransform") - #print ("omit closing document for debugging") + # print ("omit closing document for debugging") diff --git a/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py b/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py index c1a0f34328..098ee81874 100644 --- a/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py +++ b/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py @@ -785,6 +785,7 @@ class TestTopologicalNamingProblem(unittest.TestCase): body = self.Doc.addObject("PartDesign::Body", "Body") box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") body.addObject(box) + self.Doc.recompute() sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") sketch.AttachmentSupport = (box, "Face6") sketch.MapMode = "FlatFace" @@ -803,10 +804,9 @@ class TestTopologicalNamingProblem(unittest.TestCase): self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 32) self.assertEqual(body.Shape.ElementMapSize, 32) self.assertEqual(sketch.Shape.ElementMapSize, 2) - self.assertEqual(hole.Shape.ElementMapSize, 32) - # self.assertNotEqual(hole.Shape.ElementReverseMap['Vertex1'],"Vertex1") # NewName, not OldName + self.assertNotEqual(body.Shape.ElementReverseMap['Vertex1'],"Vertex1") # NewName, not OldName self.assertEqual( - self.countFacesEdgesVertexes(hole.Shape.ElementReverseMap), (7, 15, 10) + self.countFacesEdgesVertexes(body.Shape.ElementReverseMap), (7, 15, 10) ) volume = 1000 - 10 * math.pi * 3 * 3 self.assertAlmostEqual(hole.Shape.Volume, volume) From b3818aa5839327ceaccd05430995f880e6a9ff65 Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Sat, 25 Jan 2025 04:25:41 -0600 Subject: [PATCH 2/6] PD: Migrate onlyHasToRefine This was a later addition that got missed when merging. --- src/Mod/PartDesign/App/FeatureAddSub.h | 5 ---- src/Mod/PartDesign/App/FeatureRefine.cpp | 34 +++++++++++++++++++++--- src/Mod/PartDesign/App/FeatureRefine.h | 12 ++++++++- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureAddSub.h b/src/Mod/PartDesign/App/FeatureAddSub.h index b84e79662a..fc5cc7e1cc 100644 --- a/src/Mod/PartDesign/App/FeatureAddSub.h +++ b/src/Mod/PartDesign/App/FeatureAddSub.h @@ -40,11 +40,6 @@ public: Subtractive }; - enum class RefineErrorPolicy { - Raise = 0, - Warn - }; - FeatureAddSub(); Type getAddSubType(); diff --git a/src/Mod/PartDesign/App/FeatureRefine.cpp b/src/Mod/PartDesign/App/FeatureRefine.cpp index c023860193..730d720788 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.cpp +++ b/src/Mod/PartDesign/App/FeatureRefine.cpp @@ -50,12 +50,40 @@ FeatureRefine::FeatureRefine() this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } -TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape) const +bool FeatureRefine::onlyHasToRefine() const +{ + if( ! Refine.isTouched()){ + return false; + } + if (rawShape.isNull()){ + return false; + } + std::vector propList; + getPropertyList(propList); + for (auto prop : propList){ + if (prop != &Refine + /*&& prop != &SuppressedShape*/ + && prop->isTouched()){ + return false; + } + } + return true; +} + +TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError) const { if (this->Refine.getValue()) { TopoShape shape(oldShape); - // Potentially also "fixShape" to repair it ( as a workaround to OCCT bugs? ) - return shape.makeElementRefine(); + try { + return shape.makeElementRefine(); + } + catch (Standard_Failure& err) { + if(onError == RefineErrorPolicy::Warn){ + Base::Console().Warning((std::string("Refine failed: ") + err.GetMessageString()).c_str()); + } else { + throw; + } + } } return oldShape; } diff --git a/src/Mod/PartDesign/App/FeatureRefine.h b/src/Mod/PartDesign/App/FeatureRefine.h index 49da26cc1c..a29fc1ee09 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.h +++ b/src/Mod/PartDesign/App/FeatureRefine.h @@ -35,12 +35,22 @@ class PartDesignExport FeatureRefine : public PartDesign::Feature PROPERTY_HEADER_WITH_OVERRIDE(PartDesign::FeatureRefine); public: + + enum class RefineErrorPolicy { + Raise = 0, + Warn + }; + FeatureRefine(); App::PropertyBool Refine; protected: - TopoShape refineShapeIfActive(const TopoShape&) const; + //store the shape before refinement + TopoShape rawShape; + + bool onlyHasToRefine() const; + TopoShape refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError = RefineErrorPolicy::Raise) const; }; using FeatureRefinePython = App::FeaturePythonT; From a56756d81467c41811306797d32299106dca6d04 Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Fri, 7 Feb 2025 21:44:43 -0600 Subject: [PATCH 3/6] PD: Add onlyHaveRefined() to FeatureRefine --- src/Mod/PartDesign/App/FeatureChamfer.cpp | 6 +-- src/Mod/PartDesign/App/FeatureExtrude.cpp | 7 +-- src/Mod/PartDesign/App/FeatureFillet.cpp | 7 +-- src/Mod/PartDesign/App/FeatureGroove.cpp | 6 +-- src/Mod/PartDesign/App/FeatureHelix.cpp | 7 +-- src/Mod/PartDesign/App/FeatureLoft.cpp | 6 +-- src/Mod/PartDesign/App/FeaturePipe.cpp | 6 +-- src/Mod/PartDesign/App/FeaturePrimitive.cpp | 6 +-- src/Mod/PartDesign/App/FeatureRefine.cpp | 52 ++++++++++++-------- src/Mod/PartDesign/App/FeatureRefine.h | 42 ++++++++-------- src/Mod/PartDesign/App/FeatureRevolution.cpp | 7 +-- src/Mod/PartDesign/App/FeatureThickness.cpp | 6 +-- 12 files changed, 67 insertions(+), 91 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureChamfer.cpp b/src/Mod/PartDesign/App/FeatureChamfer.cpp index 406e094d4a..9a0bfab347 100644 --- a/src/Mod/PartDesign/App/FeatureChamfer.cpp +++ b/src/Mod/PartDesign/App/FeatureChamfer.cpp @@ -104,11 +104,7 @@ short Chamfer::mustExecute() const App::DocumentObjectExecReturn *Chamfer::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } // NOTE: Normally the Base property and the BaseFeature property should point to the same object. // The only difference is that the Base property also stores the edges that are to be chamfered diff --git a/src/Mod/PartDesign/App/FeatureExtrude.cpp b/src/Mod/PartDesign/App/FeatureExtrude.cpp index e2deb3f82b..73659cc6bd 100644 --- a/src/Mod/PartDesign/App/FeatureExtrude.cpp +++ b/src/Mod/PartDesign/App/FeatureExtrude.cpp @@ -468,11 +468,8 @@ void FeatureExtrude::setupObject() App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions options) { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } + bool makeface = options.testFlag(ExtrudeOption::MakeFace); bool fuse = options.testFlag(ExtrudeOption::MakeFuse); diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp b/src/Mod/PartDesign/App/FeatureFillet.cpp index 9524cd6bb6..25d60c2778 100644 --- a/src/Mod/PartDesign/App/FeatureFillet.cpp +++ b/src/Mod/PartDesign/App/FeatureFillet.cpp @@ -65,11 +65,8 @@ short Fillet::mustExecute() const App::DocumentObjectExecReturn *Fillet::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } + Part::TopoShape baseShape; try { diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index 24e3fa6e57..66f27fdcd3 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -81,11 +81,7 @@ short Groove::mustExecute() const App::DocumentObjectExecReturn *Groove::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } // Validate parameters double angle = Angle.getValue(); diff --git a/src/Mod/PartDesign/App/FeatureHelix.cpp b/src/Mod/PartDesign/App/FeatureHelix.cpp index 62c70e5efa..10e4d22f0c 100644 --- a/src/Mod/PartDesign/App/FeatureHelix.cpp +++ b/src/Mod/PartDesign/App/FeatureHelix.cpp @@ -126,12 +126,7 @@ short Helix::mustExecute() const App::DocumentObjectExecReturn* Helix::execute() { - - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape, RefineErrorPolicy::Warn); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } // Validate and normalize parameters HelixMode mode = static_cast(Mode.getValue()); diff --git a/src/Mod/PartDesign/App/FeatureLoft.cpp b/src/Mod/PartDesign/App/FeatureLoft.cpp index 70a7de5f19..8b53808ea5 100644 --- a/src/Mod/PartDesign/App/FeatureLoft.cpp +++ b/src/Mod/PartDesign/App/FeatureLoft.cpp @@ -112,11 +112,7 @@ Loft::getSectionShape(const char *name, App::DocumentObjectExecReturn *Loft::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } std::vector wires; try { diff --git a/src/Mod/PartDesign/App/FeaturePipe.cpp b/src/Mod/PartDesign/App/FeaturePipe.cpp index 6d7642f31e..371bee53d4 100644 --- a/src/Mod/PartDesign/App/FeaturePipe.cpp +++ b/src/Mod/PartDesign/App/FeaturePipe.cpp @@ -104,11 +104,7 @@ short Pipe::mustExecute() const App::DocumentObjectExecReturn *Pipe::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } auto getSectionShape = [](App::DocumentObject* feature, const std::vector& subs) -> TopoDS_Shape { diff --git a/src/Mod/PartDesign/App/FeaturePrimitive.cpp b/src/Mod/PartDesign/App/FeaturePrimitive.cpp index e7a52f76b2..21cc034d8d 100644 --- a/src/Mod/PartDesign/App/FeaturePrimitive.cpp +++ b/src/Mod/PartDesign/App/FeaturePrimitive.cpp @@ -68,11 +68,7 @@ FeaturePrimitive::FeaturePrimitive() App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& primitive) { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } try { //transform the primitive in the correct coordinance diff --git a/src/Mod/PartDesign/App/FeatureRefine.cpp b/src/Mod/PartDesign/App/FeatureRefine.cpp index 730d720788..3199fc03fe 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.cpp +++ b/src/Mod/PartDesign/App/FeatureRefine.cpp @@ -1,23 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2024 * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * ***************************************************************************/ @@ -70,6 +71,17 @@ bool FeatureRefine::onlyHasToRefine() const return true; } + +bool FeatureRefine::onlyHaveRefined() +{ + if (onlyHasToRefine()){ + TopoShape result = refineShapeIfActive(rawShape); + Shape.setValue(result); + return true; + } + return false; +} + TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError) const { if (this->Refine.getValue()) { diff --git a/src/Mod/PartDesign/App/FeatureRefine.h b/src/Mod/PartDesign/App/FeatureRefine.h index a29fc1ee09..73ee4fc353 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.h +++ b/src/Mod/PartDesign/App/FeatureRefine.h @@ -1,23 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2024 * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * ***************************************************************************/ @@ -50,6 +51,7 @@ protected: TopoShape rawShape; bool onlyHasToRefine() const; + bool onlyHaveRefined(); TopoShape refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError = RefineErrorPolicy::Raise) const; }; diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index 0f9cca70cb..d60b1f6558 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -80,11 +80,8 @@ short Revolution::mustExecute() const App::DocumentObjectExecReturn* Revolution::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } + // Validate parameters // All angles are in radians unless explicitly stated diff --git a/src/Mod/PartDesign/App/FeatureThickness.cpp b/src/Mod/PartDesign/App/FeatureThickness.cpp index 002fcf0700..7be41c2ded 100644 --- a/src/Mod/PartDesign/App/FeatureThickness.cpp +++ b/src/Mod/PartDesign/App/FeatureThickness.cpp @@ -65,11 +65,7 @@ int16_t Thickness::mustExecute() const { } App::DocumentObjectExecReturn *Thickness::execute() { - if (onlyHasToRefine()){ - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return App::DocumentObject::StdReturn; - } + if (onlyHaveRefined()) { return App::DocumentObject::StdReturn; } // Base shape Part::TopoShape TopShape; From 23d98b8d0b1b5d3edbe62b15043ae2ca47032f19 Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Tue, 11 Feb 2025 20:56:41 -0600 Subject: [PATCH 4/6] PD: address FeatureRefine reviewer comments --- src/Mod/PartDesign/App/FeatureRefine.cpp | 72 ++++++++++++++---------- src/Mod/PartDesign/App/FeatureRefine.h | 17 ++++++ 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureRefine.cpp b/src/Mod/PartDesign/App/FeatureRefine.cpp index 3199fc03fe..6106129914 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.cpp +++ b/src/Mod/PartDesign/App/FeatureRefine.cpp @@ -24,7 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -44,27 +44,34 @@ PROPERTY_SOURCE(PartDesign::FeatureRefine, PartDesign::Feature) FeatureRefine::FeatureRefine() { - ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after operations"); - //init Refine property - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); + ADD_PROPERTY_TYPE(Refine, + (0), + "Part Design", + (App::PropertyType)(App::Prop_None), + "Refine shape (clean up redundant edges) after operations"); + // init Refine property + Base::Reference hGrp = App::GetApplication() + .GetUserParameter() + .GetGroup("BaseApp") + ->GetGroup("Preferences") + ->GetGroup("Mod/PartDesign"); this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } bool FeatureRefine::onlyHasToRefine() const { - if( ! Refine.isTouched()){ + if (!Refine.isTouched()) { return false; } - if (rawShape.isNull()){ + if (rawShape.isNull()) { return false; } std::vector propList; getPropertyList(propList); - for (auto prop : propList){ + for (auto prop : propList) { if (prop != &Refine /*&& prop != &SuppressedShape*/ - && prop->isTouched()){ + && prop->isTouched()) { return false; } } @@ -74,7 +81,7 @@ bool FeatureRefine::onlyHasToRefine() const bool FeatureRefine::onlyHaveRefined() { - if (onlyHasToRefine()){ + if (onlyHasToRefine()) { TopoShape result = refineShapeIfActive(rawShape); Shape.setValue(result); return true; @@ -82,37 +89,46 @@ bool FeatureRefine::onlyHaveRefined() return false; } -TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError) const +TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape, + const RefineErrorPolicy onError) const { - if (this->Refine.getValue()) { - TopoShape shape(oldShape); - try { - return shape.makeElementRefine(); + if (!this->Refine.getValue()) { + return oldShape; + } + TopoShape shape(oldShape); + try { + return shape.makeElementRefine(); + } + catch (Standard_Failure& err) { + if (onError == RefineErrorPolicy::Warn) { + Base::Console().Warning( + fmt::format("Refine failed: {}", err.GetMessageString()).c_str()); } - catch (Standard_Failure& err) { - if(onError == RefineErrorPolicy::Warn){ - Base::Console().Warning((std::string("Refine failed: ") + err.GetMessageString()).c_str()); - } else { - throw; - } + else { + throw; } } return oldShape; } -} +} // namespace PartDesign -namespace App { +namespace App +{ /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(PartDesign::FeatureRefinePython, PartDesign::FeatureRefine) -template<> const char* PartDesign::FeatureRefinePython::getViewProviderName() const { +template<> +const char* PartDesign::FeatureRefinePython::getViewProviderName() const +{ return "PartDesignGui::ViewProviderPython"; } -template<> PyObject* PartDesign::FeatureRefinePython::getPyObject() { +template<> +PyObject* PartDesign::FeatureRefinePython::getPyObject() +{ if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new FeaturePythonPyT(this),true); + PythonObject = Py::Object(new FeaturePythonPyT(this), true); } return Py::new_reference_to(PythonObject); } @@ -120,6 +136,4 @@ template<> PyObject* PartDesign::FeatureRefinePython::getPyObject() { // explicit template instantiation template class PartDesignExport FeaturePythonT; -} - - +} // namespace App diff --git a/src/Mod/PartDesign/App/FeatureRefine.h b/src/Mod/PartDesign/App/FeatureRefine.h index 73ee4fc353..a6f5229e12 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.h +++ b/src/Mod/PartDesign/App/FeatureRefine.h @@ -50,7 +50,24 @@ protected: //store the shape before refinement TopoShape rawShape; + /** + * Check to see if this feature can just execute the refine operation, or if a more complete + * calculation is necessary (e.g. if some other property has changed). See also + * `onlyHaveRefined()`, which actually *does* the refinement if this is true. + * + * @return true if only the refinement needs to be done, false if a recompute is necessary + */ bool onlyHasToRefine() const; + + /** + * Check if the feature *only* requires the refinement operation, and do that refinement if so. + * Typically called as the first operation in a subclass's `execute()` method to provide an + * early exit if no other parameters have been changed (so the base feature is still + * up-to-date). + * + * @return true if the refine was done and that was the only thing needed, or false if further + * computation is necessary. + */ bool onlyHaveRefined(); TopoShape refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError = RefineErrorPolicy::Raise) const; }; From a2cef23dbd2e85e64a733f870efdb089edf5af4e Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Sun, 16 Feb 2025 11:25:45 -0600 Subject: [PATCH 5/6] PD: Combine onlyHaveRefined and onlyHasToRefine Co-authored-by: Florian Foinant-Willig --- src/Mod/PartDesign/App/FeatureRefine.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureRefine.cpp b/src/Mod/PartDesign/App/FeatureRefine.cpp index 6106129914..b56e9c5ba5 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.cpp +++ b/src/Mod/PartDesign/App/FeatureRefine.cpp @@ -58,7 +58,7 @@ FeatureRefine::FeatureRefine() this->Refine.setValue(hGrp->GetBool("RefineModel", true)); } -bool FeatureRefine::onlyHasToRefine() const +bool FeatureRefine::onlyHaveRefined() { if (!Refine.isTouched()) { return false; @@ -75,20 +75,10 @@ bool FeatureRefine::onlyHasToRefine() const return false; } } + TopoShape result = refineShapeIfActive(rawShape); + Shape.setValue(result); return true; } - - -bool FeatureRefine::onlyHaveRefined() -{ - if (onlyHasToRefine()) { - TopoShape result = refineShapeIfActive(rawShape); - Shape.setValue(result); - return true; - } - return false; -} - TopoShape FeatureRefine::refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError) const { From c50cb07974b60dace88352d023b92520f4856ccf Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Sun, 16 Feb 2025 13:56:54 -0600 Subject: [PATCH 6/6] Update src/Mod/PartDesign/App/FeatureRefine.h Co-authored-by: Florian Foinant-Willig --- src/Mod/PartDesign/App/FeatureRefine.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureRefine.h b/src/Mod/PartDesign/App/FeatureRefine.h index a6f5229e12..52b790b13a 100644 --- a/src/Mod/PartDesign/App/FeatureRefine.h +++ b/src/Mod/PartDesign/App/FeatureRefine.h @@ -50,14 +50,6 @@ protected: //store the shape before refinement TopoShape rawShape; - /** - * Check to see if this feature can just execute the refine operation, or if a more complete - * calculation is necessary (e.g. if some other property has changed). See also - * `onlyHaveRefined()`, which actually *does* the refinement if this is true. - * - * @return true if only the refinement needs to be done, false if a recompute is necessary - */ - bool onlyHasToRefine() const; /** * Check if the feature *only* requires the refinement operation, and do that refinement if so.