Salome HOME
Issue #3222: 1d fillet
authorArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Sat, 25 Apr 2020 11:43:00 +0000 (14:43 +0300)
committerArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Sat, 25 Apr 2020 11:43:00 +0000 (14:43 +0300)
* Additional test cases for filleting several wires at once.
* Stabilize the sequence of fillet results.

src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Fillet1D.cpp
src/FeaturesPlugin/FeaturesPlugin_Fillet1D.h
src/FeaturesPlugin/Test/TestFillet1D_Vertices_2.py
src/FeaturesPlugin/Test/TestFillet1D_Vertices_3.py
src/FeaturesPlugin/Test/TestFillet1D_Vertices_9.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestFillet1D_Wire_5.py [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Fillet1D.cpp

index b75a1a17e4dc554b7fee696580911803c13965f4..761c6035048c54d477a1408c9c37df4ebf25fbe1 100644 (file)
@@ -670,8 +670,10 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestFillet1D_Vertices_6.py
                TestFillet1D_Vertices_7.py
                TestFillet1D_Vertices_8.py
+               TestFillet1D_Vertices_9.py
                TestFillet1D_Wire_1.py
                TestFillet1D_Wire_2.py
                TestFillet1D_Wire_3.py
                TestFillet1D_Wire_4.py
+               TestFillet1D_Wire_5.py
 )
index d62f6acf4a1dbc17090fedddeb9392d0ae2ddd65..ee83fad2092e7f8b89c527ad198b315dac2169ec 100644 (file)
@@ -47,24 +47,25 @@ void FeaturesPlugin_Fillet1D::initAttributes()
 
 void FeaturesPlugin_Fillet1D::execute()
 {
-  MapShapeSubs aWireVertices;
-  if (!baseShapes(aWireVertices))
+  ListOfShape aWires;
+  MapShapeSubs aVertices;
+  if (!baseShapes(aWires, aVertices))
     return;
 
   int aResultIndex = 0;
-  for (MapShapeSubs::iterator anIt = aWireVertices.begin(); anIt != aWireVertices.end(); ++anIt)
-    if (!performFillet(anIt->first, anIt->second, aResultIndex++))
+  for (ListOfShape::iterator anIt = aWires.begin(); anIt != aWires.end(); ++anIt)
+    if (!performFillet(*anIt, aVertices[*anIt], aResultIndex++))
       break;
   removeResults(aResultIndex);
 }
 
-bool FeaturesPlugin_Fillet1D::baseShapes(MapShapeSubs& theWireVertices)
+bool FeaturesPlugin_Fillet1D::baseShapes(ListOfShape& theWires, MapShapeSubs& theWireVertices)
 {
+  std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aProcessedWires;
   std::string aMethod = string(CREATION_METHOD())->value();
   if (aMethod == CREATION_BY_WIRES()) {
     AttributeSelectionListPtr aSelList = selectionList(WIRE_LIST_ID());
 
-    std::set<GeomShapePtr> aProcessedWires;
     int aNbSel = aSelList->size();
     for (int ind = 0; ind < aNbSel; ++ind) {
       AttributeSelectionPtr aCurSel = aSelList->value(ind);
@@ -106,7 +107,8 @@ bool FeaturesPlugin_Fillet1D::baseShapes(MapShapeSubs& theWireVertices)
       }
 
 
-      // keep the sequence of fillet vertices stable
+      // keep the sequence of wires and fillet vertices stable
+      theWires.push_back(aWire);
       for (GeomAPI_WireExplorer anExp(aWire->wire()); anExp.more(); anExp.next()) {
         GeomShapePtr aVertex = anExp.currentVertex();
         if (aFilletVertices.find(aVertex) != aFilletVertices.end())
@@ -121,6 +123,13 @@ bool FeaturesPlugin_Fillet1D::baseShapes(MapShapeSubs& theWireVertices)
       AttributeSelectionPtr aCurSel = aSelList->value(ind);
       GeomShapePtr aWire = aCurSel->context()->shape();
       GeomShapePtr aVertex = aCurSel->value();
+
+      // keep the sequence of wires stable
+      if (aProcessedWires.find(aWire) == aProcessedWires.end()) {
+        theWires.push_back(aWire);
+        aProcessedWires.insert(aWire);
+      }
+
       theWireVertices[aWire].push_back(aVertex);
     }
   }
index de2a380249f8bbedf0a7ed65a80508b9c859c50a..961d69ee424ae259c650cfa6dbe95ca00fa46377 100644 (file)
@@ -100,7 +100,7 @@ public:
 private:
   /// Get the list of wires and fillet vertices
   /// \retun \c false if errors occured
-  bool baseShapes(MapShapeSubs& theWireVertices);
+  bool baseShapes(ListOfShape& theWires, MapShapeSubs& theWireVertices);
 
   /// Run fillet operation and store result.
   /// \return \c false if fillet failed.
index 8bd49a151e236f0a5451bf8124795807c2efeac0..295f226633682b56f65a236d329be9feab918063 100644 (file)
@@ -46,7 +46,7 @@ model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.VERTEX, [18])
 model.testResultsVolumes(Fillet1D_1, [0])
 
 ### Create Fillet1D
-Fillet1D_2 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Wire_1_1/Edge_1]e[Wire_1_1/Edge_3]e")], 1)
+Fillet1D_2 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_1]e[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_3]e")], 1)
 
 model.testNbResults(Fillet1D_2, 1)
 model.testNbSubResults(Fillet1D_2, [0])
@@ -57,7 +57,7 @@ model.testNbSubShapes(Fillet1D_2, GeomAPI_Shape.VERTEX, [20])
 model.testResultsVolumes(Fillet1D_2, [0])
 
 ### Create Fillet1D
-Fillet1D_3 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[(Wire_1_1/Edge_8)4(Wire_1_1/Edge_5)4_Fillet1D_2_1]e[(Wire_1_1/Edge_8)3(Wire_1_1/Edge_7)4_Fillet1D_2_1]e")], 5)
+Fillet1D_3 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Fillet1D_2_1/ME:Fillet1D&Wire_1_1/Edge_2]e[Fillet1D_2_1/ME:Fillet1D&Wire_1_1/Edge_4]e")], 5)
 
 model.testHaveNamingByType(Fillet1D_3, model, Part_1_doc, GeomAPI_Shape.VERTEX)
 model.testHaveNamingByType(Fillet1D_3, model, Part_1_doc, GeomAPI_Shape.EDGE)
index 37e0ee2352577cbe2ae57314945c6ed73bb62e9a..2d1a78b7a592797f37235d183b40205d4a013487 100644 (file)
@@ -46,7 +46,7 @@ model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.VERTEX, [12])
 model.testResultsVolumes(Fillet1D_1, [0])
 
 ### Create Fillet1D
-Fillet1D_2 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Wire_1_1/Edge_4]e[Wire_1_1/Edge_3]e")], 3)
+Fillet1D_2 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_4]e[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_3]e")], 3)
 
 model.testHaveNamingByType(Fillet1D_2, model, Part_1_doc, GeomAPI_Shape.VERTEX)
 model.testHaveNamingByType(Fillet1D_2, model, Part_1_doc, GeomAPI_Shape.EDGE)
diff --git a/src/FeaturesPlugin/Test/TestFillet1D_Vertices_9.py b/src/FeaturesPlugin/Test/TestFillet1D_Vertices_9.py
new file mode 100644 (file)
index 0000000..2305d0c
--- /dev/null
@@ -0,0 +1,70 @@
+# Copyright (C) 2020  CEA/DEN, EDF R&D
+#
+# This library 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.
+#
+# 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Wire_1_objects = [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+
+### Create Wire
+Wire_1 = model.addWire(Part_1_doc, Wire_1_objects, False)
+
+### Create Recover
+Recover_1 = model.addRecover(Part_1_doc, Wire_1, [Box_1.result()])
+
+### Create Wire
+Wire_2_objects = [model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Right][Recover_1_1/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Back][Recover_1_1/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Back][Recover_1_1/Modified_Face&Box_1_1/Top]")]
+Wire_2 = model.addWire(Part_1_doc, Wire_2_objects, False)
+
+### Create Fillet1D
+Fillet1D_1 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Wire_1_1/Edge_1]e[Wire_1_1/Edge_2]e"), model.selection("VERTEX", "[Wire_2_1/Edge_2]e[Wire_2_1/Edge_3]e")], 2)
+
+model.testNbResults(Fillet1D_1, 2)
+model.testNbSubResults(Fillet1D_1, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.SOLID, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.FACE, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.EDGE, [4, 4])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.VERTEX, [8, 8])
+model.testResultsVolumes(Fillet1D_1, [0, 0])
+
+### Create Fillet1D
+Fillet1D_2 = model.addFillet(Part_1_doc, [model.selection("VERTEX", "[Fillet1D_1_2/ME:Fillet1D&Wire_2_1/Edge_1]e[Fillet1D_1_2/ME:Fillet1D&Wire_2_1/Edge_2]e"), model.selection("VERTEX", "[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_2]e[Fillet1D_1_1/ME:Fillet1D&Wire_1_1/Edge_3]e")], 5)
+
+model.testHaveNamingByType(Fillet1D_2, model, Part_1_doc, GeomAPI_Shape.VERTEX)
+model.testHaveNamingByType(Fillet1D_2, model, Part_1_doc, GeomAPI_Shape.EDGE)
+model.end()
+
+model.testNbResults(Fillet1D_2, 2)
+model.testNbSubResults(Fillet1D_2, [0, 0])
+model.testNbSubShapes(Fillet1D_2, GeomAPI_Shape.SOLID, [0, 0])
+model.testNbSubShapes(Fillet1D_2, GeomAPI_Shape.FACE, [0, 0])
+model.testNbSubShapes(Fillet1D_2, GeomAPI_Shape.EDGE, [5, 5])
+model.testNbSubShapes(Fillet1D_2, GeomAPI_Shape.VERTEX, [10, 10])
+model.testResultsVolumes(Fillet1D_2, [0, 0])
+
+assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING))
diff --git a/src/FeaturesPlugin/Test/TestFillet1D_Wire_5.py b/src/FeaturesPlugin/Test/TestFillet1D_Wire_5.py
new file mode 100644 (file)
index 0000000..b05c0c6
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright (C) 2020  CEA/DEN, EDF R&D
+#
+# This library 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.
+#
+# 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Wire_1_objects = [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+
+### Create Wire
+Wire_1 = model.addWire(Part_1_doc, Wire_1_objects, False)
+
+### Create Recover
+Recover_1 = model.addRecover(Part_1_doc, Wire_1, [Box_1.result()])
+
+### Create Wire
+Wire_2_objects = [model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Right][Recover_1_1/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Back][Recover_1_1/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "[Recover_1_1/Modified_Face&Box_1_1/Back][Recover_1_1/Modified_Face&Box_1_1/Top]")]
+Wire_2 = model.addWire(Part_1_doc, Wire_2_objects, False)
+
+### Create Fillet1D
+Fillet1D_1 = model.addFillet(Part_1_doc, [model.selection("WIRE", "Wire_1_1"), model.selection("WIRE", "Wire_2_1")], 2)
+
+model.testHaveNamingByType(Fillet1D_1, model, Part_1_doc, GeomAPI_Shape.VERTEX)
+model.testHaveNamingByType(Fillet1D_1, model, Part_1_doc, GeomAPI_Shape.EDGE)
+model.end()
+
+model.testNbResults(Fillet1D_1, 2)
+model.testNbSubResults(Fillet1D_1, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.SOLID, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.FACE, [0, 0])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.EDGE, [5, 5])
+model.testNbSubShapes(Fillet1D_1, GeomAPI_Shape.VERTEX, [10, 10])
+model.testResultsVolumes(Fillet1D_1, [0, 0])
+
+assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING))
index 5eca5b879c1fb65666db013ec42976eb2e9e9332..344ac9415ee5535967dd0c9f720904d2a10bfc19 100644 (file)
@@ -18,6 +18,8 @@
 //
 
 #include <GeomAlgoAPI_Fillet1D.h>
+
+#include <GeomAlgoAPI_Copy.h>
 #include <GeomAlgoAPI_MapShapesAndAncestors.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 
@@ -71,6 +73,13 @@ void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
   if (!theBaseWire || theFilletVertices.empty() || theRadius < 0.)
     return;
 
+  // store all edges of a base wire as modified, because they will be rebuild by ShapeFix
+  for (GeomAPI_WireExplorer aWExp(theBaseWire->wire()); aWExp.more(); aWExp.next()) {
+    GeomShapePtr aCurrent = aWExp.current();
+    GeomAlgoAPI_Copy aCopy(aCurrent);
+    myModified[aCurrent].push_back(aCopy.shape());
+  }
+
   GeomAlgoAPI_MapShapesAndAncestors aMapVE(theBaseWire, GeomAPI_Shape::VERTEX,
                                                         GeomAPI_Shape::EDGE);