Salome HOME
Task #3015 3.1. To add a mode 'through all' for features ExtrusionCut and ExtrusionFuse
authorjfa <jfa@opencascade.com>
Mon, 28 Oct 2019 11:51:31 +0000 (14:51 +0300)
committerjfa <jfa@opencascade.com>
Mon, 28 Oct 2019 11:51:31 +0000 (14:51 +0300)
21 files changed:
src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp
src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h
src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h
src/FeaturesPlugin/Test/TestExtrusionCut_ThroughAll.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestExtrusionFuse_ThroughAll.py [new file with mode: 0644]
src/FeaturesPlugin/doc/extrusionFuseFeature.rst
src/FeaturesPlugin/doc/images/extrusion_fuse_through_all_result.png [new file with mode: 0644]
src/FeaturesPlugin/extrusioncut_widget.xml
src/FeaturesPlugin/extrusionfuse_widget.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.h [new file with mode: 0644]

index 934a9ae02e0c35113e8d653070896dbb6fd9f227..af4102734031cc1e34379f6061a6b9cfd9292c4e 100644 (file)
@@ -155,6 +155,8 @@ void FeaturesAPI_ExtrusionBoolean::dump(ModelHighAPI_Dumper& theDumper) const
 
     theDumper << ", " << anAttrToObject << ", " << anAttrToOffset <<
       ", " << anAttrFromObject << ", " << anAttrFromOffset;
+  } else {
+    // Through all
   }
 
   AttributeSelectionListPtr anAttrBoolObjects =
@@ -183,6 +185,20 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
   initialize();
 }
 
+//==================================================================================================
+FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+: FeaturesAPI_ExtrusionBoolean(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_THROUGH_ALL(), mycreationMethod);
+    setBooleanObjects(theBooleanObjects);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
   const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -198,6 +214,22 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
   }
 }
 
+//==================================================================================================
+FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+  const ModelHighAPI_Selection& theDirection,
+  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+: FeaturesAPI_ExtrusionBoolean(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_THROUGH_ALL(), mycreationMethod);
+    setBooleanObjects(theBooleanObjects);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
   const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -287,6 +319,17 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut(
   }
 }
 
+//==================================================================================================
+ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    thePart->addFeature(FeaturesPlugin_ExtrusionCut::ID());
+  return ExtrusionCutPtr(new FeaturesAPI_ExtrusionCut(aFeature, theBaseObjects,
+                                                      theBooleanObjects));
+}
+
 //==================================================================================================
 ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
                                 const std::list<ModelHighAPI_Selection>& theBaseObjects,
@@ -299,6 +342,18 @@ ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePar
                                                       theSize, theBooleanObjects));
 }
 
+//==================================================================================================
+ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                const ModelHighAPI_Selection& theDirection,
+                                const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    thePart->addFeature(FeaturesPlugin_ExtrusionCut::ID());
+  return ExtrusionCutPtr(new FeaturesAPI_ExtrusionCut(aFeature, theBaseObjects, theDirection,
+                                                      theBooleanObjects));
+}
+
 //==================================================================================================
 ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
                                 const std::list<ModelHighAPI_Selection>& theBaseObjects,
@@ -394,6 +449,20 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
   initialize();
 }
 
+//==================================================================================================
+FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+: FeaturesAPI_ExtrusionBoolean(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_THROUGH_ALL(), mycreationMethod);
+    setBooleanObjects(theBooleanObjects);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
   const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -409,6 +478,22 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
   }
 }
 
+//==================================================================================================
+FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+  const ModelHighAPI_Selection& theDirection,
+  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+: FeaturesAPI_ExtrusionBoolean(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theBaseObjects, mybaseObjects);
+    fillAttribute(theDirection, mydirection);
+    fillAttribute(FeaturesPlugin_Extrusion::CREATION_METHOD_THROUGH_ALL(), mycreationMethod);
+    setBooleanObjects(theBooleanObjects);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
   const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -498,6 +583,17 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse(
   }
 }
 
+//==================================================================================================
+ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    thePart->addFeature(FeaturesPlugin_ExtrusionFuse::ID());
+  return ExtrusionFusePtr(new FeaturesAPI_ExtrusionFuse(aFeature, theBaseObjects,
+                                                        theBooleanObjects));
+}
+
 //==================================================================================================
 ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
                                   const std::list<ModelHighAPI_Selection>& theBaseObjects,
@@ -510,6 +606,18 @@ ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& theP
                                                         theSize, theBooleanObjects));
 }
 
+//==================================================================================================
+ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                  const ModelHighAPI_Selection& theDirection,
+                                  const std::list<ModelHighAPI_Selection>& theBooleanObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    thePart->addFeature(FeaturesPlugin_ExtrusionFuse::ID());
+  return ExtrusionFusePtr(new FeaturesAPI_ExtrusionFuse(aFeature, theBaseObjects,
+                                                        theDirection, theBooleanObjects));
+}
+
 //==================================================================================================
 ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
                                   const std::list<ModelHighAPI_Selection>& theBaseObjects,
index 42a4791195bcdabcdc8e9b4776fe5b2598e1ab68..c5777d3192130c161619a5ca0a1fbdfcedf1d507 100644 (file)
@@ -130,6 +130,12 @@ public:
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature);
 
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                    const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -137,6 +143,13 @@ public:
                                     const ModelHighAPI_Double& theSize,
                                     const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                    const ModelHighAPI_Selection& theDirection,
+                                    const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -187,6 +200,13 @@ public:
 /// Pointer on ExtrusionCut object.
 typedef std::shared_ptr<FeaturesAPI_ExtrusionCut> ExtrusionCutPtr;
 
+/// \ingroup CPPHighAPI
+/// \brief Create ExtrusionCut feature.
+FEATURESAPI_EXPORT
+ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
 /// \ingroup CPPHighAPI
 /// \brief Create ExtrusionCut feature.
 FEATURESAPI_EXPORT
@@ -195,6 +215,14 @@ ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePar
                                 const ModelHighAPI_Double& theSize,
                                 const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+/// \ingroup CPPHighAPI
+/// \brief Create ExtrusionCut feature.
+FEATURESAPI_EXPORT
+ExtrusionCutPtr addExtrusionCut(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                const ModelHighAPI_Selection& theDirection,
+                                const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
 /// \ingroup CPPHighAPI
 /// \brief Create ExtrusionCut feature.
 FEATURESAPI_EXPORT
@@ -259,6 +287,12 @@ public:
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr<ModelAPI_Feature>& theFeature);
 
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                     const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -266,6 +300,13 @@ public:
                                      const ModelHighAPI_Double& theSize,
                                      const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                     const ModelHighAPI_Selection& theDirection,
+                                     const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -316,6 +357,13 @@ public:
 /// Pointer on ExtrusionFuse object.
 typedef std::shared_ptr<FeaturesAPI_ExtrusionFuse> ExtrusionFusePtr;
 
+/// \ingroup CPPHighAPI
+/// \brief Create ExtrusionFuse feature.
+FEATURESAPI_EXPORT
+ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                  const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
 /// \ingroup CPPHighAPI
 /// \brief Create ExtrusionFuse feature.
 FEATURESAPI_EXPORT
@@ -324,6 +372,14 @@ ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& theP
                                   const ModelHighAPI_Double& theSize,
                                   const std::list<ModelHighAPI_Selection>& theBooleanObjects);
 
+/// \ingroup CPPHighAPI
+/// \brief Create ExtrusionFuse feature.
+FEATURESAPI_EXPORT
+ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                                  const ModelHighAPI_Selection& theDirection,
+                                  const std::list<ModelHighAPI_Selection>& theBooleanObjects);
+
 /// \ingroup CPPHighAPI
 /// \brief Create ExtrusionFuse feature.
 FEATURESAPI_EXPORT
index 5316c8c07fac08f0201e56c69896e943a6c91307..224e940847ea804c34f912c8e7e64793b78c83cd 100644 (file)
@@ -178,9 +178,11 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestExtrusionCut_BySize.py
                TestExtrusionCut_ByPlanesAndOffsets.py
                TestExtrusionCut_ByFaces.py
+               TestExtrusionCut_ThroughAll.py
                TestExtrusionFuse.py
                TestExtrusionFuse_BySize.py
                TestExtrusionFuse_ByPlanesAndOffsets.py
+               TestExtrusionFuse_ThroughAll.py
                TestExtrusion_ErrorMsg.py
                TestExtrusion_ZeroOffsetError.py
                TestExtrusion_ByFaces01.py
index bfcbde007c375efe9356930b07a5597be1e84e97..57b1ba874b20897df91b6a0d5875b18093f244c9 100644 (file)
@@ -101,53 +101,20 @@ bool FeaturesPlugin_Extrusion::makeExtrusions(ListOfShape& theBaseShapes,
   getBaseShapes(theBaseShapes);
 
   //Getting direction.
-  static const std::string aSelectionError = "Error: The direction shape selection is bad.";
-  AttributeSelectionPtr aSelection = selection(DIRECTION_OBJECT_ID());
-  GeomShapePtr aShape = aSelection->value();
-  if (!aShape.get()) {
-    if (aSelection->context().get()) {
-      aShape = aSelection->context()->shape();
-    }
-  }
-
-  GeomEdgePtr anEdge;
-  if (aShape.get()) {
-    if (aShape->isEdge())
-    {
-      anEdge = aShape->edge();
-    }
-    else if (aShape->isCompound())
-    {
-      GeomAPI_ShapeIterator anIt(aShape);
-      anEdge = anIt.current()->edge();
-    }
-  }
-
   std::shared_ptr<GeomAPI_Dir> aDir;
-  if(anEdge.get()) {
-    if(anEdge->isLine()) {
-      aDir = anEdge->line()->direction();
-    }
-  }
+  getDirection(aDir);
 
   // Getting sizes.
   double aToSize = 0.0;
   double aFromSize = 0.0;
-
-  if(string(CREATION_METHOD())->value() == CREATION_METHOD_BY_SIZES()) {
-    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();
-  }
+  getSizes(aToSize, aFromSize);
 
   // Getting bounding planes.
   GeomShapePtr aToShape;
   GeomShapePtr aFromShape;
 
   if(string(CREATION_METHOD())->value() == CREATION_METHOD_BY_PLANES()) {
-    aSelection = selection(TO_OBJECT_ID());
+    AttributeSelectionPtr aSelection = selection(TO_OBJECT_ID());
     if(aSelection.get()) {
       aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aSelection->value());
       if(!aToShape.get() && aSelection->context().get()) {
@@ -214,3 +181,48 @@ void FeaturesPlugin_Extrusion::storeResultWithBoundaries(
 
   setResult(aResultBody, theIndex);
 }
+
+//=================================================================================================
+void FeaturesPlugin_Extrusion::getDirection(std::shared_ptr<GeomAPI_Dir>& theDir)
+{
+  static const std::string aSelectionError = "Error: The direction shape selection is bad.";
+  AttributeSelectionPtr aSelection = selection(DIRECTION_OBJECT_ID());
+  GeomShapePtr aShape = aSelection->value();
+  if (!aShape.get()) {
+    if (aSelection->context().get()) {
+      aShape = aSelection->context()->shape();
+    }
+  }
+
+  GeomEdgePtr anEdge;
+  if (aShape.get()) {
+    if (aShape->isEdge())
+    {
+      anEdge = aShape->edge();
+    }
+    else if (aShape->isCompound())
+    {
+      GeomAPI_ShapeIterator anIt(aShape);
+      anEdge = anIt.current()->edge();
+    }
+  }
+
+  if (anEdge.get()) {
+    if (anEdge->isLine()) {
+      theDir = anEdge->line()->direction();
+    }
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_Extrusion::getSizes(double& theToSize, double& theFromSize)
+{
+  if (string(CREATION_METHOD())->value() == CREATION_METHOD_BY_SIZES()) {
+    theToSize = real(TO_SIZE_ID())->value();
+    theFromSize = real(FROM_SIZE_ID())->value();
+  } if (string(CREATION_METHOD())->value() == CREATION_METHOD_BY_PLANES()) {
+    theToSize = real(TO_OFFSET_ID())->value();
+    theFromSize = real(FROM_OFFSET_ID())->value();
+  } else {
+  }
+}
index d0a6e374530dcb3d161aa2397426660cb74691a1..7a80cc5875570c0f754bb9d10601ca8d0646e7c0 100644 (file)
@@ -67,6 +67,13 @@ public:
     return MY_CREATION_METHOD_ID;
   }
 
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_THROUGH_ALL()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ThroughAll");
+    return MY_CREATION_METHOD_ID;
+  }
+
   /// Attribute name of an object to which the extrusion grows.
   inline static const std::string& DIRECTION_OBJECT_ID()
   {
@@ -144,6 +151,12 @@ protected:
                                  const ListOfShape& theBoundaryShapes,
                                  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
                                  const int theIndex = 0);
+
+  /// Retrieve direction argument.
+  void getDirection(std::shared_ptr<GeomAPI_Dir>& theDir);
+
+  /// Retrieve or calculate prism sizes.
+  virtual void getSizes(double& theToSize, double& theFromSize);
 };
 
 #endif
index edbdcf948aaeefa4c9a8c490237543c7a5eee256..7075175e3e40d71205c2945eb2bb9fd8497ea9dc 100644 (file)
 
 #include "FeaturesPlugin_ExtrusionBoolean.h"
 
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
 //=================================================================================================
 void FeaturesPlugin_ExtrusionBoolean::initAttributes()
 {
@@ -42,3 +47,35 @@ void FeaturesPlugin_ExtrusionBoolean::storeGenerationHistory(ResultBodyPtr theRe
 {
   FeaturesPlugin_Extrusion::storeGenerationHistory(theResultBody, theBaseShape, theMakeShape);
 }
+
+//=================================================================================================
+void FeaturesPlugin_ExtrusionBoolean::getSizes(double& theToSize, double& theFromSize)
+{
+  if (string(CREATION_METHOD())->value() != CREATION_METHOD_THROUGH_ALL()) {
+    FeaturesPlugin_Extrusion::getSizes(theToSize, theFromSize);
+  } else {
+    // Getting objects.
+    ListOfShape anObjects;
+    AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID());
+    for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+      AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+      GeomShapePtr anObject = anObjectAttr->value();
+      if (!anObject.get()) {
+        myFeature->setError("Error: Could not get object.");
+        return;
+      }
+      anObjects.push_back(anObject);
+    }
+
+    // Getting prism bases.
+    ListOfShape aBaseShapes;
+    getBaseShapes(aBaseShapes);
+
+    // Getting prism direction.
+    std::shared_ptr<GeomAPI_Dir> aDir;
+    getDirection(aDir);
+
+    // Calculate sizes
+    GeomAlgoAPI_ShapeTools::computeThroughAll(anObjects, aBaseShapes, aDir, theToSize, theFromSize);
+  }
+}
index ee575471bf4ff6f92d3260e208671fa9e9938a82..ee624029b74738f9411e38db98ca51b9efadf092 100644 (file)
@@ -44,6 +44,10 @@ protected:
   void storeGenerationHistory(ResultBodyPtr theResultBody,
                               const GeomShapePtr theBaseShape,
                               const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
+  /// Calculate prism sizes to ensure that it passes through all objects
+  /// Redefined from FeaturesPlugin_Extrusion
+  virtual void getSizes(double& theToSize, double& theFromSize);
 };
 
 #endif
index 52461e30388f73559141f7991b4d2e94fd942d26..a50ec376897ae6168498a0e36213ab781d8ae743 100644 (file)
 
 #include "FeaturesPlugin_ExtrusionFuse.h"
 
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeSelectionList.h>
+
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_Prism.h>
+#include <GeomAlgoAPI_ThroughAll.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
+
 //=================================================================================================
 FeaturesPlugin_ExtrusionFuse::FeaturesPlugin_ExtrusionFuse()
 {
@@ -29,5 +37,127 @@ FeaturesPlugin_ExtrusionFuse::FeaturesPlugin_ExtrusionFuse()
 //=================================================================================================
 void FeaturesPlugin_ExtrusionFuse::execute()
 {
-  executeCompositeBoolean();
+  if (string(CREATION_METHOD())->value() != CREATION_METHOD_THROUGH_ALL())
+    executeCompositeBoolean();
+  else {
+    executeFuseThroughAll();
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_ExtrusionFuse::executeFuseThroughAll()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID());
+  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    GeomShapePtr anObject = anObjectAttr->value();
+    if (!anObject.get()) {
+      myFeature->setError("Error: Could not get object.");
+      return;
+    }
+    anObjects.push_back(anObject);
+  }
+
+  // Make generation.
+  ListOfShape aGenBaseShapes;
+  ListOfMakeShape aGenMakeShapes;
+  if (!makeGeneration(aGenBaseShapes, aGenMakeShapes)) {
+    return;
+  }
+
+  // Getting tools.
+  ListOfShape aNewTools;
+  ListOfMakeShape aToolsMakeShapes;
+  for (ListOfMakeShape::const_iterator
+         anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) {
+    GeomMakeShapePtr anAlgo = (*anIt);
+    std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_Prism>(anAlgo);
+
+    // Cut the prism by all objects and throw away end pieces
+    std::shared_ptr<GeomAlgoAPI_ThroughAll> aToolAlgo (new GeomAlgoAPI_ThroughAll(aPrismAlgo, anObjects));
+
+    // Checking that the algorithm worked properly
+    if (!aToolAlgo->isDone() || aToolAlgo->shape()->isNull() || !aToolAlgo->isValid()) {
+      myFeature->setError("Error: ThroughAll algorithm failed.");
+    } else {
+      GeomShapePtr aCuttedTool = aToolAlgo->shape();
+      aNewTools.push_back(aCuttedTool);
+      aToolsMakeShapes.push_back(aToolAlgo);
+    }
+  }
+
+  // Perform FeaturesPlugin_CompositeBoolean::makeBoolean() with new (cutted) tools
+  ListOfShape aBooleanObjects;
+  ListOfMakeShape aBooleanMakeShapes;
+  if (!makeBoolean(aNewTools, aBooleanObjects, aBooleanMakeShapes)) {
+    return;
+  }
+
+  if (myOperationType == BOOL_FUSE) {
+    aNewTools.splice(aNewTools.begin(), aBooleanObjects);
+    aBooleanObjects.splice(aBooleanObjects.begin(), aNewTools, aNewTools.begin());
+  }
+
+  // 4. Store result (like in FeaturesPlugin_CompositeBoolean::executeCompositeBoolean())
+  int aResultIndex = 0;
+  std::vector<ResultBaseAlgo> aResultBaseAlgoList;
+  ListOfShape aResultShapesList;
+  ListOfShape::const_iterator aBoolObjIt = aBooleanObjects.cbegin();
+  ListOfMakeShape::const_iterator aBoolMSIt = aBooleanMakeShapes.cbegin();
+  for(; aBoolObjIt != aBooleanObjects.cend() && aBoolMSIt != aBooleanMakeShapes.cend();
+      ++aBoolObjIt, ++aBoolMSIt) {
+
+    ResultBodyPtr aResultBody = myFeature->document()->createBody(myFeature->data(), aResultIndex);
+
+    if((*aBoolObjIt)->isEqual((*aBoolMSIt)->shape())) {
+      aResultBody->store((*aBoolMSIt)->shape(), false);
+    }
+    else
+    {
+      aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape());
+
+      // Store generation history.
+      ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin();
+      ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin();
+      for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend();
+          ++aGenBaseIt, ++aGenMSIt) {
+
+        // ???
+        ListOfMakeShape::const_iterator aToolsMSIt = aToolsMakeShapes.cbegin();
+        for(; aToolsMSIt != aToolsMakeShapes.cend(); ++aToolsMSIt) {
+          std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMSList(new GeomAlgoAPI_MakeShapeList());
+
+          // prism generation
+          aMSList->appendAlgo(*aGenMSIt);
+
+          // tool modification (cut by objects)
+          aMSList->appendAlgo(*aToolsMSIt);
+
+          // bool fuse
+          aMSList->appendAlgo(*aBoolMSIt);
+          storeGenerationHistory(aResultBody, *aGenBaseIt, aMSList);
+        }
+      }
+
+      storeModificationHistory(aResultBody, *aBoolObjIt, aNewTools, *aBoolMSIt);
+
+      ResultBaseAlgo aRBA;
+      aRBA.resultBody = aResultBody;
+      aRBA.baseShape = *aBoolObjIt;
+      aRBA.makeShape = *aBoolMSIt;
+      aResultBaseAlgoList.push_back(aRBA);
+      aResultShapesList.push_back((*aBoolMSIt)->shape());
+    }
+
+    myFeature->setResult(aResultBody, aResultIndex++);
+  }
+
+  // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
+  // result shape has been deleted, but in another it was modified or stayed.
+  GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
+  storeDeletedShapes(aResultBaseAlgoList, aNewTools, aResultShapesCompound);
+
+  myFeature->removeResults(aResultIndex);
 }
index 55f5a671ee1a1f2fe3705f285a127cb991d6d308..a2daea88a44c51a251be0dc499987d4d58b7ded3 100644 (file)
@@ -28,7 +28,7 @@
 ///        fuse result with other objects in a single operation.
 class FeaturesPlugin_ExtrusionFuse : public FeaturesPlugin_ExtrusionBoolean
 {
-public:
+ public:
   /// Use plugin manager for features creation.
   FeaturesPlugin_ExtrusionFuse();
 
@@ -48,6 +48,9 @@ public:
 
   /// Creates a new part document if needed.
   FEATURESPLUGIN_EXPORT virtual void execute();
+
+ private:
+  void executeFuseThroughAll();
 };
 
 #endif
diff --git a/src/FeaturesPlugin/Test/TestExtrusionCut_ThroughAll.py b/src/FeaturesPlugin/Test/TestExtrusionCut_ThroughAll.py
new file mode 100644 (file)
index 0000000..ce66b25
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (C) 2018-2019  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from GeomAPI import *
+
+import math
+
+def checkMiddlePoint(shape, x, y, z, tolerance = 1.e-7):
+    assert(shape is not None)
+    middlePoint = shape.middlePoint()
+    assert(math.fabs(middlePoint.x() - x) < tolerance), "{} != {}".format(middlePoint.x(), x)
+    assert(math.fabs(middlePoint.y() - y) < tolerance), "{} != {}".format(middlePoint.y(), y)
+    assert(math.fabs(middlePoint.z() - z) < tolerance), "{} != {}".format(middlePoint.z(), z)
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Axis_1 = model.addAxis(Part_1_doc, 0, -10, 10)
+
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), [model.selection("SOLID", "Box_1_1")])
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Left"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchCircle_1 = Sketch_1.addCircle(5, 10, 2)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchCircle_1.center())
+ExtrusionCut_1.setNestedSketch(Sketch_1)
+model.do()
+Shape = ExtrusionCut_1.results()[0].resultSubShapePair()[0].shape()
+checkMiddlePoint(Shape, 5.0, 5.0, 4.97049495)
+
+ExtrusionCut_1.setDirection(model.selection("EDGE", "Axis_1"))
+model.do()
+Shape = ExtrusionCut_1.results()[0].resultSubShapePair()[0].shape()
+checkMiddlePoint(Shape, 4.99796028, 5.00196717, 4.97487226)
+
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], [model.selection("SOLID", "ExtrusionCut_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Front"))
+SketchCircle_2 = Sketch_2.addCircle(2, 7, 1.5)
+ExtrusionCut_2.setNestedSketch(Sketch_2)
+model.do()
+
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [], [model.selection("SOLID", "ExtrusionCut_2_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modified_Face&Box_1_1/Front"))
+SketchCircle_3 = Sketch_3.addCircle(7, 2, 1.5)
+ExtrusionCut_3.setNestedSketch(Sketch_3)
+model.do()
+Shape = ExtrusionCut_3.results()[0].resultSubShapePair()[0].shape()
+checkMiddlePoint(Shape, 4.99787246, 4.92218515, 4.91081244)
+
+model.end()
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/TestExtrusionFuse_ThroughAll.py b/src/FeaturesPlugin/Test/TestExtrusionFuse_ThroughAll.py
new file mode 100644 (file)
index 0000000..e84a50b
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (C) 2018-2019  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from GeomAPI import *
+
+import math
+
+def checkMiddlePoint(shape, x, y, z, tolerance = 1.e-7):
+    assert(shape is not None)
+    middlePoint = shape.middlePoint()
+    assert(math.fabs(middlePoint.x() - x) < tolerance), "{} != {}".format(middlePoint.x(), x)
+    assert(math.fabs(middlePoint.y() - y) < tolerance), "{} != {}".format(middlePoint.y(), y)
+    assert(math.fabs(middlePoint.z() - z) < tolerance), "{} != {}".format(middlePoint.z(), z)
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Box_3 = model.addBox(Part_1_doc, 20, 20, 20)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_2_1")], 20, 10, 0)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], 40, 20, 0)
+Edge_1 = model.addEdge(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Translation_2_1/MF:Translated&Box_3_1/Front][Translation_2_1/MF:Translated&Box_3_1/Right][Translation_2_1/MF:Translated&Box_3_1/Top]"))
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Back"))
+SketchCircle_1 = Sketch_1.addCircle(2.134236344973221, -2.430731739079631, 1.564909384334321)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")])
+ExtrusionFuse_1_objects_2 = [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("SOLID", "Translation_2_1")]
+ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "Edge_1_1"), ExtrusionFuse_1_objects_2)
+
+model.do()
+Shape = ExtrusionFuse_1.results()[0].resultSubShapePair()[0].shape()
+checkMiddlePoint(Shape, 37.46245068, 23.05267081, 8.52187757)
+
+model.end()
+
+assert(model.checkPythonDump())
index 65d971a871b21f82f4358dd120fbcacf9c3ad18c..59d49043e4fb252d961d51e94d3a7bbc0a64a045 100644 (file)
@@ -18,7 +18,7 @@ The following property panel will be opened:
 .. centered::
   Start sketch
 
-There are two variants of the property panel for Extrusion Fuse depending on the chosen option:
+There are three variants of the property panel for Extrusion Fuse depending on the chosen option:
 
 .. image:: images/extrusion_by_sizes.png
    :align: left
@@ -28,6 +28,10 @@ There are two variants of the property panel for Extrusion Fuse depending on the
    :align: left
 **By Bounding Planes** extrudes objects by specifying bounding planes and offsets.
 
+.. image:: images/extrusion_through_all.png
+   :align: left
+**Through All** extrudes base objects to pass through all objects fuse with.
+
 
 By sizes
 --------
@@ -149,3 +153,46 @@ The Result of the operation will be an extruded shape:
    **Extrusion Fuse created**
 
 **See Also** a sample TUI Script of :ref:`tui_create_extrusion_fuse_by_bounding_planes` operation.
+
+Through all
+-----------
+
+.. image:: images/ExtrusionFuse3.png
+  :align: center
+
+.. centered::
+  Extrusion Fuse: definition through all objects
+
+- **Base objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be extruded.
+- **Axis** - if selected, it will be the direction of extrusion, otherwise objects normals will be used.
+- **Fuse with** - contains a list of objects which will be fused with the result of extrusion.
+
+**TUI Commands**:
+
+.. py:function:: model.addExtrusionFuse(part, objectsToExtrude, objectsToFuse)
+
+    :param part: The current part object.
+    :param list: A list of objects for extrusion.
+    :param list: A list of objects to fuse with.
+    :return: Created object.
+
+.. py:function:: model.addExtrusionFuse(part, objectsToExtrude, direction, objectsToFuse)
+
+    :param part: The current part object.
+    :param list: A list of objects for extrusion.
+    :param object: A direction of extrusion
+    :param list: A list of objects to fuse with.
+    :return: Created object.
+
+Result
+""""""
+
+The Result of the operation will be an extruded shape:
+
+.. image:: images/extrusion_fuse_through_all_result.png
+          :align: center
+
+.. centered::
+   **Extrusion Fuse created**
+
+**See Also** a sample TUI Script of :ref:`tui_create_extrusion_fuse_through_all` operation.
diff --git a/src/FeaturesPlugin/doc/images/extrusion_fuse_through_all_result.png b/src/FeaturesPlugin/doc/images/extrusion_fuse_through_all_result.png
new file mode 100644 (file)
index 0000000..d043450
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/extrusion_fuse_through_all_result.png differ
index c8561193e7c5879980a62224f52b4d6385c44cf7..bbbf73dd86acfdb799be51dc52b2ae2f5c7d63d4 100644 (file)
@@ -83,6 +83,8 @@
           </doublevalue>
         </groupbox>
       </box>
+      <box id="ThroughAll" title="Through all" icon="icons/Features/extrusion_throughall_32x32.png">
+      </box>
     </toolbox>
   </groupbox>
   <multi_selector id="main_objects"
index b0c18a5c4d981744eb6f254aadf17ea394058c08..5e9d7355698c63a689089848627233e0230331e6 100644 (file)
@@ -83,6 +83,8 @@
           </doublevalue>
         </groupbox>
       </box>
+      <box id="ThroughAll" title="Through all" icon="icons/Features/extrusion_throughall_32x32.png">
+      </box>
     </toolbox>
   </groupbox>
   <multi_selector id="main_objects"
index 460aebe7e4b16a1a9794b0e7b4361c752e4fc617..33f39251f7a0efa17bea2345f5fbf602941347a6 100644 (file)
@@ -33,6 +33,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Prism.h
     GeomAlgoAPI_Revolution.h
     GeomAlgoAPI_Boolean.h
+    GeomAlgoAPI_ThroughAll.h
     GeomAlgoAPI_Rotation.h
     GeomAlgoAPI_Translation.h
     GeomAlgoAPI_MakeShape.h
@@ -94,6 +95,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Prism.cpp
     GeomAlgoAPI_Revolution.cpp
     GeomAlgoAPI_Boolean.cpp
+    GeomAlgoAPI_ThroughAll.cpp
     GeomAlgoAPI_Rotation.cpp
     GeomAlgoAPI_Translation.cpp
     GeomAlgoAPI_MakeShape.cpp
index 32224162bc0d10a1d38f0f3571be27ded0212f2e..1b07fabae681eb16649c8339cbc421c83683972a 100644 (file)
@@ -51,7 +51,7 @@ public:
 
   /// Redefinition of the generic method for the Fuse problem: OCCT 30481
   GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape,
-    ListOfShape& theNewShapes);
+                                           ListOfShape& theNewShapes);
 
 private:
   /// Builds resulting shape.
index d1d3abe8b5317f5b03ee1e892e3e19c53f65b07f..71426779d1f35c582a94a430a84aaaee21f300c5 100644 (file)
 #include <GeomAPI_Wire.h>
 
 #include <Bnd_Box.hxx>
+
+#include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
-#include <BRepAdaptor_Curve.hxx>
 #include <BRepAlgo.hxx>
 #include <BRepAlgo_FaceRestrictor.hxx>
+#include <BRepAdaptor_Curve.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepExtrema_ExtCF.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <BRepClass_FaceClassifier.hxx>
+#include <BRepLib_CheckCurveOnSurface.hxx>
+
+#include <BOPAlgo_Builder.hxx>
+
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_Curve.hxx>
-#include <BRepLib_CheckCurveOnSurface.hxx>
-#include <BRep_Tool.hxx>
-#include  <Geom_CylindricalSurface.hxx>
+
+#include <Geom_CylindricalSurface.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomAPI_ShapeIterator.h>
+
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
 #include <GeomAPI_IntCS.hxx>
+
 #include <gp_Pln.hxx>
 #include <GProp_GProps.hxx>
+
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
-#include <NCollection_Vector.hxx>
+
 #include <ShapeAnalysis.hxx>
 #include <ShapeAnalysis_Surface.hxx>
-#include <TopoDS_Builder.hxx>
+
+#include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <TopoDS.hxx>
+#include <TopoDS_Builder.hxx>
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
 
+#include <TopTools_ListIteratorOfListOfShape.hxx>
 
-#include <BOPAlgo_Builder.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <TopoDS_Edge.hxx>
+#include <NCollection_Vector.hxx>
 
 //==================================================================================================
 static GProp_GProps props(const TopoDS_Shape& theShape)
@@ -1076,6 +1087,7 @@ static TopoDS_Wire fixParametricGaps(const TopoDS_Wire& theWire)
   return aFixedWire;
 }
 
+//==================================================================================================
 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
       const std::shared_ptr<GeomAPI_Wire>& theWire)
 {
@@ -1094,6 +1106,7 @@ std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
   return anEdge;
 }
 
+//==================================================================================================
 ListOfShape GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(const GeomShapePtr& theShape)
 {
   ListOfShape aSubShapes;
@@ -1114,4 +1127,123 @@ ListOfShape GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(const GeomShapePtr& the
   }
 
   return aSubShapes;
-}
\ No newline at end of file
+}
+
+//==================================================================================================
+static void getMinMaxPointsOnLine(const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
+                                  const gp_Dir theDir,
+                                  double& theMin, double& theMax)
+{
+  theMin = RealLast();
+  theMax = RealFirst();
+  // Project bounding points on theDir
+  for (std::list<std::shared_ptr<GeomAPI_Pnt> >::const_iterator
+         aPointsIt = thePoints.begin(); aPointsIt != thePoints.end(); aPointsIt++) {
+    const gp_Pnt& aPnt = (*aPointsIt)->impl<gp_Pnt>();
+    gp_Dir aPntDir (aPnt.XYZ());
+    Standard_Real proj = (theDir*aPntDir) * aPnt.XYZ().Modulus();
+    if (proj < theMin) theMin = proj;
+    if (proj > theMax) theMax = proj;
+  }
+}
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeTools::computeThroughAll(const ListOfShape& theObjects,
+                                               const ListOfShape& theBaseShapes,
+                                               const std::shared_ptr<GeomAPI_Dir> theDir,
+                                               double& theToSize, double& theFromSize)
+{
+  // Bounding box of objects
+  std::list<std::shared_ptr<GeomAPI_Pnt> > aBndObjs = GeomAlgoAPI_ShapeTools::getBoundingBox(theObjects);
+  if (aBndObjs.size() != 8) {
+    return;
+  }
+
+  // Prism direction
+  if (theDir.get()) {
+    // One direction for all prisms
+    gp_Dir aDir = theDir->impl<gp_Dir>();
+
+    // Bounding box of the base
+    std::list<std::shared_ptr<GeomAPI_Pnt> > aBndBases = GeomAlgoAPI_ShapeTools::getBoundingBox(theBaseShapes);
+    if (aBndBases.size() != 8) {
+      return;
+    }
+
+    // Objects bounds
+    Standard_Real lowBnd, upperBnd;
+    getMinMaxPointsOnLine(aBndObjs, aDir, lowBnd, upperBnd);
+
+    // Base bounds
+    Standard_Real lowBase, upperBase;
+    getMinMaxPointsOnLine(aBndBases, aDir, lowBase, upperBase);
+
+    // ----------.-----.---------.--------------.-----------> theDir
+    //       lowBnd   lowBase   upperBase    upperBnd
+
+    theToSize = upperBnd - lowBase;
+    theFromSize = upperBase - lowBnd;
+  } else {
+    // Direction is a normal to each base shape (different normals to bases)
+    // So we calculate own sizes for each base shape
+    theToSize = 0.0;
+    theFromSize = 0.0;
+
+    for (ListOfShape::const_iterator anIt = theBaseShapes.begin(); anIt != theBaseShapes.end(); ++anIt) {
+      const GeomShapePtr& aBaseShape_i = (*anIt);
+      ListOfShape aBaseShapes_i;
+      aBaseShapes_i.push_back(aBaseShape_i);
+
+      // Bounding box of the base
+      std::list<std::shared_ptr<GeomAPI_Pnt> > aBndBases = GeomAlgoAPI_ShapeTools::getBoundingBox(aBaseShapes_i);
+      if (aBndBases.size() != 8) {
+        return;
+      }
+
+      // Direction (normal to aBaseShapes_i)
+      // Code like in GeomAlgoAPI_Prism
+      gp_Dir aDir;
+      const TopoDS_Shape& aBaseShape = aBaseShape_i->impl<TopoDS_Shape>();
+      BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
+      if (aFindPlane.Found() == Standard_True) {
+        Handle(Geom_Plane) aPlane;
+        if (aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) {
+          TopExp_Explorer anExp(aBaseShape, TopAbs_FACE);
+          const TopoDS_Shape& aFace = anExp.Current();
+          Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFace));
+          if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
+              Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
+            aSurface = aTrimSurface->BasisSurface();
+          }
+          if(aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
+            return;
+          }
+          aPlane = Handle(Geom_Plane)::DownCast(aSurface);
+        } else {
+          aPlane = aFindPlane.Plane();
+        }
+        aDir = aPlane->Axis().Direction();
+      } else {
+        return;
+      }
+
+      // Objects bounds
+      Standard_Real lowBnd, upperBnd;
+      getMinMaxPointsOnLine(aBndObjs, aDir, lowBnd, upperBnd);
+
+      // Base bounds
+      Standard_Real lowBase, upperBase;
+      getMinMaxPointsOnLine(aBndBases, aDir, lowBase, upperBase);
+
+      // ----------.-----.---------.--------------.-----------> theDir
+      //       lowBnd   lowBase   upperBase    upperBnd
+
+      double aToSize_i = upperBnd - lowBase;
+      double aFromSize_i = upperBase - lowBnd;
+
+      if (aToSize_i > theToSize) theToSize = aToSize_i;
+      if (aFromSize_i > theFromSize) theFromSize = aFromSize_i;
+    }
+  }
+}
index da415d359c49cbfbe56e0b1e082e0016dceae297..49b3432445b394744ae06d5faa901f6dde0dc01f 100644 (file)
@@ -193,6 +193,17 @@ public:
   /// \param[in] theShape shape that should be exploded
   /// \return list of sub-shapes (vertices, edges, faces, solids)
   GEOMALGOAPI_EXPORT static ListOfShape getLowLevelSubShapes(const GeomShapePtr& theShape);
+
+  /// \brief Calculate prism sizes to ensure that it passes through all objects
+  /// \param[in] theObjects objects to be joined/cutted by the prism
+  /// \param[in] theBaseShapes bases of the prism
+  /// \param[in] theDir direction of the prism
+  /// \param[out] theToSize upper offset of the prism
+  /// \param[out] theFromSize lower offset of the prism
+  GEOMALGOAPI_EXPORT static void computeThroughAll(const ListOfShape& theObjects,
+                                                   const ListOfShape& theBaseShapes,
+                                                   const std::shared_ptr<GeomAPI_Dir> theDir,
+                                                   double& theToSize, double& theFromSize);
 };
 
 #endif
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp
new file mode 100644 (file)
index 0000000..f64ef60
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "GeomAlgoAPI_ThroughAll.h"
+
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <BRep_Builder.hxx>
+#include <BOPAlgo_BOP.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_ThroughAll::GeomAlgoAPI_ThroughAll(std::shared_ptr<GeomAlgoAPI_Prism> thePrismAlgo,
+                                               const ListOfShape& theObjects)
+: GeomAlgoAPI_Boolean(thePrismAlgo->shape(), theObjects, GeomAlgoAPI_Tools::BOOL_CUT)
+{
+  removeEnds(thePrismAlgo);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_ThroughAll::removeEnds(std::shared_ptr<GeomAlgoAPI_Prism> thePrismAlgo)
+{
+  GeomShapePtr aCuttedTool = shape(); // result of BOP Cut (thePrismAlgo->shape() by theObjects)
+
+  // Simplify the result
+  ListOfShape aPieces = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aCuttedTool);
+
+  // Get end shapes of Prism
+  const ListOfShape& fromShapes = thePrismAlgo->fromShapes();
+  const ListOfShape& toShapes = thePrismAlgo->toShapes();
+  ListOfShape endShapes (fromShapes);
+  endShapes.insert(endShapes.end(), toShapes.begin(), toShapes.end());
+
+  // Throw away end pieces of cutted tools (containing endShapes)
+  TopTools_ListOfShape listTools;
+  for (ListOfShape::const_iterator
+         anIt = aPieces.begin(); anIt != aPieces.end(); anIt++) {
+    TopoDS_Shape aPiece = (*anIt)->impl<TopoDS_Shape>();
+    bool endPiece = false;
+
+    for (ListOfShape::const_iterator aBaseIt = endShapes.begin();
+         aBaseIt != endShapes.end() && !endPiece; aBaseIt++) {
+      // Check, if the piece contains aBase (one of endShapes)
+      TopoDS_Shape aBase = (*aBaseIt)->impl<TopoDS_Shape>();
+      TopExp_Explorer anExp (aPiece, aBase.ShapeType());
+      for (; anExp.More() && !endPiece; anExp.Next()) {
+        if (anExp.Current().IsSame(aBase))
+          endPiece = true;
+      }
+    }
+
+    if (!endPiece) {
+      listTools.Append(aPiece);
+    }
+  }
+
+  BRep_Builder aBuilder;
+  TopoDS_Compound aCompound;
+  aBuilder.MakeCompound(aCompound);
+  for (TopTools_ListOfShape::Iterator anIt(listTools); anIt.More(); anIt.Next()) {
+    aBuilder.Add(aCompound, anIt.Value());
+  }
+
+  std::shared_ptr<GeomAPI_Shape> aShape (new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aCompound));
+  this->setShape(aShape);
+  this->setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.h b/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.h
new file mode 100644 (file)
index 0000000..bd54dd7
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef GeomAlgoAPI_ThroughAll_H_
+#define GeomAlgoAPI_ThroughAll_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_Prism.h>
+//#include <GeomAlgoAPI_Tools.h>
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_ThroughAll
+/// \ingroup DataAlgo
+/// \brief Cuts a prism by all given objects, throw away end pieces
+class GeomAlgoAPI_ThroughAll : public GeomAlgoAPI_Boolean
+{
+public:
+
+  /// Constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_ThroughAll (std::shared_ptr<GeomAlgoAPI_Prism> thePrismAlgo,
+                                             const ListOfShape& theObjects);
+
+private:
+  /// Builds resulting shape.
+  void removeEnds (std::shared_ptr<GeomAlgoAPI_Prism> thePrismAlgo);
+};
+
+#endif