Salome HOME
Task 3.4 Build/Face and Build/Shell on a whole Sketch (issue #3078).
authorazv <azv@opencascade.com>
Fri, 22 Nov 2019 12:35:45 +0000 (15:35 +0300)
committerazv <azv@opencascade.com>
Fri, 22 Nov 2019 12:35:45 +0000 (15:35 +0300)
src/BuildPlugin/BuildPlugin_Face.cpp
src/BuildPlugin/BuildPlugin_Shell.cpp
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/Test/TestFace_WholeSketch_1.py [new file with mode: 0644]
src/BuildPlugin/Test/TestFace_WholeSketch_2.py [new file with mode: 0644]
src/BuildPlugin/Test/TestShell_WholeSketch_1.py [new file with mode: 0644]
src/BuildPlugin/Test/TestShell_WholeSketch_2.py [new file with mode: 0644]
src/BuildPlugin/face_widget.xml
src/BuildPlugin/shell_widget.xml

index 022865abdd3682773a3b4a0a1cee2e70858ea434..ac88ffe6aaa6837d8d67440fd060a658fdc5456b 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_PlanarEdges.h>
@@ -71,11 +72,21 @@ void BuildPlugin_Face::execute()
     if(!aShape.get()) {
       aShape = aContext;
     }
-    // keep selected faces "as is"
     if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+      // keep selected faces "as is"
       anOriginalFaces.push_back(aShape);
       continue;
     }
+    else if (!aSelection->value() && aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+      // collect faces from the sketch
+      ResultConstructionPtr aSketch =
+          std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelection->context());
+      if (aSketch && aSketch->facesNum() > 0) {
+        for (int i = 0; i < aSketch->facesNum(); ++i)
+          anOriginalFaces.push_back(aSketch->face(i));
+        continue;
+      }
+    }
 
     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
       GeomShapePtr anEdge = anExp.current();
index 7f1010307502ee73fa57b18556aa824de3880354..293a63818a99cd339898a292ce2f9a790dab97d8 100644 (file)
@@ -48,6 +48,18 @@ void BuildPlugin_Shell::execute()
   ListOfShape aShapes, aContexts;
   getOriginalShapesAndContexts(BASE_OBJECTS_ID(), aShapes, aContexts);
 
+  // Collect sketch faces.
+  for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+    GeomShapePtr aShape = aSelection->value();
+    ResultConstructionPtr aContext =
+        std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelection->context());
+    if (!aShape && aContext) {
+      for (int i = 0; i < aContext->facesNum(); ++i)
+        aShapes.push_back(aContext->face(i));
+    }
+  }
+
   // Sew faces.
   GeomMakeShapePtr aSewingAlgo(new GeomAlgoAPI_Sewing(aShapes));
 
index 99ba50ccb427f5359e93b1bdb99ff3f18b01b544..761fc6fa542c9acea0db48d56dfd66b820fe782e 100644 (file)
@@ -104,17 +104,6 @@ bool BuildPlugin_ValidatorBaseForBuild::isValid(const AttributePtr& theAttribute
         theError = "Infinite objects not acceptable.";
         return false;
       }
-
-      std::shared_ptr<GeomAPI_PlanarEdges> anEdges =
-        std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContextShape);
-      if(anEdges.get()) {
-        if(aShape->isEqual(aContextShape)) {
-          // It is whole sketch.
-          return false;
-        }
-
-        continue;
-      }
     }
   }
 
@@ -198,7 +187,11 @@ bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptr<ModelAPI_Fe
       }
       aShape = aSelection->context()->shape();
     }
-    if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+    ResultConstructionPtr aSketchRes =
+        std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelection->context());
+
+    if (aShape->shapeType() == GeomAPI_Shape::FACE ||
+        (!aSelection->value() && aSketchRes && aSketchRes->facesNum() > 0)) {
       // skip faces exploding
       hasFaces = true;
       continue;
index 121f992cfd039770159556bede62f16c9766522f..e8a4e470fc671d0f50fbbc7d0141b70504e8e7c3 100644 (file)
@@ -121,7 +121,11 @@ ADD_UNIT_TESTS(TestVertex.py
                TestInterpolation.py
                TestFace.py
                TestFace_ErrorMsg.py
+               TestFace_WholeSketch_1.py
+               TestFace_WholeSketch_2.py
                TestShell.py
+               TestShell_WholeSketch_1.py
+               TestShell_WholeSketch_2.py
                TestSolid.py
                TestSolid_ErrorMsg.py
                TestCompSolid.py
diff --git a/src/BuildPlugin/Test/TestFace_WholeSketch_1.py b/src/BuildPlugin/Test/TestFace_WholeSketch_1.py
new file mode 100644 (file)
index 0000000..713ccb2
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2019  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()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-5, 10, 20)
+SketchLine_4 = Sketch_2.addLine(-25, 10, 15, 10)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")])
+model.end()
+
+model.testNbResults(Face_1, 1)
+model.testNbSubShapes(Face_1, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Face_1, GeomAPI_Shape.EDGE, [3])
+model.testNbSubShapes(Face_1, GeomAPI_Shape.VERTEX, [6])
+model.testResultsVolumes(Face_1, [441.0539215686274])
+
+assert(model.checkPythonDump())
diff --git a/src/BuildPlugin/Test/TestFace_WholeSketch_2.py b/src/BuildPlugin/Test/TestFace_WholeSketch_2.py
new file mode 100644 (file)
index 0000000..c3a25de
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2019  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()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-5, 10, 20)
+SketchLine_4 = Sketch_2.addLine(-25, 10, 15, 10)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1"), model.selection("COMPOUND", "Sketch_2")])
+model.end()
+
+model.testNbResults(Face_1, 3)
+model.testNbSubShapes(Face_1, GeomAPI_Shape.FACE, [1, 1, 1])
+model.testNbSubShapes(Face_1, GeomAPI_Shape.EDGE, [3, 2, 2])
+model.testNbSubShapes(Face_1, GeomAPI_Shape.VERTEX, [6, 4, 4])
+model.testResultsVolumes(Face_1, [441.0539215686274, 628.318530717958, 628.318530717958])
+
+assert(model.checkPythonDump())
diff --git a/src/BuildPlugin/Test/TestShell_WholeSketch_1.py b/src/BuildPlugin/Test/TestShell_WholeSketch_1.py
new file mode 100644 (file)
index 0000000..0b11501
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2019  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()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-5, 10, 20)
+SketchLine_4 = Sketch_2.addLine(-25, 10, 15, 10)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Shell_1 = model.addShell(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")])
+model.end()
+
+model.testNbResults(Shell_1, 1)
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.EDGE, [3])
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.VERTEX, [6])
+model.testResultsVolumes(Shell_1, [441.0539215686274])
+
+assert(model.checkPythonDump())
diff --git a/src/BuildPlugin/Test/TestShell_WholeSketch_2.py b/src/BuildPlugin/Test/TestShell_WholeSketch_2.py
new file mode 100644 (file)
index 0000000..55a7ad2
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2019  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()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-5, 10, 20)
+SketchLine_4 = Sketch_2.addLine(-25, 10, 15, 10)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Shell_1 = model.addShell(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1"), model.selection("COMPOUND", "Sketch_2")])
+model.end()
+
+model.testNbResults(Shell_1, 2)
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.FACE, [1, 2])
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.EDGE, [3, 4])
+model.testNbSubShapes(Shell_1, GeomAPI_Shape.VERTEX, [6, 8])
+model.testResultsVolumes(Shell_1, [441.0539215686274, 1256.637061435917])
+
+assert(model.checkPythonDump())
index e61ce59d10aec18995e763c482cba998b6eb7049..78235132d23628d8e8d365f18122d84607cffd7e 100644 (file)
@@ -4,7 +4,7 @@
                   tooltip="Select edges, wires or faces."
                   shape_types="edges wires faces"
                   concealment="true">
-    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire,face"/>
+    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire,face,compound"/>
   </multi_selector>
   <validator id="BuildPlugin_ValidatorBaseForFace" parameters="base_objects"/>
 </source>
index 50575ff1e55873270f40079f3eb92f6496f76404..cb44a7c302a477335495fccae7d3444adad05fa5 100644 (file)
@@ -4,6 +4,6 @@
                   tooltip="Select faces or shells objects."
                   shape_types="faces shells"
                   concealment="true">
-    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="face,shell"/>
+    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="face,shell,compound"/>
   </multi_selector>
 </source>