X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_CompositeBoolean.cpp;h=d65e9f39888867da02726c1a3ec757688e05b5b0;hb=b928c27cd38f150c23d182df53c23ab266aa6b49;hp=5c86e7eb78717291da0d19aaa810147005d995ba;hpb=87b74a6fd4660ebfa71a40f0be84e44535f84798;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index 5c86e7eb7..d65e9f398 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: FeaturesPlugin_CompositeBoolean.cpp -// Created: 11 June 2015 -// Author: Dmitry Bobylev +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "FeaturesPlugin_CompositeBoolean.h" @@ -10,11 +23,13 @@ #include #include +#include #include #include #include +#include -#include +#include #include @@ -25,7 +40,7 @@ void FeaturesPlugin_CompositeBoolean::initBooleanAttributes() } //================================================================================================= -void FeaturesPlugin_CompositeBoolean::execute() +void FeaturesPlugin_CompositeBoolean::executeCompositeBoolean() { // Make generation. ListOfShape aGenBaseShapes; @@ -36,7 +51,8 @@ void FeaturesPlugin_CompositeBoolean::execute() // Getting tools. ListOfShape aTools; - for(ListOfMakeShape::const_iterator anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) { + for(ListOfMakeShape::const_iterator + anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) { aTools.push_back((*anIt)->shape()); } @@ -54,28 +70,158 @@ void FeaturesPlugin_CompositeBoolean::execute() // Store result. int aResultIndex = 0; + std::vector aResultBaseAlgoList; + ListOfShape aResultShapesList; ListOfShape::const_iterator aBoolObjIt = aBooleanObjects.cbegin(); ListOfMakeShape::const_iterator aBoolMSIt = aBooleanMakeShapes.cbegin(); for(; aBoolObjIt != aBooleanObjects.cend() && aBoolMSIt != aBooleanMakeShapes.cend(); ++aBoolObjIt, ++aBoolMSIt) { - int aTag = 1; - ResultBodyPtr aResultBody = myFeature->document()->createBody(myFeature->data(), aResultIndex); - aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape(), aTag); - aTag += 5000; + if((*aBoolObjIt)->isEqual((*aBoolMSIt)->shape())) { + aResultBody->store((*aBoolMSIt)->shape(), false); + } + else + { + aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape()); + + // Store generation history. + ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin(); + ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin(); + for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend(); + ++aGenBaseIt, ++aGenMSIt) { + std::shared_ptr aMSList(new GeomAlgoAPI_MakeShapeList()); + aMSList->appendAlgo(*aGenMSIt); + aMSList->appendAlgo(*aBoolMSIt); + storeGenerationHistory(aResultBody, *aGenBaseIt, aMSList); + } + + storeModificationHistory(aResultBody, *aBoolObjIt, aTools, *aBoolMSIt); + + ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = *aBoolObjIt; + aRBA.makeShape = *aBoolMSIt; + aResultBaseAlgoList.push_back(aRBA); + aResultShapesList.push_back((*aBoolMSIt)->shape()); + } + + myFeature->setResult(aResultBody, aResultIndex++); + } + + // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one + // result shape has been deleted, but in another it was modified or stayed. + GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); + storeDeletedShapes(aResultBaseAlgoList, aTools, aResultShapesCompound); + + myFeature->removeResults(aResultIndex); +} + +//================================================================================================= +bool FeaturesPlugin_CompositeBoolean::cutRecursiveCompound(const GeomShapePtr theCompound, + const ListOfShape& theTools, + std::shared_ptr& theMakeShapeList, + GeomShapePtr& theResult) +{ + // I. If theCompound is among the selected objects, + // cut it by all tools and return result through theResult. + // It can be a SOLID, ?COMPOUND?, ?COMPSOLID? + AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID()); + for (int anObjIndex = 0; anObjIndex < anObjectsSelList->size(); anObjIndex++) { + AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjIndex); + GeomShapePtr anObject = anObjectAttr->value(); + if (theCompound->isEqual(anObject)) { + // Cut theCompound itself + ListOfShape aListWithObject; + aListWithObject.push_back(anObject); + std::shared_ptr aBoolAlgo + (new GeomAlgoAPI_Boolean(aListWithObject, theTools, GeomAlgoAPI_Tools::BOOL_CUT)); + + // Checking that the algorithm worked properly. + if (!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { + myFeature->setError("Error: Boolean algorithm failed."); + return false; + } + + if (GeomAlgoAPI_ShapeTools::area(aBoolAlgo->shape()) > 1.e-27) { + theMakeShapeList->appendAlgo(aBoolAlgo); + theResult = aBoolAlgo->shape(); + return true; + } + return false; + } + } + + // II. Iterate the COMPOUND or COMPSOLID + // to find and cut Objects among its sub-shapes + if (theCompound->shapeType() == GeomAPI_Shape::COMPOUND || + theCompound->shapeType() == GeomAPI_Shape::COMPSOLID) { + + bool hasCut = false; + ListOfShape aShapesToAdd; + for (GeomAPI_ShapeIterator it (theCompound); it.more(); it.next()) { + GeomShapePtr aSubShape = it.current(); + GeomShapePtr aResult; + if (cutRecursiveCompound(aSubShape, theTools, theMakeShapeList, aResult)) { + hasCut = true; + aShapesToAdd.push_back(aResult); + } + else { + aShapesToAdd.push_back(aSubShape); + } + } - // Store generation history. - ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin(); - ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin(); - for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend(); - ++aGenBaseIt, ++aGenMSIt) { - storeGenerationHistory(aResultBody, *aGenBaseIt, *aGenMSIt, aTag); + if (hasCut) { + if (theCompound->shapeType() == GeomAPI_Shape::COMPSOLID) { + // Build COMPSOLID + std::shared_ptr aFillerAlgo + (new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + if (!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) { + myFeature->setError("Error: PaveFiller algorithm failed."); + return false; + } + theResult = aFillerAlgo->shape(); + theMakeShapeList->appendAlgo(aFillerAlgo); + } + else { + // Build COMPOUND + theResult = GeomAlgoAPI_CompoundBuilder::compound(aShapesToAdd); + std::shared_ptr aCompMkr (new GeomAlgoAPI_MakeShapeCustom); + aCompMkr->setResult(theResult); + aCompMkr->addModified(theCompound, theResult); // ?? + theMakeShapeList->appendAlgo(aCompMkr); + } + return true; } + } - int aModTag = aTag; - storeModificationHistory(aResultBody, *aBoolObjIt, aTools, *aBoolMSIt, aModTag); + return false; // no cuts +} + +//================================================================================================= +void FeaturesPlugin_CompositeBoolean::addSubShapes (const GeomShapePtr theCompound, + const ListOfShape& theSubShapesToAvoid, + ListOfShape& theSubShapesToAdd) { + for (GeomAPI_ShapeIterator aCompoundIt (theCompound); + aCompoundIt.more(); + aCompoundIt.next()) { + GeomShapePtr aCompoundSS = aCompoundIt.current(); + ListOfShape::const_iterator aUseIt = theSubShapesToAvoid.cbegin(); + for (; aUseIt != theSubShapesToAvoid.cend(); aUseIt++) { + if (aCompoundSS->isEqual(*aUseIt)) { + break; + } + } + if (aUseIt == theSubShapesToAvoid.cend()) { + if (aCompoundSS->shapeType() == GeomAPI_Shape::COMPSOLID || + aCompoundSS->shapeType() == GeomAPI_Shape::COMPOUND) { + addSubShapes(aCompoundSS, theSubShapesToAvoid, theSubShapesToAdd); + } + else { + theSubShapesToAdd.push_back(aCompoundSS); + } + } } } @@ -87,7 +233,27 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, // Getting objects. ListOfShape anObjects, anEdgesAndFaces, aCompSolids; std::map aCompSolidsObjects; + bool aCompoundsOnly = true;// if there are only compounds, do not use filler restoring compsolids + AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID()); + + // collect recursive (complex) compounds, if any + ListOfShape aCompounds; // recursive compounds + GeomAPI_DataMapOfShapeShape aCompoundsMap; // recursive compounds map + for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { + AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); + ResultPtr aContext = anObjectAttr->context(); + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); + if (aResCompSolidPtr.get()) { + // Root body owner (true) + ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true); + if (!aResRootPtr->isSame(aResCompSolidPtr)) { + aCompoundsMap.bind(aResRootPtr->shape(), aResRootPtr->shape()); + aCompounds.push_back(aResRootPtr->shape()); + } + } + } + for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); GeomShapePtr anObject = anObjectAttr->value(); @@ -96,19 +262,25 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, return false; } ResultPtr aContext = anObjectAttr->context(); - ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext); + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); if(aResCompSolidPtr.get()) { - GeomShapePtr aContextShape = aResCompSolidPtr->shape(); - std::map::iterator anIt = aCompSolidsObjects.begin(); - for(; anIt != aCompSolidsObjects.end(); anIt++) { - if(anIt->first->isEqual(aContextShape)) { - aCompSolidsObjects[anIt->first].push_back(anObject); - break; + ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true); + if (!aCompoundsMap.isBound(aResRootPtr->shape())) { + // Compsolid or a simple (one-level) compound + GeomShapePtr aContextShape = aResCompSolidPtr->shape(); + std::map::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); + aCompSolids.push_back(aContextShape); + if (aContextShape->shapeType() != GeomAPI_Shape::COMPOUND) + aCompoundsOnly = false; } - } - if(anIt == aCompSolidsObjects.end()) { - aCompSolidsObjects[aContextShape].push_back(anObject); - aCompSolids.push_back(aContextShape); } } else { if(anObject->shapeType() == GeomAPI_Shape::EDGE || @@ -122,19 +294,21 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, switch(myOperationType) { case BOOL_CUT: { - if((anObjects.empty() && aCompSolidsObjects.empty()) || theTools.empty()) { + if((anObjects.empty() && aCompSolidsObjects.empty() + && aCompoundsMap.size() < 1) || theTools.empty()) { myFeature->setError("Error: Not enough objects for boolean operation."); return false; } // For solids cut each object with all tools. - for(ListOfShape::const_iterator anIt = anObjects.cbegin(); anIt != anObjects.cend(); ++anIt) { + for(ListOfShape::const_iterator + anIt = anObjects.cbegin(); anIt != anObjects.cend(); ++anIt) { GeomShapePtr anObject = *anIt; ListOfShape aListWithObject; aListWithObject.push_back(anObject); std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aListWithObject, - theTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + theTools, + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { @@ -142,7 +316,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, return false; } - if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo->shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::area(aBoolAlgo->shape()) > 1.e-27) { theObjects.push_back(anObject); theMakeShapes.push_back(aBoolAlgo); } @@ -156,8 +330,11 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, // Collecting solids from compsolids which will not be modified in boolean operation. ListOfShape aShapesToAdd; - for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) { - GeomShapePtr aSolidInCompSolid = anExp.current(); + for (GeomAPI_ShapeIterator aCompSolidIt(aCompSolid); + aCompSolidIt.more(); + aCompSolidIt.next()) + { + GeomShapePtr aSolidInCompSolid = aCompSolidIt.current(); ListOfShape::const_iterator aUsedShapesIt = aUsedShapes.cbegin(); for(; aUsedShapesIt != aUsedShapes.cend(); ++aUsedShapesIt) { if(aSolidInCompSolid->isEqual(*aUsedShapesIt)) { @@ -170,8 +347,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, } std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedShapes, - theTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + theTools, + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { @@ -179,24 +356,53 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, return false; } - GeomAlgoAPI_MakeShapeList aMakeShapeList; - aMakeShapeList.appendAlgo(aBoolAlgo); + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + aMakeShapeList->appendAlgo(aBoolAlgo); // Add result to not used solids from compsolid. - aShapesToAdd.push_back(aBoolAlgo->shape()); - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) { - myFeature->setError("Error: PaveFiller algorithm failed."); - return false; + GeomShapePtr aBoolRes = aBoolAlgo->shape(); + if (!aShapesToAdd.empty()) { + aShapesToAdd.push_back(aBoolRes); + if (aCompoundsOnly) + { // 23885: if there are no compsolids in input, do not use filler to make compsolids + aBoolRes = GeomAlgoAPI_CompoundBuilder::compound(aShapesToAdd); + std::shared_ptr aCompMkr(new GeomAlgoAPI_MakeShapeCustom); + aCompMkr->setResult(aBoolRes); + for(ListOfShape::iterator aCS = aCompSolids.begin(); aCS != aCompSolids.end(); aCS++) + aCompMkr->addModified(*aCS, aBoolRes); + aMakeShapeList->appendAlgo(aCompMkr); + } + else + { + std::shared_ptr aFillerAlgo( + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + if (!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) + { + myFeature->setError("Error: PaveFiller algorithm failed."); + return false; + } + aBoolRes = aFillerAlgo->shape(); + aMakeShapeList->appendAlgo(aFillerAlgo); + } } - aMakeShapeList.appendAlgo(aFillerAlgo); - - if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo->shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::area(aBoolRes) > 1.e-27) { theObjects.push_back(aCompSolid); - theMakeShapes.push_back(aBoolAlgo); + theMakeShapes.push_back(aMakeShapeList); } } + + // Complex (recursive) compounds handling + for(ListOfShape::const_iterator anIt = aCompounds.cbegin(); + anIt != aCompounds.cend(); ++anIt) { + GeomShapePtr aCompound = (*anIt); + GeomShapePtr aRes; + std::shared_ptr aMakeShapeList (new GeomAlgoAPI_MakeShapeList()); + cutRecursiveCompound(aCompound, theTools, aMakeShapeList, aRes); + theObjects.push_back(aCompound); + theMakeShapes.push_back(aMakeShapeList); + } + break; } case BOOL_FUSE: { @@ -204,10 +410,11 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, theObjects.insert(theObjects.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end()); theObjects.insert(theObjects.end(), anObjects.begin(), anObjects.end()); theObjects.insert(theObjects.end(), aCompSolids.begin(), aCompSolids.end()); + theObjects.insert(theObjects.end(), aCompounds.begin(), aCompounds.end()); // Filter edges and faces in tools. ListOfShape aTools; - for(ListOfShape::const_iterator anIt = aTools.cbegin(); anIt != aTools.cend(); ++anIt) { + for(ListOfShape::const_iterator anIt = theTools.cbegin(); anIt != theTools.cend(); ++anIt) { if((*anIt)->shapeType() == GeomAPI_Shape::EDGE || (*anIt)->shapeType() == GeomAPI_Shape::FACE) { anEdgesAndFaces.push_back(*anIt); @@ -216,7 +423,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, } } - if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) { + if((anObjects.size() + aTools.size() + aCompounds.size() + + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) { myFeature->setError("Error: Not enough objects for boolean operation."); return false; } @@ -226,27 +434,23 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, 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 and will be added to result. + // Collecting solids and compsolids from compounds which will not be + // modified in boolean operation and will be added to result. ListOfShape aShapesToAdd; - for(std::map::iterator anIt = aCompSolidsObjects.begin(); - anIt != aCompSolidsObjects.end(); anIt++) { + for (ListOfShape::iterator anIt = aCompounds.begin(); + anIt != aCompounds.end(); anIt++) { + GeomShapePtr aCompound = (*anIt); + addSubShapes(aCompound, anObjects, aShapesToAdd); + } + + // Collecting solids from compsolids which will not be + // modified in boolean operation and will be added to result. + for (std::map::iterator anIt = aCompSolidsObjects.begin(); + anIt != aCompSolidsObjects.end(); anIt++) { GeomShapePtr aCompSolid = anIt->first; ListOfShape& aUsedShapes = anIt->second; - aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.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()) { - GeomShapePtr aSolidInCompSolid = anExp.current(); - ListOfShape::iterator anIt = aUsedShapes.begin(); - for(; anIt != aUsedShapes.end(); anIt++) { - if(aSolidInCompSolid->isEqual(*anIt)) { - break; - } - } - if(anIt == aUsedShapes.end()) { - aShapesToAdd.push_back(aSolidInCompSolid); - } - } + aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end()); //??? + addSubShapes(aCompSolid, aUsedShapes, aShapesToAdd); } // Cut edges and faces(if we have any) with solids. @@ -255,27 +459,27 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, aCutTools.insert(aCutTools.end(), aCompSolids.begin(), aCompSolids.end()); aCutTools.insert(aCutTools.end(), aTools.begin(), aTools.end()); - GeomAlgoAPI_MakeShapeList aMakeShapeList; + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); if(!anEdgesAndFaces.empty() && !aCutTools.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, - aCutTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + aCutTools, + GeomAlgoAPI_Tools::BOOL_CUT)); if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) { anEdgesAndFaces.clear(); anEdgesAndFaces.push_back(aCutAlgo->shape()); - aMakeShapeList.appendAlgo(aCutAlgo); + aMakeShapeList->appendAlgo(aCutAlgo); } } // If we have compsolids then cut with not used solids all others. if(!aShapesToAdd.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse, - aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); - if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) { + aShapesToAdd, + GeomAlgoAPI_Tools::BOOL_CUT)); + if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::area(aCutAlgo->shape()) > 1.e-27) { aSolidsToFuse.clear(); aSolidsToFuse.push_back(aCutAlgo->shape()); - aMakeShapeList.appendAlgo(aCutAlgo); + aMakeShapeList->appendAlgo(aCutAlgo); } } @@ -290,8 +494,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, aTools = aSolidsToFuse; std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, - aTools, - GeomAlgoAPI_Boolean::BOOL_FUSE)); + aTools, + GeomAlgoAPI_Tools::BOOL_FUSE)); // Checking that the algorithm worked properly. if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) { @@ -300,7 +504,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, } aFusedShape = aFuseAlgo->shape(); - aMakeShapeList.appendAlgo(aFuseAlgo); + aMakeShapeList->appendAlgo(aFuseAlgo); } // Combine result with not used solids from compsolid and edges and faces (if we have any). @@ -310,16 +514,21 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, aShapesToAdd.push_back(aFusedShape); } - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + std::shared_ptr aFillerAlgo( + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) { myFeature->setError("Error: PaveFiller algorithm failed."); return false; } - aMakeShapeList.appendAlgo(aFillerAlgo); + aMakeShapeList->appendAlgo(aFillerAlgo); } + + theMakeShapes.push_back(aMakeShapeList); break; } + default: // [to avoid compilation warnings] + break; } return true; @@ -329,37 +538,41 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, void FeaturesPlugin_CompositeBoolean::storeModificationHistory(ResultBodyPtr theResultBody, const GeomShapePtr theObject, const ListOfShape& theTools, - const std::shared_ptr theMakeShape, - int& theTag) + const std::shared_ptr theMakeShape) { - int aModTag = theTag; - int anEdgesAndFacesTag = ++aModTag; - int aDelTag = ++anEdgesAndFacesTag; - theTag = aDelTag; - - const std::string aModName = "Modfied"; - ListOfShape aTools = theTools; aTools.push_back(theObject); - std::shared_ptr aMap = theMakeShape->mapOfSubShapes(); - - int aTag; - std::string aName; for(ListOfShape::const_iterator anIt = aTools.begin(); anIt != aTools.end(); anIt++) { - if((*anIt)->shapeType() == GeomAPI_Shape::EDGE) { - aTag = anEdgesAndFacesTag; - aName = aModName + "_Edge"; - } - else if((*anIt)->shapeType() == GeomAPI_Shape::FACE) { - aTag = anEdgesAndFacesTag; - aName = aModName + "_Face"; - } else { - aTag = aModTag; - aName = aModName; + theResultBody->loadModifiedShapes(theMakeShape, *anIt, + (*anIt)->shapeType() == GeomAPI_Shape::EDGE ? + GeomAPI_Shape::EDGE : + GeomAPI_Shape::FACE); + } +} + +//================================================================================================== +void FeaturesPlugin_CompositeBoolean::storeDeletedShapes( + std::vector& theResultBaseAlgoList, + const ListOfShape& theTools, + const GeomShapePtr theResultShapesCompound) +{ + for (std::vector::iterator anIt = theResultBaseAlgoList.begin(); + anIt != theResultBaseAlgoList.end(); + ++anIt) + { + ResultBaseAlgo& aRCA = *anIt; + aRCA.resultBody->loadDeletedShapes(aRCA.makeShape, + aRCA.baseShape, + GeomAPI_Shape::FACE, + theResultShapesCompound); + + for (ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) + { + aRCA.resultBody->loadDeletedShapes(aRCA.makeShape, + *anIter, + GeomAPI_Shape::FACE, + theResultShapesCompound); } - theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, (*anIt)->shapeType() == GeomAPI_Shape::EDGE ? - GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get()); - theResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag); } }