]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1343: Architecture changes. Composite features now derived from extrusion...
authordbv <dbv@opencascade.com>
Fri, 1 Apr 2016 12:46:56 +0000 (15:46 +0300)
committerdbv <dbv@opencascade.com>
Wed, 6 Apr 2016 10:25:16 +0000 (13:25 +0300)
43 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.h
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.h
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionCut.cpp
src/FeaturesPlugin/FeaturesPlugin_ExtrusionCut.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.cpp [deleted file]
src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.h [deleted file]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.h
src/FeaturesPlugin/FeaturesPlugin_RevolutionBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_RevolutionBoolean.h
src/FeaturesPlugin/FeaturesPlugin_RevolutionCut.cpp
src/FeaturesPlugin/FeaturesPlugin_RevolutionCut.h
src/FeaturesPlugin/FeaturesPlugin_RevolutionFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_RevolutionFuse.h
src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.cpp [deleted file]
src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.h [deleted file]
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/Test/TestExtrusionSketch.py [deleted file]
src/FeaturesPlugin/Test/TestRevolutionSketch.py [deleted file]
src/FeaturesPlugin/extrusion_widget.xml
src/FeaturesPlugin/extrusioncut_widget.xml
src/FeaturesPlugin/extrusionfuse_widget.xml
src/FeaturesPlugin/extrusionsketch_widget.xml [deleted file]
src/FeaturesPlugin/pipe_widget.xml
src/FeaturesPlugin/revolution_widget.xml
src/FeaturesPlugin/revolutioncut_widget.xml
src/FeaturesPlugin/revolutionfuse_widget.xml
src/FeaturesPlugin/revolutionsketch_widget.xml [deleted file]
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp
src/GeomValidators/GeomValidators_ShapeType.cpp
src/PartSet/PartSet_WidgetSketchCreator.cpp

index 86530f1647f1f58a8cdcf1a41d0d43138b65af25..0ae589cc71404b6762c77f5848840b23585bb63d 100644 (file)
@@ -19,10 +19,8 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_CompositeBoolean.h
     FeaturesPlugin_CompositeSketch.h
     FeaturesPlugin_ExtrusionBoolean.h
-    FeaturesPlugin_ExtrusionSketch.h
     FeaturesPlugin_ExtrusionCut.h
     FeaturesPlugin_ExtrusionFuse.h
-    FeaturesPlugin_RevolutionSketch.h
     FeaturesPlugin_RevolutionBoolean.h
     FeaturesPlugin_RevolutionCut.h
     FeaturesPlugin_RevolutionFuse.h
@@ -45,11 +43,9 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Placement.cpp
     FeaturesPlugin_CompositeBoolean.cpp
     FeaturesPlugin_CompositeSketch.cpp
-    FeaturesPlugin_ExtrusionSketch.cpp
     FeaturesPlugin_ExtrusionBoolean.cpp
     FeaturesPlugin_ExtrusionCut.cpp
     FeaturesPlugin_ExtrusionFuse.cpp
-    FeaturesPlugin_RevolutionSketch.cpp
     FeaturesPlugin_RevolutionBoolean.cpp
     FeaturesPlugin_RevolutionCut.cpp
     FeaturesPlugin_RevolutionFuse.cpp
@@ -61,11 +57,9 @@ SET(PROJECT_SOURCES
 SET(XML_RESOURCES
   plugin-Features.xml
   extrusion_widget.xml
-  extrusionsketch_widget.xml
   extrusioncut_widget.xml
   extrusionfuse_widget.xml
   revolution_widget.xml
-  revolutionsketch_widget.xml
   revolutioncut_widget.xml
   revolutionfuse_widget.xml
   rotation_widget.xml
@@ -102,11 +96,9 @@ INSTALL(TARGETS FeaturesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES})
 INSTALL(FILES ${XML_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
 
 ADD_UNIT_TESTS(TestExtrusion.py
-               TestExtrusionSketch.py
                TestExtrusionCut.py
                TestExtrusionFuse.py
                TestRevolution.py
-               TestRevolutionSketch.py
                TestRevolutionCut.py
                TestRevolutionFuse.py
                TestCompositeFeaturesOnCompSolids.py
index 65a6c6a8dcf961361c114f9c44f9588bd5974055..5c86e7eb78717291da0d19aaa810147005d995ba 100644 (file)
 #include "FeaturesPlugin_CompositeBoolean.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
-#include <ModelAPI_AttributeReference.h>
-#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_Session.h>
 #include <ModelAPI_Tools.h>
-#include <ModelAPI_Validator.h>
 
-#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_Boolean.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
-#include <GeomAlgoAPI_MakeSweep.h>
 #include <GeomAlgoAPI_PaveFiller.h>
-#include <GeomAlgoAPI_Prism.h>
-#include <GeomAlgoAPI_Revolution.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+
 #include <GeomAPI_ShapeExplorer.h>
 
 #include <map>
-#include <sstream>
 
 //=================================================================================================
-void FeaturesPlugin_CompositeBoolean::initAttributes()
+void FeaturesPlugin_CompositeBoolean::initBooleanAttributes()
 {
-  AttributeSelectionListPtr aSelection = 
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-
-  data()->addAttribute(SKETCH_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
-                                                               SKETCH_OBJECT_ID());
-
-  // Boolean works with solids always.
-  data()->addAttribute(BOOLEAN_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
-  aSelection = data()->selectionList(BOOLEAN_OBJECTS_ID());
-  aSelection->setSelectionType("SOLID");
-
-  initMakeSolidsAttributes();
-
-  data()->addAttribute(SKETCH_SELECTION_ID(), ModelAPI_AttributeSelection::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_SELECTION_ID());
+  myFeature->data()->addAttribute(OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
 }
 
 //=================================================================================================
-std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeBoolean::addFeature(std::string theID)
+void FeaturesPlugin_CompositeBoolean::execute()
 {
-  std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
-  if (aNew) {
-    data()->reference(SKETCH_OBJECT_ID())->setValue(aNew);
+  // Make generation.
+  ListOfShape aGenBaseShapes;
+  ListOfMakeShape aGenMakeShapes;
+  if(!makeGeneration(aGenBaseShapes, aGenMakeShapes)) {
+    return;
   }
-  // set as current also after it becomes sub to set correctly enabled for other sketch subs
-  document()->setCurrentFeature(aNew, false);
-  return aNew;
-}
 
-//=================================================================================================
-int FeaturesPlugin_CompositeBoolean::numberOfSubs(bool forTree) const
-{
-  ObjectPtr aObj = data()->reference(SKETCH_OBJECT_ID())->value();
-  return aObj.get()? 1 : 0;
-}
+  // Getting tools.
+  ListOfShape aTools;
+  for(ListOfMakeShape::const_iterator anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) {
+    aTools.push_back((*anIt)->shape());
+  }
 
-//=================================================================================================
-std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeBoolean::subFeature(const int theIndex, bool forTree)
-{
-  if (theIndex == 0)
-    return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
-  return std::shared_ptr<ModelAPI_Feature>();
-}
+  // Make boolean.
+  ListOfShape aBooleanObjects;
+  ListOfMakeShape aBooleanMakeShapes;
+  if(!makeBoolean(aTools, aBooleanObjects, aBooleanMakeShapes)) {
+    return;
+  }
 
-//=================================================================================================
-int FeaturesPlugin_CompositeBoolean::subFeatureId(const int theIndex) const
-{
-  if (theIndex == 0) {
-    FeaturePtr aFeature = 
-      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
-    if (aFeature.get())
-      return aFeature->data()->featureId();
+  if(myOperationType == BOOL_FUSE) {
+    aTools.splice(aTools.begin(), aBooleanObjects);
+    aBooleanObjects.splice(aBooleanObjects.begin(), aTools, aTools.begin());
   }
-  return -1;
-}
 
-//=================================================================================================
-bool FeaturesPlugin_CompositeBoolean::isSub(ObjectPtr theObject) const
-{
-  // check is this feature of result
-  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
-  if (!aFeature)
-    return false;
-  ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value();
-  return aSub == theObject;
-}
+  // Store result.
+  int aResultIndex = 0;
+  ListOfShape::const_iterator aBoolObjIt = aBooleanObjects.cbegin();
+  ListOfMakeShape::const_iterator aBoolMSIt = aBooleanMakeShapes.cbegin();
+  for(; aBoolObjIt != aBooleanObjects.cend() && aBoolMSIt != aBooleanMakeShapes.cend();
+      ++aBoolObjIt, ++aBoolMSIt) {
 
-//=================================================================================================
-void FeaturesPlugin_CompositeBoolean::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
-{
-  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-  if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0)
-    aFacesSelectionList->clear();
-}
+    int aTag = 1;
 
-//=================================================================================================
-void FeaturesPlugin_CompositeBoolean::erase()
-{
-  if (data().get() && data()->isValid()) { // on abort of sketch of this composite it may be invalid
-    FeaturePtr aSketch =
-      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
-    if (aSketch.get() && aSketch->data()->isValid()) {
-      document()->removeFeature(aSketch);
+    ResultBodyPtr aResultBody = myFeature->document()->createBody(myFeature->data(), aResultIndex);
+    aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape(), aTag);
+
+    aTag += 5000;
+
+    // Store generation history.
+    ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin();
+    ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin();
+    for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend();
+        ++aGenBaseIt, ++aGenMSIt) {
+      storeGenerationHistory(aResultBody, *aGenBaseIt, *aGenMSIt, aTag);
     }
+
+    int aModTag = aTag;
+    storeModificationHistory(aResultBody, *aBoolObjIt, aTools, *aBoolMSIt, aModTag);
   }
-  ModelAPI_CompositeFeature::erase();
 }
 
-
 //=================================================================================================
-void FeaturesPlugin_CompositeBoolean::execute()
+bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
+                                                  ListOfShape& theObjects,
+                                                  ListOfMakeShape& theMakeShapes)
 {
-  /// feature extrusion does not have the next attribute
-  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-  if (aFacesSelectionList.get() && !aFacesSelectionList->isInitialized()) {
-    AttributeReferencePtr aSketchAttr = reference(SKETCH_OBJECT_ID());
-    if (aSketchAttr.get() && aSketchAttr->isInitialized())
-      setSketchObjectToList();
-  }
-
-  // Getting faces to create solids.
-  std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
-                                                     reference(SKETCH_OBJECT_ID())->value());
-  if(!aSketchFeature || aSketchFeature->results().empty()) {
-    return;
-  }
-  ResultPtr aSketchRes = aSketchFeature->results().front();
-  ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
-  if(!aConstruction.get()) {
-    return;
-  }
-  selection(SKETCH_SELECTION_ID())->setValue(aSketchRes, std::shared_ptr<GeomAPI_Shape>());
-  int aSketchFacesNum = aConstruction->facesNum();
-  if(aSketchFacesNum == 0) {
-    return;
-  }
-  ListOfShape aFacesList;
-  for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) {
-    std::shared_ptr<GeomAPI_Shape> aFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
-    aFacesList.push_back(aFace);
-  }
-
-  // Searching faces with common edges.
-  ListOfShape aShells;
-  ListOfShape aFreeFaces;
-  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
-  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
-  aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
-
-  // Pass shells/faces to solids creation function.
-  ListOfShape aTools;
-  ListOfMakeShape aSolidsAlgos;
-  makeSolids(aShells, aTools, aSolidsAlgos);
-  if(aTools.empty()) {
-    return;
-  }
-
-  // Getting objects for boolean operation.
-  ListOfShape anObjects;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
-  AttributeSelectionListPtr anObjectsSelList = selectionList(BOOLEAN_OBJECTS_ID());
-  if(anObjectsSelList->size() == 0) {
-    return;
-  }
+  // Getting objects.
+  ListOfShape anObjects, anEdgesAndFaces, aCompSolids;
+  std::map<GeomShapePtr, ListOfShape> aCompSolidsObjects;
+  AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID());
   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
     AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
-    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
+    GeomShapePtr anObject = anObjectAttr->value();
     if(!anObject.get()) {
-      return;
+      myFeature->setError("Error: Could not get object.");
+      return false;
     }
     ResultPtr aContext = anObjectAttr->context();
     ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
     if(aResCompSolidPtr.get()) {
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
-      std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+      GeomShapePtr aContextShape = aResCompSolidPtr->shape();
+      std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
       for(; anIt != aCompSolidsObjects.end(); anIt++) {
         if(anIt->first->isEqual(aContextShape)) {
           aCompSolidsObjects[anIt->first].push_back(anObject);
@@ -195,302 +108,258 @@ void FeaturesPlugin_CompositeBoolean::execute()
       }
       if(anIt == aCompSolidsObjects.end()) {
         aCompSolidsObjects[aContextShape].push_back(anObject);
+        aCompSolids.push_back(aContextShape);
       }
     } else {
-      anObjects.push_back(anObject);
+      if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
+         anObject->shapeType() == GeomAPI_Shape::FACE) {
+        anEdgesAndFaces.push_back(anObject);
+      } else {
+        anObjects.push_back(anObject);
+      }
     }
   }
 
-  // Cut from each object solids.
-  int aResultIndex = 0;
+  switch(myOperationType) {
+    case BOOL_CUT: {
+      if((anObjects.empty() && aCompSolidsObjects.empty()) || theTools.empty()) {
+        myFeature->setError("Error: Not enough objects for boolean operation.");
+        return false;
+      }
 
-  switch(myBooleanOperationType) {
-    case GeomAlgoAPI_Boolean::BOOL_CUT:
-    case GeomAlgoAPI_Boolean::BOOL_COMMON:{
-      // Cut each object with all tools
-      for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
-        std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+      // For solids cut each object with all tools.
+      for(ListOfShape::const_iterator anIt = anObjects.cbegin(); anIt != anObjects.cend(); ++anIt) {
+        GeomShapePtr anObject = *anIt;
         ListOfShape aListWithObject;
         aListWithObject.push_back(anObject);
-        GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, myBooleanOperationType);
+        std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aListWithObject,
+                                                                               theTools,
+                                                                               GeomAlgoAPI_Boolean::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
-        if(!aBoolAlgo.isDone() || aBoolAlgo.shape()->isNull() || !aBoolAlgo.isValid()) {
-          setError("Error: Boolean algorithm failed.");
-          return;
+        if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
+          myFeature->setError("Error: Boolean algorithm failed.");
+          return false;
         }
 
-        if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo.shape()) > 1.e-7) {
-          std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-          loadNamingDS(aResultBody, aShells, aSolidsAlgos, anObject, aTools, aBoolAlgo.shape(),
-                       aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get());
-          setResult(aResultBody, aResultIndex);
-          aResultIndex++;
+        if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo->shape()) > 1.e-7) {
+          theObjects.push_back(anObject);
+          theMakeShapes.push_back(aBoolAlgo);
         }
       }
 
       // Compsolids handling
-      for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
-        anIt != aCompSolidsObjects.end(); anIt++) {
-        std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
-        ListOfShape& aUsedInOperationSolids = anIt->second;
+      for(std::map<GeomShapePtr, ListOfShape>::const_iterator anIt = aCompSolidsObjects.cbegin();
+          anIt != aCompSolidsObjects.cend(); ++anIt) {
+        GeomShapePtr aCompSolid = anIt->first;
+        const ListOfShape& aUsedShapes = anIt->second;
 
         // Collecting solids from compsolids which will not be modified in boolean operation.
-        ListOfShape aNotUsedSolids;
+        ListOfShape aShapesToAdd;
         for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
-          std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
-          ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
-          for(; anIt != aUsedInOperationSolids.end(); anIt++) {
-            if(aSolidInCompSolid->isEqual(*anIt)) {
+          GeomShapePtr aSolidInCompSolid = anExp.current();
+          ListOfShape::const_iterator aUsedShapesIt = aUsedShapes.cbegin();
+          for(; aUsedShapesIt != aUsedShapes.cend(); ++aUsedShapesIt) {
+            if(aSolidInCompSolid->isEqual(*aUsedShapesIt)) {
               break;
             }
           }
-          if(anIt == aUsedInOperationSolids.end()) {
-            aNotUsedSolids.push_back(aSolidInCompSolid);
+          if(aUsedShapesIt == aUsedShapes.end()) {
+            aShapesToAdd.push_back(aSolidInCompSolid);
           }
         }
 
-        std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, myBooleanOperationType));
+        std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedShapes,
+                                                                               theTools,
+                                                                               GeomAlgoAPI_Boolean::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
-          setError("Error: Boolean algorithm failed.");
-          return;
+          myFeature->setError("Error: Boolean algorithm failed.");
+          return false;
         }
 
         GeomAlgoAPI_MakeShapeList aMakeShapeList;
         aMakeShapeList.appendAlgo(aBoolAlgo);
-        GeomAPI_DataMapOfShapeShape aMapOfShapes;
-        aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
 
         // Add result to not used solids from compsolid.
-        ListOfShape aShapesToAdd = aNotUsedSolids;
         aShapesToAdd.push_back(aBoolAlgo->shape());
         std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
-        if(!aFillerAlgo->isDone()) {
-          std::string aFeatureError = "Error: PaveFiller algorithm failed.";
-          setError(aFeatureError);
-          return;
+        if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) {
+          myFeature->setError("Error: PaveFiller algorithm failed.");
+          return false;
         }
 
         aMakeShapeList.appendAlgo(aFillerAlgo);
-        aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
 
         if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo->shape()) > 1.e-7) {
-          std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-          loadNamingDS(aResultBody, aShells, aSolidsAlgos, aCompSolid, aTools, aFillerAlgo->shape(), aMakeShapeList, aMapOfShapes);
-          setResult(aResultBody, aResultIndex);
-          aResultIndex++;
+          theObjects.push_back(aCompSolid);
+          theMakeShapes.push_back(aBoolAlgo);
         }
       }
       break;
     }
-    case GeomAlgoAPI_Boolean::BOOL_FUSE: {
+    case BOOL_FUSE: {
+      // Set objects.
+      theObjects.insert(theObjects.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
+      theObjects.insert(theObjects.end(), anObjects.begin(), anObjects.end());
+      theObjects.insert(theObjects.end(), aCompSolids.begin(), aCompSolids.end());
+
+      // Filter edges and faces in tools.
+      ListOfShape aTools;
+      for(ListOfShape::const_iterator anIt = aTools.cbegin(); anIt != aTools.cend(); ++anIt) {
+        if((*anIt)->shapeType() == GeomAPI_Shape::EDGE ||
+           (*anIt)->shapeType() == GeomAPI_Shape::FACE) {
+          anEdgesAndFaces.push_back(*anIt);
+        } else {
+          aTools.push_back(*anIt);
+        }
+      }
+
+      if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
+        myFeature->setError("Error: Not enough objects for boolean operation.");
+        return false;
+      }
+
       // Collecting all solids which will be fused.
       ListOfShape aSolidsToFuse;
       aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
       aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
 
-      // Collecting solids from compsolids which will not be modified in boolean operation.
-      ListOfShape aNotUsedSolids;
-      for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
-        anIt != aCompSolidsObjects.end(); anIt++) {
-        std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
-        ListOfShape& aUsedInOperationSolids = anIt->second;
-        aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end());
+      // Collecting solids from compsolids which will not be modified in boolean operation and will be added to result.
+      ListOfShape aShapesToAdd;
+      for(std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+          anIt != aCompSolidsObjects.end(); anIt++) {
+        GeomShapePtr aCompSolid = anIt->first;
+        ListOfShape& aUsedShapes = anIt->second;
+        aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end());
 
         // Collect solids from compsolid which will not be modified in boolean operation.
         for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
-          std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
-          ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
-          for(; anIt != aUsedInOperationSolids.end(); anIt++) {
+          GeomShapePtr aSolidInCompSolid = anExp.current();
+          ListOfShape::iterator anIt = aUsedShapes.begin();
+          for(; anIt != aUsedShapes.end(); anIt++) {
             if(aSolidInCompSolid->isEqual(*anIt)) {
               break;
             }
           }
-          if(anIt == aUsedInOperationSolids.end()) {
-            aNotUsedSolids.push_back(aSolidInCompSolid);
+          if(anIt == aUsedShapes.end()) {
+            aShapesToAdd.push_back(aSolidInCompSolid);
           }
         }
       }
 
-      ListOfShape anOriginalSolids = aSolidsToFuse;
-      anOriginalSolids.insert(anOriginalSolids.end(), aNotUsedSolids.begin(), aNotUsedSolids.end());
+      // Cut edges and faces(if we have any) with solids.
+      ListOfShape aCutTools;
+      aCutTools.insert(aCutTools.end(), anObjects.begin(), anObjects.end());
+      aCutTools.insert(aCutTools.end(), aCompSolids.begin(), aCompSolids.end());
+      aCutTools.insert(aCutTools.end(), aTools.begin(), aTools.end());
+
       GeomAlgoAPI_MakeShapeList aMakeShapeList;
-      GeomAPI_DataMapOfShapeShape aMapOfShapes;
+      if(!anEdgesAndFaces.empty() && !aCutTools.empty()) {
+        std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
+                                                                              aCutTools,
+                                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+        if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) {
+          anEdgesAndFaces.clear();
+          anEdgesAndFaces.push_back(aCutAlgo->shape());
+          aMakeShapeList.appendAlgo(aCutAlgo);
+        }
+      }
 
       // If we have compsolids then cut with not used solids all others.
-      if(!aNotUsedSolids.empty()) {
-        aSolidsToFuse.clear();
-        for(ListOfShape::iterator anIt = anOriginalSolids.begin(); anIt != anOriginalSolids.end(); anIt++) {
-          ListOfShape aOneObjectList;
-          aOneObjectList.push_back(*anIt);
-          std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aOneObjectList, aNotUsedSolids, GeomAlgoAPI_Boolean::BOOL_CUT));
-
-          if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) {
-            aSolidsToFuse.push_back(aCutAlgo->shape());
-            aMakeShapeList.appendAlgo(aCutAlgo);
-            aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
-          }
+      if(!aShapesToAdd.empty()) {
+        std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse,
+                                                                              aShapesToAdd,
+                                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+        if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) {
+          aSolidsToFuse.clear();
+          aSolidsToFuse.push_back(aCutAlgo->shape());
+          aMakeShapeList.appendAlgo(aCutAlgo);
         }
       }
 
-      anObjects.clear();
-      anObjects.push_back(aSolidsToFuse.back());
-      aSolidsToFuse.pop_back();
-      aTools = aSolidsToFuse;
-
       // Fuse all objects and all tools.
-      std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, myBooleanOperationType));
+      GeomShapePtr aFusedShape;
+      if(aSolidsToFuse.size() == 1) {
+        aFusedShape = aSolidsToFuse.front();
+      } else if(aSolidsToFuse.size() > 1){
+        anObjects.clear();
+        anObjects.push_back(aSolidsToFuse.front());
+        aSolidsToFuse.pop_front();
+        aTools = aSolidsToFuse;
+
+        std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
+                                                                               aTools,
+                                                                               GeomAlgoAPI_Boolean::BOOL_FUSE));
 
-      // Checking that the algorithm worked properly.
-      if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) {
-        static const std::string aFeatureError = "Error: Boolean algorithm failed.";
-        setError(aFeatureError);
-        return;
+        // Checking that the algorithm worked properly.
+        if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) {
+          myFeature->setError("Error: Boolean algorithm failed.");
+          return false;
+        }
+
+        aFusedShape = aFuseAlgo->shape();
+        aMakeShapeList.appendAlgo(aFuseAlgo);
       }
 
-      std::shared_ptr<GeomAPI_Shape> aShape = aFuseAlgo->shape();
-      aMakeShapeList.appendAlgo(aFuseAlgo);
-      aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
-
-      // Add result to not used solids from compsolid (if we have any).
-      if(!aNotUsedSolids.empty()) {
-        aNotUsedSolids.push_back(aShape);
-        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aNotUsedSolids, true));
-        if(!aFillerAlgo->isDone()) {
-          std::string aFeatureError = "Error: PaveFiller algorithm failed.";
-          setError(aFeatureError);
-          return;
+      // Combine result with not used solids from compsolid and edges and faces (if we have any).
+      aShapesToAdd.insert(aShapesToAdd.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
+      if(!aShapesToAdd.empty()) {
+        if(aFusedShape.get()) {
+          aShapesToAdd.push_back(aFusedShape);
         }
-        if(aFillerAlgo->shape()->isNull()) {
-          static const std::string aShapeError = "Error: Resulting shape is Null.";
-          setError(aShapeError);
-          return;
-        }
-        if(!aFillerAlgo->isValid()) {
-          std::string aFeatureError = "Error: Resulting shape is not valid.";
-          setError(aFeatureError);
-          return;
+
+        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
+        if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) {
+          myFeature->setError("Error: PaveFiller algorithm failed.");
+          return false;
         }
 
-        aShape = aFillerAlgo->shape();
         aMakeShapeList.appendAlgo(aFillerAlgo);
-        aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
       }
-
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-      loadNamingDS(aResultBody, aShells, aSolidsAlgos, anOriginalSolids.front(), anOriginalSolids, aShape, aMakeShapeList, aMapOfShapes);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
       break;
     }
-    default: {
-      setError("Error: Wrong type of boolean operation.");
-      return;
-    }
   }
 
-  // Remove the rest results if there were produced in the previous pass.
-  removeResults(aResultIndex);
+  return true;
 }
 
 //=================================================================================================
-void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                                                   const ListOfShape& theShells,
-                                                   ListOfMakeShape& theSolidsAlgos,
-                                                   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_CompositeBoolean::storeModificationHistory(ResultBodyPtr theResultBody,
+                                const GeomShapePtr theObject,
+                                const ListOfShape& theTools,
+                                const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                int& theTag)
 {
-  //load result
-  if(theBaseShape->isEqual(theResultShape)) {
-    theResultBody->store(theResultShape);
-  } else {
-    const int aGenTag = 1;
-    const int aModTag = 2;
-    const int aDelTag = 3;
-    const int aSubsolidsTag=4; /// sub solids will be placed at labels 6, 7, etc. if result is compound of solids
-    int aToTag = 5000; // may be many labels, starting from this index
-    int aFromTag = 10000; // may be many labels, starting from this index or last aToTag index
-    const std::string aGenName = "Generated";
-    const std::string aModName = "Modified";
-    const std::string aLatName = "LateralFace";
-    const std::string aFromName = "FromFace";
-    const std::string aToName = "ToFace";
-
-    theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
-
-    ListOfShape::const_iterator aShellsIter = theShells.begin();
-    ListOfMakeShape::const_iterator aSolidsAlgosIter = theSolidsAlgos.begin();
-    for(; aShellsIter != theShells.end() && aSolidsAlgosIter != theSolidsAlgos.end(); aShellsIter++, aSolidsAlgosIter++) {
-      //Insert lateral face : Face from Edge
-      std::shared_ptr<GeomAlgoAPI_MakeShape> aSolidAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_MakeShape>(*aSolidsAlgosIter);
-      if(aSolidAlgo.get()) {
-        std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = aSolidAlgo->mapOfSubShapes();
-        theResultBody->loadAndOrientGeneratedShapes(aSolidAlgo.get(), *aShellsIter, GeomAPI_Shape::EDGE, aGenTag,
-                                                    aLatName, *aSubShapes.get());
-
-
-        std::shared_ptr<GeomAlgoAPI_MakeSweep> aSweepAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(aSolidAlgo);
-        if(aSweepAlgo.get()) {
-          //Insert to faces
-          int aToFaceIndex = 1;
-          const ListOfShape& aToFaces = aSweepAlgo->toShapes();
-          for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
-            std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
-            if(aSubShapes->isBound(aToFace)) {
-              aToFace = aSubShapes->find(aToFace);
-            }
-            std::ostringstream aStr;
-            aStr << aToName << "_" << aToFaceIndex++;
-            theResultBody->generated(aToFace, aStr.str(), aToTag++);
-          }
+  int aModTag = theTag;
+  int anEdgesAndFacesTag = ++aModTag;
+  int aDelTag = ++anEdgesAndFacesTag;
+  theTag = aDelTag;
 
-          //Insert from faces
-          int aFromFaceIndex = 1;
-          const ListOfShape& aFromFaces = aSweepAlgo->fromShapes();
-          if (aFromTag < aToTag) aFromTag = aToTag;
-          for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
-            std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
-            if(aSubShapes->isBound(aFromFace)) {
-              aFromFace = aSubShapes->find(aFromFace);
-            }
-            std::ostringstream aStr;
-            aStr << aFromName << "_" << aFromFaceIndex++;
-            theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
-          }
-        }
-      }
-    }
+  const std::string aModName = "Modfied";
 
-    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
-                                               aModTag, aModName, theMapOfShapes);
-    theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDelTag);
+  ListOfShape aTools = theTools;
+  aTools.push_back(theObject);
 
-    for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
-      theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE,
-                                                 aModTag, aModName, theMapOfShapes);
-      theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDelTag);
-    }
-  }
-}
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMap = theMakeShape->mapOfSubShapes();
 
-//=================================================================================================
-void FeaturesPlugin_CompositeBoolean::setSketchObjectToList()
-{
-  std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
-                                                       reference(SKETCH_OBJECT_ID())->value());
-
-  if(aSketchFeature.get() && !aSketchFeature->results().empty()) {
-    ResultPtr aSketchRes = aSketchFeature->results().front();
-    ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
-    if(aConstruction.get()) {
-      AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-      if (aFacesSelectionList.get() && aFacesSelectionList->size() == 0)
-        aFacesSelectionList->append(aSketchRes, std::shared_ptr<GeomAPI_Shape>());
+  int aTag;
+  std::string aName;
+  for(ListOfShape::const_iterator anIt = aTools.begin(); anIt != aTools.end(); anIt++) {
+    if((*anIt)->shapeType() == GeomAPI_Shape::EDGE) {
+      aTag = anEdgesAndFacesTag;
+      aName = aModName + "_Edge";
+    }
+    else if((*anIt)->shapeType() == GeomAPI_Shape::FACE) {
+      aTag = anEdgesAndFacesTag;
+      aName = aModName + "_Face";
+    } else {
+      aTag = aModTag;
+      aName = aModName;
     }
+    theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, (*anIt)->shapeType() == GeomAPI_Shape::EDGE ?
+                                               GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get());
+    theResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
   }
 }
index 7cae61fd9da390ab4442f4d8112b907f88f5156c..daa2e060d9635cf00c9bd1232ff797547b984a40 100644 (file)
 #ifndef FeaturesPlugin_CompositeBoolean_H_
 #define FeaturesPlugin_CompositeBoolean_H_
 
-#include <FeaturesPlugin.h>
+#include "FeaturesPlugin.h"
 
-#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultBody.h>
+#include <GeomAlgoAPI_MakeShape.h>
 
-#include <GeomAlgoAPI_Boolean.h>
-
-/** \class FeaturesPlugin_CompositeBoolean
- *  \ingroup Plugins
- *  \brief Interface for the composite boolean feature.
- */
-class FeaturesPlugin_CompositeBoolean : public ModelAPI_CompositeFeature
+/// \class FeaturesPlugin_CompositeBoolean
+/// \ingroup Plugins
+/// \brief Interface for the composite boolean feature.
+class FeaturesPlugin_CompositeBoolean
 {
- public:
-  /// Attribute name of sketch feature.
-  inline static const std::string& SKETCH_OBJECT_ID()
-  {
-    static const std::string MY_SKETCH_OBJECT_ID("sketch");
-    return MY_SKETCH_OBJECT_ID;
-  }
-
-  /// attribute name of references sketch entities list, it should contain a sketch result or
-  /// a pair a sketch result to sketch face
-  inline static const std::string& LIST_ID()
+public:
+  enum OperationType {
+    BOOL_CUT,
+    BOOL_FUSE,
+    BOOL_COMMON,
+    BOOL_SMASH
+  };
+
+  /// Attribute name of main objects.
+  inline static const std::string& OBJECTS_ID()
   {
-    static const std::string MY_GROUP_LIST_ID("base");
-    return MY_GROUP_LIST_ID;
-  }
-
-  /// Attribute name of sketch feature.
-  inline static const std::string& SKETCH_SELECTION_ID()
-  {
-    static const std::string MY_SKETCH_SELECTION_ID("sketch_selection");
-    return MY_SKETCH_SELECTION_ID;
-  }
-
-  /// Attribute name of objects for boolean operation.
-  inline static const std::string& BOOLEAN_OBJECTS_ID()
-  {
-    static const std::string MY_BOOLEAN_OBJECTS_ID("boolean_objects");
-    return MY_BOOLEAN_OBJECTS_ID;
+    static const std::string MY_OBJECTS_ID("main_objects");
+    return MY_OBJECTS_ID;
   }
 
   /// Creates a new part document if needed.
   FEATURESPLUGIN_EXPORT virtual void execute();
 
-  /// Request for initialization of data model of the feature: adding all attributes.
-  FEATURESPLUGIN_EXPORT virtual void initAttributes();
-
-  /// Appends a feature to the sketch sub-elements container.
-  FEATURESPLUGIN_EXPORT virtual std::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
-
-  /// \return the number of sub-elements.
-  FEATURESPLUGIN_EXPORT virtual int numberOfSubs(bool forTree = false) const;
-
-  /// \return the sub-feature by zero-base index.
-  FEATURESPLUGIN_EXPORT virtual std::shared_ptr<ModelAPI_Feature> subFeature(const int theIndex, bool forTree = false);
-
-  /// \return the sub-feature unique identifier in this composite feature by zero-base index.
-  FEATURESPLUGIN_EXPORT virtual int subFeatureId(const int theIndex) const;
-
-  /// \return true if feature or reuslt belong to this composite feature as subs.
-  FEATURESPLUGIN_EXPORT virtual bool isSub(ObjectPtr theObject) const;
-
-  /// This method to inform that sub-feature is removed and must be removed from the internal data
-  /// structures of the owner (the remove from the document will be done outside just after)
-  FEATURESPLUGIN_EXPORT virtual void removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature);
-
-  /// removes also all sub-sketch
-  FEATURESPLUGIN_EXPORT virtual void erase();
-
 protected:
   FeaturesPlugin_CompositeBoolean(){};
 
-  /// Define this function to init attributes for extrusion/revolution.
-  virtual void initMakeSolidsAttributes() = 0;
-
-  /// Define this function to create solids from faces with extrusion/revolution.
-  virtual void makeSolids(const ListOfShape& theFaces,
-                          ListOfShape& theResults,
-                          ListOfMakeShape& theAlgos) = 0;
-
-  /// Results naming.
-  void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                    const ListOfShape& theShells,
-                    ListOfMakeShape& theSolidsAlgos,
-                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
-                    const ListOfShape& theTools,
-                    const std::shared_ptr<GeomAPI_Shape> theResultShape,
-                    GeomAlgoAPI_MakeShape& theMakeShape,
-                    GeomAPI_DataMapOfShapeShape& theMapOfShapes);
-
-  /// Set the sub-object to list of exturusion base.
-  void setSketchObjectToList();
+  /// Initializes boolean attributes.
+  void initBooleanAttributes();
+
+  /// This function need to be defined for extrusion/revolution generation.
+  virtual bool makeGeneration(ListOfShape& theBaseShapes,
+                              ListOfMakeShape& theMakeShapes) = 0;
+
+  /// Makes boolean operation.
+  /// \param[in] theTools list of tools.
+  /// \param[out] theObjects list of objects.
+  /// \param[out] theMakeShapes list of according algos.
+  /// \return false in failed.
+  bool makeBoolean(const ListOfShape& theTools,
+                   ListOfShape& theObjects,
+                   ListOfMakeShape& theMakeShapes);
+
+  /// Stores generation history.
+  virtual void storeGenerationHistory(ResultBodyPtr theResultBody,
+                                      const GeomShapePtr theBaseShape,
+                                      const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                      int& theTag) = 0;
+
+  /// Stores modification history.
+  void storeModificationHistory(ResultBodyPtr theResultBody,
+                                const GeomShapePtr theObject,
+                                const ListOfShape& theTools,
+                                const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                int& theTag);
 
 protected:
-  /// Type of boolean operation.
-  GeomAlgoAPI_Boolean::OperationType myBooleanOperationType;
+  ModelAPI_Feature* myFeature;
+  OperationType myOperationType;
 };
 
 #endif
index 57a711e0ccc2d1598eed7cc25585c05883bf901f..0b5a103ceb74a3e604583f174019fa0a9243e37e 100644 (file)
@@ -9,7 +9,6 @@
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_BodyBuilder.h>
-#include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 #include <GeomAlgoAPI_Prism.h>
 #include <GeomAlgoAPI_Revolution.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_ShapeExplorer.h>
 
 #include <sstream>
 
 //=================================================================================================
-void FeaturesPlugin_CompositeSketch::initAttributes()
+void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags)
 {
-  data()->addAttribute(SKETCH_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
-  data()->addAttribute(SKETCH_SELECTION_ID(), ModelAPI_AttributeSelection::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_SELECTION_ID());
+  // Initialize sketch launcher.
+  if(theInitFlags & InitSketchLauncher) {
+    data()->addAttribute(SKETCH_ID(), ModelAPI_AttributeReference::typeId());
+    ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_ID());
+  }
 
-  //initMakeSolidsAttributes();
+  // Initialize selection list.
+  if(theInitFlags & InitBaseObjectsList) {
+    data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+  }
 }
 
 //=================================================================================================
 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std::string theID)
 {
-  std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
-  if (aNew) {
-    data()->reference(SKETCH_OBJECT_ID())->setValue(aNew);
+  FeaturePtr aNew = document()->addFeature(theID, false);
+  if(aNew) {
+    data()->reference(SKETCH_ID())->setValue(aNew);
   }
-  // set as current also after it becomes sub to set correctly enabled for other sketch subs
+
+  // Set as current also after it becomes sub to set correctly enabled for other sketch subs.
   document()->setCurrentFeature(aNew, false);
   return aNew;
 }
@@ -46,194 +52,301 @@ std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std
 //=================================================================================================
 int FeaturesPlugin_CompositeSketch::numberOfSubs(bool forTree) const
 {
-  ObjectPtr aObj = data()->reference(SKETCH_OBJECT_ID())->value();
-  return aObj.get()? 1 : 0;
+  ObjectPtr aObj = data()->reference(SKETCH_ID())->value();
+  return aObj.get() ? 1 : 0;
 }
 
 //=================================================================================================
 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::subFeature(const int theIndex, bool forTree)
 {
-  if (theIndex == 0)
-    return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
+  if(theIndex == 0) {
+    return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
+  }
+
   return std::shared_ptr<ModelAPI_Feature>();
 }
 
 //=================================================================================================
 int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const
 {
-  if (theIndex == 0) {
-    FeaturePtr aFeature = 
-      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
-    if (aFeature.get())
+  if(theIndex == 0) {
+    FeaturePtr aFeature =
+      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
+    if(aFeature.get()) {
       return aFeature->data()->featureId();
+    }
   }
+
   return -1;
 }
 
 //=================================================================================================
 bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const
 {
-  // check is this feature of result
+  // Check is this feature of result
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
-  if (!aFeature)
+  if(!aFeature.get()) {
     return false;
-  ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value();
+  }
+
+  ObjectPtr aSub = data()->reference(SKETCH_ID())->value();
   return aSub == theObject;
 }
 
 //=================================================================================================
 void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
 {
-  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-  if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0)
-    aFacesSelectionList->clear();
+  AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
+  if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) {
+    aBaseObjectsSelectionList->clear();
+  }
 
-  data()->reference(SKETCH_OBJECT_ID())->setValue(ObjectPtr());
+  reference(SKETCH_ID())->setValue(ObjectPtr());
 }
 
 //=================================================================================================
 void FeaturesPlugin_CompositeSketch::erase()
 {
-  if (data().get() && data()->isValid()) { // on abort of sketch of this composite it may be invalid
-    FeaturePtr aSketch =
-      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
-    if (aSketch.get() && aSketch->data()->isValid()) {
+  if(data().get() && data()->isValid()) { // on abort of sketch of this composite it may be invalid
+    FeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_Feature>(reference(SKETCH_ID())->value());
+    if(aSketch.get() && aSketch->data()->isValid()) {
       document()->removeFeature(aSketch);
     }
   }
+
   ModelAPI_CompositeFeature::erase();
 }
 
-
 //=================================================================================================
-void FeaturesPlugin_CompositeSketch::execute()
+void FeaturesPlugin_CompositeSketch::setSketchObjectToList()
 {
-  // Getting faces to create solids.
-  std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
-                                                     reference(SKETCH_OBJECT_ID())->value());
-  if(!aSketchFeature || aSketchFeature->results().empty()) {
+  AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
+  if(!aBaseObjectsSelectionList.get() || aBaseObjectsSelectionList->isInitialized()) {
     return;
   }
+
+  AttributeReferencePtr aSketchLauncherRef = reference(SKETCH_ID());
+  if(!aSketchLauncherRef.get() || !aSketchLauncherRef->isInitialized()) {
+    return;
+  }
+
+  FeaturePtr aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aSketchLauncherRef->value());
+
+  if(!aSketchFeature.get() || aSketchFeature->results().empty()) {
+    return;
+  }
+
   ResultPtr aSketchRes = aSketchFeature->results().front();
   ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
   if(!aConstruction.get()) {
     return;
   }
 
-  /// feature extrusion does not have the next attribute
-  if (data()->attribute(SKETCH_SELECTION_ID()).get()) {
-    if (!selection(SKETCH_SELECTION_ID())->isInitialized() || selection(SKETCH_SELECTION_ID())->context() != aSketchRes) {
-      selection(SKETCH_SELECTION_ID())->setValue(aSketchRes, std::shared_ptr<GeomAPI_Shape>());
-    }
+  if(aBaseObjectsSelectionList->size() == 0) {
+    aBaseObjectsSelectionList->append(aSketchRes, GeomShapePtr());
   }
-  int aSketchFacesNum = aConstruction->facesNum();
-  if(aSketchFacesNum == 0) {
+}
+
+//=================================================================================================
+void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList,
+                                                   const bool theIsMakeShells)
+{
+  theBaseShapesList.clear();
+
+  ListOfShape aBaseFacesList;
+  AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
+  if(!aBaseObjectsSelectionList.get()) {
+    setError("Error: Could not get base objects selection list.");
     return;
   }
-  ListOfShape aFacesList;
-  for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) {
-    std::shared_ptr<GeomAPI_Shape> aFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
-    aFacesList.push_back(aFace);
+  if(aBaseObjectsSelectionList->size() == 0) {
+    setError("Error: Base objects list is empty.");
+    return;
+  }
+  for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) {
+    AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex);
+    if(!aBaseObjectSelection.get()) {
+      setError("Error: One of the selected base objects is empty.");
+      return;
+    }
+    GeomShapePtr aBaseShape = aBaseObjectSelection->value();
+    if(aBaseShape.get() && !aBaseShape->isNull()) {
+      aBaseShape->shapeType() == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
+                                                       theBaseShapesList.push_back(aBaseShape);
+    } else {
+      // This may be the whole sketch result selected, check and get faces.
+      ResultConstructionPtr aConstruction =
+        std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseObjectSelection->context());
+      if(!aConstruction.get()) {
+        setError("Error: One of selected sketches does not have results.");
+        return;
+      }
+      int aFacesNum = aConstruction->facesNum();
+      if(aFacesNum == 0) {
+        // Probably it can be construction.
+        aBaseShape = aConstruction->shape();
+        if(aBaseShape.get() && !aBaseShape->isNull()) {
+          aBaseShape->shapeType() == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
+                                                           theBaseShapesList.push_back(aBaseShape);
+        }
+      } else {
+        for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
+          GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex);
+          if(!aBaseFace.get() || aBaseFace->isNull()) {
+            setError("Error: One of the faces on selected sketch is Null.");
+            return;
+          }
+          aBaseFacesList.push_back(aBaseFace);
+        }
+      }
+    }
   }
 
   // Searching faces with common edges.
-  ListOfShape aShells;
-  ListOfShape aFreeFaces;
-  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
-  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
-  aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
-
-  // Generating result for each shell and face.
-  int aErrorsNum = 0;
-  int aResultIndex = 0;
-  for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
-    std::shared_ptr<GeomAlgoAPI_MakeShape> aMakeShape;
-
-    std::shared_ptr<GeomAPI_Shape> aBaseFace = *anIter;
-    makeSolid(aBaseFace, aMakeShape);
-    if(!aMakeShape.get()) {
-      aErrorsNum++;
-      continue;
-    }
+  if(theIsMakeShells) {
+    ListOfShape aShells;
+    ListOfShape aFreeFaces;
+    GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList);
+    GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
+    theBaseShapesList.insert(theBaseShapesList.end(), aFreeFaces.begin(), aFreeFaces.end());
+    theBaseShapesList.insert(theBaseShapesList.end(), aShells.begin(), aShells.end());
+  } else {
+    theBaseShapesList.insert(theBaseShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end());
+  }
+}
 
-    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    loadNamingDS(aResultBody, aBaseFace, aMakeShape);
-    setResult(aResultBody, aResultIndex);
-    aResultIndex++;
+//=================================================================================================
+bool FeaturesPlugin_CompositeSketch::isMakeShapeValid(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+  // Check that algo is done.
+  if(!theMakeShape->isDone()) {
+    setError("Error:" + getKind() + "algorithm failed.");
+    return false;
   }
 
-  if(aErrorsNum > 0) {
-    std::ostringstream aStringStream;
-    aStringStream << "Error: Could not create solid(s) from " << aErrorsNum << " face(s).";
-    setError(aStringStream.str());
+  // Check if shape is not null.
+  if(!theMakeShape->shape().get() || theMakeShape->shape()->isNull()) {
+    setError("Error: Resulting shape is null.");
+    return false;
   }
 
-  // Remove the rest results if there were produced in the previous pass.
-  removeResults(aResultIndex);
+  // Check that resulting shape is valid.
+  if(!theMakeShape->isValid()) {
+    setError("Error: Resulting shape is not valid.");
+    return false;
+  }
+
+  return true;
 }
 
 //=================================================================================================
-void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                                                  const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
-                                                  const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
+void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape,
+                                                 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                                 const int theResultIndex)
 {
-  //load result
-  theResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
-
-  //Insert lateral face : Face from Edge
-  const std::string aLatName = "LateralFace";
-  const int aLatTag = 1;
-  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aDataMap = theMakeShape->mapOfSubShapes();
-  theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aDataMap.get());
-
-  std::shared_ptr<GeomAlgoAPI_MakeSweep> aSweepAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
-  if(aSweepAlgo.get()) {
-    //Insert to faces
-    int aToFaceIndex = 1;
-    const std::string aToName = "ToFace";
-    int aToTag = 2;
-    const ListOfShape& aToFaces = aSweepAlgo->toShapes();
-    for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
-      std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
-      if(aDataMap->isBound(aToFace)) {
-        aToFace = aDataMap->find(aToFace);
-      }
-      std::ostringstream aStr;
-      aStr << aToName << "_" << aToFaceIndex++;
-      theResultBody->generated(aToFace, aStr.str(), aToTag++);
-    }
+  // Create result body.
+  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
 
-    //Insert from faces
-    int aFromFaceIndex = 1;
-    const std::string aFromName = "FromFace";
-    int aFromTag = aToTag > 10000 ? aToTag : 10000;
-    const ListOfShape& aFromFaces = aSweepAlgo->fromShapes();
-    for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
-      std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
-      if(aDataMap->isBound(aFromFace)) {
-        aFromFace = aDataMap->find(aFromFace);
-      }
-      std::ostringstream aStr;
-      aStr << aFromName << "_" << aFromFaceIndex++;
-      theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
+  // Store generated shape.
+  aResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
+
+  // Store generated edges/faces.
+  int aGenTag = 1;
+  storeGenerationHistory(aResultBody, theBaseShape, theMakeShape, aGenTag);
+
+  setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody,
+                                                            const GeomShapePtr theBaseShape,
+                                                            const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                                            int& theTag)
+{
+  GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
+  GeomAPI_Shape::ShapeType aShapeTypeToExplode;
+  std::string aGenName = "Generated_";
+
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
+  switch(aBaseShapeType) {
+    case GeomAPI_Shape::VERTEX: {
+      aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
+      aGenName += "Edge";
+      break;
+    }
+    case GeomAPI_Shape::EDGE:
+    case GeomAPI_Shape::WIRE: {
+      std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
+      GeomAlgoAPI_ShapeTools::findBounds(theBaseShape, aV1, aV2);
+      ListOfShape aV1History, aV2History;
+      theMakeShape->generated(aV1, aV1History);
+      theMakeShape->generated(aV2, aV2History);
+      theResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", theTag++);
+      theResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", theTag++);
+    }
+    case GeomAPI_Shape::FACE:
+    case GeomAPI_Shape::SHELL: {
+      aShapeTypeToExplode = GeomAPI_Shape::EDGE;
+      aGenName += "Face";
+      break;
     }
   }
+  theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, aShapeTypeToExplode,
+                                              theTag++, aGenName, *aMapOfSubShapes.get());
+
+  std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep = std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
+  if(aMakeSweep.get()) {
+    // Store from shapes.
+    storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->fromShapes(), "From_", theTag);
+
+    // Store to shapes.
+    storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->toShapes(), "To_", theTag);
+  }
 }
+
 //=================================================================================================
-void FeaturesPlugin_CompositeSketch::setSketchObjectToList()
+void FeaturesPlugin_CompositeSketch::storeShapes(ResultBodyPtr theResultBody,
+                                                 const GeomAPI_Shape::ShapeType theBaseShapeType,
+                                                 const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
+                                                 const ListOfShape& theShapes,
+                                                 const std::string theName,
+                                                 int& theTag)
 {
-  std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
-                                                       reference(SKETCH_OBJECT_ID())->value());
-
-  if(aSketchFeature.get() && !aSketchFeature->results().empty()) {
-    ResultPtr aSketchRes = aSketchFeature->results().front();
-    ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
-    if(aConstruction.get()) {
-      AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-      if (aFacesSelectionList.get() && aFacesSelectionList->size() == 0)
-        aFacesSelectionList->append(aSketchRes, std::shared_ptr<GeomAPI_Shape>());
+  GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
+  std::string aShapeTypeStr = "Face";
+  switch(theBaseShapeType) {
+    case GeomAPI_Shape::VERTEX: {
+      aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
+      aShapeTypeStr = "Vertex";
+      break;
+    }
+    case GeomAPI_Shape::EDGE:
+    case GeomAPI_Shape::WIRE: {
+      aShapeTypeToExplore = GeomAPI_Shape::EDGE;
+      aShapeTypeStr = "Edge";
+      break;
+    }
+    case GeomAPI_Shape::FACE:
+    case GeomAPI_Shape::SHELL: {
+      aShapeTypeToExplore = GeomAPI_Shape::FACE;
+      aShapeTypeStr = "Face";
+      break;
     }
   }
-}
 
+  // Store shapes.
+  int aShapeIndex = 1;
+  std::string aName = theName + aShapeTypeStr;
+  for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
+    GeomShapePtr aShape = *anIt;
+    for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) {
+      GeomShapePtr aSubShape = anExp.current();
+      if(theMapOfSubShapes->isBound(aSubShape)) {
+        aSubShape = theMapOfSubShapes->find(aSubShape);
+      }
+      std::ostringstream aStr;
+      aStr << aName << "_" << aShapeIndex++;
+      theResultBody->generated(aSubShape, aStr.str(), theTag++);
+    }
+  }
+}
\ No newline at end of file
index 7f0a9e9ce6b0ffc0c2bd0cd136a81ba81aa98ca2..d2c7be54e2fe699be5bd018a86b06c97f8824aa9 100644 (file)
@@ -7,47 +7,32 @@
 #ifndef FeaturesPlugin_CompositeSketch_H_
 #define FeaturesPlugin_CompositeSketch_H_
 
-#include <FeaturesPlugin.h>
+#include "FeaturesPlugin.h"
 
 #include <ModelAPI_CompositeFeature.h>
 
-#include <GeomAlgoAPI_Boolean.h>
+#include <ModelAPI_ResultBody.h>
 
-/** \class FeaturesPlugin_CompositeSketch
- *  \ingroup Plugins
- *  \brief Interface for the composite sketch feature.
- */
+/// \class FeaturesPlugin_CompositeSketch
+/// \ingroup Plugins
+/// \brief Interface for the composite sketch feature.
 class FeaturesPlugin_CompositeSketch : public ModelAPI_CompositeFeature
 {
- public:
+public:
   /// Attribute name of sketch feature.
-  inline static const std::string& SKETCH_OBJECT_ID()
+  inline static const std::string& SKETCH_ID()
   {
-    static const std::string MY_SKETCH_OBJECT_ID("sketch");
-    return MY_SKETCH_OBJECT_ID;
+    static const std::string MY_SKETCH_ID("sketch");
+    return MY_SKETCH_ID;
   }
 
-  /// Attribute name of sketch feature selection: needed for naming of the selected sketch.
-  inline static const std::string& SKETCH_SELECTION_ID()
+  /// Attribute name of base objects.
+  inline static const std::string& BASE_OBJECTS_ID()
   {
-    static const std::string MY_SKETCH_SELECTION_ID("sketch_selection");
-    return MY_SKETCH_SELECTION_ID;
+    static const std::string MY_BASE_OBJECTS_ID("base");
+    return MY_BASE_OBJECTS_ID;
   }
 
-  /// attribute name of references sketch entities list, it should contain a sketch result or
-  /// a pair a sketch result to sketch face
-  inline static const std::string& LIST_ID()
-  {
-    static const std::string MY_GROUP_LIST_ID("base");
-    return MY_GROUP_LIST_ID;
-  }
-
-  /// Creates a new part document if needed.
-  FEATURESPLUGIN_EXPORT virtual void execute();
-
-  /// Request for initialization of data model of the feature: adding all attributes.
-  FEATURESPLUGIN_EXPORT virtual void initAttributes();
-
   /// Appends a feature to the sketch sub-elements container.
   FEATURESPLUGIN_EXPORT virtual std::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
 
@@ -64,30 +49,53 @@ class FeaturesPlugin_CompositeSketch : public ModelAPI_CompositeFeature
   FEATURESPLUGIN_EXPORT virtual bool isSub(ObjectPtr theObject) const;
 
   /// This method to inform that sub-feature is removed and must be removed from the internal data
-  /// structures of the owner (the remove from the document will be done outside just after)
+  /// structures of the owner (the remove from the document will be done outside just after).
   FEATURESPLUGIN_EXPORT virtual void removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature);
 
-  /// removes also all sub-sketch
+  /// Removes also all sub-sketch.
   FEATURESPLUGIN_EXPORT virtual void erase();
 
 protected:
-  FeaturesPlugin_CompositeSketch(){};
-
-  /// Define this function to init attributes for extrusion/revolution.
-  //virtual void initMakeSolidsAttributes() {};
+  enum InitFlags {
+    InitSketchLauncher   = 1 << 0,
+    InitBaseObjectsList  = 1 << 1
+  };
 
-  /// Define this function to create solids from faces with extrusion/revolution.
-  virtual void makeSolid(const std::shared_ptr<GeomAPI_Shape> theFace,
-                         std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape) {};
+  FeaturesPlugin_CompositeSketch(){};
 
-  /// Results naming.
-  void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                    const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
-                    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+  /// Initializes composite sketch attributes.
+  void initCompositeSketchAttribtues(const int theInitFlags);
 
-  /// Set the sub-object to list of exturusion base.
+  /// Sets the sub-object to list of base.
   void setSketchObjectToList();
 
+  /// \brief Returns list of base shapes.
+  /// \param[out] theBaseShapesList list of base shapes (warning: list not cleared).
+  /// \param[in] theIsMakeShells if true make shells from faces with shared edges.
+  void getBaseShapes(ListOfShape& theBaseShapesList, const bool theIsMakeShells = true);
+
+  /// Checks make shape algo.
+  bool isMakeShapeValid(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
+  /// Stores result of generation.
+  void storeResult(const GeomShapePtr theBaseShape,
+                   const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                   const int theIndex = 0);
+
+  /// Stores generation history.
+  void storeGenerationHistory(ResultBodyPtr theResultBody,
+                              const GeomShapePtr theBaseShape,
+                              const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                              int& theTag);
+
+  /// Used to store from and to shapes.
+  void storeShapes(ResultBodyPtr theResultBody,
+                   const GeomAPI_Shape::ShapeType theBaseShapeType,
+                   const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
+                   const ListOfShape& theShapes,
+                   const std::string theName,
+                   int& theTag);
+
 };
 
 #endif
index 0be521794d60d2a6715c3f6ab3ef158500f34555..20b7c254ae2c0148e193db24eea484b9143253eb 100644 (file)
@@ -6,21 +6,13 @@
 
 #include "FeaturesPlugin_Extrusion.h"
 
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
-#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
 
-#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_Prism.h>
-#include <GeomAlgoAPI_ShapeTools.h>
-
-#include <sstream>
 
 //=================================================================================================
 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
@@ -30,11 +22,7 @@ FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
 //=================================================================================================
 void FeaturesPlugin_Extrusion::initAttributes()
 {
-  AttributeSelectionListPtr aSelection = 
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
-  aSelection->setSelectionType("FACE");
+  initCompositeSketchAttribtues(InitBaseObjectsList);
 
   data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
 
@@ -47,175 +35,95 @@ void FeaturesPlugin_Extrusion::initAttributes()
   data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
 
+  data()->addAttribute(DIRECTION_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DIRECTION_OBJECT_ID());
 
-  // Composite Sketch attribute
-  data()->addAttribute(FeaturesPlugin_CompositeSketch::SKETCH_OBJECT_ID(),
-                       ModelAPI_AttributeReference::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
-                       FeaturesPlugin_CompositeSketch::SKETCH_OBJECT_ID());
+  initCompositeSketchAttribtues(InitSketchLauncher);
 }
 
 //=================================================================================================
 void FeaturesPlugin_Extrusion::execute()
 {
-  /// sub feature of the composite should be set in the base list
-  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-  if (aFacesSelectionList.get() && !aFacesSelectionList->isInitialized()) {
-    AttributeReferencePtr aSketchAttr = reference(SKETCH_OBJECT_ID());
-    if (aSketchAttr.get() && aSketchAttr->isInitialized())
-      setSketchObjectToList();
+  ListOfShape aBaseShapesList;
+  ListOfMakeShape aMakeShapesList;
+
+  // Make extrusions.
+  if(!makeExtrusions(aBaseShapesList, aMakeShapesList)) {
+    return;
   }
 
-  // Getting faces.
-  ListOfShape aFacesList;
-  for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
-    AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
-    std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
-    if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
-      aFacesList.push_back(aFaceShape);
-    } else { // This may be the whole sketch result selected, check and get faces.
-      ResultPtr aContext = aFaceSel->context();
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
-      if(!aContextShape.get()) {
-        static const std::string aContextError = "Error: The selection context is bad.";
-        setError(aContextError);
-        return;
-      }
-      ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
-      if(!aConstruction.get()) {
-        static const std::string aFaceError = "Error: Can not find basis for extrusion.";
-        setError(aFaceError);
-        return;
-      }
-      int aFacesNum = aConstruction->facesNum();
-      for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
-        aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
-        aFacesList.push_back(aFaceShape);
-      }
-    }
+  // Store results.
+  int aResultIndex = 0;
+  ListOfShape::const_iterator aBaseIt = aBaseShapesList.cbegin();
+  ListOfMakeShape::const_iterator anAlgoIt = aMakeShapesList.cbegin();
+  for(; aBaseIt != aBaseShapesList.cend() && anAlgoIt != aMakeShapesList.cend(); ++aBaseIt, ++anAlgoIt) {
+    storeResult(*aBaseIt, *anAlgoIt, aResultIndex++);
   }
 
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+bool FeaturesPlugin_Extrusion::makeExtrusions(ListOfShape& theBaseShapes,
+                                              ListOfMakeShape& theMakeShapes)
+{
+  theMakeShapes.clear();
+
+  /// Sub-feature of the composite should be set in the base list.
+  setSketchObjectToList();
+
+  // Getting base shapes.
+  getBaseShapes(theBaseShapes);
+
   // Getting sizes.
   double aToSize = 0.0;
   double aFromSize = 0.0;
 
   if(string(CREATION_METHOD())->value() == "BySizes") {
     aToSize = real(TO_SIZE_ID())->value();
-    aFromSize =  real(FROM_SIZE_ID())->value();
+    aFromSize = real(FROM_SIZE_ID())->value();
   } else {
     aToSize = real(TO_OFFSET_ID())->value();
-    aFromSize =  real(FROM_OFFSET_ID())->value();
+    aFromSize = real(FROM_OFFSET_ID())->value();
   }
 
   // Getting bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
+  GeomShapePtr aToShape;
+  GeomShapePtr aFromShape;
 
   if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
+    AttributeSelectionPtr aSelection = selection(TO_OBJECT_ID());
+    if(aSelection.get()) {
+      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aSelection->value());
+      if(!aToShape.get() && aSelection->context().get()) {
+        aToShape = aSelection->context()->shape();
       }
     }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
+    aSelection = selection(FROM_OBJECT_ID());
+    if(aSelection.get()) {
+      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aSelection->value());
+      if(!aFromShape.get() && aSelection->context().get()) {
+        aFromShape = aSelection->context()->shape();
       }
     }
   }
 
-  // Searching faces with common edges.
-  ListOfShape aShells;
-  ListOfShape aFreeFaces;
-  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
-  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
-  aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
-
-  // Generating result for each shell and face.
-  int aResultIndex = 0;
-  for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
+  // Generating result for each base shape.
+  for(ListOfShape::const_iterator anIter = theBaseShapes.cbegin(); anIter != theBaseShapes.cend(); anIter++) {
     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
 
-    GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aToShape, aToSize, aFromShape, aFromSize);
-    if(!aPrismAlgo.isDone()) {
-      static const std::string aPrismAlgoError = "Error: Extrusion algorithm failed.";
-      setError(aPrismAlgoError);
-      aResultIndex = 0;
-      break;
+    std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo(new GeomAlgoAPI_Prism(aBaseShape,
+                                                                        aToShape, aToSize,
+                                                                        aFromShape, aFromSize));
+    if(!isMakeShapeValid(aPrismAlgo)) {
+      return false;
     }
 
-    // Check if shape is valid
-    if(!aPrismAlgo.shape().get() || aPrismAlgo.shape()->isNull()) {
-      static const std::string aShapeError = "Error: Resulting shape is Null.";
-      setError(aShapeError);
-      aResultIndex = 0;
-      break;
-    }
-    if(!aPrismAlgo.isValid()) {
-      std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
-      setError(aPrismAlgoError);
-      aResultIndex = 0;
-      break;
-    }
-
-    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    loadNamingDS(aPrismAlgo, aResultBody, aBaseShape);
-    setResult(aResultBody, aResultIndex);
-    aResultIndex++;
-  }
-
-  removeResults(aResultIndex);
-}
-
-//=================================================================================================
-void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
-                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                                            std::shared_ptr<GeomAPI_Shape> theBasis)
-{
-  //load result
-  theResultBody->storeGenerated(theBasis, thePrismAlgo.shape());
-
-  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = thePrismAlgo.mapOfSubShapes();
-
-  //Insert lateral face : Face from Edge
-  const std::string aLatName = "LateralFace";
-  const int aLatTag = 1;
-  theResultBody->loadAndOrientGeneratedShapes(&thePrismAlgo, theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
-
-  //Insert to faces
-  int aToFaceIndex = 1;
-  const std::string aToName = "ToFace";
-  int aToTag = 2;
-  const ListOfShape& aToFaces = thePrismAlgo.toShapes();
-  for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
-    std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
-    if(aSubShapes->isBound(aToFace)) {
-      aToFace = aSubShapes->find(aToFace);
-    }
-    std::ostringstream aStr;
-    aStr << aToName << "_" << aToFaceIndex++;
-    theResultBody->generated(aToFace, aStr.str(), aToTag++);
+    theMakeShapes.push_back(aPrismAlgo);
   }
 
-  //Insert from faces
-  int aFromFaceIndex = 1;
-  const std::string aFromName = "FromFace";
-  int aFromTag = aToTag > 10000 ? aToTag : 10000;
-  const ListOfShape& aFromFaces = thePrismAlgo.fromShapes();
-  for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
-    std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
-    if(aSubShapes->isBound(aFromFace)) {
-      aFromFace = aSubShapes->find(aFromFace);
-    }
-    std::ostringstream aStr;
-    aStr << aFromName << "_" << aFromFaceIndex++;
-    theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
-  }
+  return true;
 }
-
index a9330faf2fc8b1f31c67bb87983ecc6a06c5c76f..f2a8fc1776acfd582445b48d89dac1b329227645 100644 (file)
 #ifndef FeaturesPlugin_Extrusion_H_
 #define FeaturesPlugin_Extrusion_H_
 
-#include <FeaturesPlugin.h>
-#include <GeomAlgoAPI_Prism.h>
-
-#include <FeaturesPlugin_CompositeSketch.h>
-
-class GeomAPI_Shape;
-class ModelAPI_ResultBody;
-
-/**\class FeaturesPlugin_Extrusion
- * \ingroup Plugins
- * \brief Feature for creation of extrusion from the planar face.
- *
- * Extrusion creates the lateral faces based on edges of the base face and
- * the top and bottom faces equal to the base face or this faces can be projection on the
- * bounding planes if they were set. Direction of extrusion is taken from the face
- * plane or if the bounding faces were set then it will be from the bottom to the top plane.
- */
-class FeaturesPlugin_Extrusion : public FeaturesPlugin_CompositeSketch
+#include "FeaturesPlugin.h"
+
+#include "FeaturesPlugin_CompositeSketch.h"
+
+#include <GeomAlgoAPI_MakeShape.h>
+
+/// \class FeaturesPlugin_Extrusion
+/// \ingroup Plugins
+/// \brief Feature for creation of extrusion from the planar face.
+/// Extrusion creates the lateral faces based on edges of the base face and
+/// the top and bottom faces equal to the base face or this faces can be projection on the
+/// bounding planes if they were set. Direction of extrusion is taken from the face
+/// plane or if the bounding faces were set then it will be from the bottom to the top plane.
+class FeaturesPlugin_Extrusion: public FeaturesPlugin_CompositeSketch
 {
- public:
-  /// Extrusion kind
+public:
+  /// Use plugin manager for features creation
+  FeaturesPlugin_Extrusion();
+
+  /// Feature kind.
   inline static const std::string& ID()
   {
-    static const std::string MY_EXTRUSION_ID("Extrusion");
-    return MY_EXTRUSION_ID;
+    static const std::string MY_ID("Extrusion");
+    return MY_ID;
   }
 
-  /// attribute name of an object to which the extrusion grows
-  inline static const std::string& AXIS_OBJECT_ID()
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
   {
-    static const std::string MY_TO_OBJECT_ID("axis_object");
-    return MY_TO_OBJECT_ID;
+    static const std::string MY_CREATION_METHOD_ID("CreationMethod");
+    return MY_CREATION_METHOD_ID;
   }
 
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
+  /// Attribute name of an object to which the extrusion grows.
+  inline static const std::string& DIRECTION_OBJECT_ID()
   {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
+    static const std::string MY_DIRECTION_OBJECT_ID("direction_object");
+    return MY_DIRECTION_OBJECT_ID;
   }
 
-  /// attribute name of extrusion size
+  /// Attribute name of extrusion to size.
   inline static const std::string& TO_SIZE_ID()
   {
     static const std::string MY_TO_SIZE_ID("to_size");
     return MY_TO_SIZE_ID;
   }
 
-  /// attribute name of extrusion size
+  /// Attribute name of extrusion from size.
   inline static const std::string& FROM_SIZE_ID()
   {
     static const std::string MY_FROM_SIZE_ID("from_size");
     return MY_FROM_SIZE_ID;
   }
 
-  /// attribute name of an object to which the extrusion grows
+  /// Attribute name of an object to which the extrusion grows.
   inline static const std::string& TO_OBJECT_ID()
   {
     static const std::string MY_TO_OBJECT_ID("to_object");
     return MY_TO_OBJECT_ID;
   }
 
-  /// attribute name of extrusion offset
+  /// Attribute name of extrusion offset.
   inline static const std::string& TO_OFFSET_ID()
   {
     static const std::string MY_TO_OFFSET_ID("to_offset");
     return MY_TO_OFFSET_ID;
   }
 
-  /// attribute name of tool object
+  /// Attribute name of an object from which the extrusion grows.
   inline static const std::string& FROM_OBJECT_ID()
   {
     static const std::string MY_FROM_OBJECT_ID("from_object");
     return MY_FROM_OBJECT_ID;
   }
 
-  /// attribute name of extrusion offset
+  /// Attribute name of extrusion offset.
   inline static const std::string& FROM_OFFSET_ID()
   {
     static const std::string MY_FROM_OFFSET_ID("from_offset");
     return MY_FROM_OFFSET_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_Extrusion::ID();
     return MY_KIND;
   }
 
-  /// Creates a new part document if needed
-  FEATURESPLUGIN_EXPORT virtual void execute();
-
-  /// Request for initialization of data model of the feature: adding all attributes
+  /// Request for initialization of data model of the feature: adding all attributes.
   FEATURESPLUGIN_EXPORT virtual void initAttributes();
 
-  /// Use plugin manager for features creation
-  FeaturesPlugin_Extrusion();
+  /// Creates a new part document if needed.
+  FEATURESPLUGIN_EXPORT virtual void execute();
 
-private:
-  /// Load Naming data structure of the feature to the document
-  void loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
-                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                    std::shared_ptr<GeomAPI_Shape> theBasis);
+protected:
+  /// Generates extrusions.
+  /// \param[out] theBaseShapes list of base shapes.
+  /// \param[out] theMakeShapes list of according algos.
+  /// \return false in case one of algo failed.
+  bool makeExtrusions(ListOfShape& theBaseShapes,
+                      ListOfMakeShape& theMakeShapes);
 };
 
 #endif
index bc514dcd603c3cceaa458291ccbded42c4722e36..4501a81911ea8e59d5b5e7cb1f4a5309bc43f9c5 100755 (executable)
@@ -4,86 +4,28 @@
 // Created:     11 June 2015
 // Author:      Dmitry Bobylev
 
-#include <FeaturesPlugin_ExtrusionBoolean.h>
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-#include <GeomAlgoAPI_Prism.h>
+#include "FeaturesPlugin_ExtrusionBoolean.h"
 
 //=================================================================================================
-void FeaturesPlugin_ExtrusionBoolean::initMakeSolidsAttributes()
+void FeaturesPlugin_ExtrusionBoolean::initAttributes()
 {
-  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
-
-  data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
+  FeaturesPlugin_Extrusion::initAttributes();
 
-  data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
+  initBooleanAttributes();
 }
 
 //=================================================================================================
-void FeaturesPlugin_ExtrusionBoolean::makeSolids(const ListOfShape& theFaces,
-                                                 ListOfShape& theResults,
-                                                 ListOfMakeShape& theAlgos)
+bool FeaturesPlugin_ExtrusionBoolean::makeGeneration(ListOfShape& theBaseShapes,
+                                                     ListOfMakeShape& theMakeShapes)
 {
-  // Getting extrusion sizes.
-  double aToSize = 0.0;
-  double aFromSize = 0.0;
-
-  if(string(CREATION_METHOD())->value() == "BySizes") {
-    aToSize = real(TO_SIZE_ID())->value();
-    aFromSize =  real(FROM_SIZE_ID())->value();
-  } else {
-    aToSize = real(TO_OFFSET_ID())->value();
-    aFromSize =  real(FROM_OFFSET_ID())->value();
-  }
-
-  // Getting extrusion bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
-
-  if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
-      }
-    }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
-      }
-    }
-  }
-
-  // Extrude faces.
-  theResults.clear();
-  for(ListOfShape::const_iterator aFacesIt = theFaces.begin(); aFacesIt != theFaces.end(); aFacesIt++) {
-    std::shared_ptr<GeomAPI_Shape> aBaseShape = *aFacesIt;
-    std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo = std::shared_ptr<GeomAlgoAPI_Prism>(new GeomAlgoAPI_Prism(aBaseShape, aToShape, aToSize, aFromShape, aFromSize));
+  return makeExtrusions(theBaseShapes, theMakeShapes);
+}
 
-    // Checking that the algorithm worked properly.
-    if(!aPrismAlgo->isDone() || !aPrismAlgo->shape().get() || aPrismAlgo->shape()->isNull() ||
-       !aPrismAlgo->isValid()) {
-      setError("Error: Extrusion algorithm failed.");
-      theResults.clear();
-      return;
-    }
-    theResults.push_back(aPrismAlgo->shape());
-    theAlgos.push_back(aPrismAlgo);
-  }
+//=================================================================================================
+void FeaturesPlugin_ExtrusionBoolean::storeGenerationHistory(ResultBodyPtr theResultBody,
+                                                             const GeomShapePtr theBaseShape,
+                                                             const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                                             int& theTag)
+{
+  FeaturesPlugin_Extrusion::storeGenerationHistory(theResultBody, theBaseShape, theMakeShape, theTag);
 }
index b9efd63f6f2fc7fa47dea7e517df0afd5735ef19..4e4cbad45d636de552156e348db961f8152bd91d 100644 (file)
@@ -7,76 +7,30 @@
 #ifndef FeaturesPlugin_ExtrusionBoolean_H_
 #define FeaturesPlugin_ExtrusionBoolean_H_
 
-#include <FeaturesPlugin_CompositeBoolean.h>
+#include "FeaturesPlugin_Extrusion.h"
+#include "FeaturesPlugin_CompositeBoolean.h"
 
-/** \class FeaturesPlugin_ExtrusionBoolean
- *  \ingroup Plugins
- *  \brief Interface for the composite extrusion feature.
- */
-class FeaturesPlugin_ExtrusionBoolean : public FeaturesPlugin_CompositeBoolean
+/// \class FeaturesPlugin_ExtrusionBoolean
+/// \ingroup Plugins
+/// \brief Interface for the composite extrusion feature.
+class FeaturesPlugin_ExtrusionBoolean: public FeaturesPlugin_Extrusion, public FeaturesPlugin_CompositeBoolean
 {
- public:
-
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
-  {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
-  }
-
-  /// attribute name of extrusion size
-  inline static const std::string& TO_SIZE_ID()
-  {
-    static const std::string MY_TO_SIZE_ID("to_size");
-    return MY_TO_SIZE_ID;
-  }
-
-  /// attribute name of extrusion size
-  inline static const std::string& FROM_SIZE_ID()
-  {
-    static const std::string MY_FROM_SIZE_ID("from_size");
-    return MY_FROM_SIZE_ID;
-  }
-
-  /// attribute name of an object to which the extrusion grows.
-  inline static const std::string& TO_OBJECT_ID()
-  {
-    static const std::string MY_TO_OBJECT_ID("to_object");
-    return MY_TO_OBJECT_ID;
-  }
-
-  /// attribute name of extrusion offset
-  inline static const std::string& TO_OFFSET_ID()
-  {
-    static const std::string MY_TO_OFFSET_ID("to_offset");
-    return MY_TO_OFFSET_ID;
-  }
-
-  /// Attribute name of an object from which the extrusion grows.
-  inline static const std::string& FROM_OBJECT_ID()
-  {
-    static const std::string MY_FROM_OBJECT_ID("from_object");
-    return MY_FROM_OBJECT_ID;
-  }
-
-  /// attribute name of extrusion offset
-  inline static const std::string& FROM_OFFSET_ID()
-  {
-    static const std::string MY_FROM_OFFSET_ID("from_offset");
-    return MY_FROM_OFFSET_ID;
-  }
+public:
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
 
 protected:
-  /// Init attributes for extrusion.
-  virtual void initMakeSolidsAttributes();
+  FeaturesPlugin_ExtrusionBoolean(){};
 
-  /// Create solids from faces with extrusion.
-  virtual void makeSolids(const ListOfShape& theFaces,
-                          ListOfShape& theResults,
-                          ListOfMakeShape& theAlgos);
+  // Creates extrusions.
+  bool makeGeneration(ListOfShape& theBaseShapes,
+                      ListOfMakeShape& theMakeShapes);
 
-protected:
-  FeaturesPlugin_ExtrusionBoolean(){};
+  /// Stores generation history.
+  void storeGenerationHistory(ResultBodyPtr theResultBody,
+                              const GeomShapePtr theBaseShape,
+                              const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                              int& theTag);
 };
 
 #endif
index 908986033348a21731a0c93b761aa20dd42fa0ea..7b885df7a16eb038dcb424fff9a959fe08c5ae87 100644 (file)
@@ -6,7 +6,9 @@
 
 #include "FeaturesPlugin_ExtrusionCut.h"
 
+//=================================================================================================
 FeaturesPlugin_ExtrusionCut::FeaturesPlugin_ExtrusionCut()
 {
-  myBooleanOperationType = GeomAlgoAPI_Boolean::BOOL_CUT;
+  myFeature = this;
+  myOperationType = BOOL_CUT;
 }
index fd78e8f6d28fe6f6a425e90fb2f700e4f0bb80b0..acfa643c8f47f5fb4feefb7bd40389921a14478a 100755 (executable)
@@ -7,17 +7,19 @@
 #ifndef FeaturesPlugin_ExtrusionCut_H_
 #define FeaturesPlugin_ExtrusionCut_H_
 
-#include <FeaturesPlugin_ExtrusionBoolean.h>
+#include "FeaturesPlugin_ExtrusionBoolean.h"
 
-/** \class FeaturesPlugin_ExtrusionCut
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch, extrude faces from this sketch and
- *         cut result from other objects in a single operation.
- */
+/// \class FeaturesPlugin_ExtrusionCut
+/// \ingroup Plugins
+/// \brief This feature allows to create sketch, extrude faces from this sketch and
+///        cut result from other objects in a single operation.
 class FeaturesPlugin_ExtrusionCut : public FeaturesPlugin_ExtrusionBoolean
 {
- public:
-  /// Feature kind.
+public:
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_ExtrusionCut();
+
+   /// Feature kind.
   inline static const std::string& ID()
   {
     static const std::string MY_EXTRUSION_ID("ExtrusionCut");
@@ -30,9 +32,6 @@ class FeaturesPlugin_ExtrusionCut : public FeaturesPlugin_ExtrusionBoolean
     static std::string MY_KIND = FeaturesPlugin_ExtrusionCut::ID();
     return MY_KIND;
   }
-
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_ExtrusionCut();
 };
 
 #endif
index a30db92052825c1684a2bcec1031820a099526c5..956a02648b2ac9d16be9c3ea5414d6df89303836 100644 (file)
@@ -6,7 +6,9 @@
 
 #include "FeaturesPlugin_ExtrusionFuse.h"
 
+//=================================================================================================
 FeaturesPlugin_ExtrusionFuse::FeaturesPlugin_ExtrusionFuse()
 {
-  myBooleanOperationType = GeomAlgoAPI_Boolean::BOOL_FUSE;
+  myFeature = this;
+  myOperationType = BOOL_FUSE;
 }
index 706e770db59c5f937542f6fead683b3efff8b0b7..5e7a3236fdcde2cedc12c9a8f6f3519325217d1e 100644 (file)
@@ -7,17 +7,19 @@
 #ifndef FeaturesPlugin_ExtrusionFuse_H_
 #define FeaturesPlugin_ExtrusionFuse_H_
 
-#include <FeaturesPlugin_ExtrusionBoolean.h>
+#include "FeaturesPlugin_ExtrusionBoolean.h"
 
-/** \class FeaturesPlugin_ExtrusionFuse
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch, extrude faces from this sketch and
- *         fuse result with other objects in a single operation.
- */
+/// \class FeaturesPlugin_ExtrusionFuse
+/// \ingroup Plugins
+/// \brief This feature allows to create sketch, extrude faces from this sketch and
+///        fuse result with other objects in a single operation.
 class FeaturesPlugin_ExtrusionFuse : public FeaturesPlugin_ExtrusionBoolean
 {
- public:
-  /// Feature kind.
+public:
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_ExtrusionFuse();
+
+   /// Feature kind.
   inline static const std::string& ID()
   {
     static const std::string MY_EXTRUSION_ID("ExtrusionFuse");
@@ -30,9 +32,6 @@ class FeaturesPlugin_ExtrusionFuse : public FeaturesPlugin_ExtrusionBoolean
     static std::string MY_KIND = FeaturesPlugin_ExtrusionFuse::ID();
     return MY_KIND;
   }
-
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_ExtrusionFuse();
 };
 
 #endif
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.cpp
deleted file mode 100644 (file)
index 7854fc2..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        FeaturesPlugin_ExtrusionSketch.cpp
-// Created:     11 September 2015
-// Author:      Dmitry Bobylev
-
-#include <FeaturesPlugin_ExtrusionSketch.h>
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-#include <GeomAlgoAPI_Prism.h>
-
-//=================================================================================================
-FeaturesPlugin_ExtrusionSketch::FeaturesPlugin_ExtrusionSketch()
-{
-}
-
-//=================================================================================================
-void FeaturesPlugin_ExtrusionSketch::initMakeSolidsAttributes()
-{
-  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
-
-  data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
-}
-
-//=================================================================================================
-void FeaturesPlugin_ExtrusionSketch::makeSolid(const std::shared_ptr<GeomAPI_Shape> theFace,
-                                               std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
-{
-  // Getting extrusion sizes.
-  double aToSize = 0.0;
-  double aFromSize = 0.0;
-
-  if(string(CREATION_METHOD())->value() == "BySizes") {
-    aToSize = real(TO_SIZE_ID())->value();
-    aFromSize =  real(FROM_SIZE_ID())->value();
-  } else {
-    aToSize = real(TO_OFFSET_ID())->value();
-    aFromSize =  real(FROM_OFFSET_ID())->value();
-  }
-
-  // Getting extrusion bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
-
-  if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
-      }
-    }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
-      }
-    }
-  }
-
-  // Extrude face
-  std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo(new GeomAlgoAPI_Prism(theFace, aToShape, aToSize, aFromShape, aFromSize));
-
-  // Checking that the algorithm worked properly.
-  if(!aPrismAlgo->isDone() || !aPrismAlgo->shape().get() || aPrismAlgo->shape()->isNull() ||
-     !aPrismAlgo->isValid()) {
-    return;
-  }
-
-  theMakeShape = aPrismAlgo;
-}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.h b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionSketch.h
deleted file mode 100644 (file)
index fd6da45..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        FeaturesPlugin_ExtrusionSketch.h
-// Created:     11 September 2015
-// Author:      Dmitry Bobylev
-
-#ifndef FeaturesPlugin_ExtrusionSketch_H_
-#define FeaturesPlugin_ExtrusionSketch_H_
-
-#include <FeaturesPlugin_CompositeSketch.h>
-
-/** \class FeaturesPlugin_ExtrusionSketch
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch and extrude faces from this sketch
- *         in a single operation.
- */
-class FeaturesPlugin_ExtrusionSketch : public FeaturesPlugin_CompositeSketch
-{
- public:
-  /// Feature kind.
-  inline static const std::string& ID()
-  {
-    static const std::string MY_EXTRUSION_ID("ExtrusionSketch");
-    return MY_EXTRUSION_ID;
-  }
-
-  /// \return the kind of a feature
-  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
-  {
-    static std::string MY_KIND = FeaturesPlugin_ExtrusionSketch::ID();
-    return MY_KIND;
-  }
-
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
-  {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
-  }
-
-  /// attribute name of extrusion size
-  inline static const std::string& TO_SIZE_ID()
-  {
-    static const std::string MY_TO_SIZE_ID("to_size");
-    return MY_TO_SIZE_ID;
-  }
-
-  /// attribute name of extrusion size
-  inline static const std::string& FROM_SIZE_ID()
-  {
-    static const std::string MY_FROM_SIZE_ID("from_size");
-    return MY_FROM_SIZE_ID;
-  }
-
-  /// attribute name of an object to which the extrusion grows.
-  inline static const std::string& TO_OBJECT_ID()
-  {
-    static const std::string MY_TO_OBJECT_ID("to_object");
-    return MY_TO_OBJECT_ID;
-  }
-
-  /// attribute name of extrusion offset
-  inline static const std::string& TO_OFFSET_ID()
-  {
-    static const std::string MY_TO_OFFSET_ID("to_offset");
-    return MY_TO_OFFSET_ID;
-  }
-
-  /// Attribute name of an object from which the extrusion grows.
-  inline static const std::string& FROM_OBJECT_ID()
-  {
-    static const std::string MY_FROM_OBJECT_ID("from_object");
-    return MY_FROM_OBJECT_ID;
-  }
-
-  /// attribute name of extrusion offset
-  inline static const std::string& FROM_OFFSET_ID()
-  {
-    static const std::string MY_FROM_OFFSET_ID("from_offset");
-    return MY_FROM_OFFSET_ID;
-  }
-
-protected:
-  /// Init attributes for extrusion.
-  virtual void initMakeSolidsAttributes();
-
-  /// Create solid from face with extrusion.
-  virtual void makeSolid(const std::shared_ptr<GeomAPI_Shape> theFace,
-                         std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
-
-public:
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_ExtrusionSketch();
-};
-
-#endif
index 0fd2ba3b4efb4fa6ba21c99ea9f0d52f27eb36b7..baa8a115077f6132f7e708612244cb2a4c9a9e14 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <FeaturesPlugin_Boolean.h>
 #include <FeaturesPlugin_Extrusion.h>
-#include <FeaturesPlugin_ExtrusionSketch.h>
 #include <FeaturesPlugin_ExtrusionCut.h>
 #include <FeaturesPlugin_ExtrusionFuse.h>
 #include <FeaturesPlugin_Group.h>
@@ -14,7 +13,6 @@
 #include <FeaturesPlugin_Pipe.h>
 #include <FeaturesPlugin_Placement.h>
 #include <FeaturesPlugin_Revolution.h>
-#include <FeaturesPlugin_RevolutionSketch.h>
 #include <FeaturesPlugin_RevolutionCut.h>
 #include <FeaturesPlugin_RevolutionFuse.h>
 #include <FeaturesPlugin_Rotation.h>
@@ -41,6 +39,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorTransform);
   aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionBase",
                               new FeaturesPlugin_ValidatorExtrusionBase);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorBaseForGeneration",
+                              new FeaturesPlugin_ValidatorBaseForGeneration);
   aFactory->registerValidator("FeaturesPlugin_PipeLocationsValidator",
                               new FeaturesPlugin_PipeLocationsValidator);
 
@@ -78,10 +78,6 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_RevolutionCut);
   } else if (theFeatureID == FeaturesPlugin_RevolutionFuse::ID()) {
     return FeaturePtr(new FeaturesPlugin_RevolutionFuse);
-  } else if (theFeatureID == FeaturesPlugin_ExtrusionSketch::ID()) {
-    return FeaturePtr(new FeaturesPlugin_ExtrusionSketch);
-  } else if (theFeatureID == FeaturesPlugin_RevolutionSketch::ID()) {
-    return FeaturePtr(new FeaturesPlugin_RevolutionSketch);
   }
   // feature of such kind is not found
   return FeaturePtr();
index e71194aefe88f666d8ebf63bc84efb117dcaec5c..fb3d594adecb7942017b1ad51f6a5680cfa47f1d 100644 (file)
@@ -7,22 +7,16 @@
 #include "FeaturesPlugin_Revolution.h"
 
 #include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeString.h>
-#include <ModelAPI_AttributeReference.h>
-#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_ResultBody.h>
 
-#include <GeomAlgoAPI_CompoundBuilder.h>
-#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_Revolution.h>
+
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
 
-#include <sstream>
-
 //=================================================================================================
 FeaturesPlugin_Revolution::FeaturesPlugin_Revolution()
 {
@@ -31,11 +25,7 @@ FeaturesPlugin_Revolution::FeaturesPlugin_Revolution()
 //=================================================================================================
 void FeaturesPlugin_Revolution::initAttributes()
 {
-  AttributeSelectionListPtr aSelection = 
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // revolution works with faces always
-  aSelection->setSelectionType("FACE");
+  initCompositeSketchAttribtues(InitBaseObjectsList);
 
   data()->addAttribute(AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
 
@@ -53,185 +43,105 @@ void FeaturesPlugin_Revolution::initAttributes()
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
 
-  // Composite Sketch attribute
-  data()->addAttribute(FeaturesPlugin_CompositeSketch::SKETCH_OBJECT_ID(),
-                       ModelAPI_AttributeReference::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
-                       FeaturesPlugin_CompositeSketch::SKETCH_OBJECT_ID());
+  initCompositeSketchAttribtues(InitSketchLauncher);
 }
 
 //=================================================================================================
 void FeaturesPlugin_Revolution::execute()
 {
-  /// sub feature of the composite should be set in the base list
-  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
-  if (aFacesSelectionList.get() && !aFacesSelectionList->isInitialized()) {
-    AttributeReferencePtr aSketchAttr = reference(SKETCH_OBJECT_ID());
-    if (aSketchAttr.get() && aSketchAttr->isInitialized())
-      setSketchObjectToList();
+  ListOfShape aBaseShapesList;
+  ListOfMakeShape aMakeShapesList;
+
+  // Make revolutions.
+  if(!makeRevolutions(aBaseShapesList, aMakeShapesList)) {
+    return;
   }
 
-  // Getting faces.
-  ListOfShape aFacesList;
-  aFacesSelectionList = selectionList(LIST_ID());
-  for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
-    AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
-    std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
-    if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
-      aFacesList.push_back(aFaceShape);
-    } else { // This may be the whole sketch result selected, check and get faces.
-      ResultPtr aContext = aFaceSel->context();
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
-      if(!aContextShape.get()) {
-        static const std::string aContextError = "Error: The selection context is bad.";
-        setError(aContextError);
-        return;
-      }
-      ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
-      if(!aConstruction.get()) {
-        static const std::string aFaceError = "Error: Can not find basis for revolution.";
-        setError(aFaceError);
-        return;
-      }
-      int aFacesNum = aConstruction->facesNum();
-      for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
-        aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
-        aFacesList.push_back(aFaceShape);
-      }
-    }
+  // Store results.
+  int aResultIndex = 0;
+  ListOfShape::const_iterator aBaseIt = aBaseShapesList.cbegin();
+  ListOfMakeShape::const_iterator anAlgoIt = aMakeShapesList.cbegin();
+  for(; aBaseIt != aBaseShapesList.cend() && anAlgoIt != aMakeShapesList.cend(); ++aBaseIt, ++anAlgoIt) {
+    storeResult(*aBaseIt, *anAlgoIt, aResultIndex++);
   }
 
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+bool FeaturesPlugin_Revolution::makeRevolutions(ListOfShape& theBaseShapes,
+                                                ListOfMakeShape& theMakeShapes)
+{
+  theMakeShapes.clear();
+
+  /// Sub-feature of the composite should be set in the base list.
+  setSketchObjectToList();
+
+  // Getting base shapes.
+  getBaseShapes(theBaseShapes);
+
   //Getting axis.
   std::shared_ptr<GeomAPI_Ax1> anAxis;
   std::shared_ptr<GeomAPI_Edge> anEdge;
-  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(AXIS_OBJECT_ID());
-  if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
-  } else if(anObjRef->context() && anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
+  AttributeSelectionPtr aSelection = selection(AXIS_OBJECT_ID());
+  if(aSelection.get() && aSelection->value().get() && aSelection->value()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aSelection->value()));
+  } else if(aSelection->context().get() &&
+            aSelection->context()->shape().get() &&
+            aSelection->context()->shape()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aSelection->context()->shape()));
   }
-  if(anEdge) {
-    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(), anEdge->line()->direction()));
+  if(anEdge.get()) {
+    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
+                                                          anEdge->line()->direction()));
   }
 
   // Getting angles.
-  double aToAngle = real(TO_ANGLE_ID())->value();
-  double aFromAngle = real(FROM_ANGLE_ID())->value();
+  double aToAngle = 0.0;
+  double aFromAngle = 0.0;
 
   if(string(CREATION_METHOD())->value() == "ByAngles") {
     aToAngle = real(TO_ANGLE_ID())->value();
-    aFromAngle =  real(FROM_ANGLE_ID())->value();
+    aFromAngle = real(FROM_ANGLE_ID())->value();
   } else {
     aToAngle = real(TO_OFFSET_ID())->value();
-    aFromAngle =  real(FROM_OFFSET_ID())->value();
+    aFromAngle = real(FROM_OFFSET_ID())->value();
   }
 
   // Getting bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
+  GeomShapePtr aToShape;
+  GeomShapePtr aFromShape;
 
   if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
+    aSelection = selection(TO_OBJECT_ID());
+    if(aSelection.get()) {
+      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aSelection->value());
+      if(!aToShape.get() && aSelection->context().get()) {
+        aToShape = aSelection->context()->shape();
       }
     }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
+    aSelection = selection(FROM_OBJECT_ID());
+    if(aSelection.get()) {
+      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aSelection->value());
+      if(!aFromShape.get() && aSelection->context().get()) {
+        aFromShape = aSelection->context()->shape();
       }
     }
   }
 
-  // Searching faces with common edges.
-  ListOfShape aShells;
-  ListOfShape aFreeFaces;
-  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
-  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
-  aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
-
-  // Generating result for each shell and face.
-  int aResultIndex = 0;
-  for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
-    std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
-
-    GeomAlgoAPI_Revolution aRevolAlgo(aBaseShape, anAxis, aToShape, aToAngle, aFromShape, aFromAngle);
-    if(!aRevolAlgo.isDone()) {
-      static const std::string aPrismAlgoError = "Error: Revolution algorithm failed.";
-      setError(aPrismAlgoError);
-      aResultIndex = 0;
-      break;
-    }
+  // Generating result for each base shape.
+  for(ListOfShape::const_iterator anIter = theBaseShapes.cbegin(); anIter != theBaseShapes.cend(); anIter++) {
+    GeomShapePtr aBaseShape = *anIter;
 
-    // Check if shape is valid
-    if(!aRevolAlgo.shape().get() || aRevolAlgo.shape()->isNull()) {
-      static const std::string aShapeError = "Error: Resulting shape is Null.";
-      setError(aShapeError);
-      aResultIndex = 0;
-      break;
-    }
-    if(!aRevolAlgo.isValid()) {
-      std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
-      setError(aPrismAlgoError);
-      aResultIndex = 0;
-      break;
+    std::shared_ptr<GeomAlgoAPI_Revolution> aRevolAlgo(new GeomAlgoAPI_Revolution(aBaseShape, anAxis,
+                                                                                  aToShape, aToAngle,
+                                                                                  aFromShape, aFromAngle));
+    if(!isMakeShapeValid(aRevolAlgo)) {
+      return false;
     }
 
-    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    loadNamingDS(aRevolAlgo, aResultBody, aBaseShape);
-    setResult(aResultBody, aResultIndex);
-    aResultIndex++;
+    theMakeShapes.push_back(aRevolAlgo);
   }
 
-  removeResults(aResultIndex);
-}
-
-//=================================================================================================
-void FeaturesPlugin_Revolution::loadNamingDS(GeomAlgoAPI_Revolution& theRevolAlgo,
-                                             std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                                             std::shared_ptr<GeomAPI_Shape> theBasis)
-{
-  //load result
-  theResultBody->storeGenerated(theBasis, theRevolAlgo.shape());
-
-  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theRevolAlgo.mapOfSubShapes();
-
-  //Insert lateral face : Face from Edge
-  const std::string aLatName = "LateralFace";
-  const int aLatTag = 1;
-  theResultBody->loadAndOrientGeneratedShapes(&theRevolAlgo, theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
-
-  //Insert to faces
-  int aToFaceIndex = 1;
-  const std::string aToName = "ToFace";
-  int aToTag = 2;
-  const ListOfShape& aToFaces = theRevolAlgo.toShapes();
-  for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
-    std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
-    if(aSubShapes->isBound(aToFace)) {
-      aToFace = aSubShapes->find(aToFace);
-    }
-    std::ostringstream aStr;
-    aStr << aToName << "_" << aToFaceIndex++;
-    theResultBody->generated(aToFace, aStr.str(), aToTag++);
-  }
-
-  //Insert from faces
-  int aFromFaceIndex = 1;
-  const std::string aFromName = "FromFace";
-  int aFromTag = aToTag > 10000 ? aToTag : 10000;
-  const ListOfShape& aFromFaces = theRevolAlgo.fromShapes();
-  for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
-    std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
-    if(aSubShapes->isBound(aFromFace)) {
-      aFromFace = aSubShapes->find(aFromFace);
-    }
-    std::ostringstream aStr;
-    aStr << aFromName << "_" << aFromFaceIndex++;
-    theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
-  }
+  return true;
 }
index 7c16ec3b279b817284aa9b38c7e09106713ef4c0..f31e4c917e0640e7a1287bd5ec73a40ab1362221 100644 (file)
@@ -7,52 +7,49 @@
 #ifndef FeaturesPlugin_Revolution_H_
 #define FeaturesPlugin_Revolution_H_
 
-#include <FeaturesPlugin.h>
+#include "FeaturesPlugin.h"
 
-#include <GeomAlgoAPI_Revolution.h>
-#include <FeaturesPlugin_CompositeSketch.h>
+#include "FeaturesPlugin_CompositeSketch.h"
 
-class GeomAPI_Shape;
-class ModelAPI_ResultBody;
+#include <GeomAlgoAPI_MakeShape.h>
 
-/** \class FeaturesPlugin_Revolution
- *  \ingroup Plugins
- *  \brief Feature for creation of revolution from the planar face.
- *  Revolution creates the lateral faces based on edges of the base face and
- *  the start and end faces and/or start and end angles.
- */
-class FeaturesPlugin_Revolution : public FeaturesPlugin_CompositeSketch
+/// \class FeaturesPlugin_Revolution
+/// \ingroup Plugins
+/// \brief Feature for creation of revolution from the planar face.
+/// Revolution creates the lateral faces based on edges of the base face and
+/// the start and end faces and/or start and end angles.
+class FeaturesPlugin_Revolution: public FeaturesPlugin_CompositeSketch
 {
- public:
-  /// Revolution kind.
+public:
+  /// Feature kind.
   inline static const std::string& ID()
   {
-    static const std::string MY_REVOLUTION_ID("Revolution");
-    return MY_REVOLUTION_ID;
+    static const std::string MY_ID("Revolution");
+    return MY_ID;
   }
 
-  /// Attribute name of an revolution axis.
-  inline static const std::string& AXIS_OBJECT_ID()
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
   {
-    static const std::string MY_AXIS_ID("axis_object");
-    return MY_AXIS_ID;
+    static const std::string MY_CREATION_METHOD_ID("CreationMethod");
+    return MY_CREATION_METHOD_ID;
   }
 
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
+  /// Attribute name of an revolution axis.
+  inline static const std::string& AXIS_OBJECT_ID()
   {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
+    static const std::string MY_AXIS_OBJECT_ID("axis_object");
+    return MY_AXIS_OBJECT_ID;
   }
 
-  /// Attribute name of revolution angle.
+  /// Attribute name of revolution to angle.
   inline static const std::string& TO_ANGLE_ID()
   {
     static const std::string MY_TO_ANGLE_ID("to_angle");
     return MY_TO_ANGLE_ID;
   }
 
-  /// Attribute name of revolution angle.
+  /// Attribute name of revolution from angle.
   inline static const std::string& FROM_ANGLE_ID()
   {
     static const std::string MY_FROM_ANGLE_ID("from_angle");
@@ -66,21 +63,21 @@ class FeaturesPlugin_Revolution : public FeaturesPlugin_CompositeSketch
     return MY_TO_OBJECT_ID;
   }
 
-  /// attribute name of extrusion offset.
+  /// Attribute name of revolution offset.
   inline static const std::string& TO_OFFSET_ID()
   {
     static const std::string MY_TO_OFFSET_ID("to_offset");
     return MY_TO_OFFSET_ID;
   }
 
-  /// Attribute name of tool object.
+  /// Attribute name of an object from which the revolution grows.
   inline static const std::string& FROM_OBJECT_ID()
   {
     static const std::string MY_FROM_OBJECT_ID("from_object");
     return MY_FROM_OBJECT_ID;
   }
 
-  /// attribute name of extrusion offset.
+  /// Attribute name of revolution offset.
   inline static const std::string& FROM_OFFSET_ID()
   {
     static const std::string MY_FROM_OFFSET_ID("from_offset");
@@ -103,11 +100,13 @@ class FeaturesPlugin_Revolution : public FeaturesPlugin_CompositeSketch
   /// Use plugin manager for features creation.
   FeaturesPlugin_Revolution();
 
-private:
-  /// Load Naming data structure of the feature to the document.
-  void loadNamingDS(GeomAlgoAPI_Revolution& theRevolAlgo,
-                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                    std::shared_ptr<GeomAPI_Shape> theBasis);
+  protected:
+  /// Generates revolutions.
+  /// \param[out] theBaseShapes list of base shapes.
+  /// \param[out] theMakeShapes list of according algos.
+  /// \return false in case one of algo failed.
+  bool makeRevolutions(ListOfShape& theBaseShapes,
+                       ListOfMakeShape& theMakeShapes);
 };
 
 #endif
index aaade0a86721e76a6dc4aeac36424029a4887720..479fd51e97612d29e3166b0dfd907ba2bb5cd597 100644 (file)
 // Created:     11 June 2015
 // Author:      Dmitry Bobylev
 
-#include <FeaturesPlugin_RevolutionBoolean.h>
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-#include <GeomAlgoAPI_Revolution.h>
-#include <GeomAPI_Edge.h>
-#include <GeomAPI_Lin.h>
+#include "FeaturesPlugin_RevolutionBoolean.h"
 
 //=================================================================================================
-void FeaturesPlugin_RevolutionBoolean::initMakeSolidsAttributes()
+void FeaturesPlugin_RevolutionBoolean::initAttributes()
 {
-  data()->addAttribute(FeaturesPlugin_RevolutionBoolean::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-
-  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
-
-  data()->addAttribute(TO_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(FROM_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
+  FeaturesPlugin_Revolution::initAttributes();
 
-  data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
+  initBooleanAttributes();
 }
 
 //=================================================================================================
-void FeaturesPlugin_RevolutionBoolean::makeSolids(const ListOfShape& theFaces,
-                                                  ListOfShape& theResults,
-                                                  ListOfMakeShape& theAlgos)
+bool FeaturesPlugin_RevolutionBoolean::makeGeneration(ListOfShape& theBaseShapes,
+                                                      ListOfMakeShape& theMakeShapes)
 {
-  //Getting axis.
-  std::shared_ptr<GeomAPI_Ax1> anAxis;
-  std::shared_ptr<GeomAPI_Edge> anEdge;
-  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(FeaturesPlugin_RevolutionBoolean::AXIS_OBJECT_ID());
-  if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
-  } else if(anObjRef->context() && anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
-  }
-  if(anEdge) {
-    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(), anEdge->line()->direction()));
-  }
-
-  // Getting revolution angles.
-  double aToAngle = real(TO_ANGLE_ID())->value();
-  double aFromAngle = real(FROM_ANGLE_ID())->value();
-
-  if(string(CREATION_METHOD())->value() == "ByAngles") {
-    aToAngle = real(TO_ANGLE_ID())->value();
-    aFromAngle =  real(FROM_ANGLE_ID())->value();
-  } else {
-    aToAngle = real(TO_OFFSET_ID())->value();
-    aFromAngle =  real(FROM_OFFSET_ID())->value();
-  }
-
-  // Getting revolution bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
-
-  if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
-      }
-    }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
-      }
-    }
-  }
-
-  // Revol faces.
-  theResults.clear();
-  for(ListOfShape::const_iterator aFacesIt = theFaces.begin(); aFacesIt != theFaces.end(); aFacesIt++) {
-    std::shared_ptr<GeomAPI_Shape> aBaseShape = *aFacesIt;
-    std::shared_ptr<GeomAlgoAPI_Revolution> aRevolAlgo = std::shared_ptr<GeomAlgoAPI_Revolution>(new GeomAlgoAPI_Revolution(aBaseShape, anAxis, aToShape, aToAngle, aFromShape, aFromAngle));
+  return makeRevolutions(theBaseShapes, theMakeShapes);
+}
 
-    // Checking that the algorithm worked properly.
-    if(!aRevolAlgo->isDone()  || !aRevolAlgo->shape().get() || aRevolAlgo->shape()->isNull() ||
-       !aRevolAlgo->isValid()) {
-      setError("Error: Revolution algorithm failed.");
-      theResults.clear();
-      return;
-    }
-    theResults.push_back(aRevolAlgo->shape());
-    theAlgos.push_back(aRevolAlgo);
-  }
+//=================================================================================================
+void FeaturesPlugin_RevolutionBoolean::storeGenerationHistory(ResultBodyPtr theResultBody,
+                                                             const GeomShapePtr theBaseShape,
+                                                             const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                                                             int& theTag)
+{
+  FeaturesPlugin_Revolution::storeGenerationHistory(theResultBody, theBaseShape, theMakeShape, theTag);
 }
index b645190f7f8f193594a170075999174e48a65a21..fc0252ba1e4848303325f7b5981b2eb3dd48685e 100644 (file)
@@ -7,82 +7,30 @@
 #ifndef FeaturesPlugin_RevolutionBoolean_H_
 #define FeaturesPlugin_RevolutionBoolean_H_
 
-#include <FeaturesPlugin_CompositeBoolean.h>
+#include "FeaturesPlugin_Revolution.h"
+#include "FeaturesPlugin_CompositeBoolean.h"
 
-/** \class FeaturesPlugin_RevolutionBoolean
- *  \ingroup Plugins
- *  \brief Interface for the composite revolution feature.
- */
-class FeaturesPlugin_RevolutionBoolean : public FeaturesPlugin_CompositeBoolean
+/// \class FeaturesPlugin_RevolutionBoolean
+/// \ingroup Plugins
+/// \brief Interface for the composite revolution feature.
+class FeaturesPlugin_RevolutionBoolean : public FeaturesPlugin_Revolution, public FeaturesPlugin_CompositeBoolean
 {
 public:
-  /// Attribute name of an revolution axis.
-  inline static const std::string& AXIS_OBJECT_ID()
-  {
-    static const std::string MY_AXIS_ID("axis_object");
-    return MY_AXIS_ID;
-  }
-
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
-  {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
-  }
-
-  /// Attribute name of revolution to angle.
-  inline static const std::string& TO_ANGLE_ID()
-  {
-    static const std::string MY_TO_ANGLE_ID("to_angle");
-    return MY_TO_ANGLE_ID;
-  }
-
-  /// Attribute name of revolution from angle.
-  inline static const std::string& FROM_ANGLE_ID()
-  {
-    static const std::string MY_FROM_ANGLE_ID("from_angle");
-    return MY_FROM_ANGLE_ID;
-  }
-  
-  /// Attribute name of an object to which the revolution grows.
-  inline static const std::string& TO_OBJECT_ID()
-  {
-    static const std::string MY_TO_OBJECT_ID("to_object");
-    return MY_TO_OBJECT_ID;
-  }
-
-  /// Attribute name of extrusion offset.
-  inline static const std::string& TO_OFFSET_ID()
-  {
-    static const std::string MY_TO_OFFSET_ID("to_offset");
-    return MY_TO_OFFSET_ID;
-  }
-
-  /// Attribute name of an object from which the revolution grows.
-  inline static const std::string& FROM_OBJECT_ID()
-  {
-    static const std::string MY_FROM_OBJECT_ID("from_object");
-    return MY_FROM_OBJECT_ID;
-  }
-
-  /// Attribute name of extrusion offset.
-  inline static const std::string& FROM_OFFSET_ID()
-  {
-    static const std::string MY_FROM_OFFSET_ID("from_offset");
-    return MY_FROM_OFFSET_ID;
-  }
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
 
 protected:
-  /// Init attributes for revolution.
-  virtual void initMakeSolidsAttributes();
+  FeaturesPlugin_RevolutionBoolean(){};
 
-  /// Create solids from faces with revolution.
-  virtual void makeSolids(const ListOfShape& theFaces,
-                          ListOfShape& theResults,
-                          ListOfMakeShape& theAlgos);
+  // Creates revolutions.
+  bool makeGeneration(ListOfShape& theBaseShapes,
+                      ListOfMakeShape& theMakeShapes);
 
-protected:
-  FeaturesPlugin_RevolutionBoolean(){};
+  /// Stores generation history.
+  void storeGenerationHistory(ResultBodyPtr theResultBody,
+                              const GeomShapePtr theBaseShape,
+                              const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+                              int& theTag);
 };
 
 #endif
index 521e7337b0cfef64909bf4b8c1ef0135ff5eb836..7685a77cb45cce3a8c0e3a261d82c680e1ec743f 100644 (file)
@@ -6,7 +6,9 @@
 
 #include "FeaturesPlugin_RevolutionCut.h"
 
+//=================================================================================================
 FeaturesPlugin_RevolutionCut::FeaturesPlugin_RevolutionCut()
 {
-  myBooleanOperationType = GeomAlgoAPI_Boolean::BOOL_CUT;
+  myFeature = this;
+  myOperationType = BOOL_CUT;
 }
index 3c1340262ba1a953287a3c004394cbad385cccef..481cfd99590549ea9fec786c3cc65f9ec18bdaf9 100644 (file)
@@ -7,16 +7,18 @@
 #ifndef FeaturesPlugin_RevolutionCut_H_
 #define FeaturesPlugin_RevolutionCut_H_
 
-#include <FeaturesPlugin_RevolutionBoolean.h>
+#include "FeaturesPlugin_RevolutionBoolean.h"
 
-/** \class FeaturesPlugin_RevolutionCut
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch, revol faces from this sketch and
- *         cut result from other objects in a single operation.
- */
+/// \class FeaturesPlugin_RevolutionCut
+/// \ingroup Plugins
+/// \brief This feature allows to create sketch, revol faces from this sketch and
+///        cut result from other objects in a single operation.
 class FeaturesPlugin_RevolutionCut : public FeaturesPlugin_RevolutionBoolean
 {
- public:
+public:
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_RevolutionCut();
+
   /// Feature kind.
   inline static const std::string& ID()
   {
@@ -30,9 +32,6 @@ class FeaturesPlugin_RevolutionCut : public FeaturesPlugin_RevolutionBoolean
     static std::string MY_KIND = FeaturesPlugin_RevolutionCut::ID();
     return MY_KIND;
   }
-
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_RevolutionCut();
 };
 
 #endif
index a4efacba720b4703ce16e26e3a229aa02eefcf47..8bed6dad71e55c657f7f959d79f65b0d9ff3999b 100644 (file)
@@ -6,7 +6,9 @@
 
 #include "FeaturesPlugin_RevolutionFuse.h"
 
+//=================================================================================================
 FeaturesPlugin_RevolutionFuse::FeaturesPlugin_RevolutionFuse()
 {
-  myBooleanOperationType = GeomAlgoAPI_Boolean::BOOL_FUSE;
+  myFeature = this;
+  myOperationType = BOOL_FUSE;
 }
index 75f16aa67e1818136e47659aad86e9dcdaf0aea7..bdc7f8e57586b4adf790c88bdab182634b9d44b6 100644 (file)
@@ -7,17 +7,19 @@
 #ifndef FeaturesPlugin_RevolutionFuse_H_
 #define FeaturesPlugin_RevolutionFuse_H_
 
-#include <FeaturesPlugin_RevolutionBoolean.h>
+#include "FeaturesPlugin_RevolutionBoolean.h"
 
-/** \class FeaturesPlugin_RevolutionFuse
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch, revol faces from this sketch and
- *         fuse result with other objects in a single operation.
- */
+/// \class FeaturesPlugin_RevolutionFuse
+/// \ingroup Plugins
+/// \brief This feature allows to create sketch, revol faces from this sketch and
+///        fuse result with other objects in a single operation.
 class FeaturesPlugin_RevolutionFuse : public FeaturesPlugin_RevolutionBoolean
 {
  public:
-  /// Feature kind.
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_RevolutionFuse();
+
+   /// Feature kind.
   inline static const std::string& ID()
   {
     static const std::string MY_REVOLUTION_ID("RevolutionFuse");
@@ -30,9 +32,6 @@ class FeaturesPlugin_RevolutionFuse : public FeaturesPlugin_RevolutionBoolean
     static std::string MY_KIND = FeaturesPlugin_RevolutionFuse::ID();
     return MY_KIND;
   }
-
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_RevolutionFuse();
 };
 
 #endif
diff --git a/src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.cpp
deleted file mode 100644 (file)
index 1835080..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        FeaturesPlugin_RevolutionSketch.cpp
-// Created:     11 September 2015
-// Author:      Dmitry Bobylev
-
-#include "FeaturesPlugin_RevolutionSketch.h"
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-#include <GeomAlgoAPI_Revolution.h>
-#include <GeomAPI_Edge.h>
-#include <GeomAPI_Lin.h>
-
-//=================================================================================================
-FeaturesPlugin_RevolutionSketch::FeaturesPlugin_RevolutionSketch()
-{
-}
-
-//=================================================================================================
-void FeaturesPlugin_RevolutionSketch::initMakeSolidsAttributes()
-{
-  data()->addAttribute(FeaturesPlugin_RevolutionSketch::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-
-  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
-
-  data()->addAttribute(TO_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(FROM_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
-
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
-}
-
-//=================================================================================================
-void FeaturesPlugin_RevolutionSketch::makeSolid(const std::shared_ptr<GeomAPI_Shape> theFace,
-                                                std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
-{
-  //Getting axis.
-  std::shared_ptr<GeomAPI_Ax1> anAxis;
-  std::shared_ptr<GeomAPI_Edge> anEdge;
-  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(FeaturesPlugin_RevolutionSketch::AXIS_OBJECT_ID());
-  if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
-  } else if(anObjRef->context() && anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
-    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
-  }
-  if(anEdge) {
-    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(), anEdge->line()->direction()));
-  }
-
-  // Getting revolution angles.
-  double aToAngle = real(TO_ANGLE_ID())->value();
-  double aFromAngle = real(FROM_ANGLE_ID())->value();
-
-  if(string(CREATION_METHOD())->value() == "ByAngles") {
-    aToAngle = real(TO_ANGLE_ID())->value();
-    aFromAngle =  real(FROM_ANGLE_ID())->value();
-  } else {
-    aToAngle = real(TO_OFFSET_ID())->value();
-    aFromAngle =  real(FROM_OFFSET_ID())->value();
-  }
-
-  // Getting revolution bounding planes.
-  std::shared_ptr<GeomAPI_Shape> aToShape;
-  std::shared_ptr<GeomAPI_Shape> aFromShape;
-
-  if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
-    anObjRef = selection(TO_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aToShape =  anObjRef->context()->shape();
-      }
-    }
-    anObjRef = selection(FROM_OBJECT_ID());
-    if(anObjRef.get() != NULL) {
-      aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-      if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
-        aFromShape = anObjRef->context()->shape();
-      }
-    }
-  }
-
-  // Revol face
-  std::shared_ptr<GeomAlgoAPI_Revolution> aRevolAlgo(new GeomAlgoAPI_Revolution(theFace, anAxis, aToShape, aToAngle, aFromShape, aFromAngle));
-
-  // Checking that the algorithm worked properly.
-  if(!aRevolAlgo->isDone() || !aRevolAlgo->shape().get() || aRevolAlgo->shape()->isNull() ||
-     !aRevolAlgo->isValid()) {
-    return;
-  }
-
-  theMakeShape = aRevolAlgo;
-}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.h b/src/FeaturesPlugin/FeaturesPlugin_RevolutionSketch.h
deleted file mode 100644 (file)
index b3d61b2..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        FeaturesPlugin_RevolutionSketch.h
-// Created:     11 September 2015
-// Author:      Dmitry Bobylev
-
-#ifndef FeaturesPlugin_RevolutionSketch_H_
-#define FeaturesPlugin_RevolutionSketch_H_
-
-#include <FeaturesPlugin_CompositeSketch.h>
-
-/** \class FeaturesPlugin_RevolutionSketch
- *  \ingroup Plugins
- *  \brief This feature allows to create sketch and revol faces from this sketch 
- *         in a single operation.
- */
-class FeaturesPlugin_RevolutionSketch : public FeaturesPlugin_CompositeSketch
-{
-public:
-  /// Feature kind.
-  inline static const std::string& ID()
-  {
-    static const std::string MY_REVOLUTION_ID("RevolutionSketch");
-    return MY_REVOLUTION_ID;
-  }
-
-  /// \return the kind of a feature
-  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
-  {
-    static std::string MY_KIND = FeaturesPlugin_RevolutionSketch::ID();
-    return MY_KIND;
-  }
-
-  /// Attribute name of an revolution axis.
-  inline static const std::string& AXIS_OBJECT_ID()
-  {
-    static const std::string MY_AXIS_ID("axis_object");
-    return MY_AXIS_ID;
-  }
-
-  /// attribute name for creation method
-  inline static const std::string& CREATION_METHOD()
-  {
-    static const std::string METHOD_ATTR("CreationMethod");
-    return METHOD_ATTR;
-  }
-
-  /// Attribute name of revolution to angle.
-  inline static const std::string& TO_ANGLE_ID()
-  {
-    static const std::string MY_TO_ANGLE_ID("to_angle");
-    return MY_TO_ANGLE_ID;
-  }
-
-  /// Attribute name of revolution from angle.
-  inline static const std::string& FROM_ANGLE_ID()
-  {
-    static const std::string MY_FROM_ANGLE_ID("from_angle");
-    return MY_FROM_ANGLE_ID;
-  }
-  
-  /// Attribute name of an object to which the revolution grows.
-  inline static const std::string& TO_OBJECT_ID()
-  {
-    static const std::string MY_TO_OBJECT_ID("to_object");
-    return MY_TO_OBJECT_ID;
-  }
-
-  /// Attribute name of extrusion offset.
-  inline static const std::string& TO_OFFSET_ID()
-  {
-    static const std::string MY_TO_OFFSET_ID("to_offset");
-    return MY_TO_OFFSET_ID;
-  }
-
-  /// Attribute name of an object from which the revolution grows.
-  inline static const std::string& FROM_OBJECT_ID()
-  {
-    static const std::string MY_FROM_OBJECT_ID("from_object");
-    return MY_FROM_OBJECT_ID;
-  }
-
-  /// Attribute name of extrusion offset.
-  inline static const std::string& FROM_OFFSET_ID()
-  {
-    static const std::string MY_FROM_OFFSET_ID("from_offset");
-    return MY_FROM_OFFSET_ID;
-  }
-
-protected:
-  /// Init attributes for revolution.
-  virtual void initMakeSolidsAttributes();
-
-  /// Create solids from faces with revolution.
-  virtual void makeSolid(const std::shared_ptr<GeomAPI_Shape> theFace,
-                         std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
-
-public:
-  /// Use plugin manager for features creation.
-  FeaturesPlugin_RevolutionSketch();
-};
-
-#endif
index 40c1197db3424471f59a58c588cd88633dc88dbf..f23ef720b49d6e361ac891b9b6ee3f478dd6c7fc 100644 (file)
@@ -9,6 +9,7 @@
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultConstruction.h>
 
 //=================================================================================================
 bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -19,7 +20,6 @@ bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr<ModelA
   static const std::string aBaseObjectsID = "base_objects";
   static const std::string aLocationsID = "locations_objects";
 
-
   if(theFeature->getKind() != "Pipe") {
     theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
     return false;
@@ -58,8 +58,105 @@ bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr<ModelA
 //=================================================================================================
 bool FeaturesPlugin_PipeLocationsValidator::isNotObligatory(std::string theFeature, std::string theAttribute)
 {
-  if(theFeature == "Pipe" && theAttribute == "locations") {
-    return true;
-  }
   return false;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
+                                                        const std::list<std::string>& theArguments,
+                                                        std::string& theError) const
+{
+  // Checking attribute.
+  if(!isValidAttribute(theAttribute, theError)) {
+    if(theError.empty()) {
+      theError = "Attribute contains shape with unacceptable type.";
+    }
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
+                                                                 std::string& theError) const
+{
+  if(!theAttribute.get()) {
+    theError = "Empty attribute.";
+    return false;
+  }
+
+  std::string anAttributeType = theAttribute->attributeType();
+  if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+    AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+    for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+      // If at least one attribute is invalid, the result is false.
+      if(!isValidAttribute(aListAttr->value(anIndex), theError)) {
+        return false;
+      }
+    }
+  } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+    // Getting context.
+    AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+    ResultPtr aContext = anAttr->context();
+    if(!aContext.get()) {
+      theError = "Attribute have empty context.";
+      return false;
+    }
+
+    GeomShapePtr aShape = anAttr->value();
+    GeomShapePtr aContextShape = aContext->shape();
+    if(!aShape.get()) {
+      aShape = aContextShape;
+    }
+    if(!aShape.get()) {
+      theError = "Empty shape selected";
+      return false;
+    }
+
+    ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+    if(aConstruction.get()) {
+      // Construciotn selected. Check that is is not infinite.
+      if(aConstruction->isInfinite()) {
+        theError = "Infinite constructions is not allowed as base.";
+        return false;
+      }
+
+      if(aShape->isEqual(aContextShape)) {
+        // Whole construction selected. Check that it have faces.
+        if(aConstruction->facesNum() > 0) {
+          return true;
+        }
+      } else {
+        // Shape on construction selected. Check that it is a face or wire.
+        if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
+          return true;
+        }
+      }
+    }
+
+    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;
+    }
+
+    // Check that object is a shape with allowed type.
+    aShape = aContext->shape();
+    GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
+    if(aShapeType != GeomAPI_Shape::VERTEX &&
+       aShapeType != GeomAPI_Shape::EDGE &&
+       aShapeType != GeomAPI_Shape::WIRE &&
+       aShapeType != GeomAPI_Shape::FACE) {
+      theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, \
+                  whole sketch(if it has at least one face), and following objects: vertex, edge, wire, face.";
+      return false;
+    }
+
+  } else {
+    theError = "Following attribute does not supported: " + anAttributeType + ".";
+    return false;
+  }
+
+  return true;
 }
\ No newline at end of file
index 47a12e4347ad62287c4fa25e9e5477e7afacc128..2e0978b910ac0baea874ac7f85335901626b8f4b 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef FeaturesPlugin_Validators_H_
 #define FeaturesPlugin_Validators_H_
 
+#include <ModelAPI_AttributeValidator.h>
 #include <ModelAPI_FeatureValidator.h>
 
 /// \class FeaturesPlugin_PipeLocationsValidator
@@ -27,4 +28,24 @@ class FeaturesPlugin_PipeLocationsValidator : public ModelAPI_FeatureValidator
   virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
 };
 
+/// \class FeaturesPlugin_ValidatorBaseForGeneration
+/// \ingroup Validators
+/// \brief A validator for selection base for generation. Allows to select faces on sketch,
+/// whole sketch(if it has at least one face), and following objects: vertex, edge, wire, face.
+class FeaturesPlugin_ValidatorBaseForGeneration : public ModelAPI_AttributeValidator
+{
+public:
+  //! Returns true if attribute has selection type listed in the parameter arguments.
+  //! \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;
+
+private:
+  bool isValidAttribute(const AttributePtr& theAttribute,
+                        std::string& theError) const;
+};
+
 #endif
diff --git a/src/FeaturesPlugin/Test/TestExtrusionSketch.py b/src/FeaturesPlugin/Test/TestExtrusionSketch.py
deleted file mode 100644 (file)
index 9f5aae8..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-#=========================================================================
-# Initialization of the test
-#=========================================================================
-from ModelAPI import *
-from GeomDataAPI import *
-from GeomAlgoAPI import *
-from GeomAPI import *
-import math
-
-aSession = ModelAPI_Session.get()
-aDocument = aSession.moduleDocument()
-
-aSession.startOperation()
-aPartFeature = aDocument.addFeature("Part")
-aSession.finishOperation()
-assert (len(aPartFeature.results()) == 1)
-aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
-aPart = aPartResult.partDoc()
-
-#=========================================================================
-# Make extrusion sketch
-#=========================================================================
-aSession.startOperation()
-anExtrusionSketchFt = featureToCompositeFeature(aPart.addFeature("ExtrusionSketch"))
-assert (anExtrusionSketchFt.getKind() == "ExtrusionSketch")
-# selection type FACE=4
-aSession.startOperation()
-aCircleSketchFeature = featureToCompositeFeature(anExtrusionSketchFt.addFeature("Sketch"))
-origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
-anCircleCentr.setValue(0, 0)
-aCircleRadius.setValue(10)
-aSession.finishOperation()
-aSession.startOperation()
-anExtrusionSketchFt.string("CreationMethod").setValue("BySizes")
-anExtrusionSketchFt.real("to_size").setValue(10)
-anExtrusionSketchFt.real("from_size").setValue(10)
-anExtrusionSketchFt.real("to_offset").setValue(0) #TODO: remove
-anExtrusionSketchFt.real("from_offset").setValue(0) #TODO: remove
-anExtrusionSketchFt.execute()
-aSession.finishOperation()
-aSession.finishOperation()
-
-#=========================================================================
-# Test results
-#=========================================================================
-aFactory = ModelAPI_Session.get().validators()
-assert (aFactory.validate(anExtrusionSketchFt))
-assert (len(anExtrusionSketchFt.results()) > 0)
-aCurrentResult = modelAPI_ResultBody(anExtrusionSketchFt.firstResult())
-assert (aCurrentResult is not None)
-
-#=========================================================================
-# Test extrusion between bounding planes
-#=========================================================================
-# Create from plane
-aSession.startOperation()
-aSketchPlaneFeature = aPart.addFeature("Plane")
-aSketchPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
-aSketchPlaneFeature.real("A").setValue(0.)
-aSketchPlaneFeature.real("B").setValue(0.)
-aSketchPlaneFeature.real("C").setValue(1.)
-aSketchPlaneFeature.real("D").setValue(30.)
-aSession.finishOperation()
-aFromResult = aSketchPlaneFeature.firstResult()
-aFromShape = modelAPI_ResultConstruction(aFromResult).shape()
-
-# Create to plane
-aSession.startOperation()
-aToPlaneFeature = aPart.addFeature("Plane")
-aToPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
-aToPlaneFeature.real("A").setValue(0.)
-aToPlaneFeature.real("B").setValue(0.)
-aToPlaneFeature.real("C").setValue(1.)
-aToPlaneFeature.real("D").setValue(-30.)
-aSession.finishOperation()
-aToResult = aToPlaneFeature.firstResult()
-aToShape = modelAPI_ResultConstruction(aToResult).shape()
-
-#=========================================================================
-# Make extrusion sketch
-#=========================================================================
-aSession.startOperation()
-anExtrusionSketchFt = featureToCompositeFeature(aPart.addFeature("ExtrusionSketch"))
-assert (anExtrusionSketchFt.getKind() == "ExtrusionSketch")
-aSession.startOperation()
-aCircleSketchFeature = featureToCompositeFeature(anExtrusionSketchFt.addFeature("Sketch"))
-origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
-anCircleCentr.setValue(0, 0)
-aCircleRadius.setValue(10)
-aSession.finishOperation()
-aSession.startOperation()
-anExtrusionSketchFt.string("CreationMethod").setValue("ByPlanesAndOffsets")
-anExtrusionSketchFt.real("to_size").setValue(0) #TODO: remove
-anExtrusionSketchFt.real("from_size").setValue(0) #TODO: remove
-anExtrusionSketchFt.selection("to_object").setValue(aToResult, aToShape)
-anExtrusionSketchFt.real("to_offset").setValue(0)
-anExtrusionSketchFt.selection("from_object").setValue(aFromResult, aFromShape)
-anExtrusionSketchFt.real("from_offset").setValue(0)
-anExtrusionSketchFt.execute()
-aSession.finishOperation()
-aSession.finishOperation()
-
-#=========================================================================
-# Test results
-#=========================================================================
-aFactory = ModelAPI_Session.get().validators()
-assert (aFactory.validate(anExtrusionSketchFt))
-assert (len(anExtrusionSketchFt.results()) > 0)
-aCurrentResult = modelAPI_ResultBody(anExtrusionSketchFt.firstResult())
-assert (aCurrentResult is not None)
diff --git a/src/FeaturesPlugin/Test/TestRevolutionSketch.py b/src/FeaturesPlugin/Test/TestRevolutionSketch.py
deleted file mode 100644 (file)
index ed54d92..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#=========================================================================
-# Initialization of the test
-#=========================================================================
-from ModelAPI import *
-from GeomDataAPI import *
-from GeomAlgoAPI import *
-from GeomAPI import *
-import math
-
-aSession = ModelAPI_Session.get()
-aDocument = aSession.moduleDocument()
-
-aSession.startOperation()
-aPartFeature = aDocument.addFeature("Part")
-aSession.finishOperation()
-assert (len(aPartFeature.results()) == 1)
-aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
-aPart = aPartResult.partDoc()
-
-#=========================================================================
-# Create a sketch line to revol
-#=========================================================================
-aSession.startOperation()
-aLineSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
-origin = geomDataAPI_Point(aLineSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aLineSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aLineSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSketchLine = aLineSketchFeature.addFeature("SketchLine")
-aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
-aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
-aLineStartPoint.setValue(-20, -20)
-aLineEndPoint.setValue(20, -20)
-aSession.finishOperation()
-
-# Build shape from sketcher results
-aLineSketchResult = aLineSketchFeature.firstResult()
-aLineSketchShape = modelAPI_ResultConstruction(aLineSketchResult).shape()
-aShapeExplorer = GeomAPI_ShapeExplorer(aLineSketchShape, GeomAPI_Shape.EDGE)
-aLineEdge = aShapeExplorer.current()
-
-#=========================================================================
-# Make revolution sketch
-#=========================================================================
-aSession.startOperation()
-anRevolutionSketchFt = featureToCompositeFeature(aPart.addFeature("RevolutionSketch"))
-assert (anRevolutionSketchFt.getKind() == "RevolutionSketch")
-# selection type FACE=4
-aSession.startOperation()
-aCircleSketchFeature = featureToCompositeFeature(anRevolutionSketchFt.addFeature("Sketch"))
-origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
-anCircleCentr.setValue(0, 0)
-aCircleRadius.setValue(10)
-aSession.finishOperation()
-aSession.startOperation()
-anRevolutionSketchFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge)
-anRevolutionSketchFt.string("CreationMethod").setValue("ByAngles")
-anRevolutionSketchFt.real("to_angle").setValue(50)
-anRevolutionSketchFt.real("from_angle").setValue(50)
-anRevolutionSketchFt.real("to_offset").setValue(0) #TODO: remove
-anRevolutionSketchFt.real("from_offset").setValue(0) #TODO: remove
-anRevolutionSketchFt.execute()
-aSession.finishOperation()
-aSession.finishOperation()
-
-#=========================================================================
-# Test results
-#=========================================================================
-aFactory = ModelAPI_Session.get().validators()
-assert (aFactory.validate(anRevolutionSketchFt))
-assert (len(anRevolutionSketchFt.results()) > 0)
-aCurrentResult = modelAPI_ResultBody(anRevolutionSketchFt.firstResult())
-assert (aCurrentResult is not None)
-
-#=========================================================================
-# Test revolution between bounding planes
-#=========================================================================
-# Create from plane
-aSession.startOperation()
-aSketchPlaneFeature = aPart.addFeature("Plane")
-aSketchPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
-aSketchPlaneFeature.real("A").setValue(0.)
-aSketchPlaneFeature.real("B").setValue(0.)
-aSketchPlaneFeature.real("C").setValue(1.)
-aSketchPlaneFeature.real("D").setValue(15.)
-aSession.finishOperation()
-aFromResult = aSketchPlaneFeature.firstResult()
-aFromShape = modelAPI_ResultConstruction(aFromResult).shape()
-
-# Create to plane
-aSession.startOperation()
-aToPlaneFeature = aPart.addFeature("Plane")
-aToPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
-aToPlaneFeature.real("A").setValue(0.)
-aToPlaneFeature.real("B").setValue(0.)
-aToPlaneFeature.real("C").setValue(1.)
-aToPlaneFeature.real("D").setValue(-15.)
-aSession.finishOperation()
-aToResult = aToPlaneFeature.firstResult()
-aToShape = modelAPI_ResultConstruction(aToResult).shape()
-
-#=========================================================================
-# Make revolution sketch
-#=========================================================================
-aSession.startOperation()
-anRevolutionSketchFt = featureToCompositeFeature(aPart.addFeature("RevolutionSketch"))
-assert (anRevolutionSketchFt.getKind() == "RevolutionSketch")
-# selection type FACE=4
-aSession.startOperation()
-aCircleSketchFeature = featureToCompositeFeature(anRevolutionSketchFt.addFeature("Sketch"))
-origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
-anCircleCentr.setValue(0, 0)
-aCircleRadius.setValue(10)
-aSession.finishOperation()
-aSession.startOperation()
-anRevolutionSketchFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge)
-anRevolutionSketchFt.string("CreationMethod").setValue("ByPlanesAndOffsets")
-anRevolutionSketchFt.real("to_angle").setValue(0) #TODO: remove
-anRevolutionSketchFt.real("from_angle").setValue(0) #TODO: remove
-anRevolutionSketchFt.selection("to_object").setValue(aToResult, aToShape)
-anRevolutionSketchFt.real("to_offset").setValue(0)
-anRevolutionSketchFt.selection("from_object").setValue(aFromResult, aFromShape)
-anRevolutionSketchFt.real("from_offset").setValue(0)
-anRevolutionSketchFt.execute()
-aSession.finishOperation()
-aSession.finishOperation()
-
-#=========================================================================
-# Test results
-#=========================================================================
-aFactory = ModelAPI_Session.get().validators()
-assert (aFactory.validate(anRevolutionSketchFt))
-assert (len(anRevolutionSketchFt.results()) > 0)
-aCurrentResult = modelAPI_ResultBody(anRevolutionSketchFt.firstResult())
-assert (aCurrentResult is not None)
index 63099b851e56828becd9b12721ea1b8b2c205479..7a9043658d1c4dde7e7f1e58c2a9157b3c6e412d 100644 (file)
@@ -2,44 +2,51 @@
 
 <source>
   <sketch_launcher id="sketch"
-    attribute_list_id="base"
-    label="Select:&lt;br /&gt;
+                   attribute_list_id="base"
+                   label="Select:&lt;br /&gt;
 1. Planar face of non-sketch object or a plane. Sketch creation will be started.&lt;br /&gt;
 2. An existing sketch face or contour. Extrusion will be filled by it.&lt;br /&gt;
 3. An existing result shape of kind: wires/edge/vertices.Extrusion will be filled by it."
-    shape_types="face objects">
+                   shape_types="faces objects">
   </sketch_launcher>
   <composite_multi_selector id="base"
-    label="Select a sketch face"
-    icon=":icons/sketch.png"
-    tooltip="Select a sketch face"
-    type_choice="Faces Objects">
+                            label="Base objects:"
+                            tooltip="Select a base objects"
+                            type_choice="faces objects">
     <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
   </composite_multi_selector>
+  <shape_selector id="direction_object"
+                  icon=":icons/axis.png"
+                  label="Direction"
+                  tooltip="Select an edge for direction"
+                  shape_types="edge"
+                  default="">
+    <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
+  </shape_selector>
   <toolbox id="CreationMethod">
-    <box id="BySizes" title="By sizes" icon=":icons/dimension_up_down_32x32.png">
+    <box id="BySizes"
+         title="By sizes"
+         icon=":icons/dimension_up_down_32x32.png">
       <groupbox>
-        <doublevalue
-          id="to_size"
-          label="Size"
-          step="1.0"
-          default="10"
-          icon=":icons/dimension_up.png"
-          tooltip="To size">
-        </doublevalue>
+        <doublevalue id="to_size"
+                     label="Size"
+                     step="1.0"
+                     default="10"
+                     icon=":icons/dimension_up.png"
+                     tooltip="To size"/>
       </groupbox>
       <groupbox>
-        <doublevalue
-          id="from_size"
-          label="Size"
-          step="1.0"
-          default="0"
-          icon=":icons/dimension_down.png"
-          tooltip="From size">
-        </doublevalue>
+        <doublevalue id="from_size"
+                     label="Size"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/dimension_down.png"
+                     tooltip="From size"/>
       </groupbox>
     </box>
-    <box id="ByPlanesAndOffsets" title="By bounding planes and offsets" icon=":icons/plane_inverted_32x32.png">
+    <box id="ByPlanesAndOffsets"
+         title="By bounding planes and offsets"
+         icon=":icons/plane_inverted_32x32.png">
       <groupbox title="From">
         <shape_selector id="from_object"
                         icon=":icons/plane.png"
                         default="&lt;base sketch&gt;">
           <validator id="GeomValidators_Face" parameters="plane"/>
         </shape_selector>
-        <doublevalue
-          id="from_offset"
-          label="Offset"
-          step="1.0"
-          default="0"
-          icon=":icons/dimension_up_down.png"
-          tooltip="Offset for bounding plane">
-        </doublevalue>
+        <doublevalue id="from_offset"
+                     label="Offset"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/dimension_up_down.png"
+                     tooltip="Offset for &quot;from&quot; bounding plane"/>
       </groupbox>
       <groupbox title="To">
         <shape_selector id="to_object"
                         default="&lt;base sketch&gt;">
           <validator id="GeomValidators_Face" parameters="plane"/>
         </shape_selector>
-        <doublevalue
-          id="to_offset"
-          label="Offset"
-          step="1.0"
-          default="0"
-          icon=":icons/dimension_up_down.png"
-          tooltip="Offset for bounding plane">
-        </doublevalue>
+        <doublevalue id="to_offset"
+                     label="Offset"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/dimension_up_down.png"
+                     tooltip="Offset for &quot;to&quot; bounding plane"/>
       </groupbox>
     </box>
   </toolbox>
index 610509a097ef26008e3c90dbfa158c6d1ca22b5f..fe01e3a419ad02d9baa9ad806d32459c02923edd 100755 (executable)
       type_choice="Faces Objects">
       <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
     </composite_multi_selector>
+    <shape_selector id="direction_object"
+                    icon=":icons/axis.png"
+                    label="Direction"
+                    tooltip="Select an edge for direction"
+                    shape_types="edge"
+                    default="">
+      <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
+    </shape_selector>
     <toolbox id="CreationMethod">
       <box id="BySizes" title="By sizes" icon=":icons/dimension_up_down_32x32.png">
         <groupbox>
@@ -74,7 +82,7 @@
       </box>
     </toolbox>
   </groupbox>
-  <multi_selector id="boolean_objects"
+  <multi_selector id="main_objects"
     label="Cut from:"
     icon=":icons/cut_shape.png"
     tooltip="Objects to Cut"
index e918b46268f228a0a5c32727289f23491a30cfef..1d1d19fc6df245752eee9bf290684257fc829093 100644 (file)
       type_choice="Faces Objects">
       <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
     </composite_multi_selector>
+    <shape_selector id="direction_object"
+                    icon=":icons/axis.png"
+                    label="Direction"
+                    tooltip="Select an edge for direction"
+                    shape_types="edge"
+                    default="">
+      <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
+    </shape_selector>
     <toolbox id="CreationMethod">
       <box id="BySizes" title="By sizes" icon=":icons/dimension_up_down_32x32.png">
         <groupbox>
@@ -74,7 +82,7 @@
       </box>
     </toolbox>
   </groupbox>
-  <multi_selector id="boolean_objects"
+  <multi_selector id="main_objects"
     label="Fuse with:"
     icon=":icons/cut_shape.png"
     tooltip="Objects to Fuse"
diff --git a/src/FeaturesPlugin/extrusionsketch_widget.xml b/src/FeaturesPlugin/extrusionsketch_widget.xml
deleted file mode 100644 (file)
index 7394fd8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-<source>
-  <groupbox title="Extrusion">
-    <sketch_launcher id="sketch"
-      label="Sketch"
-      icon=":icons/sketch.png"
-      tooltip="Create or edit a sketch">
-    </sketch_launcher>
-    <toolbox id="CreationMethod">
-      <box id="BySizes" title="By sizes" icon=":icons/dimension_up_down_32x32.png">
-        <groupbox>
-          <doublevalue
-            id="to_size"
-            label="Size"
-            step="1.0"
-            default="10"
-            icon=":icons/dimension_up.png"
-            tooltip="To size">
-          </doublevalue>
-        </groupbox>
-        <groupbox>
-          <doublevalue
-            id="from_size"
-            label="Size"
-            step="1.0"
-            default="0"
-            icon=":icons/dimension_down.png"
-            tooltip="From size">
-          </doublevalue>
-        </groupbox>
-      </box>
-      <box id="ByPlanesAndOffsets" title="By bounding planes and offsets" icon=":icons/plane_inverted_32x32.png">
-        <groupbox title="From">
-          <shape_selector id="from_object"
-                          icon=":icons/plane.png"
-                          label="Plane face"
-                          tooltip="Bounding plane (select a planar face)"
-                          shape_types="face"
-                          default="&lt;base sketch&gt;">
-            <validator id="GeomValidators_Face" parameters="plane"/>
-          </shape_selector>
-          <doublevalue id="from_offset"
-            label="Offset" step="1.0" default="0"
-            icon=":icons/dimension_up_down.png"
-            tooltip="Offset for bounding plane">
-          </doublevalue>
-        </groupbox>
-        <groupbox title="To">
-          <shape_selector id="to_object"
-                          icon=":icons/plane_inverted.png"
-                          label="Plane face"
-                          tooltip="Bounding plane (select a planar face)"
-                          shape_types="face"
-                          default="&lt;base sketch&gt;">
-            <validator id="GeomValidators_Face" parameters="plane"/>
-          </shape_selector>
-          <doublevalue  id="to_offset"
-            label="Offset" step="1.0" default="0"
-            icon=":icons/dimension_up_down.png"
-            tooltip="Offset for bounding plane">
-          </doublevalue>
-        </groupbox>
-      </box>
-    </toolbox>
-  </groupbox>
-  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,sketch_selection,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
-</source>
index 10b07cad8f8f4f61f10e749452a7e92e0359debe..f964308ccc21e6109216747b28cca534f8b82031 100644 (file)
@@ -1,34 +1,21 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <source>
+  <multi_selector id="base_objects"
+                  label="Base objects:"
+                  tooltip="Select a base objects"
+                  type_choice="faces objects"
+                  use_choice="false">
+    <validator id="FeaturesPlugin_ValidatorBaseForGeneration"/>
+  </multi_selector>
+  <shape_selector id="path_object"
+                  label="Path object:"
+                  tooltip="Select an edge or wire for path"
+                  shape_types="edge wire">
+  </shape_selector>
   <toolbox id="creation_method">
-    <box id="simple" title="Simple pipe by objects and path" icon=":icons/pipe_simple_32x32.png">
-      <multi_selector id="base_objects"
-                      label="Base objects:"
-                      tooltip="Select a base objects"
-                      type_choice="face objects"
-                      use_choice="false">
-        <validator id="GeomValidators_BaseForGeneration"/>
-      </multi_selector>
-      <shape_selector id="path_object"
-                      label="Path object:"
-                      tooltip="Select an edge or wire for path"
-                      shape_types="edge wire">
-      </shape_selector>
-    </box>
+    <box id="simple" title="Simple pipe by objects and path" icon=":icons/pipe_simple_32x32.png"/>
     <box id="binormal" title="Pipe by objects, path and Bi-Normal" icon=":icons/pipe_binormal_32x32.png">
-      <multi_selector id="base_objects"
-                      label="Base objects:"
-                      tooltip="Select a base objects"
-                      type_choice="face objects"
-                      use_choice="false">
-        <validator id="GeomValidators_BaseForGeneration"/>
-      </multi_selector>
-      <shape_selector id="path_object"
-                      label="Path object:"
-                      tooltip="Select an edge or wire for path"
-                      shape_types="edge wire">
-      </shape_selector>
       <shape_selector id="binormal"
                       label="Bi-Normal:"
                       tooltip="Select an edge for Bi-Normal"
       </shape_selector>
     </box>
     <box id="locations" title="Pipe by objects, path and locations" icon=":icons/pipe_locations_32x32.png">
-      <multi_selector id="base_objects"
-                      label="Base objects:"
-                      tooltip="Select a base objects"
-                      type_choice="face objects"
-                      use_choice="false">
-        <validator id="GeomValidators_BaseForGeneration"/>
-      </multi_selector>
       <multi_selector id="locations_objects"
                       label="Locations:"
                       tooltip="Select one or more vertices to specify the locations"
                       type_choice="vertex">
       </multi_selector>
-      <shape_selector id="path_object"
-                      label="Path object:"
-                      tooltip="Select an edge or wire for path"
-                      shape_types="edge wire">
-      </shape_selector>
     </box>
   </toolbox>
   <validator id="FeaturesPlugin_PipeLocationsValidator"/>
index a7a5b82d2c2d2ae77809ad42605f5231fe4a52b2..ac18d203bae803276f87c7215c5a635391d7ea7e 100644 (file)
@@ -2,60 +2,51 @@
 
 <source>
   <sketch_launcher id="sketch"
-    attribute_list_id="base"
-    label="Select:&lt;br /&gt;
+                   attribute_list_id="base"
+                   label="Select:&lt;br /&gt;
 1. Planar face of non-sketch object or a plane. Sketch creation will be started.&lt;br /&gt;
 2. An existing sketch face or contour. Extrusion will be filled by it.&lt;br /&gt;
 3. An existing result shape of kind: wires/edge/vertices.Extrusion will be filled by it."
-    shape_types="face objects">
+                   shape_types="faces objects">
   </sketch_launcher>
   <composite_multi_selector id="base"
-    label="Select a sketch face"
-    icon=":icons/sketch.png"
-    tooltip="Select a sketch face"
-    type_choice="Faces Objects">
+                            label="Base objects:"
+                            tooltip="Select a base objects"
+                            type_choice="faces objects">
     <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
   </composite_multi_selector>
+  <shape_selector id="axis_object"
+                  icon=":icons/axis.png"
+                  label="Axis"
+                  tooltip="Select an edge for axis"
+                  shape_types="edge"
+                  default="">
+    <validator id="GeomValidators_ShapeType" parameters="line"/>
+  </shape_selector>
   <toolbox id="CreationMethod">
-    <box id="ByAngles" title="By angles" icon=":icons/angle_up_down_32x32.png">
-      <shape_selector id="axis_object"
-                      icon=":icons/axis.png"
-                      label="Axis"
-                      tooltip="Select an edge for axis"
-                      shape_types="edge"
-                      default="">
-        <validator id="GeomValidators_ShapeType" parameters="line"/>
-      </shape_selector>
+    <box id="ByAngles"
+         title="By angles"
+         icon=":icons/angle_up_down_32x32.png">
       <groupbox>
-        <doublevalue
-          id="to_angle"
-          label="Angle"
-          step="1.0"
-          default="360"
-          icon=":icons/angle_up.png"
-          tooltip="To angle">
-        </doublevalue>
+        <doublevalue id="to_angle"
+                     label="Angle"
+                     step="1.0"
+                     default="360"
+                     icon=":icons/angle_up.png"
+                     tooltip="To angle"/>
       </groupbox>
       <groupbox>
-        <doublevalue
-          id="from_angle"
-          label="Angle"
-          step="1.0"
-          default="0"
-          icon=":icons/angle_down.png"
-          tooltip="From angle">
-        </doublevalue>
+        <doublevalue id="from_angle"
+                     label="Angle"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/angle_down.png"
+                     tooltip="From angle"/>
       </groupbox>
     </box>
-    <box id="ByPlanesAndOffsets" title="By bounding planes and angles" icon=":icons/plane_inverted_32x32.png">
-      <shape_selector id="axis_object"
-                      icon=":icons/axis.png"
-                      label="Axis"
-                      tooltip="Select an edge for axis"
-                      shape_types="edge"
-                      default="">
-        <validator id="GeomValidators_ShapeType" parameters="line"/>
-      </shape_selector>
+    <box id="ByPlanesAndOffsets"
+         title="By bounding planes and angles"
+         icon=":icons/plane_inverted_32x32.png">
       <groupbox title="From">
         <shape_selector id="from_object"
                         icon=":icons/plane.png"
                         default="&lt;base sketch&gt;">
           <validator id="GeomValidators_Face" parameters="plane"/>
         </shape_selector>
-        <doublevalue
-          id="from_offset"
-          label="Angle"
-          step="1.0"
-          default="0"
-          icon=":icons/angle_up_down.png"
-          tooltip="Angle for &quot;from&quot; bounding plane">
-        </doublevalue>
+        <doublevalue id="from_offset"
+                     label="Angle"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/angle_up_down.png"
+                     tooltip="Angle for &quot;from&quot; bounding plane"/>
       </groupbox>
       <groupbox title="To">
         <shape_selector id="to_object"
                         default="&lt;base sketch&gt;">
           <validator id="GeomValidators_Face" parameters="plane"/>
         </shape_selector>
-        <doublevalue
-          id="to_offset"
-          label="Angle"
-          step="1.0"
-          default="0"
-          icon=":icons/angle_up_down.png"
-          tooltip="Angle for &quot;to&quot; bounding plane">
-        </doublevalue>
+        <doublevalue id="to_offset"
+                     label="Angle"
+                     step="1.0"
+                     default="0"
+                     icon=":icons/angle_up_down.png"
+                     tooltip="Angle for &quot;to&quot; bounding plane"/>
       </groupbox>
     </box>
   </toolbox>
index 00a98448665fc9b71fbbc401ad95bf98e0823356..a42e01027b7a87e65256265e60334504840a979c 100644 (file)
       type_choice="Faces Objects">
       <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
     </composite_multi_selector>
+    <shape_selector id="axis_object"
+                    icon=":icons/axis.png"
+                    label="Axis"
+                    tooltip="Select an edge for axis"
+                    shape_types="edge"
+                    default="">
+      <validator id="GeomValidators_ShapeType" parameters="line"/>
+    </shape_selector>
     <toolbox id="CreationMethod">
       <box id="ByAngles" title="By angles" icon=":icons/angle_up_down_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
         <groupbox>
           <doublevalue
             id="to_angle"
         </groupbox>
       </box>
       <box id="ByPlanesAndOffsets" title="By bounding planes and angles" icon=":icons/plane_inverted_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
         <groupbox title="From">
           <shape_selector id="from_object"
                           icon=":icons/plane.png"
@@ -90,7 +82,7 @@
       </box>
     </toolbox>
   </groupbox>
-  <multi_selector id="boolean_objects"
+  <multi_selector id="main_objects"
     label="Cut from:"
     icon=":icons/cut_shape.png"
     tooltip="Objects to Cut"
index 00f1496ad8498cdc4987f7b99708173b891bbd48..03fd77ed7a4a754d13e003d264919d284265d350 100644 (file)
       type_choice="Faces Objects">
       <validator id="FeaturesPlugin_ValidatorExtrusionBase" parameters="Sketch"/>
     </composite_multi_selector>
+    <shape_selector id="axis_object"
+                    icon=":icons/axis.png"
+                    label="Axis"
+                    tooltip="Select an edge for axis"
+                    shape_types="edge"
+                    default="">
+      <validator id="GeomValidators_ShapeType" parameters="line"/>
+    </shape_selector>
     <toolbox id="CreationMethod">
       <box id="ByAngles" title="By angles" icon=":icons/angle_up_down_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
         <groupbox>
           <doublevalue
             id="to_angle"
         </groupbox>
       </box>
       <box id="ByPlanesAndOffsets" title="By bounding planes and angles" icon=":icons/plane_inverted_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
         <groupbox title="From">
           <shape_selector id="from_object"
                           icon=":icons/plane.png"
@@ -90,7 +82,7 @@
       </box>
     </toolbox>
   </groupbox>
-  <multi_selector id="boolean_objects"
+  <multi_selector id="main_objects"
     label="Fuse with:"
     icon=":icons/cut_shape.png"
     tooltip="Objects to Fuse"
diff --git a/src/FeaturesPlugin/revolutionsketch_widget.xml b/src/FeaturesPlugin/revolutionsketch_widget.xml
deleted file mode 100644 (file)
index 1af1dae..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-<source>
-  <groupbox title="Revolution">
-    <sketch_launcher id="sketch"
-      label="Sketch"
-      icon=":icons/sketch.png"
-      tooltip="Create or edit a sketch">
-    </sketch_launcher>
-    <toolbox id="CreationMethod">
-      <box id="ByAngles" title="By angles" icon=":icons/angle_up_down_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
-        <groupbox>
-          <doublevalue
-            id="to_angle"
-            label="Angle"
-            step="1.0"
-            default="10"
-            icon=":icons/angle_up.png"
-            tooltip="To angle">
-          </doublevalue>
-        </groupbox>
-        <groupbox>
-          <doublevalue
-            id="from_angle"
-            label="Angle"
-            step="1.0"
-            default="0"
-            icon=":icons/angle_down.png"
-            tooltip="From angle">
-          </doublevalue>
-        </groupbox>
-      </box>
-      <box id="ByPlanesAndOffsets" title="By bounding planes and angles" icon=":icons/plane_inverted_32x32.png">
-        <shape_selector id="axis_object"
-                        icon=":icons/axis.png"
-                        label="Axis"
-                        tooltip="Select an edge for axis"
-                        shape_types="edge"
-                        default="">
-          <validator id="GeomValidators_ShapeType" parameters="line"/>
-        </shape_selector>
-        <groupbox title="From">
-          <shape_selector id="from_object"
-                          icon=":icons/plane.png"
-                          label="Plane face"
-                          tooltip="Bounding plane (select a planar face)"
-                          shape_types="face"
-                          default="&lt;sketch&gt;">
-            <validator id="GeomValidators_Face" parameters="plane"/>
-          </shape_selector>
-          <doublevalue id="from_offset" label="Angle"
-            step="1.0" default="0"
-            icon=":icons/angle_up_down.png"
-            tooltip="Angle for &quot;from&quot; bounding plane">
-          </doublevalue>
-        </groupbox>
-        <groupbox title="To">
-          <shape_selector id="to_object"
-                          icon=":icons/plane_inverted.png"
-                          label="Plane face"
-                          tooltip="Bounding plane (select a planar face)"
-                          shape_types="face"
-                          default="&lt;sketch&gt;">
-            <validator id="GeomValidators_Face" parameters="plane"/>
-          </shape_selector>
-          <doublevalue  id="to_offset" label="Angle"
-            step="1.0" default="0"
-            icon=":icons/angle_up_down.png"
-            tooltip="Angle for &quot;to&quot; bounding plane">
-          </doublevalue>
-        </groupbox>
-      </box>
-    </toolbox>
-  </groupbox>
-  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,ByAngles,sketch_selection,to_angle,from_angle,to_object,to_offset,from_object,from_offset"/>
-</source>
index b5e40ef2439bc5c0fd97618c01c5ff7d133a671a..0131da44660d4a454a108377a63d6c352e15c66d 100644 (file)
@@ -93,6 +93,9 @@ protected:
   /// \param[in] theShape new shape.
   void setShape(const std::shared_ptr<GeomAPI_Shape> theShape);
 
+protected:
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> myMap; ///< Data map to keep correct orientation of sub-shapes.
+
 private:
   /// \brief Initializes internals.
   void initialize();
@@ -101,7 +104,6 @@ private:
   GeomAlgoAPI_MakeShape::BuilderType myBuilderType; ///< Type of make shape builder.
   bool myDone; ///< Builder status.
   std::shared_ptr<GeomAPI_Shape> myShape; ///< Resulting shape.
-  std::shared_ptr<GeomAPI_DataMapOfShapeShape> myMap; ///< Data map to keep correct orientation of sub-shapes.
 };
 
 typedef std::list<std::shared_ptr<GeomAlgoAPI_MakeShape> > ListOfMakeShape;
index 1442c5b324204398f776174c4e77fb6a022258a2..7be7d7c12571d913d033c8ed67d144dbbaad4f4d 100644 (file)
@@ -24,13 +24,28 @@ GeomAlgoAPI_MakeShapeList::GeomAlgoAPI_MakeShapeList(const ListOfMakeShape& theM
 //=================================================================================================
 void GeomAlgoAPI_MakeShapeList::init(const ListOfMakeShape& theMakeShapeList)
 {
+  if(myMap.get()) {
+    myMap->clear();
+  } else {
+    myMap.reset(new GeomAPI_DataMapOfShapeShape);
+  }
+
   myListOfMakeShape = theMakeShapeList;
+
+  for(ListOfMakeShape::const_iterator anIt = theMakeShapeList.cbegin();
+      anIt != theMakeShapeList.cend(); ++anIt) {
+    myMap->merge((*anIt)->mapOfSubShapes());
+  }
 }
 
 //=================================================================================================
 void GeomAlgoAPI_MakeShapeList::appendAlgo(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
 {
   myListOfMakeShape.push_back(theMakeShape);
+  if(!myMap.get()) {
+    myMap.reset(new GeomAPI_DataMapOfShapeShape());
+  }
+  myMap->merge(theMakeShape->mapOfSubShapes());
 }
 
 //=================================================================================================
index 80e6af9d02cbda14a32a29932da767a012202dae..9b7df3693cbeea1eb9c433e39b30de751525c496 100644 (file)
@@ -160,8 +160,10 @@ bool GeomValidators_ShapeType::isValidObject(const ObjectPtr& theObject,
 {
   bool aValid = true;
   if (!theObject.get()) {
-    aValid = false;
-    theError = "The object is empty";
+    if(theShapeType != Empty) {
+      aValid = false;
+      theError = "The object is empty";
+    }
   }
   else {
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
index b5b7e8b21f89334296da17b28e3cfe9b571c1567..91093ed8e88ed2cc57467e3e6239e927c3ce8f36 100644 (file)
@@ -414,7 +414,7 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
       aLoop->flush(aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY));
 
       // Add Selected body were created the sketcher to list of selected objects
-      std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
+      std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::OBJECTS_ID();
       AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
       if (aSelList.get()) {
         DataPtr aData = aSketchFeature->data();