]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
High level objects history implementation for BuildPlugin features.
authorazv <azv@opencascade.com>
Mon, 25 Feb 2019 11:41:30 +0000 (14:41 +0300)
committerazv <azv@opencascade.com>
Tue, 26 Feb 2019 09:51:50 +0000 (12:51 +0300)
26 files changed:
src/BuildPlugin/BuildPlugin_CompSolid.cpp
src/BuildPlugin/BuildPlugin_CompSolid.h
src/BuildPlugin/BuildPlugin_Edge.cpp
src/BuildPlugin/BuildPlugin_Face.cpp
src/BuildPlugin/BuildPlugin_Face.h
src/BuildPlugin/BuildPlugin_Shape.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Shape.h [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Shell.cpp
src/BuildPlugin/BuildPlugin_Shell.h
src/BuildPlugin/BuildPlugin_Solid.cpp
src/BuildPlugin/BuildPlugin_Solid.h
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/CMakeLists.txt
src/CollectionPlugin/CMakeLists.txt
src/CollectionPlugin/Test/TestGroupMove16.py [new file with mode: 0644]
src/CollectionPlugin/Test/TestGroupMove17.py [new file with mode: 0644]
src/CollectionPlugin/Test/TestGroupMove18.py [new file with mode: 0644]
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h
src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.h
src/Model/Model_ResultConstruction.cpp

index 0fdb399fa31098b109dc1c4aa34577bb503dfd9c..7b94fff13e1732bf4a09552942249e2111ef37f9 100644 (file)
@@ -33,25 +33,3 @@ void BuildPlugin_CompSolid::initAttributes()
 {
   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
 }
-
-//=================================================================================================
-void BuildPlugin_CompSolid::execute()
-{
-  // all the needed checkings are in validator, so, here just make and store result
-  ListOfShape anOriginalShapes;
-  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
-  for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
-    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    GeomShapePtr aShape = aSelection->value();
-    if (!aShape.get())
-      aShape = aSelection->context()->shape();
-    anOriginalShapes.push_back(aShape);
-  }
-  std::shared_ptr<GeomAlgoAPI_MakeVolume> anAlgo(
-    new GeomAlgoAPI_MakeVolume(anOriginalShapes, false));
-  GeomShapePtr aVolumeRes = anAlgo->shape();
-
-  // check and process result of volume maker
-  GeomShapePtr aResShape = getSingleSubshape(aVolumeRes);
-  storeResult(anOriginalShapes, aResShape, anAlgo);
-}
index e31865a13e8c55ba78c61e0a0198e8a1eba10dc5..ae99a1eda7c5f0534a0e8a4f711efff568147cb9 100644 (file)
@@ -56,9 +56,6 @@ public:
 
   /// Request for initialization of data model of the feature: adding all attributes.
   BUILDPLUGIN_EXPORT virtual void initAttributes();
-
-  /// Creates a new part document if needed.
-  BUILDPLUGIN_EXPORT virtual void execute();
 };
 
 #endif
index 28be282f6055237a5de19eb62dc3147b443a67a7..ee1339f520134873a668b2a6016612530dcc4a4f 100644 (file)
@@ -87,7 +87,10 @@ void BuildPlugin_Edge::execute()
 
     // Store result.
     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    aResultBody->storeModified(aShape, aCopyAlgo->shape());
+
+    ListOfShape aBaseShapes;
+    aBaseShapes.push_back(aShape);
+    aResultBody->storeModified(aBaseShapes, aCopyAlgo->shape(), aCopyAlgo);
     aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::VERTEX);
 
     setResult(aResultBody, aResultIndex);
index c7992999ad4dbe04b768aabb5c37e6561cf547ad..a840fd5de7832034fab1663cd6696a40d13ab70d 100644 (file)
@@ -28,6 +28,7 @@
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_ShapeExplorer.h>
 
+#include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_SketchBuilder.h>
 #include <GeomAlgoAPI_Copy.h>
@@ -60,6 +61,9 @@ void BuildPlugin_Face::execute()
   // Collect base shapes.
   ListOfShape anEdges;
   ListOfShape anOriginalFaces;
+  ListOfShape aContexts;
+  getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, aContexts);
+  anOriginalFaces.clear();
   std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
@@ -88,8 +92,10 @@ void BuildPlugin_Face::execute()
 
   // Build faces by edges.
   ListOfShape aFaces;
+  GeomMakeShapePtr aFaceBuilder;
   if (!anEdges.empty())
-    buildFacesByEdges(anEdges, aListOfNormals, aFaces);
+    buildFacesByEdges(anEdges, aListOfNormals, aFaces, aFaceBuilder);
+  int aNbFacesFromEdges = (int)aFaces.size();
 
   // Add faces selected by user.
   aFaces.insert(aFaces.end(), anOriginalFaces.begin(), anOriginalFaces.end());
@@ -97,22 +103,17 @@ void BuildPlugin_Face::execute()
   // Store result.
   int anIndex = 0;
   for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
-    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
-    GeomShapePtr aShape = *anIt;
-    GeomAlgoAPI_Copy aCopy(aShape);
-    aShape = aCopy.shape();
-    aResultBody->store(aShape);
+    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+    if (anIndex < aNbFacesFromEdges)
+      aMakeShapeList->appendAlgo(aFaceBuilder);
 
-    // Store edges.
-    int anEdgeIndex = 1;
-    for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
-      GeomShapePtr anEdge = anExp.current();
-      aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex));
-      ++anEdgeIndex;
-    }
+    GeomShapePtr aShape = *anIt;
+    GeomMakeShapePtr aCopy(new GeomAlgoAPI_Copy(aShape));
+    aMakeShapeList->appendAlgo(aCopy);
 
-    setResult(aResultBody, anIndex);
-    ++anIndex;
+    ListOfShape aBaseShapes;
+    aBaseShapes.push_back(aShape);
+    storeResult(aMakeShapeList, aBaseShapes, aContexts, aCopy->shape(), anIndex++);
   }
 
   removeResults(anIndex);
@@ -121,7 +122,8 @@ void BuildPlugin_Face::execute()
 void BuildPlugin_Face::buildFacesByEdges(
     const ListOfShape& theEdges,
     const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
-    ListOfShape& theFaces) const
+    ListOfShape& theFaces,
+    std::shared_ptr<GeomAlgoAPI_MakeShape>& theBuilderAlgo) const
 {
   // Get plane.
   std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges);
@@ -137,8 +139,10 @@ void BuildPlugin_Face::buildFacesByEdges(
   }
 
   // Get faces.
-  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
-                                         aPln->direction(), theEdges, theFaces);
+  std::shared_ptr<GeomAlgoAPI_SketchBuilder> aSketchBuilder(
+      new GeomAlgoAPI_SketchBuilder(aPln, theEdges));
+  theFaces = aSketchBuilder->faces();
+  theBuilderAlgo = aSketchBuilder;
 
   // Get wires from faces.
   ListOfShape aWires;
index 633118eb7054da34dab7767efe72d3683bec9950..ad5fd4a9781965af40ba6c332b32d18d0a599ad3 100644 (file)
 #define BuildPlugin_Face_H_
 
 #include "BuildPlugin.h"
-
-#include <ModelAPI_Feature.h>
+#include "BuildPlugin_Shape.h"
 
 class GeomAPI_Dir;
 class GeomAPI_Shape;
+class GeomAlgoAPI_MakeShape;
 
 /// \class BuildPlugin_Face
 /// \ingroup Plugins
 /// \brief Feature for creation of face from sketch edges or existing wires.
-class BuildPlugin_Face: public ModelAPI_Feature
+class BuildPlugin_Face: public BuildPlugin_Shape
 {
 public:
   /// Use plugin manager for features creation
@@ -68,7 +68,8 @@ private:
   /// Create faces basing on the list of edges
   void buildFacesByEdges(const std::list< std::shared_ptr<GeomAPI_Shape> >& theEdges,
                          const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
-                         std::list< std::shared_ptr<GeomAPI_Shape> >& theFaces) const;
+                         std::list< std::shared_ptr<GeomAPI_Shape> >& theFaces,
+                         std::shared_ptr<GeomAlgoAPI_MakeShape>& theBuilderAlgo) const;
 };
 
 #endif
diff --git a/src/BuildPlugin/BuildPlugin_Shape.cpp b/src/BuildPlugin/BuildPlugin_Shape.cpp
new file mode 100644 (file)
index 0000000..60c273c
--- /dev/null
@@ -0,0 +1,78 @@
+// 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>
+//
+
+#include "BuildPlugin_Shape.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_PlanarEdges.h>
+
+
+//=================================================================================================
+void BuildPlugin_Shape::storeResult(const GeomMakeShapePtr& theAlgorithm,
+                                    const ListOfShape& theOriginalShapes,
+                                    const ListOfShape& theOriginalSolids,
+                                    const GeomShapePtr& theResultShape,
+                                    const int theResultIndex)
+{
+  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+  aResultBody->storeModified(theOriginalSolids, theResultShape, theAlgorithm);
+
+  for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
+       anIt != theOriginalShapes.cend();
+       ++anIt)
+  {
+    GeomShapePtr aShape = *anIt;
+    aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::VERTEX);
+    aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::EDGE);
+    aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE);
+  }
+  setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void BuildPlugin_Shape::getOriginalShapesAndContexts(const std::string& theSelectionListID,
+                                                     ListOfShape& theShapes,
+                                                     ListOfShape& theContexts)
+{
+  std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aContexts;
+
+  AttributeSelectionListPtr aSelectionList = selectionList(theSelectionListID);
+  for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+    GeomShapePtr aShape = aSelection->value();
+    GeomShapePtr aContext = aSelection->context()->shape();
+    if (!aShape.get())
+      aShape = aContext;
+    theShapes.push_back(aShape);
+
+    // do not collect sketch faces, because they are stored as compounds
+    // and then are treated as modified by the algorithm
+    if (!std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContext).get())
+      aContexts.insert(aContext);
+  }
+
+  std::set<GeomShapePtr, GeomAPI_Shape::Comparator>::const_iterator anIt = aContexts.begin();
+  for (; anIt != aContexts.end(); ++anIt)
+    theContexts.push_back(*anIt);
+}
diff --git a/src/BuildPlugin/BuildPlugin_Shape.h b/src/BuildPlugin/BuildPlugin_Shape.h
new file mode 100644 (file)
index 0000000..e858ca1
--- /dev/null
@@ -0,0 +1,51 @@
+// 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>
+//
+
+#ifndef BuildPlugin_Shape_H_
+#define BuildPlugin_Shape_H_
+
+#include "BuildPlugin.h"
+
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+
+/// \class BuildPlugin_Shape
+/// \ingroup Plugins
+/// \brief Base class containing common methods for shape creating operations.
+class BuildPlugin_Shape: public ModelAPI_Feature
+{
+protected:
+  /// Obtain list of selected shapes and their contexts
+  void getOriginalShapesAndContexts(const std::string& theSelectionListID,
+                                    ListOfShape& theShapes,
+                                    ListOfShape& theContexts);
+
+  /// Store result of algorithm
+  void storeResult(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm,
+                   const ListOfShape& theOriginalShapes,
+                   const ListOfShape& theOriginalContexts,
+                   const GeomShapePtr& theResultShape,
+                   const int theResultIndex = 0);
+};
+
+#endif
index bd73c2f1fd1ac6ec5486cab5f7032a6d0561ebe4..4e27b66c29ac88016c93e6378efdca3f0d0429ed 100644 (file)
@@ -46,15 +46,8 @@ void BuildPlugin_Shell::execute()
   AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
 
   // Collect base shapes.
-  ListOfShape aShapes;
-  for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
-    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    GeomShapePtr aShape = aSelection->value();
-    if(!aShape.get()) {
-      aShape = aSelection->context()->shape();
-    }
-    aShapes.push_back(aShape);
-  }
+  ListOfShape aShapes, aContexts;
+  getOriginalShapesAndContexts(BASE_OBJECTS_ID(), aShapes, aContexts);
 
   // Sew faces.
   GeomMakeShapePtr aSewingAlgo(new GeomAlgoAPI_Sewing(aShapes));
@@ -71,35 +64,7 @@ void BuildPlugin_Shell::execute()
   int anIndex = 0;
   for(GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::SHELL); anExp.more(); anExp.next()) {
     GeomShapePtr aShell = anExp.current();
-    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
-    aResultBody->store(aShell);
-    for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) {
-      for (GeomAPI_ShapeExplorer aFaceExp(*anIt, GeomAPI_Shape::FACE);
-           aFaceExp.more();
-           aFaceExp.next())
-      {
-        GeomShapePtr aFace = aFaceExp.current();
-        ListOfShape aHistory;
-        aSewingAlgo->modified(aFace, aHistory);
-        for (ListOfShape::const_iterator aHistoryIt = aHistory.cbegin();
-             aHistoryIt != aHistory.cend();
-             ++aHistoryIt)
-        {
-          GeomShapePtr aHistoryShape = *aHistoryIt;
-          if (aShell->isSubShape(aHistoryShape, false)) {
-            aResultBody->loadModifiedShapes(aSewingAlgo,
-                                            aFace,
-                                            GeomAPI_Shape::EDGE);
-            aResultBody->loadModifiedShapes(aSewingAlgo,
-                                            aFace,
-                                            GeomAPI_Shape::FACE);
-            break;
-          }
-        }
-      }
-    }
-    setResult(aResultBody, anIndex);
-    ++anIndex;
+    storeResult(aSewingAlgo, aShapes, aContexts, aShell, anIndex++);
   }
 
   removeResults(anIndex);
index 4fe6d2fdbb904839c1ec5b1fa9c138192788b48b..3b7245482f33fda15c63f83f8ad373b466acfcaa 100644 (file)
 #define BuildPlugin_Shell_H_
 
 #include "BuildPlugin.h"
-
-#include <ModelAPI_Feature.h>
+#include "BuildPlugin_Shape.h"
 
 /// \class BuildPlugin_Shell
 /// \ingroup Plugins
 /// \brief Feature for creation of shell from faces and shells.
-class BuildPlugin_Shell: public ModelAPI_Feature
+class BuildPlugin_Shell: public BuildPlugin_Shape
 {
 public:
   /// Use plugin manager for features creation
index dc0c57ed54d37afb59bca4fb74b1f75aadaa2f36..399289537ac2d541c4141fc2e00e4aa4545a2c21 100644 (file)
@@ -23,6 +23,7 @@
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
 
+#include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_ShapeIterator.h>
 
 #include <GeomAlgoAPI_MakeVolume.h>
@@ -42,38 +43,15 @@ void BuildPlugin_Solid::initAttributes()
 void BuildPlugin_Solid::execute()
 {
   // all the needed checkings are in validator, so, here just make and store result
-  ListOfShape anOriginalShapes;
-  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
-  for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
-    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    GeomShapePtr aShape = aSelection->value();
-    if (!aShape.get())
-      aShape = aSelection->context()->shape();
-    anOriginalShapes.push_back(aShape);
-  }
+  ListOfShape anOriginalFaces;
+  ListOfShape anOriginalSolids;
+  getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, anOriginalSolids);
+
   std::shared_ptr<GeomAlgoAPI_MakeVolume> anAlgo(
-    new GeomAlgoAPI_MakeVolume(anOriginalShapes, false));
+    new GeomAlgoAPI_MakeVolume(anOriginalFaces, false));
   // check and process result of volume maker
   GeomShapePtr aResShape = getSingleSubshape(anAlgo->shape());
-  storeResult(anOriginalShapes, aResShape, anAlgo);
-}
-
-void BuildPlugin_Solid::storeResult(const ListOfShape& theOriginalShapes,
-                                    const GeomShapePtr& theResultShape,
-                                    const GeomMakeShapePtr& theAlgorithm)
-{
-  ResultBodyPtr aResultBody = document()->createBody(data());
-  aResultBody->store(theResultShape);
-
-  // Store faces
-  for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
-       anIt != theOriginalShapes.cend();
-       ++anIt)
-  {
-    GeomShapePtr aShape = *anIt;
-    aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE);
-  }
-  setResult(aResultBody);
+  storeResult(anAlgo, anOriginalFaces, anOriginalSolids, aResShape);
 }
 
 GeomShapePtr BuildPlugin_Solid::getSingleSubshape(const GeomShapePtr& theCompound)
index 1fce3df589b7968ea228226b5ce75e718398183a..1ab5168e5772486591c95f47176a710e3989bf6a 100644 (file)
 #define BuildPlugin_Solid_H_
 
 #include "BuildPlugin.h"
-
-#include <GeomAPI_Shape.h>
-#include <ModelAPI_Feature.h>
-
-class GeomAlgoAPI_MakeShape;
+#include "BuildPlugin_Shape.h"
 
 /// \class BuildPlugin_Solid
 /// \ingroup Plugins
 /// \brief Feature for creation of solid from faces or shells.
-class BuildPlugin_Solid: public ModelAPI_Feature
+class BuildPlugin_Solid: public BuildPlugin_Shape
 {
 public:
   /// Use plugin manager for features creation
@@ -65,11 +61,6 @@ public:
   BUILDPLUGIN_EXPORT virtual void execute();
 
 protected:
-  /// Store result of algorithm
-  void storeResult(const ListOfShape& theOriginalShapes,
-                   const GeomShapePtr& theResultShape,
-                   const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
-
   /// Explode compound to get single shape
   GeomShapePtr getSingleSubshape(const GeomShapePtr& theCompound);
 };
index 3b4c4b950c4d645d2f844163f730110eb815196f..de035b915a93966add2846987d278a11470805c3 100644 (file)
@@ -247,9 +247,8 @@ bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptr<ModelAPI_Fe
     }
 
     // Check that selected objects have closed contours.
-    ListOfShape aFaces;
-    GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
-                                           aPln->direction(), anEdges, aFaces);
+    GeomAlgoAPI_SketchBuilder aBuilder(aPln, anEdges);
+    const ListOfShape& aFaces = aBuilder.faces();
     if(aFaces.empty()) {
       theError = "Selected objects do not generate closed contour.";
       return false;
index ac7d7d63f6bb1a365e8e43c3a21629aac6a0d974..b1fb9f155f5f2d6b39d7301df56d4c85c3d3b830 100644 (file)
@@ -32,6 +32,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
 SET(PROJECT_HEADERS
     BuildPlugin.h
     BuildPlugin_Plugin.h
+    BuildPlugin_Shape.h
     BuildPlugin_Vertex.h
     BuildPlugin_Edge.h
     BuildPlugin_Wire.h
@@ -49,6 +50,7 @@ SET(PROJECT_HEADERS
 
 SET(PROJECT_SOURCES
     BuildPlugin_Plugin.cpp
+    BuildPlugin_Shape.cpp
     BuildPlugin_Vertex.cpp
     BuildPlugin_Edge.cpp
     BuildPlugin_Wire.cpp
index d85f2a3f963572ac24f43c849f31cdc1d87c5edb..782fdedac88d57f1342250b820608a2f8dd06c11 100644 (file)
@@ -123,5 +123,8 @@ ADD_UNIT_TESTS(
                TestGroupMove13.py
                TestGroupMove14.py
                TestGroupMove15.py
+               TestGroupMove16.py
+               TestGroupMove17.py
+               TestGroupMove18.py
                TestGroupShareTopology.py
 )
diff --git a/src/CollectionPlugin/Test/TestGroupMove16.py b/src/CollectionPlugin/Test/TestGroupMove16.py
new file mode 100644 (file)
index 0000000..ced352d
--- /dev/null
@@ -0,0 +1,70 @@
+## 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. Compsolid operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+    # move groups to the end
+    model.begin()
+    LastFeature = theLastFeature
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+        Part_1_doc.moveFeature(GroupFeature, LastFeature)
+        LastFeature = GroupFeature
+    model.end()
+
+    a = 0
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+        assert(aFactory.validate(GroupFeature))
+        assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+        a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top"))
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133)
+model.do()
+CompSolid_1 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")])
+model.do()
+model.end()
+
+num_in_groups = [2, 10, 16, 8]
+moveGroupsAndVerify(Part_1_doc, CompSolid_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
diff --git a/src/CollectionPlugin/Test/TestGroupMove17.py b/src/CollectionPlugin/Test/TestGroupMove17.py
new file mode 100644 (file)
index 0000000..673f10f
--- /dev/null
@@ -0,0 +1,71 @@
+## 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. Solid operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+    # move groups to the end
+    model.begin()
+    LastFeature = theLastFeature
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+        Part_1_doc.moveFeature(GroupFeature, LastFeature)
+        LastFeature = GroupFeature
+    model.end()
+
+    a = 0
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+        assert(aFactory.validate(GroupFeature))
+        assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+        a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top"))
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133)
+model.do()
+Solid_1_objects = [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Right")]
+Solid_1 = model.addSolid(Part_1_doc, Solid_1_objects)
+model.do()
+model.end()
+
+num_in_groups = [1, 5, 8, 4]
+moveGroupsAndVerify(Part_1_doc, Solid_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
diff --git a/src/CollectionPlugin/Test/TestGroupMove18.py b/src/CollectionPlugin/Test/TestGroupMove18.py
new file mode 100644 (file)
index 0000000..889fa54
--- /dev/null
@@ -0,0 +1,70 @@
+## 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. Shell operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+    # move groups to the end
+    model.begin()
+    LastFeature = theLastFeature
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+        Part_1_doc.moveFeature(GroupFeature, LastFeature)
+        LastFeature = GroupFeature
+    model.end()
+
+    a = 0
+    for i in range(thePart.size("Groups")):
+        GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+        assert(aFactory.validate(GroupFeature))
+        assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+        a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][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/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Shell_1_objects = [model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Left"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Right")]
+Shell_1 = model.addShell(Part_1_doc, Shell_1_objects)
+model.do()
+model.end()
+
+num_in_groups = [6, 13, 6]
+moveGroupsAndVerify(Part_1_doc, Shell_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
index d7840b16832d8cb297b4b9a024d0098ef953a5c7..7427c4e72dc96e27921453b0734578b8c093ed1d 100644 (file)
@@ -689,3 +689,9 @@ bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const
 
   return false;
 }
+
+bool GeomAPI_Shape::Comparator::operator()(const std::shared_ptr<GeomAPI_Shape>& theShape1,
+                                           const std::shared_ptr<GeomAPI_Shape>& theShape2) const
+{
+  return theShape1->impl<TopoDS_Shape>().TShape() < theShape2->impl<TopoDS_Shape>().TShape();
+}
index a70574aa4e44fb3fc54429c0e28fe4dbbec835f5..d0bc66339fef8778b8a6ab01864de3d5a201087f 100644 (file)
@@ -219,6 +219,16 @@ public:
   /// 8 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S and F/S;<br>
   /// 9 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S, F/S and S/S - all interferences (Default value)
   GEOMAPI_EXPORT bool isSelfIntersected(const int theLevelOfCheck = 9) const;
+
+public:
+  class Comparator
+  {
+  public:
+    /// Return \c true if the address of the first shape is less than the address of the second
+    GEOMAPI_EXPORT
+    bool operator ()(const std::shared_ptr<GeomAPI_Shape>& theShape1,
+                     const std::shared_ptr<GeomAPI_Shape>& theShape2) const;
+  };
 };
 
 //! Pointer on list of shapes
index a6ce40e6b7ce9143288b9b09eab61d5026e73a6d..8fb19d4baad16e6fed5a9495b0eb3ffb3ab06af7 100644 (file)
@@ -50,6 +50,7 @@
 %shared_ptr(GeomAlgoAPI_Revolution)
 %shared_ptr(GeomAlgoAPI_Rotation)
 %shared_ptr(GeomAlgoAPI_Sewing)
+%shared_ptr(GeomAlgoAPI_SketchBuilder)
 %shared_ptr(GeomAlgoAPI_ShapeBuilder)
 %shared_ptr(GeomAlgoAPI_Translation)
 %shared_ptr(GeomAlgoAPI_Transform)
index f730342fdf58d1547395c6701556cade9d6fd4ee..89549b88411a95e269a2d4615a727a4cfd87ccc7 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "GeomAlgoAPI_MakeVolume.h"
 
+#include <GeomAPI_ShapeExplorer.h>
+
 #include <GeomAlgoAPI_ShapeTools.h>
 
 #include <BOPAlgo_MakerVolume.hxx>
@@ -91,3 +93,32 @@ void GeomAlgoAPI_MakeVolume::build(const ListOfShape& theFaces)
   this->setShape(aShape);
   this->setDone(true);
 }
+
+//=================================================================================================
+void GeomAlgoAPI_MakeVolume::modified(const GeomShapePtr theOldShape,
+                                      ListOfShape& theNewShapes)
+{
+  if (theOldShape->shapeType() == GeomAPI_Shape::SOLID) {
+    ListOfShape aNewShapes;
+    // collect faces and parent shapes, if it is not done yet
+    if (!isNewShapesCollected(theOldShape, GeomAPI_Shape::FACE))
+      collectNewShapes(theOldShape, GeomAPI_Shape::FACE);
+
+    for (GeomAPI_ShapeExplorer anIt(shape(), GeomAPI_Shape::SOLID); anIt.more(); anIt.next()) {
+      for (GeomAPI_ShapeExplorer anExp(anIt.current(), GeomAPI_Shape::FACE);
+           anExp.more(); anExp.next()) {
+        GeomShapePtr anOldShapesCompound =
+            oldShapesForNew(theOldShape, anExp.current(), GeomAPI_Shape::FACE);
+        if (!anOldShapesCompound->isNull()) {
+          aNewShapes.push_back(anIt.current());
+          break;
+        }
+      }
+    }
+
+    if (!aNewShapes.empty())
+      theNewShapes = aNewShapes;
+  }
+  else
+    GeomAlgoAPI_MakeShape::modified(theOldShape, theNewShapes);
+}
index c8bcf3005f38812d5b854586fb54bd9e9eaee456..ab11e510cb5e3677f03f1a4634cb542050c69fa0 100644 (file)
@@ -44,6 +44,12 @@ public:
   GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeVolume(const ListOfShape& theFaces,
     const bool theAvoidInternal);
 
+  /// \return the list of shapes modified from the shape \a theShape.
+  /// \param[in] theOldShape base shape.
+  /// \param[out] theNewShapes shapes modified from \a theShape. Does not cleared!
+  GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape,
+                                           ListOfShape& theNewShapes);
+
 private:
   /// Builds resulting shape.
   void build(const ListOfShape& theFaces);
index b30d1dd60dff6c9a82730b1f1f6534ecffac00d3..3510f87357a3482aab5a2e84868cbec84f5bfd3f 100644 (file)
@@ -80,6 +80,30 @@ void GeomAlgoAPI_Sewing::build(const ListOfShape& theShapes)
 }
 
 //==================================================================================================
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+typedef std::map<GeomShapePtr, ListOfShape, GeomAPI_Shape::Comparator> MapFaceSolid;
+static void facesBelongingToSolids(const GeomShapePtr& theShape,
+                                   MapFaceSolid& theShapeRelations)
+{
+  for (GeomAPI_ShapeExplorer aSolidExp(theShape, GeomAPI_Shape::SHELL);
+       aSolidExp.more(); aSolidExp.next()) {
+    GeomShapePtr aSolid = aSolidExp.current();
+    for (GeomAPI_ShapeExplorer aFaceExp(aSolid, GeomAPI_Shape::FACE);
+         aFaceExp.more(); aFaceExp.next())
+      theShapeRelations[aFaceExp.current()].push_back(aSolid);
+  }
+}
+
+static bool isShapeInList(const GeomShapePtr& theShape, const ListOfShape& theList)
+{
+  for (ListOfShape::const_iterator anIt = theList.begin(); anIt != theList.end(); ++anIt)
+    if (theShape->isEqual(*anIt))
+      return true;
+  return false;
+}
+
 void GeomAlgoAPI_Sewing::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
                                   ListOfShape& theHistory)
 {
@@ -101,4 +125,21 @@ void GeomAlgoAPI_Sewing::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
     aGeomShape->setImpl(new TopoDS_Shape(anExp.Current()));
     theHistory.push_back(aGeomShape);
   }
+
+  if (theShape->shapeType() < GeomAPI_Shape::FACE) {
+    ListOfShape aNewShapes;
+    // collect faces and parent shapes, if it is not done yet
+    if (!isNewShapesCollected(theShape, GeomAPI_Shape::FACE))
+      collectNewShapes(theShape, GeomAPI_Shape::FACE);
+
+    for (GeomAPI_ShapeIterator anIt(shape()); anIt.more(); anIt.next()) {
+      GeomShapePtr anOldShapesCompound =
+          oldShapesForNew(theShape, anIt.current(), GeomAPI_Shape::FACE);
+      if (!anOldShapesCompound->isNull())
+        aNewShapes.push_back(anIt.current());
+    }
+
+    if (!aNewShapes.empty())
+      theHistory = aNewShapes;
+  }
 }
index ce3f7c82e6231e754610a8916f61cae427f1f21a..90fbacd0e4ac050bb79fc8b90b002898bf4584fb 100644 (file)
@@ -21,6 +21,8 @@
 #include <GeomAlgoAPI_SketchBuilder.h>
 #include <GeomAPI_PlanarEdges.h>
 
+#include <GeomAPI_Pln.h>
+
 #include <BOPAlgo_Builder.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepTools_WireExplorer.hxx>
@@ -199,14 +201,15 @@ static void sortFaces(TopTools_ListOfShape& theAreas,
   }
 }
 
-void GeomAlgoAPI_SketchBuilder::createFaces(
+void GeomAlgoAPI_SketchBuilder::build(
     const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
     const std::shared_ptr<GeomAPI_Dir>& theDirX,
     const std::shared_ptr<GeomAPI_Dir>& theNorm,
-    const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
-    std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
+    const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges)
 {
-  if (theFeatures.empty())
+  myResultFaces.clear();
+  setDone(false);
+  if (theEdges.empty())
     return;
 
   BRep_Builder aBuilder;
@@ -216,24 +219,31 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
   aBuilder.MakeFace(aPlnFace, aPlane, Precision::Confusion());
 
   // Use General Fuse algorithm to prepare all subfaces, bounded by given list of edges
-  BOPAlgo_Builder aBB;
-  aBB.AddArgument(aPlnFace);
+  BOPAlgo_Builder* aBB = new BOPAlgo_Builder;
+  aBB->AddArgument(aPlnFace);
+
+  setImpl(aBB);
+  setBuilderType(OCCT_BOPAlgo_Builder);
 
   NCollection_List<TopoDS_Shape> anEdges;
   NCollection_List<TopoDS_Shape>::Iterator aShapeIt;
-  std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theFeatures.begin();
-  for (; aFeatIt != theFeatures.end(); aFeatIt++) {
+  std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theEdges.begin();
+  for (; aFeatIt != theEdges.end(); aFeatIt++) {
     std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
     const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
     if (anEdge.ShapeType() == TopAbs_EDGE)
-      aBB.AddArgument(anEdge);
+      aBB->AddArgument(anEdge);
   }
-  aBB.Perform();
-  if (aBB.HasErrors())
+  aBB->Perform();
+  if (aBB->HasErrors())
     return;
+
+  TopoDS_Compound aResult;
+  aBuilder.MakeCompound(aResult);
+
   // Collect faces
-  TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace);
-  sortFaces(anAreas, theFeatures); // sort faces by the edges in them
+  TopTools_ListOfShape anAreas = aBB->Modified(aPlnFace);
+  sortFaces(anAreas, theEdges); // sort faces by the edges in them
   TopTools_ListIteratorOfListOfShape anIt(anAreas);
   for (; anIt.More(); anIt.Next()) {
     TopoDS_Face aFace = TopoDS::Face(anIt.Value());
@@ -253,7 +263,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
 
       // to make faces equal on different platforms, we will find
       // a vertex lying on an edge with the lowest index in the list of initial edges
-      TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theFeatures);
+      TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theEdges);
 
       TopoDS_Wire aNewWire;
       aBuilder.MakeWire(aNewWire);
@@ -289,30 +299,43 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
     }
 
     // store face
-    aFace = aNewFace;
+    aBuilder.Add(aResult, aNewFace);
     std::shared_ptr<GeomAPI_Shape> aResFace(new GeomAPI_Shape);
     aResFace->setImpl(new TopoDS_Face(aFace));
-    theResultFaces.push_back(aResFace);
+    myResultFaces.push_back(aResFace);
   }
+
+  // update results
+  GeomShapePtr aResShape(new GeomAPI_Shape);
+  aResShape->setImpl(new TopoDS_Shape(aResult));
+  setShape(aResShape);
+  setDone(true);
 }
 
-void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
-                                            const std::shared_ptr<GeomAPI_Dir>& theDirX,
-                                            const std::shared_ptr<GeomAPI_Dir>& theNorm,
-                                            const std::shared_ptr<GeomAPI_Shape>& theWire,
-                                std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
+GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder(
+  const std::shared_ptr<GeomAPI_Pln>& thePlane,
+  const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges)
+{
+  build(thePlane->location(), thePlane->xDirection(), thePlane->direction(), theEdges);
+}
+
+GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder(
+    const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+    const std::shared_ptr<GeomAPI_Dir>& theDirX,
+    const std::shared_ptr<GeomAPI_Dir>& theNorm,
+    const std::shared_ptr<GeomAPI_Shape>& theWire)
 {
   std::shared_ptr<GeomAPI_PlanarEdges> aWire =
     std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(theWire);
   if(aWire) {
     // Filter wires, return only faces.
-    createFaces(theOrigin, theDirX, theNorm, aWire->getEdges(), theResultFaces);
+    build(theOrigin, theDirX, theNorm, aWire->getEdges());
   } else { // it may be only one circle
     std::shared_ptr<GeomAPI_Edge> anEdge = std::dynamic_pointer_cast<GeomAPI_Edge>(theWire);
     if (anEdge) {
       std::list<std::shared_ptr<GeomAPI_Shape> > aList;
       aList.push_back(anEdge);
-      createFaces(theOrigin, theDirX, theNorm, aList, theResultFaces);
+      build(theOrigin, theDirX, theNorm, aList);
     }
   }
 }
index 9fcaec2c3c839a7767190a2bde7a42abbc0fc1fe..0c93379de6c09c5717a264e7d0050bfaafeafecd 100644 (file)
 #define GeomAlgoAPI_SketchBuilder_H_
 
 #include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
 
 #include <memory>
 #include <list>
 
-#include <GeomAPI_Dir.h>
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_Shape.h>
+class GeomAPI_Dir;
+class GeomAPI_Pln;
+class GeomAPI_Pnt;
+class GeomAPI_Shape;
 
 /** \class GeomAlgoAPI_SketchBuilder
  *  \ingroup DataAlgo
  *  \brief Creates planar faces based on the list of Sketch features
  */
-class GEOMALGOAPI_EXPORT GeomAlgoAPI_SketchBuilder
+class GeomAlgoAPI_SketchBuilder : public GeomAlgoAPI_MakeShape
 {
- public:
-  /** \brief Creates list of faces based on the features of the sketch
-   *  \param[in]  theOrigin      origin point of the sketch
-   *  \param[in]  theDirX        x-direction of the sketch
-   *  \param[in]  theNorm        normal of the sketch
-   *  \param[in]  theFeatures    initial features of the sketch
-   *  \param[out] theResultFaces faces based on closed wires
+public:
+  /** \brief Creates list of faces based on the edges of the sketch
+   *  \param[in]  thePlane  plane of the sketch
+   *  \param[in]  theEdges  initial edges of the sketch
    *
    *  The algorithm searches all loops of edges surrounding lesser areas.
    */
-  static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
-                          const std::shared_ptr<GeomAPI_Dir>& theDirX,
-                          const std::shared_ptr<GeomAPI_Dir>& theNorm,
-                          const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
-                          std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces);
+  GEOMALGOAPI_EXPORT
+  GeomAlgoAPI_SketchBuilder(const std::shared_ptr<GeomAPI_Pln>& thePlane,
+                            const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges);
 
   /** \brief Creates list of faces and unclosed wires on basis of the features of the sketch
    *  \param[in]  theOrigin      origin point of the sketch
    *  \param[in]  theDirX        x-direction of the sketch
    *  \param[in]  theNorm        normal of the sketch
    *  \param[in]  theWire        a wire which contains all edges
-   *  \param[out] theResultFaces faces based on closed wires
    *
    *  The algorithm searches all loops of edges surrounding lesser areas.
    */
-  static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
-                          const std::shared_ptr<GeomAPI_Dir>& theDirX,
-                          const std::shared_ptr<GeomAPI_Dir>& theNorm,
-                          const std::shared_ptr<GeomAPI_Shape>& theWire,
-                          std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces);
+  GEOMALGOAPI_EXPORT
+  GeomAlgoAPI_SketchBuilder(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                            const std::shared_ptr<GeomAPI_Dir>& theDirX,
+                            const std::shared_ptr<GeomAPI_Dir>& theNorm,
+                            const std::shared_ptr<GeomAPI_Shape>& theWire);
+
+  /// Return list of created faces
+  GEOMALGOAPI_EXPORT const std::list<std::shared_ptr<GeomAPI_Shape> >& faces() const
+  { return myResultFaces; }
+
+private:
+  void build(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+             const std::shared_ptr<GeomAPI_Dir>& theDirX,
+             const std::shared_ptr<GeomAPI_Dir>& theNorm,
+             const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges);
+
+private:
+  std::list<std::shared_ptr<GeomAPI_Shape> > myResultFaces;
 };
 
 #endif
index 272cb7338a24527bc298cd3b8807e42d9544fce8..8765caeb0daf9fca4bb5d7c230185a27bb78cd4b 100644 (file)
@@ -292,12 +292,12 @@ void Model_ResultConstruction::storeShape(std::shared_ptr<GeomAPI_Shape> theShap
         }
       }
 
-      std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
-      GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
-        aWirePtr->norm(), aWirePtr, aFaces);
+      GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(),
+                                               aWirePtr->norm(), aWirePtr);
+      const ListOfShape& aFaces = aSketchBuilder.faces();
       // order is important to store faces in the same order if sketch is created from scratch
       NCollection_IndexedDataMap<TopoDS_Face, TColStd_ListOfInteger> aNewIndices; // edges indices
-      std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFIter = aFaces.begin();
+      std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFIter = aFaces.begin();
       for (; aFIter != aFaces.end(); aFIter++) {
         std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
         // put them to a label, trying to keep the same faces on the same labels