]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Pipe feature
authordbv <dbv@opencascade.com>
Fri, 25 Mar 2016 13:00:26 +0000 (16:00 +0300)
committerdbv <dbv@opencascade.com>
Fri, 25 Mar 2016 13:19:16 +0000 (16:19 +0300)
40 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Pipe.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Validators.h [new file with mode: 0644]
src/FeaturesPlugin/pipe_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomAlgoAPI/GeomAlgoAPI_MakeSweep.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeSweep.h
src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Pipe.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomAlgoAPI/GeomAlgoAPI_swig.h
src/GeomValidators/CMakeLists.txt
src/GeomValidators/GeomValidators_BaseForGeneration.cpp [new file with mode: 0644]
src/GeomValidators/GeomValidators_BaseForGeneration.h [new file with mode: 0644]
src/GeomValidators/GeomValidators_BooleanSelection.cpp
src/GeomValidators/GeomValidators_Plugin.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_BodyBuilder.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/pipe.png [new file with mode: 0644]
src/PartSet/icons/pipe_binormal_32x32.png [new file with mode: 0644]
src/PartSet/icons/pipe_locations_32x32.png [new file with mode: 0644]
src/PartSet/icons/pipe_simple_32x32.png [new file with mode: 0644]

index bb7ff7c59640e21da486f9d471d85b1f6b7a809f..8a1001b85a5c495e3fcb0d81cf353471b0b35bd4 100644 (file)
@@ -14,6 +14,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_Group.h
     FeaturesPlugin_Intersection.h
     FeaturesPlugin_Partition.h
+    FeaturesPlugin_Pipe.h
     FeaturesPlugin_Placement.h
     FeaturesPlugin_CompositeBoolean.h
     FeaturesPlugin_CompositeSketch.h
@@ -26,6 +27,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_RevolutionCut.h
     FeaturesPlugin_RevolutionFuse.h
     FeaturesPlugin_ValidatorTransform.h
+    FeaturesPlugin_Validators.h
 )
 
 SET(PROJECT_SOURCES
@@ -38,6 +40,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Group.cpp
     FeaturesPlugin_Intersection.cpp
     FeaturesPlugin_Partition.cpp
+    FeaturesPlugin_Pipe.cpp
     FeaturesPlugin_Placement.cpp
     FeaturesPlugin_CompositeBoolean.cpp
     FeaturesPlugin_CompositeSketch.cpp
@@ -50,6 +53,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_RevolutionCut.cpp
     FeaturesPlugin_RevolutionFuse.cpp
     FeaturesPlugin_ValidatorTransform.cpp
+    FeaturesPlugin_Validators.cpp
 )
 
 SET(XML_RESOURCES
@@ -69,6 +73,7 @@ SET(XML_RESOURCES
   partition_widget.xml
   placement_widget.xml
   intersection_widget.xml
+  pipe_widget.xml
 )
 
 INCLUDE_DIRECTORIES(
index 701017b5238726c29f328ebcb12dd56dc9021d33..fcbcdc78e0e84086e5103b570170aba4b3f3f450 100644 (file)
@@ -23,6 +23,7 @@
 #include <GeomAPI_ShapeExplorer.h>
 
 #include <algorithm>
+#include <map>
 
 //=================================================================================================
 FeaturesPlugin_Boolean::FeaturesPlugin_Boolean()
index f3ef628e7de43697ad9ad8610597edca6e65508d..dc0b3a948c36f175306c9035bcc4243906beec27 100644 (file)
@@ -23,6 +23,7 @@
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAPI_ShapeExplorer.h>
 
+#include <map>
 #include <sstream>
 
 //=================================================================================================
@@ -420,7 +421,7 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
         if(aSweepAlgo.get()) {
           //Insert to faces
           int aToFaceIndex = 1;
-          const ListOfShape& aToFaces = aSweepAlgo->toFaces();
+          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)) {
@@ -433,7 +434,7 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
 
           //Insert from faces
           int aFromFaceIndex = 1;
-          const ListOfShape& aFromFaces = aSweepAlgo->fromFaces();
+          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;
index 3b520ba9289d5c8ee9b0fb3a00ea2563a1674b4e..628773d414e90d5a7dc635f37054a85e5665bf68 100644 (file)
@@ -185,7 +185,7 @@ void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr<ModelAPI_Resul
     int aToFaceIndex = 1;
     const std::string aToName = "ToFace";
     int aToTag = 2;
-    const ListOfShape& aToFaces = aSweepAlgo->toFaces();
+    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)) {
@@ -200,7 +200,7 @@ void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr<ModelAPI_Resul
     int aFromFaceIndex = 1;
     const std::string aFromName = "FromFace";
     int aFromTag = aToTag > 10000 ? aToTag : 10000;
-    const ListOfShape& aFromFaces = aSweepAlgo->fromFaces();
+    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)) {
index bdee88eaf77ed6e85883f88d82061067aa2dd867..1a1036a1181fa38917156815cecab04c2a065eec 100644 (file)
@@ -178,7 +178,7 @@ void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
   int aToFaceIndex = 1;
   const std::string aToName = "ToFace";
   int aToTag = 2;
-  const ListOfShape& aToFaces = thePrismAlgo.toFaces();
+  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)) {
@@ -193,7 +193,7 @@ void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
   int aFromFaceIndex = 1;
   const std::string aFromName = "FromFace";
   int aFromTag = aToTag > 10000 ? aToTag : 10000;
-  const ListOfShape& aFromFaces = thePrismAlgo.fromFaces();
+  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)) {
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp b/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp
new file mode 100644 (file)
index 0000000..3e46113
--- /dev/null
@@ -0,0 +1,387 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Pipe.cpp
+// Created:     16 March 2016
+// Author:      Dmitry Bobylev
+
+#include "FeaturesPlugin_Pipe.h"
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_Pipe.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_Pipe::FeaturesPlugin_Pipe()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Pipe::initAttributes()
+{
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+  data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(PATH_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(BINORMAL_ID(), ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(LOCATIONS_ID(), ModelAPI_AttributeSelectionList::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATIONS_ID());
+}
+
+//=================================================================================================
+void FeaturesPlugin_Pipe::execute()
+{
+  // Getting creation method.
+  std::string aCreationMethod = string(CREATION_METHOD())->value();
+
+  // Getting base objects.
+  ListOfShape aBaseShapesList, aBaseFacesList;
+  AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
+  if(!aBaseObjectsSelectionList.get()) {
+    setError("Error: Could not get base objects selection list.");
+    return;
+  }
+  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;
+    }
+    std::shared_ptr<GeomAPI_Shape> aBaseShape = aBaseObjectSelection->value();
+    if(aBaseShape.get() && !aBaseShape->isNull()) {
+      aBaseShape->shapeType() == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
+                                                       aBaseShapesList.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) :
+                                                           aBaseShapesList.push_back(aBaseShape);
+        }
+      } else {
+        for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
+          std::shared_ptr<GeomAPI_Shape> aBaseFace = std::dynamic_pointer_cast<GeomAPI_Shape>(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.
+  if(aCreationMethod == "simple") {
+    ListOfShape aShells;
+    ListOfShape aFreeFaces;
+    std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList);
+    GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
+    aBaseShapesList.insert(aBaseShapesList.end(), aFreeFaces.begin(), aFreeFaces.end());
+    aBaseShapesList.insert(aBaseShapesList.end(), aShells.begin(), aShells.end());
+  } else {
+    aBaseShapesList.insert(aBaseShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end());
+  }
+
+  // Getting path.
+  AttributeSelectionPtr aPathSelection = selection(PATH_OBJECT_ID());
+  if(!aPathSelection.get()) {
+    setError("Error: Path selection is empty.");
+    return;
+  }
+  std::shared_ptr<GeomAPI_Shape> aPathShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aPathSelection->value());
+  if(!aPathShape.get()) {
+    // Probaply it is a construction.
+    aPathShape = aPathSelection->context()->shape();
+  }
+  if(!aPathShape.get() || aPathShape->isNull()) {
+    setError("Error: Path shape is null.");
+    return;
+  }
+
+  // Getting Bi-Normal
+  std::shared_ptr<GeomAPI_Shape> aBiNormal;
+  if(aCreationMethod == "binormal") {
+    AttributeSelectionPtr aBiNormalSelection = selection(BINORMAL_ID());
+    if(!aBiNormalSelection.get()) {
+      setError("Error: Bi-Normal selection is empty.");
+      return;
+    }
+    aBiNormal = std::dynamic_pointer_cast<GeomAPI_Shape>(aBiNormalSelection->value());
+    if(!aBiNormal.get()) {
+      // Probably it is a construction.
+      aBiNormal = aBiNormalSelection->context()->shape();
+    }
+    if(!aBiNormal.get() || aBiNormal->isNull()) {
+      setError("Error: Bi-Normal shape is null.");
+      return;
+    }
+  }
+
+  // Getting locations.
+  ListOfShape aLocations;
+  if(aCreationMethod == "locations") {
+    AttributeSelectionListPtr aLocationsSelectionList = selectionList(LOCATIONS_ID());
+    if(!aLocationsSelectionList.get()) {
+      setError("Error: Could not get locations selection list.");
+      return;
+    }
+    for(int anIndex = 0; anIndex < aLocationsSelectionList->size(); anIndex++) {
+      AttributeSelectionPtr aLocationSelection = aLocationsSelectionList->value(anIndex);
+      if(!aLocationSelection.get()) {
+        setError("Error: One of the selected location is empty.");
+        return;
+      }
+      std::shared_ptr<GeomAPI_Shape> aLocationShape = aLocationSelection->value();
+      if(!aLocationShape.get()) {
+        // Probably it is a construction.
+        aLocationShape = aLocationSelection->context()->shape();
+      }
+      if(!aLocationShape.get() || aLocationShape->isNull()) {
+        setError("Error: One of the selected location shape is null.");
+        return;
+      }
+      aLocations.push_back(aLocationShape);
+    }
+  }
+
+  // Generating result for each object.
+  int aResultIndex = 0;
+  if(aCreationMethod == "simple" || aCreationMethod == "binormal") {
+    for(ListOfShape::const_iterator anIter = aBaseShapesList.cbegin(); anIter != aBaseShapesList.cend(); anIter++) {
+      std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
+
+      GeomAlgoAPI_Pipe aPipeAlgo = aCreationMethod == "simple" ? GeomAlgoAPI_Pipe(aBaseShape, aPathShape) :
+                                                                 GeomAlgoAPI_Pipe(aBaseShape, aPathShape, aBiNormal);
+
+      if(!aPipeAlgo.isDone()) {
+        setError("Error: Pipe algorithm failed.");
+        aResultIndex = 0;
+        break;
+      }
+
+      // Check if shape is valid
+      if(!aPipeAlgo.shape().get() || aPipeAlgo.shape()->isNull()) {
+        setError("Error: Resulting shape is Null.");
+        aResultIndex = 0;
+        break;
+      }
+      if(!aPipeAlgo.isValid()) {
+        setError("Error: Resulting shape is not valid.");
+        aResultIndex = 0;
+        break;
+      }
+
+      storeResult(aBaseShape, aPipeAlgo, aResultIndex++);
+    }
+  } else if(aCreationMethod == "locations") {
+    GeomAlgoAPI_Pipe aPipeAlgo = GeomAlgoAPI_Pipe(aBaseShapesList, aLocations, aPathShape);
+
+    if(!aPipeAlgo.isDone()) {
+      setError("Error: Pipe algorithm failed.");
+      removeResults(0);
+      return;
+    }
+
+    // Check if shape is valid
+    if(!aPipeAlgo.shape().get() || aPipeAlgo.shape()->isNull()) {
+      setError("Error: Resulting shape is Null.");
+      removeResults(0);
+      return;
+    }
+    if(!aPipeAlgo.isValid()) {
+      setError("Error: Resulting shape is not valid.");
+      removeResults(0);
+      return;
+    }
+
+    storeResult(aBaseShapesList, aPipeAlgo, aResultIndex++);
+  } else {
+    setError("Error: Wrong creation method.");
+    return;
+  }
+
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Pipe::storeResult(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                      GeomAlgoAPI_Pipe& thePipeAlgo,
+                                      const int theResultIndex)
+{
+  // Create result body.
+  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+
+  // Store generated shape.
+  aResultBody->storeGenerated(theBaseShape, thePipeAlgo.shape());
+
+  // Store generated edges/faces.
+  GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
+  GeomAPI_Shape::ShapeType aShapeTypeToExplode;
+  int aGenTag = 1;
+  std::string aGenName = "Generated_";
+
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = thePipeAlgo.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;
+      thePipeAlgo.generated(aV1, aV1History);
+      thePipeAlgo.generated(aV2, aV2History);
+      aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
+      aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
+    }
+    case GeomAPI_Shape::FACE:
+    case GeomAPI_Shape::SHELL: {
+      aShapeTypeToExplode = GeomAPI_Shape::EDGE;
+      aGenName += "Face";
+      break;
+    }
+  }
+  aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, theBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
+
+  // Store from shapes.
+  int aFromTag = aGenTag;
+  storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.fromShapes(), "From_", aFromTag);
+
+  // Store to shapes.
+  int aToTag = aFromTag;
+  storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.toShapes(), "To_", aToTag);
+
+  setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Pipe::storeResult(const ListOfShape& theBaseShapes,
+                                      GeomAlgoAPI_Pipe& thePipeAlgo,
+                                      const int theResultIndex)
+{
+  // Create result body.
+  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+
+  // Store generated shape.
+  aResultBody->storeGenerated(theBaseShapes.front(), thePipeAlgo.shape());
+
+  // Store generated edges/faces.
+  int aGenTag = 1;
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = thePipeAlgo.mapOfSubShapes();
+
+  for(ListOfShape::const_iterator anIter = theBaseShapes.cbegin(); anIter != theBaseShapes.cend(); anIter++) {
+    GeomShapePtr aBaseShape = *anIter;
+    GeomAPI_Shape::ShapeType aBaseShapeType = aBaseShape->shapeType();
+    GeomAPI_Shape::ShapeType aShapeTypeToExplode;
+    std::string aGenName = "Generated_";
+    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(aBaseShape, aV1, aV2);
+        ListOfShape aV1History, aV2History;
+        thePipeAlgo.generated(aV1, aV1History);
+        thePipeAlgo.generated(aV2, aV2History);
+        aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
+        aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
+      }
+      case GeomAPI_Shape::FACE:
+      case GeomAPI_Shape::SHELL: {
+        aShapeTypeToExplode = GeomAPI_Shape::EDGE;
+        aGenName += "Face";
+        break;
+      }
+    }
+    aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, aBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
+  }
+
+  // Store from shapes.
+  int aFromTag = aGenTag;
+  storeShapes(aResultBody, theBaseShapes.front()->shapeType(), aMapOfSubShapes, thePipeAlgo.fromShapes(), "From", aFromTag);
+
+  // Store to shapes.
+  int aToTag = aFromTag;
+  storeShapes(aResultBody, theBaseShapes.back()->shapeType(), aMapOfSubShapes, thePipeAlgo.toShapes(), "To", aToTag);
+
+
+  setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Pipe::storeShapes(ResultBodyPtr theResultBody,
+                                      const GeomAPI_Shape::ShapeType theBaseShapeType,
+                                      const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
+                                      const ListOfShape& theShapes,
+                                      const std::string theName,
+                                      int& theTag)
+{
+  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) {
+    std::shared_ptr<GeomAPI_Shape> aShape = *anIt;
+    for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) {
+      std::shared_ptr<GeomAPI_Shape> aSubShape = anExp.current();
+      if(theMapOfSubShapes->isBound(aSubShape)) {
+        aSubShape = theMapOfSubShapes->find(aSubShape);
+      }
+      std::ostringstream aStr;
+      aStr << aName << "_" << aShapeIndex++;
+      theResultBody->generated(aSubShape, aStr.str(), theTag++);
+    }
+  }
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Pipe.h b/src/FeaturesPlugin/FeaturesPlugin_Pipe.h
new file mode 100644 (file)
index 0000000..6682f23
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Pipe.h
+// Created:     16 March 2016
+// Author:      Dmitry Bobylev
+
+#ifndef FeaturesPlugin_Pipe_H_
+#define FeaturesPlugin_Pipe_H_
+
+#include "FeaturesPlugin.h"
+
+#include <GeomAlgoAPI_Pipe.h>
+
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultBody.h>
+
+/// \class FeaturesPlugin_Pipe
+/// \ingroup Plugins
+/// \brief Feature for creation of extrusion along a path.
+/// Pipe creates extrusion of objects along a path. It produces the following results from objects:\n
+/// Vertex -> Edge\n
+/// Edge -> Face\n
+/// Wire -> Shell\n
+/// Face -> Solid
+class FeaturesPlugin_Pipe : public ModelAPI_Feature
+{
+public:
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_FEATURE_ID("Pipe");
+    return MY_FEATURE_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string MY_CREATION_METHOD("creation_method");
+    return MY_CREATION_METHOD;
+  }
+
+  /// Attribute name of base objects.
+  inline static const std::string& BASE_OBJECTS_ID()
+  {
+    static const std::string MY_BASE_OBJECTS_ID("base_objects");
+    return MY_BASE_OBJECTS_ID;
+  }
+
+  /// Attribute name of path object.
+  inline static const std::string& PATH_OBJECT_ID()
+  {
+    static const std::string MY_PATH_OBJECT_ID("path_object");
+    return MY_PATH_OBJECT_ID;
+  }
+
+  /// Attribute name of Bi-Normal.
+  inline static const std::string& BINORMAL_ID()
+  {
+    static const std::string MY_BINORMAL_ID("binormal");
+    return MY_BINORMAL_ID;
+  }
+
+  /// Attribute name of locations.
+  inline static const std::string& LOCATIONS_ID()
+  {
+    static const std::string MY_LOCATIONS_ID("locations_objects");
+    return MY_LOCATIONS_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Pipe::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
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation
+  FeaturesPlugin_Pipe();
+
+private:
+  void storeResult(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                   GeomAlgoAPI_Pipe& thePipeAlgo,
+                   const int theResultIndex = 0);
+
+  void storeResult(const ListOfShape& theBaseShapes,
+                   GeomAlgoAPI_Pipe& thePipeAlgo,
+                   const int theResultIndex = 0);
+
+  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 d40d085baaa2f05bf1cdb0ec0d68ca52608ba243..432e388507c47507a92f8fb499bd1c50e5bd6ab2 100644 (file)
@@ -11,6 +11,7 @@
 #include <FeaturesPlugin_Intersection.h>
 #include <FeaturesPlugin_Translation.h>
 #include <FeaturesPlugin_Partition.h>
+#include <FeaturesPlugin_Pipe.h>
 #include <FeaturesPlugin_Placement.h>
 #include <FeaturesPlugin_Revolution.h>
 #include <FeaturesPlugin_RevolutionSketch.h>
@@ -18,6 +19,7 @@
 #include <FeaturesPlugin_RevolutionFuse.h>
 #include <FeaturesPlugin_Rotation.h>
 #include <FeaturesPlugin_ValidatorTransform.h>
+#include <FeaturesPlugin_Validators.h>
 
 #include <ModelAPI_Session.h>
 
@@ -35,7 +37,9 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
   SessionPtr aMgr = ModelAPI_Session::get();
   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
   aFactory->registerValidator("FeaturesPlugin_ValidatorTransform",
-                              new FeaturesPlugin_ValidatorTransform);  
+                              new FeaturesPlugin_ValidatorTransform);
+  aFactory->registerValidator("FeaturesPlugin_PipeLocationsValidator",
+                              new FeaturesPlugin_PipeLocationsValidator);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
@@ -59,6 +63,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_Intersection);
   } else if (theFeatureID == FeaturesPlugin_Partition::ID()) {
     return FeaturePtr(new FeaturesPlugin_Partition);
+  } else if (theFeatureID == FeaturesPlugin_Pipe::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Pipe);
   } else if (theFeatureID == FeaturesPlugin_Placement::ID()) {
     return FeaturePtr(new FeaturesPlugin_Placement);
   } else if (theFeatureID == FeaturesPlugin_ExtrusionCut::ID()) {
index 5a7a34b399d8791c1c086a2412a905f4c12f12c5..88163729ca054980e88435b1abb2cd867c874720 100644 (file)
@@ -194,7 +194,7 @@ void FeaturesPlugin_Revolution::loadNamingDS(GeomAlgoAPI_Revolution& theRevolAlg
   int aToFaceIndex = 1;
   const std::string aToName = "ToFace";
   int aToTag = 2;
-  const ListOfShape& aToFaces = theRevolAlgo.toFaces();
+  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)) {
@@ -209,7 +209,7 @@ void FeaturesPlugin_Revolution::loadNamingDS(GeomAlgoAPI_Revolution& theRevolAlg
   int aFromFaceIndex = 1;
   const std::string aFromName = "FromFace";
   int aFromTag = aToTag > 10000 ? aToTag : 10000;
-  const ListOfShape& aFromFaces = theRevolAlgo.fromFaces();
+  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)) {
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
new file mode 100644 (file)
index 0000000..40c1197
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Validators.cpp
+// Created:     22 March 2016
+// Author:      Dmitry Bobylev
+
+#include "FeaturesPlugin_Validators.h"
+
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+
+//=================================================================================================
+bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                                    const std::list<std::string>& theArguments,
+                                                    std::string& theError) const
+{
+  static const std::string aCreationMethodID = "creation_method";
+  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;
+  }
+
+  AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
+  if(!aCreationMethodAttr.get()) {
+    theError = "Could not get \"" + aCreationMethodID + "\" attribute.";
+    return false;
+  }
+
+  if(aCreationMethodAttr->value() != "locations") {
+    return true;
+  }
+
+  AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
+  if(!aBaseObjectsSelectionList.get()) {
+    theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
+    return false;
+  }
+
+  AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
+  if(!aLocationsSelectionList.get()) {
+    theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
+    return false;
+  }
+
+  if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
+    theError = "Number of locations should be the same as base objects.";
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_PipeLocationsValidator::isNotObligatory(std::string theFeature, std::string theAttribute)
+{
+  if(theFeature == "Pipe" && theAttribute == "locations") {
+    return true;
+  }
+  return false;
+}
\ No newline at end of file
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h
new file mode 100644 (file)
index 0000000..47a12e4
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Validators.h
+// Created:     22 March 2016
+// Author:      Dmitry Bobylev
+
+#ifndef FeaturesPlugin_Validators_H_
+#define FeaturesPlugin_Validators_H_
+
+#include <ModelAPI_FeatureValidator.h>
+
+/// \class FeaturesPlugin_PipeLocationsValidator
+/// \ingroup Validators
+/// \brief Validator for the pipe locations.
+class FeaturesPlugin_PipeLocationsValidator : public ModelAPI_FeatureValidator
+{
+ public:
+  //! \return true if number of selected locations the same as number of selected bases, or empty.
+  //! \param theFeature the checked feature
+  //! \param theArguments arguments of the feature (not used)
+  //! \param theError error message
+  virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                       const std::list<std::string>& theArguments,
+                       std::string& theError) const;
+
+  /// Returns true if the attribute in feature is not obligatory for the feature execution
+  virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
+#endif
diff --git a/src/FeaturesPlugin/pipe_widget.xml b/src/FeaturesPlugin/pipe_widget.xml
new file mode 100644 (file)
index 0000000..10b07ca
--- /dev/null
@@ -0,0 +1,60 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <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="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_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </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"/>
+</source>
index afe29e4620127105acf345f4ed452f8cd8dd972f..fe897b2a54feeeddf7b7f77bc275f7bd09fa8625 100644 (file)
         <source path="revolutionfuse_widget.xml"/>
       </feature>
     </group>
+    <group id="Pipe">
+      <feature id="Pipe" title="Pipe" tooltip="Generates extrusion along a path" icon=":icons/pipe.png">
+        <source path="pipe_widget.xml"/>
+      </feature>
+    </group>
     <group id="Boolean">
       <feature id="Boolean" title="Boolean" tooltip="Perform boolean operations with solids" icon=":icons/cut.png">
           <source path="boolean_widget.xml"/>
index 17e87d85c3cd3f668e7b1c1cdb3572b18a40a7a9..d00fe34db29f733d99db9d497539b46726c1a6fd 100644 (file)
@@ -94,6 +94,53 @@ GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const
   return (ShapeType)aShape.ShapeType();
 }
 
+std::string GeomAPI_Shape::shapeTypeStr() const
+{
+  ShapeType aShapeType = shapeType();
+  std::string aShapeTypeStr;
+
+  switch(aShapeType) {
+    case COMPOUND: {
+      aShapeTypeStr = "Compound";
+      break;
+    }
+    case COMPSOLID: {
+      aShapeTypeStr = "CompSolid";
+      break;
+    }
+    case SOLID: {
+      aShapeTypeStr = "Solid";
+      break;
+    }
+    case SHELL: {
+      aShapeTypeStr = "Shell";
+      break;
+    }
+    case FACE: {
+      aShapeTypeStr = "Face";
+      break;
+    }
+    case WIRE: {
+      aShapeTypeStr = "Wire";
+      break;
+    }
+    case EDGE: {
+      aShapeTypeStr = "Edge";
+      break;
+    }
+    case VERTEX: {
+      aShapeTypeStr = "Vertex";
+      break;
+    }
+    case SHAPE: {
+      aShapeTypeStr = "Shape";
+      break;
+    }
+  }
+
+  return aShapeTypeStr;
+}
+
 bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmin,
                                 double& theXmax, double& theYmax, double& theZmax) const
 {
index 8f31318d6304242add5d76b354418ba736716af5..37ba2b462ef86d890c4fb0571c0538f95ed8d008 100644 (file)
@@ -70,6 +70,10 @@ public:
   GEOMAPI_EXPORT
   virtual ShapeType shapeType() const;
 
+  /// \return the shape type as string.
+  GEOMAPI_EXPORT
+  virtual std::string shapeTypeStr() const;
+
   /// Computes boundary dimensions of the shape
   /// Returns False if it is not possible
   GEOMAPI_EXPORT 
index 1b3390b16362925c6e56633bc0a0f90b5fa0113f..74f73a9bbed1d10c9156ecfd1e7dcbb3415610de 100644 (file)
@@ -35,6 +35,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Partition.h
     GeomAlgoAPI_PaveFiller.h
     GeomAlgoAPI_Intersection.h
+    GeomAlgoAPI_Pipe.h
 )
 
 SET(PROJECT_SOURCES
@@ -66,6 +67,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Partition.cpp
     GeomAlgoAPI_PaveFiller.cpp
     GeomAlgoAPI_Intersection.cpp
+    GeomAlgoAPI_Pipe.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 2aea45d155d2f0afe214502651a3118dfbb409bc..95fddd512b0b358a1e39763126537a947e585252 100644 (file)
@@ -41,6 +41,7 @@
 %include "GeomAlgoAPI_Transform.h"
 %include "GeomAlgoAPI_PaveFiller.h"
 %include "GeomAlgoAPI_Intersection.h"
+%include "GeomAlgoAPI_Pipe.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
index 5419c4f151465f565c3eaec968608ef3600ac674..e7d5165ce194d85bd478b8cefadc035be7fd08bd 100644 (file)
@@ -18,7 +18,7 @@
 
 //=================================================================================================
 GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
-: myBuilderType(UNKNOWN),
+: myBuilderType(Unknown),
   myDone(false)
 {
 }
@@ -150,8 +150,8 @@ void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr<GeomAPI_Shape> theSha
       myMap.reset(new GeomAPI_DataMapOfShapeShape);
     }
 
-    const TopoDS_Shape& aTopoDSSHape = myShape->impl<TopoDS_Shape>();
-    for(TopExp_Explorer anExp(aTopoDSSHape,TopAbs_FACE); anExp.More(); anExp.Next()) {
+    const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
+    for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
       myMap->bind(aCurrentShape, aCurrentShape);
@@ -179,4 +179,17 @@ void GeomAlgoAPI_MakeShape::initialize() {
       break;
     }
   }
+
+  if(myMap.get()) {
+    myMap->clear();
+  } else {
+    myMap.reset(new GeomAPI_DataMapOfShapeShape);
+  }
+
+  const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
+  for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
+    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    myMap->bind(aCurrentShape, aCurrentShape);
+  }
 }
index acbc9c84fbf5247c7820ee6dad889bf833986089..b5e40ef2439bc5c0fd97618c01c5ff7d133a671a 100644 (file)
@@ -20,9 +20,9 @@ class GeomAlgoAPI_MakeShape : public GeomAPI_Interface
 public:
   /// Builder type enum
   enum BuilderType {
+    Unknown,
     OCCT_BRepBuilderAPI_MakeShape,
-    OCCT_BOPAlgo_Builder,
-    UNKNOWN
+    OCCT_BOPAlgo_Builder
   };
 
 public:
@@ -45,7 +45,7 @@ public:
   template<class T> void initialize(T* theBuilder, const BuilderType theBuilderType = OCCT_BRepBuilderAPI_MakeShape)
   {
     setImpl(theBuilder);
-    myBuilderType = theBuilder;
+    myBuilderType = theBuilderType;
     initialize();
   }
 
index 701a99d145504caa3dd302bfdcf298a925479b38..7a59ae3444b604ce52c340899320f50a9d357378 100644 (file)
@@ -7,37 +7,37 @@
 #include "GeomAlgoAPI_MakeSweep.h"
 
 //=================================================================================================
-const ListOfShape& GeomAlgoAPI_MakeSweep::fromFaces() const
+const ListOfShape& GeomAlgoAPI_MakeSweep::fromShapes() const
 {
-  return myFromFaces;
+  return myFromShapes;
 }
 
 //=================================================================================================
-const ListOfShape& GeomAlgoAPI_MakeSweep::toFaces() const
+const ListOfShape& GeomAlgoAPI_MakeSweep::toShapes() const
 {
-  return myToFaces;
+  return myToShapes;
 }
 
 //=================================================================================================
-void GeomAlgoAPI_MakeSweep::addFromFace(const std::shared_ptr<GeomAPI_Shape> theFace)
+void GeomAlgoAPI_MakeSweep::addFromShape(const std::shared_ptr<GeomAPI_Shape> theFace)
 {
-  myFromFaces.push_back(theFace);
+  myFromShapes.push_back(theFace);
 }
 
 //=================================================================================================
-void GeomAlgoAPI_MakeSweep::setFromFaces(const ListOfShape& theListOfFaces)
+void GeomAlgoAPI_MakeSweep::setFromShapes(const ListOfShape& theListOfFaces)
 {
-  myFromFaces = theListOfFaces;
+  myFromShapes = theListOfFaces;
 }
 
 //=================================================================================================
-void GeomAlgoAPI_MakeSweep::addToFace(const std::shared_ptr<GeomAPI_Shape> theFace)
+void GeomAlgoAPI_MakeSweep::addToShape(const std::shared_ptr<GeomAPI_Shape> theFace)
 {
-  myToFaces.push_back(theFace);
+  myToShapes.push_back(theFace);
 }
 
 //=================================================================================================
-void GeomAlgoAPI_MakeSweep::setToFaces(const ListOfShape& theListOfFaces)
+void GeomAlgoAPI_MakeSweep::setToShapes(const ListOfShape& theListOfFaces)
 {
-  myToFaces = theListOfFaces;
+  myToShapes = theListOfFaces;
 }
index d9c5f4ec2a24820c29d752742c8e2577e0473734..2006c87462b7334858ece234bc1f0b835ecf63e6 100644 (file)
 class GeomAlgoAPI_MakeSweep : public GeomAlgoAPI_MakeShapeList
 {
 public:
-  /// \returns the list of from faces.
-  GEOMALGOAPI_EXPORT virtual const ListOfShape& fromFaces() const;
+  /// \returns the list of from shapes.
+  GEOMALGOAPI_EXPORT virtual const ListOfShape& fromShapes() const;
 
-  /// \return the list of to faces.
-  GEOMALGOAPI_EXPORT virtual const ListOfShape& toFaces() const;
+  /// \return the list of to shapes.
+  GEOMALGOAPI_EXPORT virtual const ListOfShape& toShapes() const;
 
 protected:
   /// Empty constructor.
   GeomAlgoAPI_MakeSweep() : GeomAlgoAPI_MakeShapeList() {};
 
-  /// \brief Adds a face to list of from faces.
-  /// \param[in] theFace a face to add.
-  void addFromFace(const std::shared_ptr<GeomAPI_Shape> theFace);
+  /// \brief Adds a shape to list of from shape.
+  /// \param[in] theShape a shape to add.
+  void addFromShape(const std::shared_ptr<GeomAPI_Shape> theShape);
 
-  /// \brief Sets from faces
-  /// \param[in] theListOfFaces list of from faces.
-  void setFromFaces(const ListOfShape& theListOfFaces);
+  /// \brief Sets from shapes
+  /// \param[in] theListOfShapes list of from shapes.
+  void setFromShapes(const ListOfShape& theListOfShapes);
 
-  /// \brief Adds a face to list of to faces.
-  /// \param[in] theFace a face to add.
-  void addToFace(const std::shared_ptr<GeomAPI_Shape> theFace);
+  /// \brief Adds a face to list of to shape.
+  /// \param[in] theShape a face to add.
+  void addToShape(const std::shared_ptr<GeomAPI_Shape> theShape);
 
-  /// \brief Sets to faces
-  /// \param[in] theListOfFaces list of to faces.
-  void setToFaces(const ListOfShape& theListOfFaces);
+  /// \brief Sets to shapes
+  /// \param[in] theListOfShapes list of to shapes.
+  void setToShapes(const ListOfShape& theListOfShapes);
 
 private:
-  ListOfShape myFromFaces;
-  ListOfShape myToFaces;
+  ListOfShape myFromShapes;
+  ListOfShape myToShapes;
 };
 
 #endif
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp
new file mode 100644 (file)
index 0000000..7761a5b
--- /dev/null
@@ -0,0 +1,391 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Pipe.cpp
+// Created:     16 March 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomAlgoAPI_Pipe.h"
+
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+
+#include <BRep_Tool.hxx>
+#include <BRepOffsetAPI_MakePipe.hxx>
+#include <BRepOffsetAPI_MakePipeShell.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
+#include <gp_Lin.hxx>
+#include <NCollection_List.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+
+static bool getBase(TopoDS_Shape& theBaseOut,
+                    TopAbs_ShapeEnum& theBaseTypeOut,
+                    const std::shared_ptr<GeomAPI_Shape> theBaseShape);
+static bool getPath(TopoDS_Wire& thePathOut,
+                    const std::shared_ptr<GeomAPI_Shape> thePathShape);
+static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder);
+
+//=================================================================================================
+GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                   const std::shared_ptr<GeomAPI_Shape> thePathShape)
+: /*myIsPipeShellUsed(false),*/
+  myBaseShape(theBaseShape),
+  myPathShape(thePathShape)
+{
+  build(theBaseShape, thePathShape);
+}
+
+//=================================================================================================
+GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                   const std::shared_ptr<GeomAPI_Shape> thePathShape,
+                                   const std::shared_ptr<GeomAPI_Shape> theBiNormal)
+//: myIsPipeShellUsed(true)
+{
+  build(theBaseShape, thePathShape, theBiNormal);
+}
+
+//=================================================================================================
+GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
+                                   const ListOfShape& theLocations,
+                                   const std::shared_ptr<GeomAPI_Shape> thePathShape)
+//: myIsPipeShellUsed(true)
+{
+  build(theBaseShapes, theLocations, thePathShape);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Pipe::build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                             const std::shared_ptr<GeomAPI_Shape> thePathShape)
+{
+  // Getting base shape.
+  if(!theBaseShape.get()) {
+    return;
+  }
+  TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
+  if(aBaseShape.IsNull()) {
+    return;
+  }
+  TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
+  if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
+     aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
+     aBaseShapeType != TopAbs_SHELL) {
+    return;
+  }
+
+  // Getting path.
+  TopoDS_Wire aPathWire;
+  if(!getPath(aPathWire, thePathShape)) {
+    return;
+  }
+
+  // Making pipe.
+  BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
+  if(!aPipeBuilder) {
+    return;
+  }
+  aPipeBuilder->Build();
+
+  // Checking result.
+  if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
+    delete aPipeBuilder;
+    return;
+  }
+  this->initialize(aPipeBuilder);
+
+  // Setting naming.
+  std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+  aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
+  aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
+  this->addFromShape(aFromShape);
+  this->addToShape(aToShape);
+
+  // Setting result.
+  TopoDS_Shape aResultShape = aPipeBuilder->Shape();
+  std::shared_ptr<GeomAPI_Shape> aResultGeomShape(new GeomAPI_Shape());
+  aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
+  this->setShape(aResultGeomShape);
+  this->setDone(true);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Pipe::build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                             const std::shared_ptr<GeomAPI_Shape> thePathShape,
+                             const std::shared_ptr<GeomAPI_Shape> theBiNormal)
+{
+  // Getting base shape.
+  TopoDS_Shape aBaseShape;
+  TopAbs_ShapeEnum aBaseShapeType;
+  if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
+    return;
+  }
+
+  // Getting path.
+  TopoDS_Wire aPathWire;
+  if(!getPath(aPathWire, thePathShape)) {
+    return;
+  }
+
+  // Getting Bi-Normal.
+  if(!theBiNormal.get()) {
+    return;
+  }
+  TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
+  if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
+    return;
+  }
+  TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
+  Standard_Real aFirst, aLast;
+  Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
+  Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
+  if(aBiNormalLine.IsNull()) {
+    return;
+  }
+  gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
+
+  // Making pipe.
+  BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
+  if(!aPipeBuilder) {
+    return;
+  }
+  aPipeBuilder->Add(aBaseShape);
+  aPipeBuilder->SetMode(aBiNormalDir);
+  if(!buildPipe(aPipeBuilder)) {
+    delete aPipeBuilder;
+    return;
+  }
+  this->initialize(aPipeBuilder);
+
+  // Checking result.
+  if(aBaseShapeType == TopAbs_FACE) {
+    if(aPipeBuilder->MakeSolid() == Standard_False) {
+      return;
+    }
+  }
+  if(aPipeBuilder->Shape().IsNull()) {
+    return;
+  }
+
+  // Setting naming.
+  std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+  aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
+  aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
+  this->addFromShape(aFromShape);
+  this->addToShape(aToShape);
+
+  // Setting result.
+  TopoDS_Shape aResultShape = aPipeBuilder->Shape();
+  std::shared_ptr<GeomAPI_Shape> aResultGeomShape(new GeomAPI_Shape());
+  aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
+  this->setShape(aResultGeomShape);
+  this->setDone(true);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
+                             const ListOfShape& theLocations,
+                             const std::shared_ptr<GeomAPI_Shape> thePathShape)
+{
+  if(theBaseShapes.empty() || (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
+    return;
+  }
+
+  bool aHasLocations = false;
+  if(!theLocations.empty()) {
+    aHasLocations = true;
+  }
+
+  // Getting path.
+  TopoDS_Wire aPathWire;
+  if(!getPath(aPathWire, thePathShape)) {
+    return;
+  }
+
+  // Making pipe.
+  BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
+  if(!aPipeBuilder) {
+    return;
+  }
+  bool anIsSolidNeeded = false;
+  ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
+  ListOfShape::const_iterator aLocIt = theLocations.cbegin();
+  while(aBaseIt != theBaseShapes.cend()) {
+    std::shared_ptr<GeomAPI_Shape> aBase = *aBaseIt;
+    TopoDS_Shape aBaseShape;
+    TopAbs_ShapeEnum aBaseShapeType;
+    if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
+      delete aPipeBuilder;
+      return;
+    }
+    ++aBaseIt;
+    if(aBaseShapeType == TopAbs_FACE) {
+      anIsSolidNeeded = true;
+    }
+
+    if(aHasLocations) {
+      std::shared_ptr<GeomAPI_Shape> aLocation = *aLocIt;
+      if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
+        delete aPipeBuilder;
+        return;
+      }
+      TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
+      ++aLocIt;
+      aPipeBuilder->Add(aBaseShape, aLocationVertex);
+    } else {
+      aPipeBuilder->Add(aBaseShape);
+    }
+  }
+
+  if(aPipeBuilder->IsReady() == Standard_False) {
+    delete aPipeBuilder;
+    return;
+  }
+
+  if(!buildPipe(aPipeBuilder)) {
+    delete aPipeBuilder;
+    return;
+  }
+  this->initialize(aPipeBuilder);
+
+  // Checking result.
+  if(anIsSolidNeeded) {
+    if(aPipeBuilder->MakeSolid() == Standard_False) {
+      return;
+    }
+  }
+  if(aPipeBuilder->Shape().IsNull()) {
+    return;
+  }
+
+  // Setting naming.
+  std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+  aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
+  aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
+  this->addFromShape(aFromShape);
+  this->addToShape(aToShape);
+
+  // Setting result.
+  TopoDS_Shape aResultShape = aPipeBuilder->Shape();
+  std::shared_ptr<GeomAPI_Shape> aResultGeomShape(new GeomAPI_Shape());
+  aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
+  this->setShape(aResultGeomShape);
+  this->setDone(true);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Pipe::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                 ListOfShape& theHistory)
+{
+  GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
+
+  //if(myIsPipeShellUsed) {
+  //  GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
+  //  return;
+  //}
+
+  //BRepOffsetAPI_MakePipe* aMakePipe = implPtr<BRepOffsetAPI_MakePipe>();
+  //const TopoDS_Shape& aProfile = theShape->impl<TopoDS_Shape>();
+  //const TopAbs_ShapeEnum aProfileShapeType = aProfile.ShapeType();
+  //if(aProfileShapeType != TopAbs_VERTEX && aProfileShapeType != TopAbs_EDGE) {
+  //  return;
+  //}
+  //const TopoDS_Shape& aBaseShape = myBaseShape->impl<TopoDS_Shape>();
+  //TopExp_Explorer anExp(aBaseShape, aProfileShapeType);
+  //Standard_Boolean ahasShape = Standard_False;
+  //for(; anExp.More(); anExp.Next()) {
+  //  if(anExp.Current().IsSame(aProfile)) {
+  //    ahasShape = Standard_True;
+  //    break;
+  //  }
+  //}
+  //if(!ahasShape) {
+  //  return;
+  //}
+  //TopExp_Explorer aShapeExplorer(myPathShape->impl<TopoDS_Shape>(), TopAbs_EDGE);
+  //for(; aShapeExplorer.More(); aShapeExplorer.Next ()) {
+  //  const TopoDS_Shape& aSpine = aShapeExplorer.Current();
+  //  const TopoDS_Shape& aGeneratedShape = aMakePipe->Generated(aSpine, aProfile);
+  //  if(aGeneratedShape.IsNull()) {
+  //    continue;
+  //  }
+  //  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  //  aShape->setImpl(new TopoDS_Shape(aGeneratedShape));
+  //  theHistory.push_back(aShape);
+  //}
+}
+
+// Auxilary functions:
+//=================================================================================================
+bool getBase(TopoDS_Shape& theBaseOut,
+             TopAbs_ShapeEnum& theBaseTypeOut,
+             const std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  if(!theBaseShape.get()) {
+    return false;
+  }
+
+  theBaseOut = theBaseShape->impl<TopoDS_Shape>();
+  if(theBaseOut.IsNull()) {
+    return false;
+  }
+  theBaseTypeOut = theBaseOut.ShapeType();
+  if(theBaseTypeOut == TopAbs_VERTEX) {
+    // Do nothing.
+  } else if(theBaseTypeOut == TopAbs_EDGE) {
+    theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
+  } else if(theBaseTypeOut == TopAbs_WIRE) {
+    // Do nothing.
+  } else if(theBaseTypeOut == TopAbs_FACE) {
+    TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
+    theBaseOut = anExp.Current();
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool getPath(TopoDS_Wire& thePathOut,
+             const std::shared_ptr<GeomAPI_Shape> thePathShape)
+{
+  if(!thePathShape.get()) {
+    return false;
+  }
+
+  TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
+  if(aPathShape.IsNull()) {
+    return false;
+  }
+  TopAbs_ShapeEnum aPathShapeType = aPathShape.ShapeType();
+  if(aPathShapeType == TopAbs_EDGE) {
+    TopoDS_Edge aPathEdge = TopoDS::Edge(aPathShape);
+    thePathOut = BRepBuilderAPI_MakeWire(aPathEdge).Wire();
+  } else if(aPathShapeType == TopAbs_WIRE) {
+    thePathOut = TopoDS::Wire(aPathShape);
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
+{
+  thePipeBuilder->Build();
+
+  Standard_Boolean isDone = thePipeBuilder->IsDone();
+
+  if (!isDone) {
+    // Try to use Descrete Trihedron mode.
+    thePipeBuilder->SetDiscreteMode();
+    thePipeBuilder->Build();
+    isDone = thePipeBuilder->IsDone();
+  }
+
+  return isDone == Standard_True;
+}
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.h b/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.h
new file mode 100644 (file)
index 0000000..8814118
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Pipe.h
+// Created:     16 March 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Pipe_H_
+#define GeomAlgoAPI_Pipe_H_
+
+#include "GeomAlgoAPI.h"
+
+#include "GeomAlgoAPI_MakeSweep.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Pipe
+/// \ingroup DataAlgo
+/// \brief Allows to create extrusion of objects along a path. It produces the following results from objects:\n
+/// Vertex -> Edge\n
+/// Edge -> Face\n
+/// Wire -> Shell\n
+/// Face -> Solid
+class GeomAlgoAPI_Pipe : public GeomAlgoAPI_MakeSweep
+{
+public:
+  /// \brief Creates extrusion for the given shape along a path.
+  /// \param[in] theBaseShape base shape(vertex, edge, wire of face).
+  /// \param[in] thePathShape path shape(edge or wire).
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                      const std::shared_ptr<GeomAPI_Shape> thePathShape);
+
+  /// \brief Creates extrusion for the given shape along a path.
+  /// \param[in] theBaseShape base shape(vertex, edge, wire of face).
+  /// \param[in] thePathShape path shape(edge or wire).
+  /// \param[in] theBiNormal edge or wire to preserve the constant angle between the normal vector
+  /// to the base object and the BiNormal vector.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                      const std::shared_ptr<GeomAPI_Shape> thePathShape,
+                                      const std::shared_ptr<GeomAPI_Shape> theBiNormal);
+
+  /// \brief Creates extrusion for the given shape along a path.
+  /// \param[in] theBaseShapes base shape(vertex, edge, wire of face).
+  /// \param[in] theLocations vertexes on the path. Should be empty or same size as theBaseShapes.
+  /// \param[in] thePathShape path shape(edge or wire).
+  /// to the base object and the BiNormal vector.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
+                                      const ListOfShape& theLocations,
+                                      const std::shared_ptr<GeomAPI_Shape> thePathShape);
+
+  /// \return the list of shapes generated from theShape.
+  /// \param[in] theShape base shape.
+  /// \param[out] theHistory generated shapes.
+  GEOMALGOAPI_EXPORT void generated(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                    ListOfShape& theHistory) override;
+
+private:
+  void build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+             const std::shared_ptr<GeomAPI_Shape> thePathShape);
+
+  void build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+             const std::shared_ptr<GeomAPI_Shape> thePathShape,
+             const std::shared_ptr<GeomAPI_Shape> theBiNormal);
+
+  void build(const ListOfShape& theBaseShapes,
+             const ListOfShape& theLocations,
+             const std::shared_ptr<GeomAPI_Shape> thePathShape);
+
+private:
+  //bool myIsPipeShellUsed;
+  std::shared_ptr<GeomAPI_Shape> myBaseShape;
+  std::shared_ptr<GeomAPI_Shape> myPathShape;
+};
+
+#endif
index 2e8b00ca7f51be556d1bffbf0541ef8134ebc391..f0a6690e2127406b08c829b09d8dc06e82bcf68a 100644 (file)
@@ -117,8 +117,8 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape
       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
       aFromShape->setImpl(new TopoDS_Shape(aPrismBuilder->FirstShape(aFace)));
       aToShape->setImpl(new TopoDS_Shape(aPrismBuilder->LastShape(aFace)));
-      this->addFromFace(aFromShape);
-      this->addToFace(aToShape);
+      this->addFromShape(aFromShape);
+      this->addToShape(aToShape);
     }
   } else {
     std::shared_ptr<GeomAPI_Shape> aBoundingFromShape = theFromShape ? theFromShape : aBasePlane;
@@ -268,7 +268,7 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape
     for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) {
       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
-      this->addToFace(aShape);
+      this->addToShape(aShape);
     }
     aResult = aToCutBuilder->Shape();
 
@@ -283,7 +283,7 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape
     for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) {
       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
-      this->addFromFace(aShape);
+      this->addFromShape(aShape);
     }
     aResult = aFromCutBuilder->Shape();
 
index eec976ee8e1c37b87ed975e364cca72e5b2916da..cd3198a77c99fac5da8876d61563d7936facb621 100644 (file)
@@ -140,8 +140,8 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBase
       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
       aFromShape->setImpl(new TopoDS_Shape(aRevolBuilder->FirstShape(aFace)));
       aToShape->setImpl(new TopoDS_Shape(aRevolBuilder->LastShape(aFace)));
-      this->addFromFace(aFromShape);
-      this->addToFace(aToShape);
+      this->addFromShape(aFromShape);
+      this->addToShape(aToShape);
     }
   } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
     // Making revolution to the 360 angle.
@@ -249,12 +249,12 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBase
       if(aFaceSurface == aFromSurface) {
         std::shared_ptr<GeomAPI_Shape> aFSHape(new GeomAPI_Shape);
         aFSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
-        this->addFromFace(aFSHape);
+        this->addFromShape(aFSHape);
       }
       if(aFaceSurface == aToSurface) {
         std::shared_ptr<GeomAPI_Shape> aTSHape(new GeomAPI_Shape);
         aTSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
-        this->addToFace(aTSHape);
+        this->addToShape(aTSHape);
       }
     }
   } else { //Case 3: When only one bounding plane was set.
@@ -324,7 +324,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBase
     for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
-      isFromFaceSet ? this->addFromFace(aShape) : this->addToFace(aShape);
+      isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
     }
 
     // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
@@ -366,7 +366,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBase
     for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
-      isFromFaceSet ? this->addToFace(aShape) : this->addFromFace(aShape);
+      isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
     }
 
     TopExp_Explorer anExp(aResult, TopAbs_SOLID);
@@ -408,7 +408,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBase
       if(aFaceSurface == aBoundingSurface) {
         std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
         aShape->setImpl(new TopoDS_Shape(aFaceOnResult));
-        isFromFaceSet ? this->addFromFace(aShape) : this->addToFace(aShape);
+        isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
       }
     }
   }
index 852163df3df21b261cf67792238218d01d92946d..d506c0023dd05bf86a22919d164957d5dab5e771 100644 (file)
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
 #include <NCollection_Vector.hxx>
+#include <ShapeAnalysis.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TopoDS_Builder.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <TopoDS.hxx>
 #include <TopExp_Explorer.hxx>
 
@@ -298,3 +300,27 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::
 
   return aResultShape;
 }
+
+//=================================================================================================
+void GeomAlgoAPI_ShapeTools::findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                        std::shared_ptr<GeomAPI_Vertex>& theV1,
+                                        std::shared_ptr<GeomAPI_Vertex>& theV2)
+{
+  if(!theShape.get()) {
+    std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex);
+    aVertex->setImpl(new TopoDS_Vertex());
+    theV1 = aVertex;
+    theV2 = aVertex;
+    return;
+  }
+
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  TopoDS_Vertex aV1, aV2;
+  ShapeAnalysis::FindBounds(aShape, aV1, aV2);
+
+  std::shared_ptr<GeomAPI_Vertex> aGeomV1(new GeomAPI_Vertex()), aGeomV2(new GeomAPI_Vertex());
+  aGeomV1->setImpl(new TopoDS_Vertex(aV1));
+  aGeomV2->setImpl(new TopoDS_Vertex(aV2));
+  theV1 = aGeomV1;
+  theV2 = aGeomV2;
+}
index d361eb927b34cd9aaefcd4b38fb4b1ef044f9813..8726f670a5dd12414650efab90f0cdc8b2c4314a 100644 (file)
@@ -7,16 +7,15 @@
 #ifndef GeomAlgoAPI_ShapeTools_H_
 #define GeomAlgoAPI_ShapeTools_H_
 
-#include <GeomAlgoAPI.h>
+#include "GeomAlgoAPI.h"
+
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Shape.h>
+#include <GeomAPI_Vertex.h>
 
-#include <map>
-
-/** \class GeomAlgoAPI_ShapeTools
- *  \ingroup DataAlgo
- *  \brief Useful tools for working with shapes.
- */
+/// \class GeomAlgoAPI_ShapeTools
+/// \ingroup DataAlgo
+/// \brief Useful tools for working with shapes.
 class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools
 {
 public:
@@ -27,37 +26,42 @@ public:
   /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
   static std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
 
-  /** \brief Combines faces with common edges to shells, or solids to compsolids.
-   *  \param[in] theCompound compound of shapes.
-   *  \param[in] theType type of combine.
-   *  \param[out] theCombinedShapes resulting shapes.
-   *  \param[out] theFreeShapes shapes that does not have common subshapes.
-   */
+  /// \brief Combines faces with common edges to shells, or solids to compsolids.
+  /// \param[in] theCompound compound of shapes.
+  /// \param[in] theType type of combine.
+  /// \param[out] theCombinedShapes resulting shapes.
+  /// \param[out] theFreeShapes shapes that does not have common subshapes.
   static void combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
                             const GeomAPI_Shape::ShapeType theType,
                             ListOfShape& theCombinedShapes,
                             ListOfShape& theFreeShapes);
 
-  /** \brief Calculates bounding box for theShapes
-   *  \return list of eight points.
-   *  \param[in] theShapes list of shapes.
-   *  \param[in] theEnlarge enlarges bounding box size.
-   */
+  /// \brief Calculates bounding box for theShapes
+  /// \return list of eight points.
+  /// \param[in] theShapes list of shapes.
+  /// \param[in] theEnlarge enlarges bounding box size.
   static std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
 
-  /**
-   * Returns infinite plane received from theFace plane.
-   */
+  /// \return infinite plane received from theFace plane.
   static std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
 
-  /** \brief Enlarges or reduces plane to fit bounding box.
-   *  \return plane that fits to bounding box.
-   *  \param[in] thePlane base plane.
-   *  \param[in] thePoints bounding box points (shoud be eight).
-   */
+  /// \brief Enlarges or reduces plane to fit bounding box.
+  /// \return plane that fits to bounding box.
+  /// \param[in] thePlane base plane.
+  /// \param[in] thePoints bounding box points (shoud be eight).
   static std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
                                                       const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
 
+  /// \brief Finds the start and end vertices of theShape. theShape can be of the following type:\n
+  /// Vertex: theV1 and theV2 are the same and equal to theShape;\n
+  /// Edge : theV1 is start and theV2 is end vertex;\n
+  /// Wire : theV1 is start vertex of the first edge, theV2 is end vertex of the last edge. If wire
+  /// contains no edges theV1 and theV2 are nullified.\n
+  /// If none of the above theV1 and theV2 are nullified.
+  static void findBounds(const std::shared_ptr<GeomAPI_Shape> theShape,
+                         std::shared_ptr<GeomAPI_Vertex>& theV1,
+                         std::shared_ptr<GeomAPI_Vertex>& theV2);
+
 };
 
 #endif
index 6c9f54bc7e19aef6fbf5d27fb8e665e580cc5ffc..f82daf66d2ee4dbac4bf27e1e41bc56d9bd05511 100644 (file)
@@ -35,6 +35,7 @@
   #include "GeomAlgoAPI_Transform.h"
   #include "GeomAlgoAPI_PaveFiller.h"
   #include "GeomAlgoAPI_Intersection.h"
+  #include "GeomAlgoAPI_Pipe.h"
 
   #include <memory>
   #include <string>
index af20eedc4c250afe68b591f44450f8404d260664..c0f6b1cba8b86176c6c2fe8d12d58ef7b197f997 100644 (file)
@@ -19,6 +19,7 @@ SET(PROJECT_HEADERS
     GeomValidators_Different.h
     GeomValidators_BooleanSelection.h
     GeomValidators_IntersectionSelection.h
+    GeomValidators_BaseForGeneration.h
 )
 
 SET(PROJECT_SOURCES
@@ -37,6 +38,7 @@ SET(PROJECT_SOURCES
     GeomValidators_Different.cpp
     GeomValidators_BooleanSelection.cpp
     GeomValidators_IntersectionSelection.cpp
+    GeomValidators_BaseForGeneration.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomValidators/GeomValidators_BaseForGeneration.cpp b/src/GeomValidators/GeomValidators_BaseForGeneration.cpp
new file mode 100644 (file)
index 0000000..7ef5502
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomValidators_BaseForGeneration.cpp
+// Created:     18 March 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomValidators_BaseForGeneration.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <algorithm>
+
+//=================================================================================================
+bool GeomValidators_BaseForGeneration::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 GeomValidators_BaseForGeneration::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;
+    }
+
+    // Getting feature.
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
+    if(!aFeature.get()) {
+      theError = "Empty feature.";
+      return false;
+    }
+
+    // Checking feature kind.
+    std::string aFeatureKind = aFeature->getKind();
+    if(aFeatureKind == "Axis" ||
+       aFeatureKind == "Plane") {
+      theError = "Shape from feature \"" + aFeatureKind +"\" is not allowed for selection.";
+      return false;
+    }
+
+    GeomShapePtr aShape = anAttr->value();
+    GeomShapePtr aContextShape = aContext->shape();
+    if(!aShape.get()) {
+      aShape = aContextShape;
+    }
+    if(!aShape.get()) {
+      theError = "Empty shape selected";
+      return false;
+    }
+
+    if(aFeatureKind == "Sketch") {
+      if(aShape->isEqual(aContextShape)) {
+        // Whole sketch selected. Check that it have faces.
+        ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+        if(aConstruction->facesNum() == 0) {
+          theError = "Selected sketch does not have faces.";
+          return false;
+        }
+      } else {
+        // Shape on sketch selected. Check that it is a face.
+        if(aShape->shapeType() != GeomAPI_Shape::FACE) {
+          theError = "Selected shape has unacceptable type. Acceptable types are: faces on sketch, \
+                      whole sketch(if it has at least one face), and following objects: vertex, edge, wire, face.";
+          return false;
+        }
+      }
+    } else {
+      if(!aShape->isEqual(aContextShape)) {
+        // Local selection does not allowed.
+        theError = "Selected shape is in the local selection. Only global selection is allowed.";
+        return false;
+      } else {
+        // 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 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
diff --git a/src/GeomValidators/GeomValidators_BaseForGeneration.h b/src/GeomValidators/GeomValidators_BaseForGeneration.h
new file mode 100644 (file)
index 0000000..eebff32
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomValidators_BaseForGeneration.h
+// Created:     18 March 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomValidators_BaseForGeneration_H
+#define GeomValidators_BaseForGeneration_H
+
+#include "GeomValidators.h"
+
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_AttributeValidator.h>
+
+/// \ingroup Validators
+/// 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 GeomValidators_BaseForGeneration : 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.
+  GEOMVALIDATORS_EXPORT 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
index c4af6a2e4b3e2a3075a4d8f22527fcc1302cc7fb..cc8823fedfa615174cd3b82b9251d95f63da0554 100644 (file)
@@ -27,27 +27,27 @@ bool GeomValidators_BooleanSelection::isValid(const AttributePtr& theAttribute,
       theError = "Error: empty attribute selection.";
       return false;
     }
+    ResultPtr aContext = anAttrSelection->context();
+    if(!aContext.get()) {
+      theError = "Error: empty selection context.";
+      return false;
+    }
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
+    if(!aFeature.get()) {
+      theError = "Error: empty feature.";
+      return false;
+    }
+    std::string aFeatureKind = aFeature->getKind();
+    if(aFeatureKind == "Sketch" || 
+        aFeatureKind == "Plane" ||
+        aFeatureKind == "Axis") {
+      theError = "Error: ";
+      theError += aFeatureKind;
+      theError += " shape is not allowed for selection.";
+      return false;
+    }
     std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
     if(!aShape.get()) {
-      ResultPtr aContext = anAttrSelection->context();
-      if(!aContext.get()) {
-        theError = "Error: empty selection context.";
-        return false;
-      }
-      FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
-      if(!aFeature.get()) {
-        theError = "Error: empty feature.";
-        return false;
-      }
-      std::string aFeatureKind = aFeature->getKind();
-      if(aFeatureKind == "Sketch" || 
-         aFeatureKind == "Plane" ||
-         aFeatureKind == "Axis") {
-        theError = "Error: ";
-        theError += aFeatureKind;
-        theError += " shape is not allowed for selection.";
-        return false;
-      }
       aShape = aContext->shape();
     }
     if(!aShape.get()) {
index 824206f632a4de4dfe64c5e12599805b8313c4f3..3cfe3e6ea7e1b52a4af1af9429cb226433bffec5 100644 (file)
@@ -14,6 +14,7 @@
 #include <GeomValidators_ShapeType.h>
 #include <GeomValidators_ZeroOffset.h>
 #include <GeomValidators_IntersectionSelection.h>
+#include <GeomValidators_BaseForGeneration.h>
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
@@ -39,6 +40,7 @@ GeomValidators_Plugin::GeomValidators_Plugin()
   aFactory->registerValidator("GeomValidators_ZeroOffset", new GeomValidators_ZeroOffset);
   aFactory->registerValidator("GeomValidators_BooleanSelection", new GeomValidators_BooleanSelection);
   aFactory->registerValidator("GeomValidators_IntersectionSelection", new GeomValidators_IntersectionSelection);
+  aFactory->registerValidator("GeomValidators_BaseForGeneration", new GeomValidators_BaseForGeneration);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
index 3ba9a1c5035e9f5139d8bdebcf183a16fd8fbbf1..9b0833a4a29605abce6b10cf259f6d95818ec7c4 100644 (file)
@@ -182,7 +182,7 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
 std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
 {
   if (myTmpContext.get() || myTmpSubShape.get()) {
-    return myTmpSubShape;
+    return myTmpSubShape.get() ? myTmpSubShape : myTmpContext->shape();
   }
 
   std::shared_ptr<GeomAPI_Shape> aResult;
index 1d3b8a4d506d48ef85e711e995ad7c75e8568f93..f84c169b2ca90b6e44937d9dee24920f7a01cbf1 100755 (executable)
@@ -307,6 +307,22 @@ void Model_BodyBuilder::generated(const std::shared_ptr<GeomAPI_Shape>& theOldSh
   builder(theTag)->Generated(anOldShape, aNewShape);
   if(!theName.empty()) 
     buildName(theTag, theName);
+  TopAbs_ShapeEnum aGenShapeType = aNewShape.ShapeType();
+  if(aGenShapeType == TopAbs_WIRE || aGenShapeType == TopAbs_SHELL) {
+    TopAbs_ShapeEnum anExplodeShapeType = aGenShapeType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE;
+    const TDF_Label aLabel = builder(theTag)->NamedShape()->Label();
+    int aTag = 1;
+    std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+    for(TopExp_Explorer anExp(aNewShape, anExplodeShapeType); anExp.More(); anExp.Next()) {
+      TDF_Label aChildLabel = aLabel.FindChild(aTag);
+      TNaming_Builder aBuilder(aChildLabel);
+      aBuilder.Generated(anOldShape, anExp.Current());
+      TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
+      aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+      TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
+      aTag++;
+    }
+  }
 }
 
 
@@ -406,7 +422,7 @@ void Model_BodyBuilder::loadAndOrientGeneratedShapes (
 {
   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
   TopTools_MapOfShape aView;
-  bool isBuilt = theName.empty();
+  bool isBuilt = !theName.empty();
   TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
   for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
     const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
@@ -417,15 +433,31 @@ void Model_BodyBuilder::loadAndOrientGeneratedShapes (
     theMS->generated(aRShape, aList);
     std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
     for (; anIt != aLast; anIt++) {
-      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();    
+      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();
       if (theSubShapes.isBound(*anIt)) {
         std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
         aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
       }
       if (!aRoot.IsSame (aNewShape)) {
         builder(theTag)->Generated(aRoot,aNewShape);
-        if(!isBuilt) 
-          buildName(theTag, theName);  
+        if(isBuilt)
+          buildName(theTag, theName);
+      }
+      TopAbs_ShapeEnum aGenShapeType = aNewShape.ShapeType();
+      if(aGenShapeType == TopAbs_WIRE || aGenShapeType == TopAbs_SHELL) {
+        TopAbs_ShapeEnum anExplodeShapeType = aGenShapeType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE;
+        const TDF_Label aLabel = builder(theTag)->NamedShape()->Label();
+        int aTag = 1;
+        std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+        for(TopExp_Explorer anExp(aNewShape, anExplodeShapeType); anExp.More(); anExp.Next()) {
+          TDF_Label aChildLabel = aLabel.FindChild(aTag);
+          TNaming_Builder aBuilder(aChildLabel);
+          aBuilder.Generated(aRoot, anExp.Current());
+          TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
+          aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+          TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
+          aTag++;
+        }
       }
     }
   }
index cd7a245704901335e12d486384599f693f0f7955..ff09bfce36743067e33ee04ce4421616b281e3be 100644 (file)
@@ -97,5 +97,9 @@
      <file>icons/intersection_point.png</file>
      <file>icons/intersection.png</file>
      <file>icons/move_to_end.png</file>
+     <file>icons/pipe.png</file>
+     <file>icons/pipe_simple_32x32.png</file>
+     <file>icons/pipe_binormal_32x32.png</file>
+     <file>icons/pipe_locations_32x32.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/pipe.png b/src/PartSet/icons/pipe.png
new file mode 100644 (file)
index 0000000..7938744
Binary files /dev/null and b/src/PartSet/icons/pipe.png differ
diff --git a/src/PartSet/icons/pipe_binormal_32x32.png b/src/PartSet/icons/pipe_binormal_32x32.png
new file mode 100644 (file)
index 0000000..b262ec9
Binary files /dev/null and b/src/PartSet/icons/pipe_binormal_32x32.png differ
diff --git a/src/PartSet/icons/pipe_locations_32x32.png b/src/PartSet/icons/pipe_locations_32x32.png
new file mode 100644 (file)
index 0000000..5e384ce
Binary files /dev/null and b/src/PartSet/icons/pipe_locations_32x32.png differ
diff --git a/src/PartSet/icons/pipe_simple_32x32.png b/src/PartSet/icons/pipe_simple_32x32.png
new file mode 100644 (file)
index 0000000..7938744
Binary files /dev/null and b/src/PartSet/icons/pipe_simple_32x32.png differ