From: jfa Date: Mon, 28 Oct 2019 11:51:31 +0000 (+0300) Subject: Task #3015 3.1. To add a mode 'through all' for features ExtrusionCut and ExtrusionFuse X-Git-Tag: V9_5_0a1~167^2~80 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=883ac186ac2c764c6209cb8ea8043e3bcadc3de9;p=modules%2Fshaper.git Task #3015 3.1. To add a mode 'through all' for features ExtrusionCut and ExtrusionFuse --- diff --git a/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp b/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp index 934a9ae02..af4102734 100644 --- a/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp +++ b/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.cpp @@ -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& theFeature, + const std::list& theBaseObjects, + const std::list& 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& theFeature, @@ -198,6 +214,22 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut( } } +//================================================================================================== +FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut( + const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& 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& theFeature, @@ -287,6 +319,17 @@ FeaturesAPI_ExtrusionCut::FeaturesAPI_ExtrusionCut( } } +//================================================================================================== +ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const std::list& theBooleanObjects) +{ + std::shared_ptr aFeature = + thePart->addFeature(FeaturesPlugin_ExtrusionCut::ID()); + return ExtrusionCutPtr(new FeaturesAPI_ExtrusionCut(aFeature, theBaseObjects, + theBooleanObjects)); +} + //================================================================================================== ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, const std::list& theBaseObjects, @@ -299,6 +342,18 @@ ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePar theSize, theBooleanObjects)); } +//================================================================================================== +ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects) +{ + std::shared_ptr aFeature = + thePart->addFeature(FeaturesPlugin_ExtrusionCut::ID()); + return ExtrusionCutPtr(new FeaturesAPI_ExtrusionCut(aFeature, theBaseObjects, theDirection, + theBooleanObjects)); +} + //================================================================================================== ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, const std::list& theBaseObjects, @@ -394,6 +449,20 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse( initialize(); } +//================================================================================================== +FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse( + const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const std::list& 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& theFeature, @@ -409,6 +478,22 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse( } } +//================================================================================================== +FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse( + const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& 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& theFeature, @@ -498,6 +583,17 @@ FeaturesAPI_ExtrusionFuse::FeaturesAPI_ExtrusionFuse( } } +//================================================================================================== +ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const std::list& theBooleanObjects) +{ + std::shared_ptr aFeature = + thePart->addFeature(FeaturesPlugin_ExtrusionFuse::ID()); + return ExtrusionFusePtr(new FeaturesAPI_ExtrusionFuse(aFeature, theBaseObjects, + theBooleanObjects)); +} + //================================================================================================== ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, const std::list& theBaseObjects, @@ -510,6 +606,18 @@ ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& theP theSize, theBooleanObjects)); } +//================================================================================================== +ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects) +{ + std::shared_ptr aFeature = + thePart->addFeature(FeaturesPlugin_ExtrusionFuse::ID()); + return ExtrusionFusePtr(new FeaturesAPI_ExtrusionFuse(aFeature, theBaseObjects, + theDirection, theBooleanObjects)); +} + //================================================================================================== ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, const std::list& theBaseObjects, diff --git a/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h b/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h index 42a479119..c5777d319 100644 --- a/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h +++ b/src/FeaturesAPI/FeaturesAPI_ExtrusionBoolean.h @@ -130,6 +130,12 @@ public: FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr& theFeature); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const std::list& theBooleanObjects); + /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr& theFeature, @@ -137,6 +143,13 @@ public: const ModelHighAPI_Double& theSize, const std::list& theBooleanObjects); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects); + /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionCut(const std::shared_ptr& theFeature, @@ -187,6 +200,13 @@ public: /// Pointer on ExtrusionCut object. typedef std::shared_ptr ExtrusionCutPtr; +/// \ingroup CPPHighAPI +/// \brief Create ExtrusionCut feature. +FEATURESAPI_EXPORT +ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const std::list& theBooleanObjects); + /// \ingroup CPPHighAPI /// \brief Create ExtrusionCut feature. FEATURESAPI_EXPORT @@ -195,6 +215,14 @@ ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePar const ModelHighAPI_Double& theSize, const std::list& theBooleanObjects); +/// \ingroup CPPHighAPI +/// \brief Create ExtrusionCut feature. +FEATURESAPI_EXPORT +ExtrusionCutPtr addExtrusionCut(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects); + /// \ingroup CPPHighAPI /// \brief Create ExtrusionCut feature. FEATURESAPI_EXPORT @@ -259,6 +287,12 @@ public: FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr& theFeature); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const std::list& theBooleanObjects); + /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr& theFeature, @@ -266,6 +300,13 @@ public: const ModelHighAPI_Double& theSize, const std::list& theBooleanObjects); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects); + /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_ExtrusionFuse(const std::shared_ptr& theFeature, @@ -316,6 +357,13 @@ public: /// Pointer on ExtrusionFuse object. typedef std::shared_ptr ExtrusionFusePtr; +/// \ingroup CPPHighAPI +/// \brief Create ExtrusionFuse feature. +FEATURESAPI_EXPORT +ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const std::list& theBooleanObjects); + /// \ingroup CPPHighAPI /// \brief Create ExtrusionFuse feature. FEATURESAPI_EXPORT @@ -324,6 +372,14 @@ ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& theP const ModelHighAPI_Double& theSize, const std::list& theBooleanObjects); +/// \ingroup CPPHighAPI +/// \brief Create ExtrusionFuse feature. +FEATURESAPI_EXPORT +ExtrusionFusePtr addExtrusionFuse(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const ModelHighAPI_Selection& theDirection, + const std::list& theBooleanObjects); + /// \ingroup CPPHighAPI /// \brief Create ExtrusionFuse feature. FEATURESAPI_EXPORT diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 5316c8c07..224e94084 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -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 diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index bfcbde007..57b1ba874 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -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 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(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& 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 { + } +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h index d0a6e3745..7a80cc587 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h @@ -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 theMakeShape, const int theIndex = 0); + + /// Retrieve direction argument. + void getDirection(std::shared_ptr& theDir); + + /// Retrieve or calculate prism sizes. + virtual void getSizes(double& theToSize, double& theFromSize); }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp index edbdcf948..7075175e3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp @@ -19,6 +19,11 @@ #include "FeaturesPlugin_ExtrusionBoolean.h" +#include +#include + +#include + //================================================================================================= 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 aDir; + getDirection(aDir); + + // Calculate sizes + GeomAlgoAPI_ShapeTools::computeThroughAll(anObjects, aBaseShapes, aDir, theToSize, theFromSize); + } +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h index ee575471b..ee624029b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.h @@ -44,6 +44,10 @@ protected: void storeGenerationHistory(ResultBodyPtr theResultBody, const GeomShapePtr theBaseShape, const std::shared_ptr theMakeShape); + + /// Calculate prism sizes to ensure that it passes through all objects + /// Redefined from FeaturesPlugin_Extrusion + virtual void getSizes(double& theToSize, double& theFromSize); }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp index 52461e303..a50ec3768 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.cpp @@ -19,6 +19,14 @@ #include "FeaturesPlugin_ExtrusionFuse.h" +#include +#include + +#include +#include +#include +#include + //================================================================================================= 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 aPrismAlgo = std::dynamic_pointer_cast(anAlgo); + + // Cut the prism by all objects and throw away end pieces + std::shared_ptr 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 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 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); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h index 55f5a671e..a2daea88a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h +++ b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionFuse.h @@ -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 index 000000000..ce66b253f --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusionCut_ThroughAll.py @@ -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 index 000000000..e84a50bbe --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusionFuse_ThroughAll.py @@ -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()) diff --git a/src/FeaturesPlugin/doc/extrusionFuseFeature.rst b/src/FeaturesPlugin/doc/extrusionFuseFeature.rst index 65d971a87..59d49043e 100644 --- a/src/FeaturesPlugin/doc/extrusionFuseFeature.rst +++ b/src/FeaturesPlugin/doc/extrusionFuseFeature.rst @@ -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 index 000000000..d043450a1 Binary files /dev/null and b/src/FeaturesPlugin/doc/images/extrusion_fuse_through_all_result.png differ diff --git a/src/FeaturesPlugin/extrusioncut_widget.xml b/src/FeaturesPlugin/extrusioncut_widget.xml index c8561193e..bbbf73dd8 100644 --- a/src/FeaturesPlugin/extrusioncut_widget.xml +++ b/src/FeaturesPlugin/extrusioncut_widget.xml @@ -83,6 +83,8 @@ + + + + #include + +#include #include -#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -46,40 +49,48 @@ #include #include #include +#include + +#include + #include #include -#include -#include -#include + +#include #include #include +#include + #include #include + #include #include #include + #include #include + #include #include -#include + #include #include -#include + +#include #include #include #include #include #include -#include +#include + #include #include -#include +#include -#include -#include -#include +#include //================================================================================================== 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 GeomAlgoAPI_ShapeTools::wireToEdge( const std::shared_ptr& theWire) { @@ -1094,6 +1106,7 @@ std::shared_ptr 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 >& thePoints, + const gp_Dir theDir, + double& theMin, double& theMax) +{ + theMin = RealLast(); + theMax = RealFirst(); + // Project bounding points on theDir + for (std::list >::const_iterator + aPointsIt = thePoints.begin(); aPointsIt != thePoints.end(); aPointsIt++) { + const gp_Pnt& aPnt = (*aPointsIt)->impl(); + 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 theDir, + double& theToSize, double& theFromSize) +{ + // Bounding box of objects + std::list > 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(); + + // Bounding box of the base + std::list > 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 > 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(); + 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; + } + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index da415d359..49b343244 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -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 theDir, + double& theToSize, double& theFromSize); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp new file mode 100644 index 000000000..f64ef6004 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.cpp @@ -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 +#include + +#include +#include +#include +#include +#include +#include + +//================================================================================================= +GeomAlgoAPI_ThroughAll::GeomAlgoAPI_ThroughAll(std::shared_ptr thePrismAlgo, + const ListOfShape& theObjects) +: GeomAlgoAPI_Boolean(thePrismAlgo->shape(), theObjects, GeomAlgoAPI_Tools::BOOL_CUT) +{ + removeEnds(thePrismAlgo); +} + +//================================================================================================= +void GeomAlgoAPI_ThroughAll::removeEnds(std::shared_ptr 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(); + 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(); + 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 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 index 000000000..bd54dd73c --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ThroughAll.h @@ -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 +#include +#include +//#include + +#include + +/// \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 thePrismAlgo, + const ListOfShape& theObjects); + +private: + /// Builds resulting shape. + void removeEnds (std::shared_ptr thePrismAlgo); +}; + +#endif