]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1366: "Partition" feature now modified to "Generalized Partition"
authordbv <dbv@opencascade.com>
Fri, 20 May 2016 13:26:27 +0000 (16:26 +0300)
committerdbv <dbv@opencascade.com>
Fri, 20 May 2016 13:26:55 +0000 (16:26 +0300)
16 files changed:
src/BuildPlugin/BuildPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp
src/FeaturesPlugin/FeaturesPlugin_Partition.cpp
src/FeaturesPlugin/FeaturesPlugin_Partition.h
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/boolean_widget.xml
src/FeaturesPlugin/group_widget.xml
src/FeaturesPlugin/partition_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Partition.h
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomValidators/GeomValidators_BodyShapes.cpp
src/Model/Model_BodyBuilder.cpp

index cde7cf95bc11cf81c3d5cb97dcaac299f5781cc2..4027ff1d89f418f2619364c36a65774b40b2352a 100644 (file)
@@ -302,7 +302,7 @@ bool BuildPlugin_ValidatorSubShapesSelection::isValid(const AttributePtr& theAtt
     }
 
     // Check that shape inside wire or face.
-    if(!GeomAlgoAPI_ShapeTools::isSubShapeInShape(aShapeInList, aBaseShape)) {
+    if(!GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aShapeInList, aBaseShape)) {
       theError = "Selected shape is not inside base face.";
       return false;
     }
index 1759b26b88cc6e136e9556f04bf6f69fce0d2ed4..309a4bd9d673ab947f8beb6062ec11ca5bf1ea04 100644 (file)
@@ -238,10 +238,10 @@ bool FeaturesPlugin_CompositeSketch::isMakeShapeValid(const std::shared_ptr<Geom
 //=================================================================================================
 void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape,
                                                  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
-                                                 const int theResultIndex)
+                                                 const int theIndex)
 {
   // Create result body.
-  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+  ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
 
   // Store generated shape.
   aResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
@@ -250,7 +250,7 @@ void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape
   int aGenTag = 1;
   storeGenerationHistory(aResultBody, theBaseShape, theMakeShape, aGenTag);
 
-  setResult(aResultBody, theResultIndex);
+  setResult(aResultBody, theIndex);
 }
 
 //=================================================================================================
index 74e68707e8fcece75c4a2a745691d4163521ea9f..7d5e2e90c5f23d1e5f5ad882df715cc45b17f50f 100755 (executable)
@@ -23,6 +23,8 @@
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 
+#include <GeomAPI_ShapeIterator.h>
+
 #include <sstream>
 
 //=================================================================================================
@@ -33,185 +35,132 @@ FeaturesPlugin_Partition::FeaturesPlugin_Partition()
 //=================================================================================================
 void FeaturesPlugin_Partition::initAttributes()
 {
-  AttributeSelectionListPtr aSelection =
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    FeaturesPlugin_Partition::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  aSelection->setSelectionType("SOLID");
-
-  aSelection =
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    FeaturesPlugin_Partition::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  aSelection->setSelectionType("SOLID");
-
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
-
-  data()->addAttribute(COMBINE_ID(), ModelAPI_AttributeBoolean::typeId());
+  data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
 }
 
 //=================================================================================================
 void FeaturesPlugin_Partition::execute()
 {
-  ListOfShape anObjects, aTools, aToolsForNaming;
+  ListOfShape anObjects, aPlanes;
 
   // Getting objects.
-  AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Partition::OBJECT_LIST_ID());
-  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
-    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
-    if (!anObject.get()) {
-      return;
+  AttributeSelectionListPtr anObjectsSelList = selectionList(BASE_OBJECTS_ID());
+  for(int anIndex = 0; anIndex < anObjectsSelList->size(); ++anIndex) {
+    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anIndex);
+    GeomShapePtr anObject = anObjectAttr->value();
+    if(!anObject.get()) {
+      // It could be a construction plane.
+      ResultPtr aContext = anObjectAttr->context();
+      aPlanes.push_back(anObjectAttr->context()->shape());
+    } else {
+      anObjects.push_back(anObject);
     }
-    anObjects.push_back(anObject);
   }
-
-  GeomAlgoAPI_MakeShapeList aMakeShapeList;
   std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
 
-  // Getting tools.
-  AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Partition::TOOL_LIST_ID());
-  for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
-    std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
-    std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
-    if(!aTool.get()) {
-      // it could be a construction plane
-      ResultPtr aContext = aToolAttr->context();
-      if(aContext.get()) {
-        aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aContext->shape(), aBoundingPoints);
-        std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
-        aMkShCustom->addModified(aContext->shape(), aTool);
-        aMakeShapeList.appendAlgo(aMkShCustom);
-        aTools.push_back(aTool);
-        aToolsForNaming.push_back(aContext->shape());
-      }
-    } else {
-      aTools.push_back(aTool);
-      aToolsForNaming.push_back(aTool);
-    }
+  // Resize planes.
+  ListOfShape aTools;
+  std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+  for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); anIt != aPlanes.cend(); ++anIt) {
+    GeomShapePtr aPlane = *anIt;
+    GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
+    std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
+    aMkShCustom->addModified(aPlane, aTool);
+    aMakeShapeList->appendAlgo(aMkShCustom);
+    aTools.push_back(aTool);
   }
 
-  // Getting combine flag.
-  bool isCombine = boolean(COMBINE_ID())->value();
+  // Create single result.
+  std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
 
-  if(anObjects.empty()/* || aTools.empty()*/) {
-    std::string aFeatureError = "Error: Not enough objects for partition operation.";
+  // Checking that the algorithm worked properly.
+  if (!aPartitionAlgo->isDone()) {
+    static const std::string aFeatureError = "Error: Partition algorithm failed.";
+    setError(aFeatureError);
+    return;
+  }
+  if (aPartitionAlgo->shape()->isNull()) {
+    static const std::string aShapeError = "Error: Resulting shape is Null.";
+    setError(aShapeError);
+    return;
+  }
+  if (!aPartitionAlgo->isValid()) {
+    std::string aFeatureError = "Error: Resulting shape is not valid.";
     setError(aFeatureError);
     return;
   }
+  aMakeShapeList->appendAlgo(aPartitionAlgo);
+  GeomShapePtr aResultShape = aPartitionAlgo->shape();
 
   int aResultIndex = 0;
-
-  if(isCombine) {
-    // Create single result.
-    //if(!aTools.empty()) {
-    //  // This is a workaround for naming. Passing compound of objects as argument instead each object separately.
-    //  std::shared_ptr<GeomAPI_Shape> aCompoud = GeomAlgoAPI_CompoundBuilder::compound(anObjects);
-    //  anObjects.clear();
-    //  anObjects.push_back(aCompoud);
-    //}
-    std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
-
-    // Checking that the algorithm worked properly.
-    if (!aPartitionAlgo->isDone()) {
-      static const std::string aFeatureError = "Error: Partition algorithm failed.";
-      setError(aFeatureError);
-      return;
-    }
-    if (aPartitionAlgo->shape()->isNull()) {
-      static const std::string aShapeError = "Error: Resulting shape is Null.";
-      setError(aShapeError);
-      return;
-    }
-    if (!aPartitionAlgo->isValid()) {
-      std::string aFeatureError = "Error: Resulting shape is not valid.";
-      setError(aFeatureError);
-      return;
-    }
-
-    if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo->shape()) > 1.e-27) {
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-      aMakeShapeList.appendAlgo(aPartitionAlgo);
-      GeomAPI_DataMapOfShapeShape& aMapOfShapes = *aPartitionAlgo->mapOfSubShapes().get();
-      std::shared_ptr<GeomAPI_Shape> aBaseShape = anObjects.front();
-      anObjects.pop_front();
-      aToolsForNaming.insert(aToolsForNaming.end(), anObjects.begin(), anObjects.end());
-      loadNamingDS(aResultBody, aBaseShape, aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeList, aMapOfShapes);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
+  anObjects.insert(anObjects.end(), aPlanes.begin(), aPlanes.end());
+  if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+    for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
+      storeResult(anObjects, anIt.current(), aMakeShapeList, aResultIndex);
+      ++aResultIndex;
     }
   } else {
-    // Create result for each object.
-    for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
-      std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
-      ListOfShape aListWithObject; aListWithObject.push_back(anObject);
-      std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(aListWithObject, aTools));
-
-      // Checking that the algorithm worked properly.
-      if (!aPartitionAlgo->isDone()) {
-        static const std::string aFeatureError = "Error: Partition algorithm failed.";
-        setError(aFeatureError);
-        return;
-      }
-      if (aPartitionAlgo->shape()->isNull()) {
-        static const std::string aShapeError = "Error: Resulting shape is Null.";
-        setError(aShapeError);
-        return;
-      }
-      if (!aPartitionAlgo->isValid()) {
-        std::string aFeatureError = "Error: Resulting shape is not valid.";
-        setError(aFeatureError);
-        return;
-      }
-
-      if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo->shape()) > 1.e-27) {
-        std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-        GeomAlgoAPI_MakeShapeList aMakeShapeListCopy = aMakeShapeList;
-        aMakeShapeListCopy.appendAlgo(aPartitionAlgo);
-        GeomAPI_DataMapOfShapeShape aMapOfShapes = *aPartitionAlgo->mapOfSubShapes().get();
-        loadNamingDS(aResultBody, anObject, aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeListCopy, aMapOfShapes);
-        setResult(aResultBody, aResultIndex);
-        aResultIndex++;
-      }
-    }
+    storeResult(anObjects, aResultShape, aMakeShapeList, aResultIndex);
+    ++aResultIndex;
   }
 
-  // remove the rest results if there were produced in the previous pass
+  // Remove the rest results if there were produced in the previous pass.
   removeResults(aResultIndex);
 }
 
 //=================================================================================================
-void FeaturesPlugin_Partition::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                                            const std::shared_ptr<GeomAPI_Shape> theBaseShape,
-                                            const ListOfShape& theTools,
-                                            const std::shared_ptr<GeomAPI_Shape> theResultShape,
-                                            GeomAlgoAPI_MakeShape& theMakeShape,
-                                            GeomAPI_DataMapOfShapeShape& theMapOfShapes)
+void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
+                                           const GeomShapePtr theResultShape,
+                                           const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                           const int theIndex)
 {
-  //load result
-  if(theBaseShape->isEqual(theResultShape)) {
-    theResultBody->store(theResultShape);
-  } else {
-    const int aDeletedTag = 1;
-    const int aSubsolidsTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
-    const int aModifyTag = 100000;
-    int aModifyToolsTag = 200000;
-    std::ostringstream aStream;
-
-    theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
-
-    std::string aModName = "Modified";
-    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
-                                               aModifyTag, aModName, theMapOfShapes, true);
-    theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag);
-
-    int anIndex = 1;
-    for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
-      aStream.str(std::string());
-      aStream.clear();
-      aStream << aModName << "_" << anIndex++;
-      theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE,
-                                                 aModifyToolsTag, aStream.str(), theMapOfShapes, true);
-      theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
-      aModifyToolsTag += 10000;
+  // Find base.
+  GeomShapePtr aBaseShape;
+  for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
+    GeomShapePtr anObjectShape = *anIt;
+    ListOfShape aModifiedShapes;
+    theMakeShape->modified(anObjectShape, aModifiedShapes);
+    for(ListOfShape::const_iterator aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
+      GeomShapePtr aModShape = *aModIt;
+      if(theResultShape->isSubShape(aModShape)) {
+        aBaseShape = anObjectShape;
+        break;
+      }
+    }
+    if(aBaseShape.get()) {
+      break;
     }
   }
+
+  // Create result body.
+  ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
+
+  // Store modified shape.
+  if(aBaseShape->isEqual(theResultShape)) {
+    aResultBody->store(theResultShape);
+    return;
+  }
+
+  const int aDelTag = 1;
+  const int aSubTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
+  int aModTag = aSubTag + 10000;
+  const std::string aModName = "Modified";
+
+  aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
+
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
+  int anIndex = 1;
+  for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
+    std::ostringstream aStream;
+    aStream << aModName << "_" << anIndex++;
+    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE,
+                                             aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
+    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE,
+                                             aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
+    aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE, aDelTag);
+    aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
+    aModTag += 10000;
+  }
+
+  setResult(aResultBody, theIndex);
 }
index bd7d7a7c5fe1f71a9a9c88ba917ea18bf67af1e4..ea50c6e0ae44318100dca849355e367b83f1205b 100755 (executable)
 
 /// \class FeaturesPlugin_Partition
 /// \ingroup Plugins
-/// \brief Feature for applying of Partition operations on Solids. Partition makes conjunctional
+/// \brief Feature for applying of Partition operations on Shapes. Partition makes conjunctional
 /// faces of solids as shared. The result of partitions is a compsolid.
-/// Main objects are solids, tool objects are solids or faces
 class FeaturesPlugin_Partition : public ModelAPI_Feature
 {
 public:
-  /// Extrusion kind
+  /// Feature kind.
   inline static const std::string& ID()
   {
     static const std::string MY_ID("Partition");
     return MY_ID;
   }
-  /// attribute name of referenced object
-  inline static const std::string& OBJECT_LIST_ID()
-  {
-    static const std::string MY_OBJECT_LIST_ID("main_objects");
-    return MY_OBJECT_LIST_ID;
-  }
-  /// attribute name of tool object
-  inline static const std::string& TOOL_LIST_ID()
-  {
-    static const std::string MY_TOOL_LIST_ID("tool_objects");
-    return MY_TOOL_LIST_ID;
-  }
 
-  /// attribute name of combine flag
-  inline static const std::string& COMBINE_ID()
+  /// Attribute name of base objects.
+  inline static const std::string& BASE_OBJECTS_ID()
   {
-    static const std::string MY_COMBINE_ID("partition_combine");
-    return MY_COMBINE_ID;
+    static const std::string MY_BASE_OBJECTS_ID("base_objects");
+    return MY_BASE_OBJECTS_ID;
   }
 
-  /// Returns the kind of a feature
+  /// \return the kind of a feature.
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
   {
     static std::string MY_KIND = FeaturesPlugin_Partition::ID();
@@ -63,14 +50,11 @@ public:
   FeaturesPlugin_Partition();
 
 private:
-  /// Load Naming data structure of the feature to the document
-  void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
-                    const ListOfShape& theTools,
-                    const std::shared_ptr<GeomAPI_Shape> theResultShape,
-                    GeomAlgoAPI_MakeShape& theMakeShape,
-                    GeomAPI_DataMapOfShapeShape& theMapOfShapes);
-
+  /// Stores result of generation.
+  void storeResult(const ListOfShape& theObjects,
+                   const GeomShapePtr theResultShape,
+                   const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                   const int theIndex = 0);
 };
 
 #endif
index 4bea20fc2c1bc1f763bb5248c69228c33b8fff85..75ee7ff6666f67e38d96f9f8f2d6d68e6cb70857 100644 (file)
@@ -44,8 +44,10 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorPipeLocations);
   aFactory->registerValidator("FeaturesPlugin_ValidatorCanBeEmpty",
                               new FeaturesPlugin_ValidatorCanBeEmpty);
-  aFactory->registerValidator("FeaturesPlugin_BooleanSelection",
-                              new FeaturesPlugin_BooleanSelection);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection",
+                              new FeaturesPlugin_ValidatorBooleanSelection);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorPartitionSelection",
+                              new FeaturesPlugin_ValidatorPartitionSelection);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
index 37d03e3a9476a17a8a9406e106dd921346da2b95..4f9d860c7a9fb0e75ffde155e2fc122a4fc11cd8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <Events_Error.h>
 
+#include <GeomValidators_BodyShapes.h>
 #include <GeomValidators_FeatureKind.h>
 #include <GeomValidators_ShapeType.h>
 
@@ -377,93 +378,9 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr&
 }
 
 //==================================================================================================
-bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribute,
-                                                  const std::list<std::string>& theArguments,
-                                                  std::string& theError) const
-{
-  // Get base objects list.
-  if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
-    Events_Error::send("Validator does not support attribute type \"" + theAttribute->attributeType()
-      + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId() + "\" supported.");
-    return false;
-  }
-  AttributeSelectionListPtr aSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
-  if(!aSelectionList.get()) {
-    theError = "Could not get selection list.";
-    return false;
-  }
-  if(aSelectionList->size() == 0) {
-    theError = "Empty selection list.";
-    return false;
-  }
-
-  // Collect base shapes.
-  ListOfShape aListOfShapes;
-  for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
-    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    if(!aSelection.get()) {
-      theError = "Could not get selection.";
-      return false;
-    }
-    ResultPtr aContext = aSelection->context();
-    if(!aContext.get()) {
-      theError = "Attribute have empty context.";
-      return false;
-    }
-
-    GeomShapePtr aShape = aSelection->value();
-    GeomShapePtr aContextShape = aContext->shape();
-    if(!aShape.get()) {
-      aShape = aContextShape;
-    }
-    if(!aShape.get()) {
-      theError = "Empty shape selected.";
-      return false;
-    }
-
-    // Check that shape has acceptable type.
-    if(aShape->shapeType() != GeomAPI_Shape::EDGE && aShape->shapeType() != GeomAPI_Shape::WIRE) {
-      theError = "Selected shape has wrong type. Only edges and wires acceptable.";
-      return false;
-    }
-
-    // Check that it is edge on sketch.
-    ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
-    if(aConstruction.get()) {
-      if(aConstruction->isInfinite()) {
-        theError = "Inifinte objects not acceptable.";
-        return false;
-      }
-
-      std::shared_ptr<GeomAPI_PlanarEdges> anEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContextShape);
-      if(!anEdges.get()) {
-        // It is not an edge on the sketch.
-        // Check that it is not local selection.
-        if(!aShape->isEqual(aContextShape)) {
-          // Local selection on body does not allowed.
-          theError = "Selected shape is in the local selection. Only global selection is allowed.";
-          return false;
-        }
-      }
-    }
-
-    aListOfShapes.push_back(aShape);
-  }
-
-  // Create wire.
-  GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes);
-  if(!aWire.get()) {
-    theError = "Result wire empty. Probably it has disconnected edges or non-manifold.";
-    return false;
-  }
-
-  return true;
-}
-
-//==================================================================================================
-bool FeaturesPlugin_BooleanSelection::isValid(const AttributePtr& theAttribute,
-                                              const std::list<std::string>& theArguments,
-                                              std::string& theError) const
+bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
+                                                       const std::list<std::string>& theArguments,
+                                                       std::string& theError) const
 {
   AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
   if(!anAttrSelectionList.get()) {
@@ -521,3 +438,22 @@ bool FeaturesPlugin_BooleanSelection::isValid(const AttributePtr& theAttribute,
 
   return true;
 }
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
+                                                         const std::list<std::string>& theArguments,
+                                                         std::string& theError) const
+{
+  GeomValidators_BodyShapes aBodyValidator;
+  if(aBodyValidator.isValid(theAttribute, theArguments, theError)) {
+    return true;
+  }
+
+  GeomValidators_FeatureKind aFeatureKindValidator;
+  if(aFeatureKindValidator.isValid(theAttribute, theArguments, theError)) {
+    return true;
+  }
+
+  theError = "Only body shapes and construction planes are allowed for selection.";
+  return false;
+}
index 1b957a7772bd37f3a405bfdb74699e5025bcdab8..905eec5c62fd1deff58f48ff177b538e6dce5564 100644 (file)
@@ -87,26 +87,26 @@ private:
                           std::string& theError) const;
 };
 
-/// \class FeaturesPlugin_ValidatorBaseForWire
+/// \class FeaturesPlugin_ValidatorBooleanSelection
 /// \ingroup Validators
-/// \brief A validator for selection base shapes for wire. Allows to select edges on sketch and
-/// wires objects that are connected to already selected shapes.
-class FeaturesPlugin_ValidatorBaseForWire: public ModelAPI_AttributeValidator
+/// \brief Validates selection for boolean operation.
+class FeaturesPlugin_ValidatorBooleanSelection: public ModelAPI_AttributeValidator
 {
 public:
-  //! Returns true if attribute is ok.
-  //! \param[in] theAttribute the checked attribute.
-  //! \param[in] theArguments arguments of the attribute.
-  //! \param[out] theError error message.
-   virtual bool isValid(const AttributePtr& theAttribute,
-                        const std::list<std::string>& theArguments,
-                        std::string& theError) const;
+  /// \return True if the attribute is valid. It checks whether the selection
+  /// is acceptable for boolean operation.
+  /// \param[in] theAttribute an attribute to check.
+  /// \param[in] theArguments a filter parameters.
+  /// \param[out] theError error message.
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments,
+                       std::string& theError) const;
 };
 
-/// \class FeaturesPlugin_BooleanSelection
+/// \class FeaturesPlugin_ValidatorPartitionSelection
 /// \ingroup Validators
-/// \brief Validates selection for boolean operation.
-class FeaturesPlugin_BooleanSelection: public ModelAPI_AttributeValidator
+/// \brief Validates selection for partition.
+class FeaturesPlugin_ValidatorPartitionSelection: public ModelAPI_AttributeValidator
 {
 public:
   /// \return True if the attribute is valid. It checks whether the selection
index 3d1a0ac58cd00c5d4598a13e4a680901c1ef4e9c..5ccf5998bc3a5cd8e97e5558fdfaae29c5cca3a3 100644 (file)
@@ -4,7 +4,7 @@
   <module_choice id="bool_type"
     widget_type="radiobuttons"
     buttons_dir="horizontal"
-    label="Operation type" 
+    label="Operation type"
     tooltip="Type of boolean operation"
     string_list="Cut Fuse Common Fill Smash"
     use_in_title="true"
@@ -19,7 +19,7 @@
     use_choice="false"
     concealment="true">
     <validator id="PartSet_DifferentObjects"/>
-    <validator id="FeaturesPlugin_BooleanSelection"/>
+    <validator id="FeaturesPlugin_ValidatorBooleanSelection"/>
   </multi_selector>
   <multi_selector id="tool_objects"
     label="Tool objects"
@@ -29,7 +29,7 @@
     use_choice="false"
     concealment="true" >
     <validator id="PartSet_DifferentObjects"/>
-    <validator id="FeaturesPlugin_BooleanSelection"/>
+    <validator id="FeaturesPlugin_ValidatorBooleanSelection"/>
   </multi_selector>
   <validator id="GeomValidators_BooleanArguments" parameters="main_objects,tool_objects,bool_type"/>
 </source>
index 731522c559459caa12ebae1d2365803ba4357324..8567eb8930dd0e5323cf94dd5acd056e5aa39fe5 100644 (file)
@@ -5,6 +5,6 @@
     tooltip="Select a set of objects"
     type_choice="Vertices Edges Faces Solids"
     use_choice="true">
-    <validator id="GeomValidators_BodyShapes" parameters="Sketch"/>
+    <validator id="GeomValidators_BodyShapes"/>
   </multi_selector>
 </source>
\ No newline at end of file
index 0c770c31887d3f7685a0358812fc64779519a95b..ec2ea7105f8ddf9022daf1140495e0df99aa9d8c 100755 (executable)
@@ -1,28 +1,12 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <source>
-  <multi_selector id="main_objects"
-    label="Main objects"
-    icon="icons/Features/cut_shape.png"
-    tooltip="Select solid objects"
-    type_choice="Solids"
+  <multi_selector id="base_objects"
+    label="Base objects:"
+    tooltip="Select objects for partitioning."
+    type_choice="objects"
     concealment="true">
-    <validator id="PartSet_DifferentObjects"/>
-    <validator id="GeomValidators_ShapeType" parameters="solid"/>
+    <validator id="FeaturesPlugin_ValidatorPartitionSelection"/>
   </multi_selector>
-  <multi_selector id="tool_objects"
-    label="Tool objects"
-    icon="icons/Features/cut_tool.png"
-    tooltip="Select a tool face or solid"
-    type_choice="Faces Solids"
-    use_choice="false"
-    concealment="true">
-    <validator id="PartSet_DifferentObjects"/>
-    <validator id="GeomValidators_ShapeType" parameters="solid,plane,empty"/>
-  </multi_selector>
-  <boolvalue id="partition_combine"
-    label="Combine results"
-    default="true"
-    tooltip="If True combines all results to one. If False builds separate result for each object."/>
-  <validator id="GeomValidators_PartitionArguments" parameters="main_objects,tool_objects,partition_combine"/>
+  <!--<validator id="GeomValidators_PartitionArguments" parameters="main_objects,tool_objects,partition_combine"/>-->
 </source>
index 7034f9d4c853e4c52170b13c6a191e4c27545a5e..06849b9f17eb42f2debdbb3f7297a674e339b9a8 100644 (file)
@@ -65,25 +65,16 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
   }
   TopoDS_Shape aResult = anOperation->Shape();
 
-  if(aResult.ShapeType() == TopAbs_COMPOUND) {
-    aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
-  }
   if(aResult.ShapeType() == TopAbs_COMPOUND) {
     std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
     aGeomShape->setImpl(new TopoDS_Shape(aResult));
-    ListOfShape aCompSolids, aFreeSolids;
-    aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
-                                                       GeomAPI_Shape::COMPSOLID,
-                                                       aCompSolids,
-                                                       aFreeSolids);
-    aResult = aGeomShape->impl<TopoDS_Shape>();
+    aResult = GeomAlgoAPI_ShapeTools::groupSharedTopology(aGeomShape)->impl<TopoDS_Shape>();
   }
 
   // Setting result.
   if(aResult.IsNull()) {
     return;
   }
-  aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
   aShape->setImpl(new TopoDS_Shape(aResult));
   this->setShape(aShape);
index ea214adde141df6678ade9dba4f7463e8c7f2935..5ab20e0653ce0d32a13c95aafa3ae2dcb65549ab 100644 (file)
@@ -21,6 +21,8 @@ public:
   /// \brief Creates common partition operation.
   /// \param[in] theObjects the main shape.
   /// \param[in] theTools  second shape.
+  /// \param[in] theGroupConnectedTopology if true then result will be a compound of groups
+  ///            with connected topology(compsolids or compounds of shapes with shared topology).
   /// \return a solid as result of operation.
   GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Shape> make(const ListOfShape& theObjects,
                                                                 const ListOfShape& theTools);
index 87e6d83c210e11c32c19f7afe222ecc0534f5bd3..e6a89baa122854fa3a6a81d8ef1cb740f91e4680 100644 (file)
@@ -49,8 +49,9 @@
 #include <TopoDS.hxx>
 #include <TopExp_Explorer.hxx>
 
-//=================================================================================================
-double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
+namespace GeomAlgoAPI_ShapeTools {
+//==================================================================================================
+double volume(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
   GProp_GProps aGProps;
   if(!theShape.get()) {
@@ -65,8 +66,8 @@ double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theSh
   return aGProps.Mass();
 }
 
-//=================================================================================================
-std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape)
+//==================================================================================================
+std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
   GProp_GProps aGProps;
   if(!theShape) {
@@ -89,11 +90,11 @@ std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(const std::sha
   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
 }
 
-//=================================================================================================
-std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
-                                                                     const GeomAPI_Shape::ShapeType theType,
-                                                                     ListOfShape& theCombinedShapes,
-                                                                     ListOfShape& theFreeShapes)
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+                                             const GeomAPI_Shape::ShapeType theType,
+                                             ListOfShape& theCombinedShapes,
+                                             ListOfShape& theFreeShapes)
 {
   GeomShapePtr aResult = theCompound;
 
@@ -112,6 +113,9 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::combineShapes(const std::
     aTA = TopAbs_SOLID;
   }
 
+  theCombinedShapes.clear();
+  theFreeShapes.clear();
+
   // Get free shapes.
   const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
   for(TopoDS_Iterator anIter(aShapesComp); anIter.More(); anIter.Next() ) {
@@ -234,8 +238,107 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::combineShapes(const std::
   return aResult;
 }
 
-//=================================================================================================
-std::list<std::shared_ptr<GeomAPI_Pnt> > GeomAlgoAPI_ShapeTools::getBoundingBox(const ListOfShape& theShapes, const double theEnlarge)
+//==================================================================================================
+static void addSimpleShapeToList(const TopoDS_Shape& theShape, NCollection_List<TopoDS_Shape>& theList)
+{
+  if(theShape.IsNull()) {
+    return;
+  }
+
+  if(theShape.ShapeType() == TopAbs_COMPOUND) {
+    for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
+      addSimpleShapeToList(anIt.Value(), theList);
+    }
+  } else {
+    theList.Append(theShape);
+  }
+}
+
+//==================================================================================================
+static TopoDS_Compound makeCompound(const NCollection_List<TopoDS_Shape> theShapes)
+{
+  TopoDS_Compound aCompound;
+
+  BRep_Builder aBuilder;
+  aBuilder.MakeCompound(aCompound);
+
+  for(NCollection_List<TopoDS_Shape>::Iterator anIt(theShapes); anIt.More(); anIt.Next()) {
+    aBuilder.Add(aCompound, anIt.Value());
+  }
+
+  return aCompound;
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> groupSharedTopology(const std::shared_ptr<GeomAPI_Shape> theCompound)
+{
+  GeomShapePtr aResult = theCompound;
+
+  if(!theCompound.get()) {
+    return aResult;
+  }
+
+  TopoDS_Shape anInShape = aResult->impl<TopoDS_Shape>();
+  NCollection_List<TopoDS_Shape> anUngroupedShapes;
+  addSimpleShapeToList(anInShape, anUngroupedShapes);
+
+  NCollection_Vector<NCollection_List<TopoDS_Shape>> aGroups;
+  while(!anUngroupedShapes.IsEmpty()) {
+    NCollection_List<TopoDS_Shape> aGroupedShapes;
+    aGroupedShapes.Append(anUngroupedShapes.First());
+    anUngroupedShapes.RemoveFirst();
+    for(NCollection_List<TopoDS_Shape>::Iterator aGroupIt(aGroupedShapes); aGroupIt.More(); aGroupIt.Next()) {
+      const TopoDS_Shape& aGroupShape = aGroupIt.Value();
+      for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes); anUngroupedIt.More(); anUngroupedIt.Next()) {
+        const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
+        bool isFound = false;
+        for(TopExp_Explorer aGroupShapeExp(aGroupShape, TopAbs_VERTEX); aGroupShapeExp.More(); aGroupShapeExp.Next()) {
+          const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
+          for(TopExp_Explorer anUngroupedShapeExp(anUngroupedShape, TopAbs_VERTEX); anUngroupedShapeExp.More(); anUngroupedShapeExp.Next()) {
+            const TopoDS_Shape& aVertex2 = anUngroupedShapeExp.Current();
+            if(aVertex1.IsSame(aVertex2)) {
+              aGroupedShapes.Append(anUngroupedShape);
+              anUngroupedShapes.Remove(anUngroupedIt);
+              isFound = true;
+              break;
+            }
+          }
+          if(isFound) {
+            break;
+          }
+        }
+        if(!anUngroupedIt.More()) {
+          break;
+        }
+      }
+    }
+    aGroups.Append(aGroupedShapes);
+  }
+
+  TopoDS_Compound aCompound;
+  BRep_Builder aBuilder;
+  aBuilder.MakeCompound(aCompound);
+  ListOfShape aCompSolids, aFreeSolids;
+  for(NCollection_Vector<NCollection_List<TopoDS_Shape>>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) {
+    TopoDS_Compound aGroupCompound = makeCompound(anIt.Value());
+    GeomShapePtr aGeomShape(new GeomAPI_Shape());
+    aGeomShape->setImpl(new TopoDS_Shape(aGroupCompound));
+    aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
+                                                       GeomAPI_Shape::COMPSOLID,
+                                                       aCompSolids,
+                                                       aFreeSolids);
+    aBuilder.Add(aCompound, aGeomShape->impl<TopoDS_Shape>());
+  }
+
+  if(!aCompound.IsNull()) {
+    aResult->setImpl(new TopoDS_Shape(aCompound));
+  }
+
+  return aResult;
+}
+
+//==================================================================================================
+std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge)
 {
   // Bounding box of all objects.
   Bnd_Box aBndBox;
@@ -268,8 +371,8 @@ std::list<std::shared_ptr<GeomAPI_Pnt> > GeomAlgoAPI_ShapeTools::getBoundingBox(
   return aResultPoints;
 }
 
-//=================================================================================================
-std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace)
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace)
 {
   if (!theFace.get())
     return std::shared_ptr<GeomAPI_Shape>();
@@ -290,9 +393,9 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const
   return aResult;
 }
 
-//=================================================================================================
-std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
-                                                                     const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints)
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+                                              const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints)
 {
   std::shared_ptr<GeomAPI_Shape> aResultShape;
 
@@ -343,10 +446,10 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::
   return aResultShape;
 }
 
-//=================================================================================================
-void GeomAlgoAPI_ShapeTools::findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
-                                        std::shared_ptr<GeomAPI_Vertex>& theV1,
-                                        std::shared_ptr<GeomAPI_Vertex>& theV2)
+//==================================================================================================
+void findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
+                std::shared_ptr<GeomAPI_Vertex>& theV1,
+                std::shared_ptr<GeomAPI_Vertex>& theV2)
 {
   if(!theShape.get()) {
     std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex);
@@ -367,14 +470,14 @@ void GeomAlgoAPI_ShapeTools::findBounds(const std::shared_ptr<GeomAPI_Shape> the
   theV2 = aGeomV2;
 }
 
-//=================================================================================================
-void GeomAlgoAPI_ShapeTools::makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pnt> theOrigin,
-                                                const std::shared_ptr<GeomAPI_Dir> theDirection,
-                                                const ListOfShape& theWires,
-                                                ListOfShape& theFaces)
+//==================================================================================================
+void makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pnt> theOrigin,
+                        const std::shared_ptr<GeomAPI_Dir> theDirection,
+                        const ListOfShape& theWires,
+                        ListOfShape& theFaces)
 {
   BRepBuilderAPI_MakeFace aMKFace(gp_Pln(theOrigin->impl<gp_Pnt>(),
-                                         theDirection->impl<gp_Dir>()));
+                                          theDirection->impl<gp_Dir>()));
   TopoDS_Face aFace = aMKFace.Face();
 
   BRepAlgo_FaceRestrictor aFRestrictor;
@@ -399,8 +502,8 @@ void GeomAlgoAPI_ShapeTools::makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pn
   }
 }
 
-//=================================================================================================
-std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_ShapeTools::findPlane(const ListOfShape& theShapes)
+//==================================================================================================
+std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes)
 {
   TopoDS_Compound aCompound;
   BRep_Builder aBuilder;
@@ -427,9 +530,9 @@ std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_ShapeTools::findPlane(const ListOfShape
   return aPln;
 }
 
-//=================================================================================================
-bool GeomAlgoAPI_ShapeTools::isSubShapeInShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
-                                               const std::shared_ptr<GeomAPI_Shape> theBaseShape)
+//==================================================================================================
+bool isSubShapeInsideShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
+                            const std::shared_ptr<GeomAPI_Shape> theBaseShape)
 {
   if(!theSubShape.get() || !theBaseShape.get()) {
     return false;
@@ -497,3 +600,4 @@ bool GeomAlgoAPI_ShapeTools::isSubShapeInShape(const std::shared_ptr<GeomAPI_Sha
 
   return true;
 }
+} //namespace GeomAlgoAPI_ShapeTools
index 9b08fe8a1fed3a9c1c4e8dbc6e1f90fc0ef9688a..41cc56983bc9a6f779d0c340ba7cac8a5e5ae6bf 100644 (file)
@@ -17,44 +17,48 @@ class GeomAPI_PlanarEdges;
 class GeomAPI_Pln;
 class GeomAPI_Pnt;
 
-/// \class GeomAlgoAPI_ShapeTools
+/// \namespace GeomAlgoAPI_ShapeTools
 /// \ingroup DataAlgo
 /// \brief Useful tools for working with shapes.
-class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools
+namespace GeomAlgoAPI_ShapeTools
 {
-public:
   /// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
-  static double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
+  GEOMALGOAPI_EXPORT double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
 
   /// \return the centre of mass of the current face. The coordinates returned for the center of mass
   /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
-  static std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
 
   /// \brief Combines faces with common edges to shells, or solids to compsolids.
   /// \param[in] theCompound compound of shapes.
   /// \param[in] theType type of combine.
   /// \param[out] theCombinedShapes resulting shapes.
   /// \param[out] theFreeShapes shapes that does not have common subshapes.
-  static std::shared_ptr<GeomAPI_Shape> combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
-                                                      const GeomAPI_Shape::ShapeType theType,
-                                                      ListOfShape& theCombinedShapes,
-                                                      ListOfShape& theFreeShapes);
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+                                                                  const GeomAPI_Shape::ShapeType theType,
+                                                                  ListOfShape& theCombinedShapes,
+                                                                  ListOfShape& theFreeShapes);
+
+  /// \brief Groups shapes with shared topology to compounds.
+  /// \param[in] theCompound compound of shapes.
+  /// \return compound of compounds with shared topology.
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> groupSharedTopology(const std::shared_ptr<GeomAPI_Shape> theCompound);
 
   /// \brief Calculates bounding box for theShapes
   /// \return list of eight points.
   /// \param[in] theShapes list of shapes.
   /// \param[in] theEnlarge enlarges bounding box size.
-  static std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
+  GEOMALGOAPI_EXPORT std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
 
   /// \return infinite plane received from theFace plane.
-  static std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
 
   /// \brief Enlarges or reduces plane to fit bounding box.
   /// \return plane that fits to bounding box.
   /// \param[in] thePlane base plane.
   /// \param[in] thePoints bounding box points (shoud be eight).
-  static std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
-                                                      const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+                                                                  const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
 
   /// \brief Finds the start and end vertices of theShape. theShape can be of the following type:\n
   /// Vertex: theV1 and theV2 are the same and equal to theShape;\n
@@ -62,29 +66,29 @@ public:
   /// Wire : theV1 is start vertex of the first edge, theV2 is end vertex of the last edge. If wire
   /// contains no edges theV1 and theV2 are nullified.\n
   /// If none of the above theV1 and theV2 are nullified.
-  static void findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
-                         std::shared_ptr<GeomAPI_Vertex>& theV1,
-                         std::shared_ptr<GeomAPI_Vertex>& theV2);
+  GEOMALGOAPI_EXPORT void findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                     std::shared_ptr<GeomAPI_Vertex>& theV1,
+                                     std::shared_ptr<GeomAPI_Vertex>& theV2);
 
   /// \brief Creates faces with holes from wires.
   /// \param[in] theWires base wires.
   /// \param[out] theFaces resulting faces.
-  static void makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pnt> theOrigin,
-                                 const std::shared_ptr<GeomAPI_Dir> theDirection,
-                                 const ListOfShape& theWires,
-                                 ListOfShape& theFaces);
+  GEOMALGOAPI_EXPORT void makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pnt> theOrigin,
+                                             const std::shared_ptr<GeomAPI_Dir> theDirection,
+                                             const ListOfShape& theWires,
+                                             ListOfShape& theFaces);
 
   /// \brief Return a plane for list of shapes if they are all planar.
   /// \param[in] theShapes shapes to find plane.
   /// \return plane where all shapes lie or empty ptr if they not planar.
-  static std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes);
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes);
 
   /// \brief Checks that vertex/edge is inside face or vertext inside wire.
   /// \param[in] theSubShape shape that should be inside.
   /// \param[in] theBaseShape base shape.
   /// \return true if edge inside the face.
-  static bool isSubShapeInShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
-                                const std::shared_ptr<GeomAPI_Shape> theBaseShape);
+  GEOMALGOAPI_EXPORT bool isSubShapeInsideShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
+                                                const std::shared_ptr<GeomAPI_Shape> theBaseShape);
 };
 
 #endif
index 734938ecc3cfffa39d853182b4d21efbf79ce0c4..13e95ace0ffc8bbb0be3a5178414575bced770c8 100644 (file)
@@ -8,27 +8,29 @@
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Object.h>
+#include <ModelAPI_ResultConstruction.h>
 
 bool GeomValidators_BodyShapes::isValid(const AttributePtr& theAttribute,
-                                      const std::list<std::string>& theArguments,
-                                      std::string& theError) const
+                                        const std::list<std::string>& theArguments,
+                                        std::string& theError) const
 {
   std::string anAttributeType = theAttribute->attributeType();
-  if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+  if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = 
                       std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
     // all context objects should not be sketch entities
-    for(int i = 0, aSize = aSelectionListAttr->size(); i < aSize; i++) {
-      AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
-      ObjectPtr anObject = aSelectAttr->context();
-      if (!anObject.get())
+    for(int anIndex = 0, aSize = aSelectionListAttr->size(); anIndex < aSize; ++anIndex) {
+      AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(anIndex);
+      ResultPtr aContext = aSelectAttr->context();
+      if(!aContext.get()) {
+        theError = "Error: Context is empty.";
+        return false;
+      }
+
+      ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+      if(aResultConstruction.get()) {
+        theError = "Error: Result construction selected.";
         return false;
-      else {
-        FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
-        std::string aFeatureKind = aFeature->getKind();
-        if(aFeatureKind == "Sketch") {
-          return false;
-        }
       }
     }
   }
index 2d025aa88d1b1402f2d7d1f28f677072a7a125c0..fe1541286a3fe7c19cdbfb242a8fe12643b026e6 100755 (executable)
@@ -370,13 +370,14 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
   GeomAPI_DataMapOfShapeShape& theSubShapes,
   const bool theIsStoreSeparate)
 {
+  int anIndex = 1;
   int aTag = theTag;
+  bool isBuilt = !theName.empty();
   std::string aName = theName;
   std::ostringstream aStream;
-  int anIndex = 1;
+  GeomShapePtr aResultShape = shape();
   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
   TopTools_MapOfShape aView;
-  bool isBuilt = theName.empty();
   TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
   for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
     const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
@@ -387,14 +388,14 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
     theMS->modified(aRShape, aList);
     std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
     for (; anIt != aLast; anIt++) {
-      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();    
+      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();
       if (theSubShapes.isBound(*anIt)) {
         std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
         aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
       }
-      if (!aRoot.IsSame (aNewShape)) {
+      if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(*anIt)) {
         builder(aTag)->Modify(aRoot,aNewShape);
-        if(!isBuilt) {
+        if(isBuilt) {
           if(theIsStoreSeparate) {
             aStream.str(std::string());
             aStream.clear();