]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implementation and part of tests of High Level Objects History task for Common, Cut...
authormpv <mpv@opencascade.com>
Thu, 24 Jan 2019 08:26:31 +0000 (11:26 +0300)
committermpv <mpv@opencascade.com>
Thu, 24 Jan 2019 08:26:31 +0000 (11:26 +0300)
src/CollectionPlugin/CMakeLists.txt
src/CollectionPlugin/Test/TestGroupMove4.py [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp
src/FeaturesPlugin/FeaturesPlugin_Tools.cpp
src/FeaturesPlugin/FeaturesPlugin_Tools.h
src/Model/Model_AttributeSelection.cpp
src/Model/Model_ResultBody.cpp

index cd20d61855dd88001c8d7b08eae2d49fd4543979..711a8cc45604d15c2cb6eead22fddc5d6f24f58e 100644 (file)
@@ -111,5 +111,6 @@ ADD_UNIT_TESTS(
                TestGroupMove.py
                TestGroupMove2.py
                TestGroupMove3.py
+               TestGroupMove4.py
                TestGroupShareTopology.py
 )
diff --git a/src/CollectionPlugin/Test/TestGroupMove4.py b/src/CollectionPlugin/Test/TestGroupMove4.py
new file mode 100644 (file)
index 0000000..4755468
--- /dev/null
@@ -0,0 +1,64 @@
+## Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Cylinders divided to two by cut, then each divided to
+# two by partition by plane, then resulting compsolids are collected in compound.
+# Checking that group on initial extrusion moved to the end contains the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI 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"))
+SketchCircle_1 = Sketch_1.addCircle(-4.602216748768477, 10.94581280788177, 9.660420057801511)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 1, True)
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchCircle_2 = Sketch_2.addCircle(-5.643073116097736, 11.91382008305256, 15.03576198961618)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2r")], model.selection(), 2, -4)
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Cut_1_1"), model.selection("FACE", "Plane_1")])
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPSOLID", "Partition_1_2")])
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Compound_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+aFactory = ModelAPI_Session.get().validators()
+# check group 1: cylindical face is divided to 6 (because of seam edge)
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_1.feature()))
+
+# check group 2: solid is divided to 4 solids
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_2.feature()))
+
+assert(model.checkPythonDump())
index df16a3149b6764ad80f33797b6e6fc1ad915d95d..fcc48e084bd18de9c0a2904f1060b00aac07204d 100644 (file)
@@ -158,13 +158,14 @@ void FeaturesPlugin_BooleanCommon::execute()
       std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
-      GeomShapePtr aBaseShape = anObjects.front();
-      anObjects.pop_front();
+      ListOfShape anEmptyTools;
       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               aBaseShape,
                                                anObjects,
+                                               anEmptyTools,
                                                aMakeShapeList,
                                                aShape);
+      GeomShapePtr aBaseShape = anObjects.front();
+      anObjects.pop_front();
       setResult(aResultBody, aResultIndex);
       aResultIndex++;
 
@@ -222,9 +223,10 @@ void FeaturesPlugin_BooleanCommon::execute()
       if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) {
         std::shared_ptr<ModelAPI_ResultBody> aResultBody =
           document()->createBody(data(), aResultIndex);
-
+        ListOfShape anObjectList;
+        anObjectList.push_back(anObject);
         FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 anObject,
+                                                 anObjectList,
                                                  aTools,
                                                  aMakeShapeList,
                                                  aResShape);
@@ -304,8 +306,10 @@ void FeaturesPlugin_BooleanCommon::execute()
         std::shared_ptr<ModelAPI_ResultBody> aResultBody =
           document()->createBody(data(), aResultIndex);
 
+        ListOfShape aCompSolidList;
+        aCompSolidList.push_back(aCompSolid);
         FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 aCompSolid,
+                                                 aCompSolidList,
                                                  aTools,
                                                  aMakeShapeList,
                                                  aResultShape);
@@ -388,8 +392,10 @@ void FeaturesPlugin_BooleanCommon::execute()
         std::shared_ptr<ModelAPI_ResultBody> aResultBody =
           document()->createBody(data(), aResultIndex);
 
+        ListOfShape aCompoundList;
+        aCompoundList.push_back(aCompound);
         FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 aCompound,
+                                                 aCompoundList,
                                                  aTools,
                                                  aMakeShapeList,
                                                  aResultShape);
index bfe0fdc2c26127ce96e9ba425a361a57dc3dc82b..a37a4a56c140a04239197434cd19b966c33c7026 100644 (file)
@@ -133,8 +133,10 @@ void FeaturesPlugin_BooleanCut::execute()
       std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
+      ListOfShape anObjectList;
+      anObjectList.push_back(anObject);
       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               anObject,
+                                               anObjectList,
                                                aTools,
                                                aMakeShapeList,
                                                aResShape);
@@ -214,8 +216,10 @@ void FeaturesPlugin_BooleanCut::execute()
       std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
+      ListOfShape anObjectList;
+      anObjectList.push_back(aCompSolid);
       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               aCompSolid,
+                                               anObjectList,
                                                aTools,
                                                aMakeShapeList,
                                                aResultShape);
@@ -296,8 +300,10 @@ void FeaturesPlugin_BooleanCut::execute()
       std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
+      ListOfShape anObjectList;
+      anObjectList.push_back(aCompound);
       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               aCompound,
+                                               anObjectList,
                                                aTools,
                                                aMakeShapeList,
                                                aResultShape);
index f6e4599f730e695f2288301057c3d34a5c149211..b8bec11c1a17d8e39e4c76f02350db5e450f1793 100644 (file)
@@ -271,20 +271,19 @@ void FeaturesPlugin_BooleanFuse::execute()
 
   int aResultIndex = 0;
 
-  GeomShapePtr aBackShape = anOriginalShapes.back();
-  anOriginalShapes.pop_back();
   ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
 
+  ListOfShape anEmptyTools;
   FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                           aBackShape,
                                            anOriginalShapes,
+                                           anEmptyTools,
                                            aMakeShapeList,
                                            aShape);
   setResult(aResultBody, aResultIndex);
   aResultIndex++;
 
   FeaturesPlugin_Tools::loadDeletedShapes(aResultBody,
-                                          aBackShape,
+                                          GeomShapePtr(),
                                           anOriginalShapes,
                                           aMakeShapeList,
                                           aShape);
index ee6c3c78538ac45b9210235df7242576d60370ff..2ec4468c4ac306b50c13775c39890308746404c2 100644 (file)
@@ -213,12 +213,10 @@ void FeaturesPlugin_BooleanSmash::execute()
     aMakeShapeList->appendAlgo(aFillerAlgo);
   }
 
-  std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
-  anOriginalShapes.pop_front();
   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
 
   FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                           aFrontShape,
+                                           anOriginalShapes,
                                            anOriginalShapes,
                                            aMakeShapeList,
                                            aShape);
@@ -227,7 +225,7 @@ void FeaturesPlugin_BooleanSmash::execute()
   aResultIndex++;
 
   FeaturesPlugin_Tools::loadDeletedShapes(aResultBody,
-                                          aFrontShape,
+                                          GeomShapePtr(),
                                           anOriginalShapes,
                                           aMakeShapeList,
                                           aShape);
index efdee580134ed3afa36a9cb0b81da35e8df9655b..c2444556d0c40416c6acab27c0703eed5b626368 100644 (file)
 
 //==================================================================================================
 void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
-                                              const GeomShapePtr theBaseShape,
+                                              const ListOfShape& theBaseShapes,
                                               const ListOfShape& theTools,
                                               const GeomMakeShapePtr& theMakeShape,
                                               const GeomShapePtr theResultShape)
 {
-  if (theBaseShape->isEqual(theResultShape)) {
-    theResultBody->store(theResultShape, false);
-    return;
-  }
-
-  theResultBody->storeModified(theBaseShape, theResultShape);
+  theResultBody->storeModified(theBaseShapes, theResultShape, theMakeShape);
 
-  ListOfShape aShapes = theTools;
-  aShapes.push_front(theBaseShape);
+  ListOfShape aShapes = theBaseShapes;
+  ListOfShape::const_iterator aToolIter = theTools.cbegin();
+  for(; aToolIter != theTools.cend(); aToolIter++)
+    aShapes.push_back(*aToolIter);
 
   for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); ++anIter)
   {
@@ -51,7 +48,7 @@ void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
 
 //==================================================================================================
 void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
-                                              const GeomShapePtr theBaseShape,
+                                              const GeomShapePtr& theBaseShape,
                                               const GeomMakeShapePtr& theMakeShape,
                                               const std::string theName)
 {
@@ -98,7 +95,8 @@ void FeaturesPlugin_Tools::loadDeletedShapes(ResultBodyPtr theResultBody,
   const GeomShapePtr theResultShapesCompound)
 {
   ListOfShape aShapes = theTools;
-  aShapes.push_front(theBaseShape);
+  if (theBaseShape.get())
+    aShapes.push_front(theBaseShape);
 
   for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); anIter++)
   {
index 22b269b045e915f24d6ad7f94b5766b3ba53f923..bda339111c61b0def7d5f310eb4d96c4b0d0cea9 100644 (file)
@@ -36,16 +36,15 @@ public:
 
 public:
   static void loadModifiedShapes(ResultBodyPtr theResultBody,
-                                 const GeomShapePtr theBaseShape,
+                                 const ListOfShape& theBaseShapes,
                                  const ListOfShape& theTools,
                                  const GeomMakeShapePtr& theMakeShape,
                                  const GeomShapePtr theResultShape);
 
   static void loadModifiedShapes(ResultBodyPtr theResultBody,
-                                 const GeomShapePtr theBaseShape,
+                                 const GeomShapePtr& theBaseShape,
                                  const GeomMakeShapePtr& theMakeShape,
                                  const std::string theName);
-
     /// Stores deleted shapes.
   static void loadDeletedShapes(ResultBodyPtr theResultBody,
                                 const GeomShapePtr theBaseShape,
index d4ce0fcd66b2c1700fd9ed474fce3706933620f5..ce8a3b77f91206f2aa3bb29263c41d0d30db519a 100644 (file)
@@ -1232,7 +1232,6 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr<Model_Document>
   std::list<ResultPtr>& theResults, TopTools_ListOfShape& theValShapes)
 {
   std::set<ResultPtr> aResults; // to avoid duplicates, new context, null if deleted
-  TopTools_ListOfShape aResContShapes;
   // iterate context and shape, but also if it is sub-shape of main shape, check also it
   TopTools_ListOfShape aContextList;
   aContextList.Append(theContShape);
@@ -1269,7 +1268,6 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr<Model_Document>
       aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
       if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
         aResults.insert(aModifierObj);
-        aResContShapes.Append(aModifierObj->shape()->impl<TopoDS_Shape>());
       } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty
         aResults.insert(ResultPtr());
       } else { // not-processed modification => don't support it
@@ -1277,6 +1275,18 @@ bool Model_AttributeSelection::searchNewContext(std::shared_ptr<Model_Document>
       }
     }
   }
+  // if there exist context composite and sub-result(s), leave only sub(s)
+  for(std::set<ResultPtr>::iterator aResIter = aResults.begin(); aResIter != aResults.end();) {
+    ResultPtr aParent = ModelAPI_Tools::bodyOwner(*aResIter);
+    for(; aParent.get(); aParent = ModelAPI_Tools::bodyOwner(aParent))
+      if (aResults.count(aParent))
+        break;
+    if (aParent.get()) { // erase from set, so, restart iteration
+      aResults.erase(aParent);
+      aResIter = aResults.begin();
+    } else aResIter++;
+  }
+
   if (aResults.empty())
     return false; // no modifications found, must stay the same
   // iterate all results to find further modifications
@@ -1420,7 +1430,8 @@ void Model_AttributeSelection::updateInHistory()
         setValue(*aNewCont, aValueShape);
         aFirst = false;
       } else if (myParent) {
-        myParent->append(*aNewCont, aValueShape);
+        if (!myParent->isInList(*aNewCont, aValueShape)) // avoid addition of duplicates
+          myParent->append(*aNewCont, aValueShape);
       }
     }
     if (aFirst) { // nothing was added, all results were deleted
index 3d28be7c668bdff13d28f9f393dc037bfbaf798b..b6fb91da1b241d606da07ff80443c24bfe57aa2b 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <TopoDS_Shape.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TDataStd_UAttribute.hxx>
 
 // if this attribute exists, the shape is connected topology
@@ -342,29 +343,55 @@ void Model_ResultBody::cleanCash()
   }
 }
 
+// adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid
+static void collectSubs(
+  const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore)
+{
+  if (theSub->isNull())
+    return;
+  if (theSubSubs.Add(theSub->impl<TopoDS_Shape>()))  {
+    bool aIsComp = theSub->isCompound() || theSub->isCompSolid();
+    if (aIsComp || theOneLevelMore) {
+      for(GeomAPI_ShapeIterator anIter(theSub); anIter.more(); anIter.next()) {
+        collectSubs(anIter.current(), theSubSubs, aIsComp && theOneLevelMore);
+      }
+    }
+  }
+}
+
 void Model_ResultBody::computeOldForSub(const GeomShapePtr& theSub,
   const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub)
 {
+  // the old can be also used for sub-shape of theSub; collect all subs of compound or compsolid
+  TopTools_MapOfShape aSubSubs;
+  collectSubs(theSub, aSubSubs, false);
+
   std::list<GeomShapePtr>::const_iterator aRootOlds = theAllOlds.cbegin();
-  for(; aRootOlds != theAllOlds.cend(); aRootOlds++) {
-    ListOfShape aNews;
-    myIsGenerated ? myAlgo->generated(*aRootOlds, aNews) : myAlgo->modified(*aRootOlds, aNews);
-    // MakeShape may return alone old shape if there is no history information for this input
-    if (aNews.size() == 1 && aNews.front()->isEqual(*aRootOlds))
-      aNews.clear();
-    if (aNews.empty()) { // try to iterate to sub-elements (for intersection of solids this is face)
-      std::list<GeomShapePtr> theAllSubOlds;
-      for(GeomAPI_ShapeIterator aSubOld(*aRootOlds); aSubOld.more(); aSubOld.next()) {
-        GeomShapePtr aSub = aSubOld.current();
-        if (aSub.get() && !aSub->isNull())
-          theAllSubOlds.push_back(aSub);
-      }
-      computeOldForSub(theSub, theAllSubOlds, theOldForSub);
-    }
-    for(ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
-      if (theSub->isSame(*aNewIter)) { // found old that was used for new theSubShape creation
-        theOldForSub.push_back(*aRootOlds);
-        break;
+  for (; aRootOlds != theAllOlds.cend(); aRootOlds++) {
+    // use sub-shapes of olds too if they are compounds or compsolids
+    TopTools_MapOfShape anOldSubs;
+    // iterate one level more (for intersection of solids this is face)
+    collectSubs(*aRootOlds, anOldSubs, true);
+    for (TopTools_MapOfShape::Iterator anOldIter(anOldSubs); anOldIter.More(); anOldIter.Next()) {
+      GeomShapePtr anOldSub(new GeomAPI_Shape);
+      anOldSub->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldIter.Value()));
+      ListOfShape aNews;
+      myIsGenerated ? myAlgo->generated(anOldSub, aNews) : myAlgo->modified(anOldSub, aNews);
+      // MakeShape may return alone old shape if there is no history information for this input
+      if (aNews.size() == 1 && aNews.front()->isEqual(anOldSub))
+        aNews.clear();
+
+      for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+        if (aSubSubs.Contains((*aNewIter)->impl<TopoDS_Shape>())) {
+          // check list already contains this sub
+          std::list<GeomShapePtr>::iterator aResIter = theOldForSub.begin();
+          for(; aResIter != theOldForSub.end(); aResIter++)
+            if ((*aResIter)->isSame(anOldSub))
+              break;
+          if (aResIter == theOldForSub.end())
+            theOldForSub.push_back(anOldSub); // found old used for new theSubShape creation
+          break;
+        }
       }
     }
   }