From: dbv Date: Thu, 14 Jan 2016 15:43:27 +0000 (+0300) Subject: Porting boolean feature to new GeomAlgoAPI_CellsBuilder which uses OCCT BOPAlgo_Cells... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d60c5f6e7426a797fb6e6c217a8eb26d1ad31547;p=modules%2Fshaper.git Porting boolean feature to new GeomAlgoAPI_CellsBuilder which uses OCCT BOPAlgo_CellsBuilder. --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index ee767710c..85ef28c97 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -34,15 +35,13 @@ void FeaturesPlugin_Boolean::initAttributes() { data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId()); - AttributeSelectionListPtr aSelection = + AttributeSelectionListPtr aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); - // extrusion works with faces always aSelection->setSelectionType("SOLID"); aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); - // extrusion works with faces always aSelection->setSelectionType("SOLID"); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID()); @@ -67,11 +66,11 @@ std::shared_ptr FeaturesPlugin_Boolean::getShape(const std::strin void FeaturesPlugin_Boolean::execute() { // Getting operation type. - std::shared_ptr aTypeAttr = std::dynamic_pointer_cast< + std::shared_ptr anOperationTypeAttr = std::dynamic_pointer_cast< ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID())); - if (!aTypeAttr) + if (!anOperationTypeAttr) return; - GeomAlgoAPI_Boolean::OperationType aType = (GeomAlgoAPI_Boolean::OperationType)aTypeAttr->value(); + GeomAlgoAPI_Boolean::OperationType anOperationType = (GeomAlgoAPI_Boolean::OperationType)anOperationTypeAttr->value(); ListOfShape anObjects, aTools; std::map, ListOfShape> aCompSolidsObjects; @@ -116,11 +115,11 @@ void FeaturesPlugin_Boolean::execute() int aResultIndex = 0; - switch(aType) { + switch(anOperationType) { case GeomAlgoAPI_Boolean::BOOL_CUT: case GeomAlgoAPI_Boolean::BOOL_COMMON:{ if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) { - std::string aFeatureError = "Not enough objects for boolean operation"; + std::string aFeatureError = "Error: not enough objects for boolean operation."; setError(aFeatureError); return; } @@ -130,21 +129,21 @@ void FeaturesPlugin_Boolean::execute() std::shared_ptr anObject = *anObjectsIt; ListOfShape aListWithObject; aListWithObject.push_back(anObject); - GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, aType); + GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, anOperationType); // Checking that the algorithm worked properly. if(!aBoolAlgo.isDone()) { - static const std::string aFeatureError = "Boolean algorithm failed"; + static const std::string aFeatureError = "Error: boolean algorithm failed."; setError(aFeatureError); return; } if(aBoolAlgo.shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; + static const std::string aShapeError = "Error: resulting shape is Null."; setError(aShapeError); return; } if(!aBoolAlgo.isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; + std::string aFeatureError = "Error: resulting shape is not valid."; setError(aFeatureError); return; } @@ -158,66 +157,76 @@ void FeaturesPlugin_Boolean::execute() } // Compsolids handling + int aMaterialId = 1; 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; + ListOfShape aNotUsedInOperationSolids; + GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(aCompSolid, aUsedInOperationSolids, aNotUsedInOperationSolids); + + // Collecting all solids from compsolid and tools, and setting them as arguments for builder. + ListOfShape anArguments; + anArguments.insert(anArguments.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aNotUsedInOperationSolids.begin(), aNotUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aTools.begin(), aTools.end()); + + // Perform splitting into cells. + GeomAlgoAPI_CellsBuilder aCellsBuilder; + aCellsBuilder.setArguments(anArguments); + aCellsBuilder.setFuzzyValue(0.0); + aCellsBuilder.setRunParallel(false); + aCellsBuilder.perform(); + + // Taking not used solids in compsolid. + ListOfShape aLSToTake, aLSToAvoid; + for(ListOfShape::const_iterator anIt = aNotUsedInOperationSolids.cbegin(); anIt != aNotUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); aLSToAvoid.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid, ++aMaterialId); + } + + // Taking result solids after boolean operation. + for(ListOfShape::const_iterator anIt = aUsedInOperationSolids.cbegin(); anIt != aUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); aLSToAvoid.clear(); + aLSToTake.push_back(*anIt); + if(anOperationType == BOOL_CUT) { + aLSToAvoid.insert(aLSToAvoid.end(), aTools.begin(), aTools.end()); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid); + } else { + for(ListOfShape::const_iterator aToolsIt = aTools.cbegin(); aToolsIt != aTools.cend(); aToolsIt++) { + aLSToTake.push_back(*aToolsIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid); } } - if(anIt == aUsedInOperationSolids.end()) { - aNotUsedSolids.push_back(aSolidInCompSolid); - } } - std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, aType)); + aCellsBuilder.removeInternalBoundaries(); // Checking that the algorithm worked properly. - if(!aBoolAlgo->isDone()) { - static const std::string aFeatureError = "Boolean algorithm failed"; + if(!aCellsBuilder.isDone()) { + static const std::string aFeatureError = "Error: cells builder algorithm failed."; setError(aFeatureError); return; } - if(aBoolAlgo->shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; + if(aCellsBuilder.shape()->isNull()) { + static const std::string aShapeError = "Error: 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.appendAlgo(aBoolAlgo); - GeomAPI_DataMapOfShapeShape aMapOfShapes; - aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes()); - - // Add result to not used solids from compsolid. - ListOfShape aShapesToAdd = aNotUsedSolids; - aShapesToAdd.push_back(aBoolAlgo->shape()); - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone()) { - std::string aFeatureError = "PaveFiller algorithm failed"; + if(!aCellsBuilder.isValid()) { + std::string aFeatureError = "Error: resulting shape is not valid."; setError(aFeatureError); return; } - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + std::shared_ptr aResultShape = aCellsBuilder.shape(); - if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo->shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-7) { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aCompSolid, aTools, aFillerAlgo->shape(), aMakeShapeList, aMapOfShapes); + loadNamingDS(aResultBody, aCompSolid, aTools, aCellsBuilder.shape(), aCellsBuilder, *(aCellsBuilder.mapOfSubShapes())); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -226,122 +235,98 @@ void FeaturesPlugin_Boolean::execute() } case GeomAlgoAPI_Boolean::BOOL_FUSE: { if((anObjects.size() + aTools.size() + aCompSolidsObjects.size()) < 2) { - std::string aFeatureError = "Not enough objects for boolean operation"; + std::string aFeatureError = "Error: 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; + // Adding solids from compsolids to list of solids which will be fused. + ListOfShape aUsedInOperationSolids, aNotUsedInOperationSolids; 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()); + ListOfShape& aSolidsToAvoid = anIt->second; + aUsedInOperationSolids.insert(aUsedInOperationSolids.end(), aSolidsToAvoid.begin(), aSolidsToAvoid.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); - } - } + GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(aCompSolid, aSolidsToAvoid, aNotUsedInOperationSolids); } - 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); - std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(aOneObjectList, aNotUsedSolids, GeomAlgoAPI_Boolean::BOOL_CUT)); - - if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) { - aSolidsToFuse.push_back(aCutAlgo->shape()); - aMakeShapeList.appendAlgo(aCutAlgo); - aMapOfShapes.merge(aCutAlgo->mapOfSubShapes()); - } - } + // Collecting objects, tools and all solids from compsolid, and setting them as arguments for builder. + ListOfShape anArguments; + anArguments.insert(anArguments.end(), anObjects.begin(), anObjects.end()); + anArguments.insert(anArguments.end(), aTools.begin(), aTools.end()); + anArguments.insert(anArguments.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aNotUsedInOperationSolids.begin(), aNotUsedInOperationSolids.end()); + + // Perform splitting into cells. + GeomAlgoAPI_CellsBuilder aCellsBuilder; + aCellsBuilder.setArguments(anArguments); + aCellsBuilder.setFuzzyValue(0.0); + aCellsBuilder.setRunParallel(false); + aCellsBuilder.perform(); + + // Taking objects. + int aMaterialId = 1; + ListOfShape aLSToTake, aLSToAvoid; + for(ListOfShape::const_iterator anIt = anObjects.cbegin(); anIt != anObjects.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); } - anObjects.clear(); - anObjects.push_back(aSolidsToFuse.back()); - aSolidsToFuse.pop_back(); - aTools = aSolidsToFuse; + // Taking tools. + for(ListOfShape::const_iterator anIt = aTools.cbegin(); anIt != aTools.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); + } - // Fuse all objects and all tools. - std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, aType)); + // Taking used solids in compsolids. + for(ListOfShape::const_iterator anIt = aUsedInOperationSolids.cbegin(); anIt != aUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); + } + + // Taking not used solids in compsolid. + for(ListOfShape::const_iterator anIt = aNotUsedInOperationSolids.cbegin(); anIt != aNotUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid, ++aMaterialId); + } + + aCellsBuilder.removeInternalBoundaries(); // Checking that the algorithm worked properly. - if(!aFuseAlgo->isDone()) { - static const std::string aFeatureError = "Boolean algorithm failed"; + if(!aCellsBuilder.isDone()) { + static const std::string aFeatureError = "Error: cells builder algorithm failed."; setError(aFeatureError); return; } - if(aFuseAlgo->shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; + if(aCellsBuilder.shape()->isNull()) { + static const std::string aShapeError = "Error: resulting shape is Null."; setError(aShapeError); return; } - if(!aFuseAlgo->isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; + if(!aCellsBuilder.isValid()) { + std::string aFeatureError = "Error: resulting shape is not valid."; setError(aFeatureError); return; } - std::shared_ptr aShape = aFuseAlgo->shape(); - aMakeShapeList.appendAlgo(aFuseAlgo); - aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes()); + std::shared_ptr aResultShape = aCellsBuilder.shape(); - // Add result to not used solids from compsolid (if we have any). - if(!aNotUsedSolids.empty()) { - aNotUsedSolids.push_back(aShape); - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(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.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-7) { + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aResultBody, anArguments.front(), anArguments, aCellsBuilder.shape(), aCellsBuilder, *(aCellsBuilder.mapOfSubShapes())); + setResult(aResultBody, aResultIndex); + aResultIndex++; } - - std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, anOriginalSolids.front(), anOriginalSolids, aShape, aMakeShapeList, aMapOfShapes); - setResult(aResultBody, aResultIndex); - aResultIndex++; break; } default: { - std::string anOperationError = "Error: wrong type of operation"; + std::string anOperationError = "Error: wrong type of operation."; setError(anOperationError); return; } diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 24c17e62d..36ea061da 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -34,6 +34,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_ShapeTools.h GeomAlgoAPI_Partition.h GeomAlgoAPI_PaveFiller.h + GeomAlgoAPI_CellsBuilder.h ) SET(PROJECT_SOURCES @@ -64,6 +65,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_ShapeTools.cpp GeomAlgoAPI_Partition.cpp GeomAlgoAPI_PaveFiller.cpp + GeomAlgoAPI_CellsBuilder.cpp ) SET(PROJECT_LIBRARIES @@ -72,8 +74,8 @@ SET(PROJECT_LIBRARIES ModelAPI ${CAS_OCAF} ${CAS_SHAPE} - ${CAS_TKBO} - ${CAS_TKBool} + ${CAS_TKBO} + ${CAS_TKBool} ${CAS_TKBRep} ${CAS_TKCAF} ${CAS_TKCAF} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 86addb6d2..88037c60a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -40,8 +40,9 @@ %include "GeomAlgoAPI_Tools.h" %include "GeomAlgoAPI_Transform.h" %include "GeomAlgoAPI_PaveFiller.h" +%include "GeomAlgoAPI_CellsBuilder.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 ); } -%template(ShapeList) std::list >; \ No newline at end of file +%template(ShapeList) std::list >; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp new file mode 100644 index 000000000..fde58c637 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp @@ -0,0 +1,167 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_CellsBuilder.h +// Created: 11 December 2015 +// Author: Dmitry Bobylev + +#include "GeomAlgoAPI_CellsBuilder.h" + +#include + +#include +#include + +#define MY_CELLSBUILDER implPtr() + +/// \brief Converts std::list to NCollection_List. +/// \param[in] theStdListOfShape std::list. +/// \param[out] theNCollectionListOfShape NCollection_List. Will be cleared before converting. +static void stdListToNCollectionList(const ListOfShape& theStdListOfShape, + NCollection_List& theNCollectionListOfShape); + +//================================================================================================= +GeomAlgoAPI_CellsBuilder::GeomAlgoAPI_CellsBuilder() +: GeomAlgoAPI_MakeShape(new BOPAlgo_CellsBuilder(), OCCT_BOPAlgo_Builder) +{ +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::setArguments(const ListOfShape &theLS) +{ + NCollection_List aLS; + stdListToNCollectionList(theLS, aLS); + + MY_CELLSBUILDER->SetArguments(aLS); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::setFuzzyValue(const double theFuzz) +{ + MY_CELLSBUILDER->SetFuzzyValue(theFuzz); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::setRunParallel(const bool theFlag) +{ + MY_CELLSBUILDER->SetRunParallel(theFlag); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::perform() +{ + MY_CELLSBUILDER->Perform(); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::clear() +{ + MY_CELLSBUILDER->Clear(); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::addToResult(const ListOfShape& theLSToTake, + const ListOfShape& theLSToAvoid, + const int theMaterial, + const bool theUpdate) +{ + NCollection_List aLSToTake, aLSToAvoid; + stdListToNCollectionList(theLSToTake, aLSToTake); + stdListToNCollectionList(theLSToAvoid, aLSToAvoid); + + MY_CELLSBUILDER->AddToResult(aLSToTake, aLSToAvoid, theMaterial, theUpdate); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::addAllToResult(const int theMaterial, + const bool theUpdate) +{ + MY_CELLSBUILDER->AddAllToResult(theMaterial, theUpdate); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::removeFromResult(const ListOfShape& theLSToTake, + const ListOfShape& theLSToAvoid) +{ + NCollection_List aLSToTake, aLSToAvoid; + stdListToNCollectionList(theLSToTake, aLSToTake); + stdListToNCollectionList(theLSToAvoid, aLSToAvoid); + + MY_CELLSBUILDER->RemoveFromResult(aLSToTake, aLSToAvoid); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::removeAllFromResult() +{ + MY_CELLSBUILDER->RemoveAllFromResult(); +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::removeInternalBoundaries() +{ + MY_CELLSBUILDER->RemoveInternalBoundaries(); +} + +//================================================================================================= +const std::shared_ptr GeomAlgoAPI_CellsBuilder::getAllParts() const +{ + const TopoDS_Shape aShape = MY_CELLSBUILDER->GetAllParts(); + std::shared_ptr aGeomShape(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + return aGeomShape; +} + +//================================================================================================= +void GeomAlgoAPI_CellsBuilder::makeContainers() +{ + MY_CELLSBUILDER->MakeContainers(); +} + +//================================================================================================= +bool GeomAlgoAPI_CellsBuilder::isDone() const +{ + return MY_CELLSBUILDER->ErrorStatus() == 0; +} + +//================================================================================================= +GEOMALGOAPI_EXPORT const std::shared_ptr GeomAlgoAPI_CellsBuilder::shape() const +{ + std::shared_ptr aResShape(new GeomAPI_Shape()); + TopoDS_Shape aShape = MY_CELLSBUILDER->Shape(); + + if(aShape.ShapeType() == TopAbs_COMPOUND) { + std::shared_ptr aCompound(new GeomAPI_Shape); + aCompound->setImpl(new TopoDS_Shape(aShape)); + ListOfShape aCompSolids, aFreeSolids; + GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); + if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { + aShape = 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()); + } + aShape = aResultComp; + } + } + + aResShape->setImpl(new TopoDS_Shape(aShape)); + const_cast(this)->setShape(aResShape); + + return GeomAlgoAPI_MakeShape::shape(); +} + +//================================================================================================= +void stdListToNCollectionList(const ListOfShape& theStdListOfShape, + NCollection_List& theNCollectionListOfShape) +{ + theNCollectionListOfShape.Clear(); + for(ListOfShape::const_iterator anIt = theStdListOfShape.cbegin(); anIt != theStdListOfShape.cend(); anIt++) { + const TopoDS_Shape aShape = (*anIt)->impl(); + theNCollectionListOfShape.Append(aShape); + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h new file mode 100644 index 000000000..e7581393d --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h @@ -0,0 +1,94 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_CellsBuilder.h +// Created: 11 December 2015 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_CellsBuilder_H_ +#define GeomAlgoAPI_CellsBuilder_H_ + +#include + +#include + +#include + +/// \class GeomAlgoAPI_CellsBuilder +/// \ingroup DataAlgo +/// \brief The purpose of this algorithm is to provide the result with the content of: +/// 1. Cells (parts) defined by the user; +/// 2. Internal boundaries defined by the user. +class GeomAlgoAPI_CellsBuilder : public GeomAlgoAPI_MakeShape +{ +public: + /// Default empty constructor. + GEOMALGOAPI_EXPORT GeomAlgoAPI_CellsBuilder(); + + /// \brief Sets arguments for the algorithm. + /// \param[in] theLS list of shape. + GEOMALGOAPI_EXPORT void setArguments(const ListOfShape &theLS); + + /// Sets the additional tolerance. + /// \param[in] theFuzz fuzz value. + GEOMALGOAPI_EXPORT void setFuzzyValue(const double theFuzz); + + /// \brief Sets the flag of parallel processing. If \p theFlag is true the parallel processing is switched on, + /// if \p theFlag is false the parallel processing is switched off. + /// \param[in] theFlag flag value. + GEOMALGOAPI_EXPORT void setRunParallel(const bool theFlag); + + /// \brief Make cells from the arguments. + GEOMALGOAPI_EXPORT void perform(); + + /// Clears the contents. + GEOMALGOAPI_EXPORT void clear(); + + /// \brief Adding the parts to result. + /// The parts are defined by two lists of shapes. To be taken into result the part must be IN + /// for all shapes from the list \p theLSToTake and must be OUT of all shapes from the list \p theLSToAvoid. + /// To remove internal boundaries between any cells in the result \p theMaterial variable should be used. + /// The boundaries between cells with the same material will be removed. Default value is 0. + /// Thus, to remove any boundary the value of this variable should not be equal to 0. + /// \param[in] theLSToTake defines the arguments which parts should be taken into result. + /// \param[in] theLSToAvoid defines the arguments which parts should not be taken into result. + /// \param[in] theMaterial material id. + /// \param[in] theUpdate defines whether to remove boundaries now or not. + GEOMALGOAPI_EXPORT void addToResult(const ListOfShape& theLSToTake, + const ListOfShape& theLSToAvoid, + const int theMaterial = 0, + const bool theUpdate = false); + + /// \brief Add all split parts to result + /// \param[in] theMaterial defines the removal of internal boundaries. + /// \param[in] theUpdate defines whether to remove boundaries now or not. + GEOMALGOAPI_EXPORT void addAllToResult(const int theMaterial = 0, + const bool theUpdate = false); + + /// \brief Removing the parts from result. + /// The parts are defined by two lists of shapes. To be removed from the result the part must be IN + /// for all shapes from the list \p theLSToTake and must be OUT of all shapes from the list \p theLSToAvoid. + /// \param[in] theLSToTake defines the arguments which parts should be removed from result. + /// \param[in] theLSToAvoid defines the arguments which parts should not be removed from result. + GEOMALGOAPI_EXPORT void removeFromResult(const ListOfShape& theLSToTake, + const ListOfShape& theLSToAvoid); + + /// Remove all parts from result. + GEOMALGOAPI_EXPORT void removeAllFromResult(); + + /// Removes internal boundaries between cells with the same material. + GEOMALGOAPI_EXPORT void removeInternalBoundaries(); + + /// Get all split parts. + GEOMALGOAPI_EXPORT const std::shared_ptr getAllParts() const; + + /// Makes the Containers of proper type from the parts added to result. + GEOMALGOAPI_EXPORT void makeContainers(); + + /// \return status of builder. + GEOMALGOAPI_EXPORT bool isDone() const; + + /// \return a shape built by the shape construction algorithm. + GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; +}; + +#endif \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index de201f61c..dcdbe50a6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -7,8 +7,7 @@ #include #include - -#include +#include #include #include @@ -20,17 +19,18 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include -#include //================================================================================================= @@ -288,3 +288,22 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std:: return aResultShape; } + +//================================================================================================= +void GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(const std::shared_ptr theCompSolid, + const ListOfShape& theSolidsToAvoid, + ListOfShape& theSolidsInCompSolid) +{ + for(GeomAPI_ShapeExplorer anExp(theCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) { + std::shared_ptr aSolidInCompSolid = anExp.current(); + ListOfShape::const_iterator anIt = theSolidsToAvoid.begin(); + for(; anIt != theSolidsToAvoid.end(); anIt++) { + if(aSolidInCompSolid->isEqual(*anIt)) { + break; + } + } + if(anIt == theSolidsToAvoid.end()) { + theSolidsInCompSolid.push_back(aSolidInCompSolid); + } + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index d361eb927..c20589487 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -13,51 +13,52 @@ #include -/** \class GeomAlgoAPI_ShapeTools - * \ingroup DataAlgo - * \brief Useful tools for working with shapes. - */ -class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools +/// \namespace GeomAlgoAPI_ShapeTools +/// \ingroup DataAlgo +/// \brief Useful tools for working with shapes. +namespace GeomAlgoAPI_ShapeTools { -public: /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. - static double volume(const std::shared_ptr theShape); + GEOMALGOAPI_EXPORT double volume(const std::shared_ptr theShape); /// \return the centre of mass of the current face. The coordinates returned for the center of mass /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). - static std::shared_ptr centreOfMass(const std::shared_ptr theShape); - - /** \brief Combines faces with common edges to shells, or solids to compsolids. - * \param[in] theCompound compound of shapes. - * \param[in] theType type of combine. - * \param[out] theCombinedShapes resulting shapes. - * \param[out] theFreeShapes shapes that does not have common subshapes. - */ - static void combineShapes(const std::shared_ptr theCompound, - const GeomAPI_Shape::ShapeType theType, - ListOfShape& theCombinedShapes, - ListOfShape& theFreeShapes); - - /** \brief Calculates bounding box for theShapes - * \return list of eight points. - * \param[in] theShapes list of shapes. - * \param[in] theEnlarge enlarges bounding box size. - */ - static std::list > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0); - - /** - * Returns infinite plane received from theFace plane. - */ - static std::shared_ptr faceToInfinitePlane(const std::shared_ptr theFace); - - /** \brief Enlarges or reduces plane to fit bounding box. - * \return plane that fits to bounding box. - * \param[in] thePlane base plane. - * \param[in] thePoints bounding box points (shoud be eight). - */ - static std::shared_ptr fitPlaneToBox(const std::shared_ptr thePlane, - const std::list >& thePoints); - -}; + GEOMALGOAPI_EXPORT std::shared_ptr centreOfMass(const std::shared_ptr theShape); + + /// \brief Combines faces with common edges to shells, or solids to compsolids. + /// \param[in] theCompound compound of shapes. + /// \param[in] theType type of combine. + /// \param[out] theCombinedShapes resulting shapes. + /// \param[out] theFreeShapes shapes that does not have common subshapes. + GEOMALGOAPI_EXPORT void combineShapes(const std::shared_ptr theCompound, + const GeomAPI_Shape::ShapeType theType, + ListOfShape& theCombinedShapes, + ListOfShape& theFreeShapes); + + /// \brief Calculates bounding box for theShapes + /// \return list of eight points. + /// \param[in] theShapes list of shapes. + /// \param[in] theEnlarge enlarges bounding box size. + GEOMALGOAPI_EXPORT std::list > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0); + + /// \return infinite plane received from theFace plane. + /// \param[in] theFace base face. + GEOMALGOAPI_EXPORT std::shared_ptr faceToInfinitePlane(const std::shared_ptr theFace); + + /// \brief Enlarges or reduces plane to fit bounding box. + /// \return plane that fits to bounding box. + /// \param[in] thePlane base plane. + /// \param[in] thePoints bounding box points (shoud be eight). + GEOMALGOAPI_EXPORT std::shared_ptr fitPlaneToBox(const std::shared_ptr thePlane, + const std::list >& thePoints); + + /// \brief Get list of solids from theCompSolid which is not present in theSolidsToAvoid list. + /// \param[in] theCompSolid compsolid. + /// \param[in] theSolidsToAvoid list of solids to avoid. + /// \param[out] theSolidsInCompSolid list of solids in compsolid. Note: list not cleared before adding. + GEOMALGOAPI_EXPORT void getSolidsInCompSolid(const std::shared_ptr theCompSolid, + const ListOfShape& theSolidsToAvoid, + ListOfShape& theSolidsInCompSolid); +} #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index 164f8ec61..d6c800bdb 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -34,6 +34,7 @@ #include "GeomAlgoAPI_Tools.h" #include "GeomAlgoAPI_Transform.h" #include "GeomAlgoAPI_PaveFiller.h" + #include "GeomAlgoAPI_CellsBuilder.h" #include #include