X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Boolean.cpp;h=63a7834b008c638ce8d1285f03fc9ff96b4dcdb0;hb=65fb6fac9731831e7197d0841e4444e69eb7d7ce;hp=b51d76b60079f828e22d108873850259b1bce324;hpb=8e97f0514a5e19febf05a98077f84f63756f169f;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index b51d76b60..63a7834b0 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -32,10 +31,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -43,15 +44,14 @@ #include //================================================================================================= -FeaturesPlugin_Boolean::FeaturesPlugin_Boolean() +FeaturesPlugin_Boolean::FeaturesPlugin_Boolean(const OperationType theOperationType) +: myOperationType(theOperationType) { } //================================================================================================= void FeaturesPlugin_Boolean::initAttributes() { - data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId()); - AttributeSelectionListPtr aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); @@ -78,16 +78,15 @@ std::shared_ptr FeaturesPlugin_Boolean::getShape(const std::strin } //================================================================================================= -void FeaturesPlugin_Boolean::execute() +FeaturesPlugin_Boolean::OperationType FeaturesPlugin_Boolean::operationType() { - // Getting operation type. - std::shared_ptr aTypeAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID())); - if (!aTypeAttr) - return; - OperationType aType = (FeaturesPlugin_Boolean::OperationType)aTypeAttr->value(); + return myOperationType; +} - ListOfShape anObjects, aTools, anEdgesAndFaces; +//================================================================================================= +void FeaturesPlugin_Boolean::execute() +{ + ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes; std::map, ListOfShape> aCompSolidsObjects; // Getting objects. @@ -100,7 +99,7 @@ void FeaturesPlugin_Boolean::execute() return; } ResultPtr aContext = anObjectAttr->context(); - ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext); + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); if(aResCompSolidPtr.get() && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) { std::shared_ptr aContextShape = aResCompSolidPtr->shape(); @@ -116,10 +115,14 @@ void FeaturesPlugin_Boolean::execute() aCompSolidsObjects[aContextShape].push_back(anObject); } } else { - if(anObject->shapeType() == GeomAPI_Shape::EDGE || - anObject->shapeType() == GeomAPI_Shape::FACE) { + if(myOperationType != BOOL_FILL + && (anObject->shapeType() == GeomAPI_Shape::EDGE + || anObject->shapeType() == GeomAPI_Shape::FACE)) + { anEdgesAndFaces.push_back(anObject); - } else { + } + else + { anObjects.push_back(anObject); } } @@ -129,12 +132,16 @@ void FeaturesPlugin_Boolean::execute() AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); - std::shared_ptr aTool = aToolAttr->value(); + GeomShapePtr aTool = aToolAttr->value(); if(!aTool.get()) { - return; + // It could be a construction plane. + ResultPtr aContext = aToolAttr->context(); + aPlanes.push_back(aToolAttr->context()->shape()); } - if(aTool->shapeType() == GeomAPI_Shape::EDGE || - aTool->shapeType() == GeomAPI_Shape::FACE) { + else if (myOperationType != BOOL_FILL + && (aTool->shapeType() == GeomAPI_Shape::EDGE + || aTool->shapeType() == GeomAPI_Shape::FACE)) + { anEdgesAndFaces.push_back(aTool); } else { aTools.push_back(aTool); @@ -143,11 +150,12 @@ void FeaturesPlugin_Boolean::execute() int aResultIndex = 0; - switch(aType) { + switch(myOperationType) { case BOOL_CUT: case BOOL_COMMON: case BOOL_FILL: { - if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) { + if((anObjects.empty() && aCompSolidsObjects.empty()) + || (aTools.empty() && aPlanes.empty())) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; @@ -159,26 +167,47 @@ void FeaturesPlugin_Boolean::execute() std::shared_ptr anObject = *anObjectsIt; ListOfShape aListWithObject; aListWithObject.push_back(anObject); - GeomAlgoAPI_MakeShape aBoolAlgo; + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + std::shared_ptr aBoolAlgo; GeomShapePtr aResShape; - switch(aType) { + switch(myOperationType) { case BOOL_CUT: { - aBoolAlgo = - GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT); - aResShape = aBoolAlgo.shape(); + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, + aTools, + GeomAlgoAPI_Boolean::BOOL_CUT)); + aResShape = aBoolAlgo->shape(); break; } case BOOL_COMMON: { - aBoolAlgo = - GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON); - aResShape = aBoolAlgo.shape(); + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, + aTools, + GeomAlgoAPI_Boolean::BOOL_COMMON)); + aResShape = aBoolAlgo->shape(); break; } case BOOL_FILL: { - aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools); - aResShape = aBoolAlgo.shape(); - if(aResShape->shapeType() == GeomAPI_Shape::COMPOUND) { + std::list > aBoundingPoints = + GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0); + + // Resize planes. + ListOfShape aToolsWithPlanes = aTools; + for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); + anIt != aPlanes.cend(); + ++anIt) + { + GeomShapePtr aPlane = *anIt; + GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); + std::shared_ptr aMkShCustom( + new GeomAlgoAPI_MakeShapeCustom); + aMkShCustom->addModified(aPlane, aTool); + aMakeShapeList->appendAlgo(aMkShCustom); + aToolsWithPlanes.push_back(aTool); + } + + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes)); + aResShape = aBoolAlgo->shape(); + if (aResShape.get() && aResShape->shapeType() == GeomAPI_Shape::COMPOUND) { int aSubResultsNb = 0; GeomAPI_ShapeIterator anIt(aResShape); for(; anIt.more(); anIt.next()) { @@ -196,7 +225,7 @@ void FeaturesPlugin_Boolean::execute() } // Checking that the algorithm worked properly. - if(!aBoolAlgo.isDone()) { + if(!aBoolAlgo->isDone()) { static const std::string aFeatureError = "Error: Boolean algorithm failed."; setError(aFeatureError); return; @@ -206,17 +235,26 @@ void FeaturesPlugin_Boolean::execute() setError(aShapeError); return; } - if(!aBoolAlgo.isValid()) { + if(!aBoolAlgo->isValid()) { std::string aFeatureError = "Error: Resulting shape is not valid."; setError(aFeatureError); return; } - if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) { + aMakeShapeList->appendAlgo(aBoolAlgo); + + if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27 + || (myOperationType != BOOL_CUT && myOperationType != BOOL_COMMON)) + { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, anObject, aTools, aResShape, - aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get()); + + ListOfShape aUsedTools = aTools; + if (myOperationType == BOOL_FILL) { + aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end()); + } + + loadNamingDS(aResultBody, anObject, aUsedTools, aResShape, aMakeShapeList); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -245,9 +283,10 @@ void FeaturesPlugin_Boolean::execute() } } + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); std::shared_ptr aBoolAlgo; - switch(aType) { + switch(myOperationType) { case BOOL_CUT: { aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, @@ -261,7 +300,25 @@ void FeaturesPlugin_Boolean::execute() break; } case BOOL_FILL: { - aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools)); + std::list > aBoundingPoints = + GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0); + + // Resize planes. + ListOfShape aToolsWithPlanes = aTools; + for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); + anIt != aPlanes.cend(); + ++anIt) + { + GeomShapePtr aPlane = *anIt; + GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); + std::shared_ptr aMkShCustom( + new GeomAlgoAPI_MakeShapeCustom); + aMkShCustom->addModified(aPlane, aTool); + aMakeShapeList->appendAlgo(aMkShCustom); + aToolsWithPlanes.push_back(aTool); + } + + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes)); break; } } @@ -283,10 +340,7 @@ void FeaturesPlugin_Boolean::execute() return; } - GeomAlgoAPI_MakeShapeList aMakeShapeList; - aMakeShapeList.appendAlgo(aBoolAlgo); - GeomAPI_DataMapOfShapeShape aMapOfShapes; - aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aBoolAlgo); GeomShapePtr aResultShape = aBoolAlgo->shape(); // Add result to not used solids from compsolid. @@ -301,15 +355,26 @@ void FeaturesPlugin_Boolean::execute() return; } - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aFillerAlgo); aResultShape = aFillerAlgo->shape(); } - if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) { + if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27 + || (myOperationType != BOOL_CUT && myOperationType != BOOL_COMMON)) + { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aCompSolid, aTools, aResultShape, aMakeShapeList, aMapOfShapes); + + ListOfShape aUsedTools = aTools; + if (myOperationType == BOOL_FILL) { + aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end()); + } + + loadNamingDS(aResultBody, + aCompSolid, + aUsedTools, + aResultShape, + aMakeShapeList); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -360,16 +425,14 @@ void FeaturesPlugin_Boolean::execute() anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end()); // Cut edges and faces(if we have any) with solids. - GeomAlgoAPI_MakeShapeList aMakeShapeList; - GeomAPI_DataMapOfShapeShape aMapOfShapes; + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); std::shared_ptr aCuttedEdgesAndFaces; if(!anEdgesAndFaces.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT)); if(aCutAlgo->isDone()) { aCuttedEdgesAndFaces = aCutAlgo->shape(); - aMakeShapeList.appendAlgo(aCutAlgo); - aMapOfShapes.merge(aCutAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aCutAlgo); } } anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(), @@ -387,8 +450,7 @@ void FeaturesPlugin_Boolean::execute() if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) { aSolidsToFuse.push_back(aCutAlgo->shape()); - aMakeShapeList.appendAlgo(aCutAlgo); - aMapOfShapes.merge(aCutAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aCutAlgo); } } } @@ -429,8 +491,7 @@ void FeaturesPlugin_Boolean::execute() } aShape = aFuseAlgo->shape(); - aMakeShapeList.appendAlgo(aFuseAlgo); - aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aFuseAlgo); } // Combine result with not used solids from compsolid and edges and faces (if we have any). @@ -462,8 +523,7 @@ void FeaturesPlugin_Boolean::execute() } aShape = aFillerAlgo->shape(); - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aFillerAlgo); } std::shared_ptr aBackShape = anOriginalShapes.back(); @@ -471,7 +531,7 @@ void FeaturesPlugin_Boolean::execute() std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); loadNamingDS(aResultBody, aBackShape, anOriginalShapes, - aShape, aMakeShapeList, aMapOfShapes); + aShape, aMakeShapeList); setResult(aResultBody, aResultIndex); aResultIndex++; break; @@ -520,8 +580,7 @@ void FeaturesPlugin_Boolean::execute() } } - GeomAlgoAPI_MakeShapeList aMakeShapeList; - GeomAPI_DataMapOfShapeShape aMapOfShapes; + std::shared_ptr aMakeShapeList; if(!aShapesToAdd.empty()) { // Cut objects with not used solids. std::shared_ptr anObjectsCutAlgo(new GeomAlgoAPI_Boolean( @@ -532,8 +591,7 @@ void FeaturesPlugin_Boolean::execute() if(GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) { aShapesToSmash.clear(); aShapesToSmash.push_back(anObjectsCutAlgo->shape()); - aMakeShapeList.appendAlgo(anObjectsCutAlgo); - aMapOfShapes.merge(anObjectsCutAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(anObjectsCutAlgo); } // Cut tools with not used solids. @@ -544,8 +602,7 @@ void FeaturesPlugin_Boolean::execute() if(GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) { aTools.clear(); aTools.push_back(aToolsCutAlgo->shape()); - aMakeShapeList.appendAlgo(aToolsCutAlgo); - aMapOfShapes.merge(aToolsCutAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aToolsCutAlgo); } } @@ -570,8 +627,7 @@ void FeaturesPlugin_Boolean::execute() setError(aFeatureError); return; } - aMakeShapeList.appendAlgo(aBoolAlgo); - aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aBoolAlgo); // Put all (cut result, tools and not used solids) to PaveFiller. aShapesToAdd.push_back(aBoolAlgo->shape()); @@ -596,15 +652,13 @@ void FeaturesPlugin_Boolean::execute() } std::shared_ptr aShape = aFillerAlgo->shape(); - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + aMakeShapeList->appendAlgo(aFillerAlgo); std::shared_ptr aFrontShape = anOriginalShapes.front(); anOriginalShapes.pop_front(); std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aFrontShape, anOriginalShapes, - aShape, aMakeShapeList, aMapOfShapes); + loadNamingDS(aResultBody, aFrontShape, anOriginalShapes, aShape, aMakeShapeList); setResult(aResultBody, aResultIndex); aResultIndex++; @@ -625,49 +679,30 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t const std::shared_ptr theBaseShape, const ListOfShape& theTools, const std::shared_ptr theResultShape, - GeomAlgoAPI_MakeShape& theMakeShape, - GeomAPI_DataMapOfShapeShape& theMapOfShapes) + const GeomMakeShapePtr& theMakeShape) { //load result if(theBaseShape->isEqual(theResultShape)) { theResultBody->store(theResultShape, false); - } else { - const int aModifyTag = 1; - const int aDeletedTag = 2; - /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids - const int aSubsolidsTag = 3; - const int anEdgesAndFacesTag = 10000; - - theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag); - - const std::string aModName = "Modified"; - const std::string aModEName = "Modified_Edge"; - const std::string aModFName = "Modified_Face"; - - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, - aModifyTag, aModName, theMapOfShapes, false, false, true); - theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, - GeomAPI_Shape::FACE, aDeletedTag); - - int aTag; - std::string aName; - for(ListOfShape::const_iterator - anIter = theTools.begin(); anIter != theTools.end(); anIter++) { - if((*anIter)->shapeType() == GeomAPI_Shape::EDGE) { - aTag = anEdgesAndFacesTag; - aName = aModEName; - } - else if((*anIter)->shapeType() == GeomAPI_Shape::FACE) { - aTag = anEdgesAndFacesTag; - aName = aModFName; - } else { - aTag = aModifyTag; - aName = aModName; - } - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, - aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, - aTag, aName, theMapOfShapes, false, false, true); - theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag); - } + return; + } + + theResultBody->storeModified(theBaseShape, theResultShape); + + theResultBody->loadModifiedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE); + theResultBody->loadModifiedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE); + + theResultBody->loadDeletedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE); + + for (ListOfShape::const_iterator anIter = theTools.begin(); + anIter != theTools.end(); + ++anIter) + { + GeomAPI_Shape::ShapeType aShapeType = + (*anIter)->shapeType() <= GeomAPI_Shape::FACE ? GeomAPI_Shape::FACE + : GeomAPI_Shape::EDGE; + theResultBody->loadModifiedShapes(theMakeShape, *anIter, aShapeType); + + theResultBody->loadDeletedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE); } }