Salome HOME
Task #3005 : To be able to create a group on a whole result. Python API support.
authormpv <mpv@opencascade.com>
Tue, 10 Sep 2019 12:17:11 +0000 (15:17 +0300)
committermpv <mpv@opencascade.com>
Tue, 10 Sep 2019 12:17:11 +0000 (15:17 +0300)
src/CollectionAPI/CollectionAPI_Group.cpp
src/CollectionAPI/CollectionAPI_Group.h
src/CollectionPlugin/CMakeLists.txt
src/CollectionPlugin/Test/TestGroupWholeResult1.py [new file with mode: 0644]
src/Model/Model_ResultGroup.cpp
src/ModelHighAPI/ModelHighAPI_Tools.cpp

index ee6594416638b53f776a2a959e0d37a3e40c3efc..98b6409d62221ad258780a2ce29d5950a86f0738 100644 (file)
@@ -63,7 +63,10 @@ void CollectionAPI_Group::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionListPtr anAttrList = aBase->selectionList(CollectionPlugin_Group::LIST_ID());
 
-  theDumper << aBase << " = model.addGroup(" << aDocName << ", " << anAttrList;
+  theDumper << aBase << " = model.addGroup(" << aDocName << ", ";
+  if (anAttrList->isWholeResultAllowed())
+    theDumper<<"\""<<anAttrList->selectionType()<<"\", ";
+  theDumper << anAttrList;
   if (anAttrList->isGeometricalSelection())
     theDumper <<", True";
   theDumper << ")" << std::endl;
@@ -79,3 +82,16 @@ GroupPtr addGroup(const std::shared_ptr<ModelAPI_Document>& thePart,
     aFeature->selectionList(CollectionPlugin_Group::LIST_ID())->setGeometricalSelection(true);
   return GroupPtr(new CollectionAPI_Group(aFeature, theGroupList));
 }
+
+//==================================================================================================
+GroupPtr addGroup(const std::shared_ptr<ModelAPI_Document>& thePart,
+  const std::string& theSelectionType,
+  const std::list<ModelHighAPI_Selection>& theGroupList,
+  const bool theShareSameTopology)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(CollectionAPI_Group::ID());
+  aFeature->selectionList(CollectionPlugin_Group::LIST_ID())->setSelectionType(theSelectionType);
+  if (theShareSameTopology)
+    aFeature->selectionList(CollectionPlugin_Group::LIST_ID())->setGeometricalSelection(true);
+  return GroupPtr(new CollectionAPI_Group(aFeature, theGroupList));
+}
index 284737e1c087a2bcff1da8a2c80e2552e3010470..3c535e5994469b2f927ed25c5d2eefb40e8dc968 100644 (file)
@@ -72,4 +72,12 @@ GroupPtr addGroup(const std::shared_ptr<ModelAPI_Document>& thePart,
                   const std::list<ModelHighAPI_Selection>& theGroupList,
                   const bool theShareSameTopology = false);
 
+/// \ingroup CPPHighAPI
+/// \brief Create Group with the additional selection type for case the whole result selected.
+COLLECTIONAPI_EXPORT
+GroupPtr addGroup(const std::shared_ptr<ModelAPI_Document>& thePart,
+  const std::string& theSelectionType,
+  const std::list<ModelHighAPI_Selection>& theGroupList,
+  const bool theShareSameTopology = false);
+
 #endif // CollectionAPI_Group_H_
index 251b91ffea8ef1c42fcb567da8d9a4604bab0b7f..936dd87e747ac39a65e863559d484c96974afd1f 100644 (file)
@@ -147,4 +147,5 @@ ADD_UNIT_TESTS(
                TestGroupSubstraction_Error1.py
                TestGroupSubstraction_Error2.py
                Test2977.py
+               TestGroupWholeResult1.py
 )
diff --git a/src/CollectionPlugin/Test/TestGroupWholeResult1.py b/src/CollectionPlugin/Test/TestGroupWholeResult1.py
new file mode 100644 (file)
index 0000000..bc1a800
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright (C) 2014-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
+#
+
+# Tests python API for the whole result in group selection
+
+from salome.shaper import model
+
+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(-16, -4, -4, 29)
+SketchLine_2 = Sketch_1.addLine(-4, 29, 21, -9)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(21, -9, -16, -4)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3r-SketchLine_2r-SketchLine_1r")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, "EDGE", [model.selection("SOLID", "Extrusion_1_1")])
+model.end()
+
+# check the group result: it must be compound of 9 edges
+assert(Group_1.groupList().selectionType() == "EDGE")
+assert(len(Group_1.results()) == 1)
+assert(Group_1.result().shapeType() == "COMPOUND")
+
+from GeomAPI import GeomAPI_ShapeIterator
+aResultShape = Group_1.feature().firstResult().shape()
+anIter = GeomAPI_ShapeIterator(aResultShape)
+aNum = 0
+while anIter.more():
+  anEdge = anIter.current()
+  assert(anEdge.isEdge())
+  aNum = aNum + 1
+  anIter.next()
+
+assert(aNum == 9)
+
+assert(model.checkPythonDump())
index 87d1620f6b3644f3525ac35273734dda34f595b8..c40c90738ed8feac8e7c1d91c34d6a1476fb4d77 100644 (file)
@@ -22,6 +22,7 @@
 #include <ModelAPI_AttributeSelectionList.h>
 
 #include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAPI_ShapeExplorer.h>
 
 #include <Config_PropManager.h>
 
@@ -68,11 +69,33 @@ std::shared_ptr<GeomAPI_Shape> Model_ResultGroup::shape()
   if (!aResult && myOwnerData) {
     AttributeSelectionListPtr aList = myOwnerData->selectionList("group_list");
     if (aList) {
+      GeomAPI_DataMapOfShapeShape aShapesMap; // to avoid shapes duplication
       std::list<std::shared_ptr<GeomAPI_Shape> > aSubs;
       for(int a = aList->size() - 1; a >= 0; a--) {
         std::shared_ptr<GeomAPI_Shape> aSelection = aList->value(a)->value();
-        if (aSelection && !aSelection->isNull()) {
-          aSubs.push_back(aSelection);
+        if (aList->isWholeResultAllowed()) { // whole result selection, explode to sub-shapes
+          if (!aSelection.get() || aSelection->isNull()) {
+            ResultPtr aContext = aList->value(a)->context();
+            if (aContext)
+              aSelection = aContext->shape();
+          }
+          if (aSelection && !aSelection->isNull()) {
+            GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::shapeTypeByStr(aList->selectionType());
+            if (aType == aSelection->shapeType()) {
+              if (aShapesMap.bind(aSelection, aSelection))
+                aSubs.push_back(aSelection);
+            } else {
+              for(GeomAPI_ShapeExplorer anExp(aSelection, aType); anExp.more(); anExp.next()) {
+                if (aShapesMap.bind(anExp.current(), anExp.current()))
+                  aSubs.push_back(anExp.current());
+              }
+            }
+          }
+        } else { // take selection as it is
+          if (aSelection && !aSelection->isNull()) {
+            if (aShapesMap.bind(aSelection, aSelection))
+              aSubs.push_back(aSelection);
+          }
         }
       }
       if (!aSubs.empty()) {
index 3aa3579ad19d4df58f63c5c2c0bdae55f275466d..0b6f6fc39c8272a3a8cc86d5cd5fb19a99fe7c1e 100644 (file)
@@ -193,7 +193,7 @@ void fillAttribute(const std::list<ModelHighAPI_Selection> & theValue,
 {
   theAttribute->clear();
 
-  if(!theValue.empty()) {
+  if(!theValue.empty() && theAttribute->selectionType().empty()) {
     const ModelHighAPI_Selection& aSelection = theValue.front();
     GeomAPI_Shape::ShapeType aSelectionType = getShapeType(aSelection);
     theAttribute->setSelectionType(strByShapeType(aSelectionType));
@@ -474,9 +474,9 @@ static bool dumpToPython(SessionPtr theSession,
   if (aDump.get()) {
     aDump->string("file_path")->setValue(theFilename);
     aDump->string("file_format")->setValue("py");
-    aDump->boolean("topological_naming")->setValue(theSelectionType & CHECK_NAMING);
-    aDump->boolean("geometric_selection")->setValue(theSelectionType & CHECK_GEOMETRICAL);
-    aDump->boolean("weak_naming")->setValue(theSelectionType & CHECK_WEAK);
+    aDump->boolean("topological_naming")->setValue((theSelectionType & CHECK_NAMING) != 0);
+    aDump->boolean("geometric_selection")->setValue((theSelectionType & CHECK_GEOMETRICAL) != 0);
+    aDump->boolean("weak_naming")->setValue((theSelectionType & CHECK_WEAK) != 0);
   }
   bool isProblem = !aDump.get() || !aDump->error().empty(); // after "finish" dump will be removed
   if (isProblem && aDump.get()) {