X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Boolean.cpp;h=99afc6e8dbf6d78c1c37838d639f26fad7caf9f4;hb=ce9a1d1c5d51c711390aa88bf348240337a93b74;hp=d4a7c0e9cf6ea2cb3b54d1b283a4dee2bd9b8a4b;hpb=b5b7c064ca02e68da4cf892ec28bb7ba80a4c550;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index d4a7c0e9c..99afc6e8d 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())); @@ -77,17 +77,16 @@ std::shared_ptr FeaturesPlugin_Boolean::getShape(const std::strin return std::shared_ptr(); } +//================================================================================================= +FeaturesPlugin_Boolean::OperationType FeaturesPlugin_Boolean::operationType() +{ + return myOperationType; +} + //================================================================================================= void FeaturesPlugin_Boolean::execute() { - // 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(); - - ListOfShape anObjects, aTools, anEdgesAndFaces; + 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; + GeomAlgoAPI_MakeShapeList aMakeShapeList; + 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,28 @@ 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, *(aBoolAlgo->mapOfSubShapes()), + myOperationType == BOOL_FILL); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -245,9 +285,10 @@ void FeaturesPlugin_Boolean::execute() } } + GeomAlgoAPI_MakeShapeList aMakeShapeList; std::shared_ptr aBoolAlgo; - switch(aType) { + switch(myOperationType) { case BOOL_CUT: { aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, @@ -261,7 +302,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,7 +342,6 @@ void FeaturesPlugin_Boolean::execute() return; } - GeomAlgoAPI_MakeShapeList aMakeShapeList; aMakeShapeList.appendAlgo(aBoolAlgo); GeomAPI_DataMapOfShapeShape aMapOfShapes; aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes()); @@ -306,10 +364,24 @@ void FeaturesPlugin_Boolean::execute() 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, + aMapOfShapes, + myOperationType == BOOL_FILL); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -626,17 +698,19 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t const ListOfShape& theTools, const std::shared_ptr theResultShape, GeomAlgoAPI_MakeShape& theMakeShape, - GeomAPI_DataMapOfShapeShape& theMapOfShapes) + GeomAPI_DataMapOfShapeShape& theMapOfShapes, + const bool theIsStoreAsGenerated) { //load result if(theBaseShape->isEqual(theResultShape)) { - theResultBody->store(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; + const int aModifyEdgeTag = 2; + const int aModifyFaceTag = 3; + const int aDeletedTag = 4; + /// sub solids will be placed at labels 5, 6, etc. if result is compound of solids + const int aSubsolidsTag = 5; theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag); @@ -644,8 +718,10 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t const std::string aModEName = "Modified_Edge"; const std::string aModFName = "Modified_Face"; + theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::EDGE, + aModifyEdgeTag, aModEName, theMapOfShapes, false, theIsStoreAsGenerated, true); theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, - aModifyTag, aModName, theMapOfShapes, false, false, true); + aModifyFaceTag, aModFName, theMapOfShapes, false, theIsStoreAsGenerated, true); theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag); @@ -653,20 +729,16 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t 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; + if((*anIter)->shapeType() <= GeomAPI_Shape::FACE) { + aTag = aModifyFaceTag; aName = aModFName; } else { - aTag = aModifyTag; - aName = aModName; + aTag = aModifyEdgeTag; + aName = aModEName; } theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, - aTag, aName, theMapOfShapes, false, false, true); + aTag, aName, theMapOfShapes, false, theIsStoreAsGenerated, true); theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag); } }