From: dbv Date: Thu, 27 Aug 2015 07:51:16 +0000 (+0300) Subject: Compsolids in boolean operations X-Git-Tag: V_1.4.0_beta4~181 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a95effb94656e5d4721f86ccb6ffbc2572bb1214;p=modules%2Fshaper.git Compsolids in boolean operations --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 364ee8b1c..e05b22cf5 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -15,15 +15,15 @@ #include #include #include +#include #include #include +#include #include +#include -#define FACE 4 -#define _MODIFY_TAG 1 -#define _DELETED_TAG 2 -#define _SUBSOLIDS_TAG 3 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids +#include //================================================================================================= FeaturesPlugin_Boolean::FeaturesPlugin_Boolean() @@ -75,22 +75,39 @@ void FeaturesPlugin_Boolean::execute() GeomAlgoAPI_Boolean::OperationType aType = (GeomAlgoAPI_Boolean::OperationType)aTypeAttr->value(); ListOfShape anObjects, aTools; + std::map, ListOfShape> aCompSolidsObjects; // Getting objects. AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID()); for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - std::shared_ptr anObjectAttr = anObjectsSelList->value(anObjectsIndex); + AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); std::shared_ptr anObject = anObjectAttr->value(); if(!anObject.get()) { return; } - anObjects.push_back(anObject); + ResultPtr aContext = anObjectAttr->context(); + ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext); + if(aResCompSolidPtr.get()) { + std::shared_ptr aContextShape = aResCompSolidPtr->shape(); + std::map, ListOfShape>::iterator anIt = aCompSolidsObjects.begin(); + for(; anIt != aCompSolidsObjects.end(); anIt++) { + if(anIt->first->isEqual(aContextShape)) { + aCompSolidsObjects[anIt->first].push_back(anObject); + break; + } + } + if(anIt == aCompSolidsObjects.end()) { + aCompSolidsObjects[aContextShape].push_back(anObject); + } + } else { + anObjects.push_back(anObject); + } } // Getting tools. AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - std::shared_ptr aToolAttr = aToolsSelList->value(aToolsIndex); + AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); std::shared_ptr aTool = aToolAttr->value(); if(!aTool.get()) { return; @@ -103,13 +120,13 @@ void FeaturesPlugin_Boolean::execute() switch(aType) { case GeomAlgoAPI_Boolean::BOOL_CUT: case GeomAlgoAPI_Boolean::BOOL_COMMON:{ - if(anObjects.empty() || aTools.empty()) { + if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) { std::string aFeatureError = "Not enough objects for boolean operation"; setError(aFeatureError); return; } - // Cut each object with all tools + // For solids cut each object with all tools. for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { std::shared_ptr anObject = *anObjectsIt; ListOfShape aListWithObject; @@ -135,7 +152,73 @@ void FeaturesPlugin_Boolean::execute() if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo.shape()) > 1.e-7) { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - LoadNamingDS(aResultBody, anObject, aTools, aBoolAlgo); + loadNamingDS(aResultBody, anObject, aBoolAlgo.shape(), aTools, *aBoolAlgo.makeShape(), *aBoolAlgo.mapOfShapes()); + setResult(aResultBody, aResultIndex); + aResultIndex++; + } + } + + // Compsolids handling + for(std::map, ListOfShape>::iterator anIt = aCompSolidsObjects.begin(); + anIt != aCompSolidsObjects.end(); anIt++) { + std::shared_ptr aCompSolid = anIt->first; + ListOfShape& aUsedInOperationSolids = anIt->second; + + // Collecting solids from compsolids which will not be modified in boolean operation. + ListOfShape aNotUsedSolids; + for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) { + std::shared_ptr aSolidInCompSolid = anExp.current(); + ListOfShape::iterator anIt = aUsedInOperationSolids.begin(); + for(; anIt != aUsedInOperationSolids.end(); anIt++) { + if(aSolidInCompSolid->isEqual(*anIt)) { + break; + } + } + if(anIt == aUsedInOperationSolids.end()) { + aNotUsedSolids.push_back(aSolidInCompSolid); + } + } + + GeomAlgoAPI_Boolean aBoolAlgo(aUsedInOperationSolids, aTools, aType); + + // Checking that the algorithm worked properly. + if(!aBoolAlgo.isDone()) { + static const std::string aFeatureError = "Boolean algorithm failed"; + setError(aFeatureError); + return; + } + if(aBoolAlgo.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + return; + } + if(!aBoolAlgo.isValid()) { + std::string aFeatureError = "Warning: resulting shape is not valid"; + setError(aFeatureError); + return; + } + + GeomAlgoAPI_MakeShapeList aMakeShapeList; + aMakeShapeList.append(aBoolAlgo.makeShape()); + GeomAPI_DataMapOfShapeShape aMapOfShapes; + aMapOfShapes.merge(aBoolAlgo.mapOfShapes()); + + // Add result to not used solids from compsolid. + ListOfShape aShapesToAdd = aNotUsedSolids; + aShapesToAdd.push_back(aBoolAlgo.shape()); + GeomAlgoAPI_PaveFiller aFillerAlgo(aShapesToAdd, true); + if(!aFillerAlgo.isDone()) { + std::string aFeatureError = "PaveFiller algorithm failed"; + setError(aFeatureError); + return; + } + + aMakeShapeList.append(aFillerAlgo.makeShape()); + aMapOfShapes.merge(aFillerAlgo.mapOfShapes()); + + if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo.shape()) > 1.e-7) { + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aResultBody, aCompSolid, aFillerAlgo.shape(), aTools, aMakeShapeList, aMapOfShapes); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -143,42 +226,117 @@ void FeaturesPlugin_Boolean::execute() break; } case GeomAlgoAPI_Boolean::BOOL_FUSE: { - if(anObjects.empty() && aTools.size() > 1) { - anObjects.push_back(aTools.back()); - aTools.pop_back(); - }else if(aTools.empty() && anObjects.size() > 1) { - aTools.push_back(anObjects.back()); - anObjects.pop_back(); - } - - if(anObjects.empty() || aTools.empty()) { + if((anObjects.size() + aTools.size() + aCompSolidsObjects.size()) < 2) { std::string aFeatureError = "Not enough objects for boolean operation"; setError(aFeatureError); return; } + // Collecting all solids which will be fused. + ListOfShape aSolidsToFuse; + aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end()); + aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end()); + + // Collecting solids from compsolids which will not be modified in boolean operation. + ListOfShape aNotUsedSolids; + for(std::map, ListOfShape>::iterator anIt = aCompSolidsObjects.begin(); + anIt != aCompSolidsObjects.end(); anIt++) { + std::shared_ptr aCompSolid = anIt->first; + ListOfShape& aUsedInOperationSolids = anIt->second; + aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + + // Collect solids from compsolid which will not be modified in boolean operation. + for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) { + std::shared_ptr aSolidInCompSolid = anExp.current(); + ListOfShape::iterator anIt = aUsedInOperationSolids.begin(); + for(; anIt != aUsedInOperationSolids.end(); anIt++) { + if(aSolidInCompSolid->isEqual(*anIt)) { + break; + } + } + if(anIt == aUsedInOperationSolids.end()) { + aNotUsedSolids.push_back(aSolidInCompSolid); + } + } + } + + ListOfShape anOriginalSolids = aSolidsToFuse; + anOriginalSolids.insert(anOriginalSolids.end(), aNotUsedSolids.begin(), aNotUsedSolids.end()); + GeomAlgoAPI_MakeShapeList aMakeShapeList; + GeomAPI_DataMapOfShapeShape aMapOfShapes; + + // If we have compsolids then cut with not used solids all others. + if(!aNotUsedSolids.empty()) { + aSolidsToFuse.clear(); + for(ListOfShape::iterator anIt = anOriginalSolids.begin(); anIt != anOriginalSolids.end(); anIt++) { + ListOfShape aOneObjectList; + aOneObjectList.push_back(*anIt); + GeomAlgoAPI_Boolean aCutAlgo(aOneObjectList, aNotUsedSolids, GeomAlgoAPI_Boolean::BOOL_CUT); + + if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo.shape()) > 1.e-7) { + aSolidsToFuse.push_back(aCutAlgo.shape()); + aMakeShapeList.append(aCutAlgo.makeShape()); + aMapOfShapes.merge(aCutAlgo.mapOfShapes()); + } + } + } + + anObjects.clear(); + anObjects.push_back(aSolidsToFuse.back()); + aSolidsToFuse.pop_back(); + aTools = aSolidsToFuse; + // Fuse all objects and all tools. - GeomAlgoAPI_Boolean aBoolAlgo(anObjects, aTools, aType); + GeomAlgoAPI_Boolean aFuseAlgo(anObjects, aTools, aType); // Checking that the algorithm worked properly. - if(!aBoolAlgo.isDone()) { + if(!aFuseAlgo.isDone()) { static const std::string aFeatureError = "Boolean algorithm failed"; setError(aFeatureError); return; } - if(aBoolAlgo.shape()->isNull()) { + if(aFuseAlgo.shape()->isNull()) { static const std::string aShapeError = "Resulting shape is Null"; setError(aShapeError); return; } - if(!aBoolAlgo.isValid()) { + if(!aFuseAlgo.isValid()) { std::string aFeatureError = "Warning: resulting shape is not valid"; setError(aFeatureError); return; } + std::shared_ptr aShape = aFuseAlgo.shape(); + aMakeShapeList.append(aFuseAlgo.makeShape()); + aMapOfShapes.merge(aFuseAlgo.mapOfShapes()); + + // Add result to not used solids from compsolid (if we have any). + if(!aNotUsedSolids.empty()) { + aNotUsedSolids.push_back(aShape); + GeomAlgoAPI_PaveFiller aFillerAlgo(aNotUsedSolids, true); + if(!aFillerAlgo.isDone()) { + std::string aFeatureError = "PaveFiller algorithm failed"; + setError(aFeatureError); + return; + } + if(aFillerAlgo.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + return; + } + if(!aFillerAlgo.isValid()) { + std::string aFeatureError = "Warning: resulting shape is not valid"; + setError(aFeatureError); + return; + } + + aShape = aFillerAlgo.shape(); + aMakeShapeList.append(aFillerAlgo.makeShape()); + aMapOfShapes.merge(aFillerAlgo.mapOfShapes()); + } + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - LoadNamingDS(aResultBody, anObjects.front(), aTools, aBoolAlgo); + loadNamingDS(aResultBody, anOriginalSolids.front(), aShape, anOriginalSolids, aMakeShapeList, aMapOfShapes); setResult(aResultBody, aResultIndex); aResultIndex++; break; @@ -194,28 +352,34 @@ void FeaturesPlugin_Boolean::execute() } //================================================================================================= -void FeaturesPlugin_Boolean::LoadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr& theBaseShape, +void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr theResultBody, + const std::shared_ptr theBaseShape, + const std::shared_ptr theResultShape, const ListOfShape& theTools, - const GeomAlgoAPI_Boolean& theAlgo) + GeomAlgoAPI_MakeShape& theMakeShape, + GeomAPI_DataMapOfShapeShape& theMapOfShapes) { //load result - if(theBaseShape->isEqual(theAlgo.shape())) { - theResultBody->store(theAlgo.shape()); + if(theBaseShape->isEqual(theResultShape)) { + theResultBody->store(theResultShape); } else { - theResultBody->storeModified(theBaseShape, theAlgo.shape(), _SUBSOLIDS_TAG); + const int aModifyTag = 1; + const int aDeletedTag = 2; + const int aSubsolidsTag = 3; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids + + theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag); GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape(); std::string aModName = "Modified"; - theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, FACE, - _MODIFY_TAG, aModName, *theAlgo.mapOfShapes().get()); - theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, FACE, _DELETED_TAG); + theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, + aModifyTag, aModName, theMapOfShapes); + theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag); for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) { - theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, FACE, - _MODIFY_TAG, aModName, *theAlgo.mapOfShapes().get()); - theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, FACE, _DELETED_TAG); + theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, + aModifyTag, aModName, theMapOfShapes); + theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag); } } } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index df9065b25..7ac31e35b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -87,10 +87,12 @@ private: std::shared_ptr getShape(const std::string& theAttrName); /// Load Naming data structure of the feature to the document - void LoadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr& theBaseObject, + void loadNamingDS(std::shared_ptr theResultBody, + const std::shared_ptr theBaseShape, + const std::shared_ptr theResultShape, const ListOfShape& theTools, - const GeomAlgoAPI_Boolean& theAlgo); + GeomAlgoAPI_MakeShape& theMakeShape, + GeomAPI_DataMapOfShapeShape& theMapOfShapes); }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index 261a32931..98735660f 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -126,9 +126,7 @@ void FeaturesPlugin_CompositeBoolean::execute() ListOfShape aFreeFaces; std::shared_ptr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList); GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces); - for(ListOfShape::const_iterator anIter = aFreeFaces.cbegin(); anIter != aFreeFaces.cend(); anIter++) { - aShells.push_back(*anIter); - } + aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end()); // Pass shells/faces to solids creation function. ListOfShape aBooleanTools; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index c9c567081..85b5b665d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -135,9 +135,7 @@ void FeaturesPlugin_Extrusion::execute() ListOfShape aFreeFaces; std::shared_ptr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList); GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces); - for(ListOfShape::const_iterator anIter = aFreeFaces.cbegin(); anIter != aFreeFaces.cend(); anIter++) { - aShells.push_back(*anIter); - } + aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end()); // Generating result for each shell and face. int aResultIndex = 0; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp b/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp index 503c1c8a9..26bbe7010 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp @@ -143,9 +143,7 @@ void FeaturesPlugin_Revolution::execute() ListOfShape aFreeFaces; std::shared_ptr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList); GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces); - for(ListOfShape::const_iterator anIter = aFreeFaces.cbegin(); anIter != aFreeFaces.cend(); anIter++) { - aShells.push_back(*anIter); - } + aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end()); // Generating result for each shell and face. int aResultIndex = 0; diff --git a/src/GeomAPI/GeomAPI_DataMapOfShapeShape.cpp b/src/GeomAPI/GeomAPI_DataMapOfShapeShape.cpp index 2d0ce7924..166922710 100644 --- a/src/GeomAPI/GeomAPI_DataMapOfShapeShape.cpp +++ b/src/GeomAPI/GeomAPI_DataMapOfShapeShape.cpp @@ -7,12 +7,13 @@ #include #include #include +#include #include using namespace std; GeomAPI_DataMapOfShapeShape::GeomAPI_DataMapOfShapeShape() - :GeomAPI_Interface((void *)new TopTools_DataMapOfShapeShape){} +: GeomAPI_Interface(new TopTools_DataMapOfShapeShape){} void GeomAPI_DataMapOfShapeShape::clear() { @@ -28,10 +29,24 @@ bool GeomAPI_DataMapOfShapeShape::bind (std::shared_ptr theKey, s { bool flag(false); if(implPtr()->Bind(theKey->impl(), theItem->impl())) - flag = true; + flag = true; return flag; } +void GeomAPI_DataMapOfShapeShape::merge(const GeomAPI_DataMapOfShapeShape& theDataMap) +{ + const TopTools_DataMapOfShapeShape& aDataMap = theDataMap.impl(); + TopTools_DataMapOfShapeShape* myDataMap = implPtr(); + for(TopTools_DataMapIteratorOfDataMapOfShapeShape anIt(aDataMap); anIt.More(); anIt.Next()) { + myDataMap->Bind(anIt.Key(), anIt.Value()); + } +} + +void GeomAPI_DataMapOfShapeShape::merge(const std::shared_ptr theDataMap) +{ + merge(*theDataMap.get()); +} + bool GeomAPI_DataMapOfShapeShape::isBound (std::shared_ptr theKey) { bool flag(false); @@ -46,12 +61,12 @@ const std::shared_ptr GeomAPI_DataMapOfShapeShape::find(std::shar aShape->setImpl(new TopoDS_Shape(impl().Find(theKey->impl()))); return aShape; } - + bool GeomAPI_DataMapOfShapeShape::unBind(std::shared_ptr theKey) { bool flag(false); if(implPtr()->UnBind(theKey->impl())) - flag = true; + flag = true; return flag; } @@ -59,6 +74,5 @@ bool GeomAPI_DataMapOfShapeShape::unBind(std::shared_ptr theKey) { if (!empty()) { implPtr()->Clear(); - //delete myImpl; } } diff --git a/src/GeomAPI/GeomAPI_DataMapOfShapeShape.h b/src/GeomAPI/GeomAPI_DataMapOfShapeShape.h index cbc5f113c..42c8a86d1 100644 --- a/src/GeomAPI/GeomAPI_DataMapOfShapeShape.h +++ b/src/GeomAPI/GeomAPI_DataMapOfShapeShape.h @@ -36,6 +36,12 @@ class GeomAPI_DataMapOfShapeShape : public GeomAPI_Interface GEOMAPI_EXPORT bool bind (std::shared_ptr theKey, std::shared_ptr theItem); + /// Merges two maps + GEOMAPI_EXPORT void merge(const GeomAPI_DataMapOfShapeShape& theDataMap); + + /// Merges two maps + GEOMAPI_EXPORT void merge(const std::shared_ptr theDataMap); + /// Returns true if theKey is stored in the map. GEOMAPI_EXPORT bool isBound (std::shared_ptr theKey); diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 4739f5025..4354f0f72 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Transform.h GeomAlgoAPI_ShapeTools.h GeomAlgoAPI_Partition.h + GeomAlgoAPI_PaveFiller.h ) SET(PROJECT_SOURCES @@ -60,6 +61,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Transform.cpp GeomAlgoAPI_ShapeTools.cpp GeomAlgoAPI_Partition.cpp + GeomAlgoAPI_PaveFiller.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 01c3b71d8..cd5474eec 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -26,6 +26,7 @@ #include "GeomAlgoAPI_STEPImport.h" #include "GeomAlgoAPI_Tools.h" #include "GeomAlgoAPI_Transform.h" + #include "GeomAlgoAPI_PaveFiller.h" #include #include @@ -66,6 +67,7 @@ %include "GeomAlgoAPI_STEPImport.h" %include "GeomAlgoAPI_Tools.h" %include "GeomAlgoAPI_Transform.h" +%include "GeomAlgoAPI_PaveFiller.h" %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp index 32b7660e2..e3f7141be 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp @@ -53,10 +53,7 @@ std::shared_ptr GeomAlgoAPI_Boolean::makeCommon(const ListOfShape GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects, const ListOfShape& theTools, const OperationType theOperationType) -: myDone(false), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) +: myDone(false) { build(theObjects, theTools, theOperationType); } @@ -104,7 +101,7 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, return; } } - myMkShape->setImpl(anOperation); + myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation)); anOperation->SetArguments(anObjects); anOperation->SetTools(aTools); @@ -121,11 +118,13 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, } // fill data map to keep correct orientation of sub-shapes + myMap.reset(new GeomAPI_DataMapOfShapeShape()); for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } + myShape.reset(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index e99700456..140a0a583 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -5,104 +5,129 @@ // Author: Sergey ZARITCHNY #include + +#include #include #include #include #include #include -GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape) - : GeomAPI_Interface(theMkShape),myShape(new GeomAPI_Shape()) +//================================================================================================= +GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape, const AlgoType theAlgoType) +: GeomAPI_Interface(theMkShape), + myAlgoType(theAlgoType), + myShape(new GeomAPI_Shape()) { - myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); + switch (myAlgoType) { + case MakeShape: + case MakePipe: { + myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); + break; + } + case BOPAlgoBuilder: { + myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); + break; + } + } } +//================================================================================================= GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape, const std::shared_ptr theWire, const std::shared_ptr theBaseShape) : GeomAPI_Interface(theMkShape), + myAlgoType(MakePipe), myShape(new GeomAPI_Shape()), myWire(theWire), myBaseShape(theBaseShape) { - myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); + myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); } -GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() - : GeomAPI_Interface(),myShape(new GeomAPI_Shape()) -{} - +//================================================================================================= const std::shared_ptr GeomAlgoAPI_MakeShape::shape() const { return myShape; } -void GeomAlgoAPI_MakeShape::generated( - const std::shared_ptr theShape, ListOfShape& theHistory) +//================================================================================================= +void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr theShape, + ListOfShape& theHistory) { - if(!myWire.get()) { - BRepBuilderAPI_MakeShape* aBuilder = implPtr(); - if(aBuilder) { - const TopTools_ListOfShape& aList = aBuilder->Generated(theShape->impl()); - TopTools_ListIteratorOfListOfShape it(aList); - for(;it.More();it.Next()) { - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(it.Value())); - theHistory.push_back(aShape); - } - } - } else { // Pipe builder - BRepOffsetAPI_MakePipe* aPipeBuilder = implPtr(); - if(aPipeBuilder) { - TopExp_Explorer aShapeExplorer(myWire->impl(), TopAbs_EDGE); - for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { - const TopoDS_Shape& aSpine = aShapeExplorer.Current(); - const TopoDS_Shape& aProfile = theShape->impl(); - if(aProfile.ShapeType() != TopAbs_EDGE && aProfile.ShapeType() != TopAbs_VERTEX) { - return; - } - const TopoDS_Shape& aBaseShape = myBaseShape->impl(); - TopExp_Explorer anExp(aBaseShape, aProfile.ShapeType()); - Standard_Boolean hasShape = Standard_False; - for(; anExp.More(); anExp.Next()) { - if(anExp.Current().IsSame(aProfile)) { - hasShape = Standard_True; - break; - } - } - if(!hasShape) { + if(myAlgoType == MakePipe) { + BRepOffsetAPI_MakePipe* aMakePipe = implPtr(); + TopExp_Explorer aShapeExplorer(myWire->impl(), TopAbs_EDGE); + for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { + const TopoDS_Shape& aSpine = aShapeExplorer.Current(); + const TopoDS_Shape& aProfile = theShape->impl(); + if(aProfile.ShapeType() != TopAbs_EDGE && aProfile.ShapeType() != TopAbs_VERTEX) { return; + } + const TopoDS_Shape& aBaseShape = myBaseShape->impl(); + TopExp_Explorer anExp(aBaseShape, aProfile.ShapeType()); + Standard_Boolean hasShape = Standard_False; + for(; anExp.More(); anExp.Next()) { + if(anExp.Current().IsSame(aProfile)) { + hasShape = Standard_True; + break; } - const TopoDS_Shape& aGeneratedShape = aPipeBuilder->Generated(aSpine, aProfile); - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(aGeneratedShape)); - theHistory.push_back(aShape); } + if(!hasShape) { + return; + } + const TopoDS_Shape& aGeneratedShape = aMakePipe->Generated(aSpine, aProfile); + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aGeneratedShape)); + theHistory.push_back(aShape); + } + } else { + TopTools_ListOfShape aList; + if(myAlgoType == MakeShape) { + BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); + aList = aMakeShape->Generated(theShape->impl()); + } else if(myAlgoType == BOPAlgoBuilder) { + BOPAlgo_Builder* aBOPBuilder = implPtr(); + aList = aBOPBuilder->Generated(theShape->impl()); + } + for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + theHistory.push_back(aShape); } } } -void GeomAlgoAPI_MakeShape::modified( - const std::shared_ptr theShape, ListOfShape& theHistory) +//================================================================================================= +void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr theShape, + ListOfShape& theHistory) { - BRepBuilderAPI_MakeShape* aBuilder = implPtr(); - if(aBuilder) { - const TopTools_ListOfShape& aList = aBuilder->Modified(theShape->impl()); - TopTools_ListIteratorOfListOfShape it(aList); - for(;it.More();it.Next()) { - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(it.Value())); - theHistory.push_back(aShape); - } + TopTools_ListOfShape aList; + if(myAlgoType == MakeShape) { + BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); + aList = aMakeShape->Modified(theShape->impl()); + } else if(myAlgoType == BOPAlgoBuilder) { + BOPAlgo_Builder* aBOPBuilder = implPtr(); + aList = aBOPBuilder->Modified(theShape->impl()); + } + for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + theHistory.push_back(aShape); } } +//================================================================================================= bool GeomAlgoAPI_MakeShape::isDeleted(const std::shared_ptr theShape) { - bool isDeleted(false); - BRepBuilderAPI_MakeShape* aBuilder = implPtr(); - if(aBuilder) { - isDeleted = aBuilder->IsDeleted(theShape->impl()) == Standard_True; + bool isDeleted = false; + if(myAlgoType == MakeShape) { + BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); + isDeleted = aMakeShape->IsDeleted(theShape->impl()) == Standard_True; + } else if(myAlgoType == BOPAlgoBuilder) { + BOPAlgo_Builder* aBOPBuilder = implPtr(); + isDeleted = aBOPBuilder->IsDeleted(theShape->impl()) == Standard_True; } + return isDeleted; } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index efafeceee..594283819 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -19,10 +19,16 @@ class GeomAlgoAPI_MakeShape : public GeomAPI_Interface { public: - /// Constructor - GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(); + /// Algo type enum + enum AlgoType { + MakeShape, + MakePipe, + BOPAlgoBuilder + }; + +public: /// Constructor by the already stored builder in the interface - GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder); + GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder, const AlgoType theAlgoType = MakeShape); /// Constructor by the builder and wire. Used for pipe builder. GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder, @@ -30,7 +36,7 @@ public: const std::shared_ptr theBaseShape); /// Returns a shape built by the shape construction algorithm - GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; + GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; /// Returns the list of shapes generated from the shape \a theShape GEOMALGOAPI_EXPORT virtual void generated( @@ -43,8 +49,11 @@ public: /// Returns whether the shape is an edge GEOMALGOAPI_EXPORT virtual bool isDeleted(const std::shared_ptr theShape); - protected: - /// The resulting shape +protected: + GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(){}; + +protected: + GeomAlgoAPI_MakeShape::AlgoType myAlgoType; std::shared_ptr myShape; std::shared_ptr myWire; std::shared_ptr myBaseShape; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp index 7b1bb7be3..71ed15947 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp @@ -29,6 +29,21 @@ void GeomAlgoAPI_MakeShapeList::init(const ListOfMakeShape& theMakeShapeList) myListOfMakeShape = theMakeShapeList; } +//================================================================================================= +void GeomAlgoAPI_MakeShapeList::append(const std::shared_ptr theMakeShape) +{ + myListOfMakeShape.push_back(theMakeShape); +} + +//================================================================================================= +void GeomAlgoAPI_MakeShapeList::append(const GeomAlgoAPI_MakeShapeList& theMakeShapeList) +{ + for(ListOfMakeShape::const_iterator anIt = theMakeShapeList.myListOfMakeShape.cbegin(); + anIt != theMakeShapeList.myListOfMakeShape.cend(); anIt++) { + myListOfMakeShape.push_back(*anIt); + } +} + //================================================================================================= const std::shared_ptr GeomAlgoAPI_MakeShapeList::shape() const { @@ -56,8 +71,8 @@ void GeomAlgoAPI_MakeShapeList::modified(const std::shared_ptr th bool GeomAlgoAPI_MakeShapeList::isDeleted(const std::shared_ptr theShape) { for(ListOfMakeShape::iterator aBuilderIt = myListOfMakeShape.begin(); aBuilderIt != myListOfMakeShape.end(); aBuilderIt++) { - BRepBuilderAPI_MakeShape* aBuilder = (*aBuilderIt)->implPtr(); - if(aBuilder && (aBuilder->IsDeleted(theShape->impl()) == Standard_True)) { + std::shared_ptr aMakeShape = *aBuilderIt; + if(aMakeShape->isDeleted(theShape)) { return true; } } @@ -113,4 +128,3 @@ void GeomAlgoAPI_MakeShapeList::result(const std::shared_ptr theS theHistory.push_back(aShape); } } - diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h index 7de577350..92f1c04df 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h @@ -37,6 +37,16 @@ public: */ GEOMALGOAPI_EXPORT void init(const ListOfMakeShape& theMakeShapeList); + /** \brief Adds algo to the end of list. + * \param[in] theMakeShape algo to be added. + */ + GEOMALGOAPI_EXPORT void append(const std::shared_ptr theMakeShape); + + /** \brief Adds another one list of algos to the end of list. + * \param[in] theMakeShapeList algo list to be added. + */ + GEOMALGOAPI_EXPORT void append(const GeomAlgoAPI_MakeShapeList& theMakeShapeList); + /// \return a shape built by the shape construction algorithms GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp index ab9b43fc2..9bef39222 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp @@ -19,10 +19,7 @@ GeomAlgoAPI_Movement::GeomAlgoAPI_Movement(std::shared_ptr theSou std::shared_ptr theAxis, double theDistance, bool theSimpleTransform) -: myDone(false), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) +: myDone(false) { build(theSourceShape, theAxis, theDistance, theSimpleTransform); } @@ -61,6 +58,7 @@ void GeomAlgoAPI_Movement::build(std::shared_ptr theSourceShape, if(!aBuilder) { return; } + myMkShape.reset(new GeomAlgoAPI_MakeShape(aBuilder)); myDone = aBuilder->IsDone() == Standard_True; @@ -70,14 +68,15 @@ void GeomAlgoAPI_Movement::build(std::shared_ptr theSourceShape, aResult = aBuilder->Shape(); // Fill data map to keep correct orientation of sub-shapes. + myMap.reset(new GeomAPI_DataMapOfShapeShape()); for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } - myMkShape->setImpl(aBuilder); } + myShape.reset(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp index 05bc5d2f4..512ac28c6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp @@ -28,10 +28,7 @@ std::shared_ptr GeomAlgoAPI_Partition::make(const ListOfShape& th //================================================================================================= GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects, const ListOfShape& theTools) -: myDone(false), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) +: myDone(false) { build(theObjects, theTools); } @@ -46,8 +43,8 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, } // Creating partition operation. - GEOMAlgo_Splitter * anOperation = new GEOMAlgo_Splitter; - myMkShape->setImpl(anOperation); + GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter; + myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder)); // Getting objects. TopTools_ListOfShape anObjects; @@ -76,11 +73,13 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, } // fill data map to keep correct orientation of sub-shapes + myMap.reset(new GeomAPI_DataMapOfShapeShape()); for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } + myShape.reset(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp new file mode 100644 index 000000000..6d3d04dd9 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp @@ -0,0 +1,118 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_PaveFiller.cpp +// Created: 27 August 2015 +// Author: Dmitry Bobylev + +#include + +#include +#include + +#include +#include +#include +#include +#include + +//================================================================================================= +GeomAlgoAPI_PaveFiller::GeomAlgoAPI_PaveFiller(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids) +: myDone(false) +{ + build(theListOfShape, theIsMakeCompSolids); +} + + +//================================================================================================= +void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids) +{ + BOPAlgo_PaveFiller aPaveFiller; + BOPCol_ListOfShape aListOfShape; + for(ListOfShape::const_iterator anIt = theListOfShape.cbegin(); anIt != theListOfShape.cend(); anIt++) { + aListOfShape.Append((*anIt)->impl()); + } + aPaveFiller.SetArguments(aListOfShape); + aPaveFiller.Perform(); + Standard_Integer iErr = aPaveFiller.ErrorStatus(); + if(iErr) { + return; + } + + BOPAlgo_Builder* aBuilder = new BOPAlgo_Builder(); + myMkShape.reset(new GeomAlgoAPI_MakeShape(aBuilder, GeomAlgoAPI_MakeShape::BOPAlgoBuilder)); + aBuilder->SetArguments(aListOfShape); + aBuilder->PerformWithFiller(aPaveFiller); + iErr = aBuilder->ErrorStatus(); + if(iErr) { + return; + } + + TopoDS_Shape aResult = aBuilder->Shape(); + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } + if(theIsMakeCompSolids && aResult.ShapeType() == TopAbs_COMPOUND) { + std::shared_ptr aCompound(new GeomAPI_Shape); + aCompound->setImpl(new TopoDS_Shape(aResult)); + ListOfShape aCompSolids, aFreeSolids; + GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); + if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { + aResult = aCompSolids.front()->impl(); + } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { + TopoDS_Compound aResultComp; + TopoDS_Builder aBuilder; + aBuilder.MakeCompound(aResultComp); + for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + aResult = aResultComp; + } + } + + // fill data map to keep correct orientation of sub-shapes + myMap.reset(new GeomAPI_DataMapOfShapeShape()); + for (TopExp_Explorer Exp(aResult, TopAbs_FACE); Exp.More(); Exp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + + myShape.reset(new GeomAPI_Shape()); + myShape->setImpl(new TopoDS_Shape(aResult)); + + myDone = true; +} + +//================================================================================================= +const bool GeomAlgoAPI_PaveFiller::isDone() const +{ + return myDone; +} + +//================================================================================================= +const bool GeomAlgoAPI_PaveFiller::isValid() const +{ + BRepCheck_Analyzer aChecker(myShape->impl()); + return (aChecker.IsValid() == Standard_True); +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_PaveFiller::shape() const +{ + return myShape; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_PaveFiller::mapOfShapes() const +{ + return myMap; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_PaveFiller::makeShape() const +{ + return myMkShape; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h new file mode 100644 index 000000000..f508e7e20 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h @@ -0,0 +1,57 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_PaveFiller.h +// Created: 27 August 2015 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_PaveFiller_H_ +#define GeomAlgoAPI_PaveFiller_H_ + +#include +#include + +#include +#include +#include + +/** \class GeomAlgoAPI_PaveFiller + * \ingroup DataAlgo + * \brief Finds the common parts from the list of shapes and breaks it to shapes with shared subshapes. + */ +class GeomAlgoAPI_PaveFiller : public GeomAPI_Interface +{ +public: + /** \brief Constructor. + * \param[in] theListOfShape list of shape which should be splitted. + * \param[in] theIsMakeCompSolids if true gather shapes with shared faces to compsolids. + */ + GEOMALGOAPI_EXPORT GeomAlgoAPI_PaveFiller(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids = false); + + /// \return true if algorithm succeed. + GEOMALGOAPI_EXPORT const bool isDone() const; + + /// \return true if resulting shape is valid. + GEOMALGOAPI_EXPORT const bool isValid() const; + + /// \return result of the boolean algorithm. + GEOMALGOAPI_EXPORT std::shared_ptr shape() const; + + /// \return map of sub-shapes of the result. To be used for History keeping. + GEOMALGOAPI_EXPORT std::shared_ptr mapOfShapes() const; + + /// \return interface for for History processing. + GEOMALGOAPI_EXPORT std::shared_ptr makeShape() const; + +private: + /// Builds resulting shape. + void build(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids); + +private: + /// Fields. + bool myDone; + std::shared_ptr myShape; + std::shared_ptr myMap; + std::shared_ptr myMkShape; +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index f4c7218af..6e2dbc1f2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -157,7 +157,8 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr& theBasis, aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); } } - Standard_Real aPipeLength = aMaxToDist + aMaxFromDist; + // We added 1 just to be sure that pipe is long enough for boolean operation. + Standard_Real aPipeLength = aMaxToDist + aMaxFromDist + 1; // Making wire for pipe. std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index 3b24af85b..0ecd76ecc 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -18,10 +18,7 @@ GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSou std::shared_ptr theAxis, double theAngle, bool theSimpleTransform) -: myDone(false), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) +: myDone(false) { build(theSourceShape, theAxis, theAngle, theSimpleTransform); } @@ -59,6 +56,7 @@ void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, if(!aBuilder) { return; } + myMkShape.reset(new GeomAlgoAPI_MakeShape(aBuilder)); myDone = aBuilder->IsDone() == Standard_True; @@ -68,14 +66,15 @@ void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, aResult = aBuilder->Shape(); // Fill data map to keep correct orientation of sub-shapes. + myMap.reset(new GeomAPI_DataMapOfShapeShape()); for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } - myMkShape->setImpl(aBuilder); } + myShape.reset(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp index e5409c49e..8c7cefb32 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp @@ -17,10 +17,7 @@ GeomAlgoAPI_Transform::GeomAlgoAPI_Transform(std::shared_ptr theSourceShape, std::shared_ptr theTrsf) : myDone(false), - myTrsf(theTrsf), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) + myTrsf(theTrsf) { build(theSourceShape, theTrsf); } @@ -44,6 +41,7 @@ void GeomAlgoAPI_Transform::build(std::shared_ptr theSourceShape, if(!aBuilder) { return; } + myMkShape.reset(new GeomAlgoAPI_MakeShape(aBuilder)); myDone = aBuilder->IsDone() == Standard_True; if(!myDone) { @@ -53,13 +51,14 @@ void GeomAlgoAPI_Transform::build(std::shared_ptr theSourceShape, TopoDS_Shape aResult = aBuilder->Shape(); // Fill data map to keep correct orientation of sub-shapes. + myMap.reset(new GeomAPI_DataMapOfShapeShape()); for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } - myMkShape->setImpl(aBuilder); + myShape.reset(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); } diff --git a/src/GeomValidators/GeomValidators_BooleanArguments.cpp b/src/GeomValidators/GeomValidators_BooleanArguments.cpp index a5caa03fa..c8a75ead5 100644 --- a/src/GeomValidators/GeomValidators_BooleanArguments.cpp +++ b/src/GeomValidators/GeomValidators_BooleanArguments.cpp @@ -46,6 +46,7 @@ bool GeomValidators_BooleanArguments::isValid(const std::shared_ptr