X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Union.cpp;h=c2385e93808972f81e654a1885d3c26f9292190f;hb=5a10b65659c971be26bd7343c50a2488e48f49e3;hp=76683a26fa5a866c2e57a40affcf19d468a82cdd;hpb=dc7d4d86b58b81684abc9b5a2be8ec30f210c2da;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp index 76683a26f..c2385e938 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 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 @@ -12,26 +12,29 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "FeaturesPlugin_Union.h" #include +#include #include #include -#include +#include +#include #include #include #include -#include +#include #include +static const int THE_UNION_VERSION_1 = 20190506; + //================================================================================================= FeaturesPlugin_Union::FeaturesPlugin_Union() { @@ -41,152 +44,92 @@ FeaturesPlugin_Union::FeaturesPlugin_Union() void FeaturesPlugin_Union::initAttributes() { data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); + initVersion(THE_UNION_VERSION_1, selectionList(BASE_OBJECTS_ID())); } //================================================================================================= void FeaturesPlugin_Union::execute() { - ListOfShape anObjects; - std::map, ListOfShape> aCompSolidsObjects; + ObjectHierarchy anObjects; + ListOfShape anEmptyList; // Getting objects. - AttributeSelectionListPtr anObjectsSelList = - selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID()); - for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if(!anObject.get()) { - return; - } - 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); - } - } - - // Collecting solids from compsolids which will not be modified in - // boolean operation and will be added to result. - ListOfShape aShapesToAdd; - for(std::map, ListOfShape>::iterator - anIt = aCompSolidsObjects.begin(); - anIt != aCompSolidsObjects.end(); anIt++) { - std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - anObjects.insert(anObjects.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); - - // Collect solids from compsolid which will not be modified in boolean operation. - for(GeomAPI_ShapeIterator anExp(aCompSolid); 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()) { - aShapesToAdd.push_back(aSolidInCompSolid); - } - } - } + if (!processAttribute(BASE_OBJECTS_ID(), anObjects, anEmptyList)) + return; - if(anObjects.size() < 2) { + if(anObjects.Objects().size() < 2) { setError("Error: Not enough objects for operation. Should be at least 2."); return; } + std::string anError; + int aResultIndex = 0; + std::vector aResultBaseAlgoList; + ListOfShape aResultShapesList; + + int aUnionVersion = version(); + GeomShapePtr aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(ListOfShape()); + // Fuse objects. - std::shared_ptr anAlgo; - ListOfShape aTools; - if (anObjects.front()->shapeType() == GeomAPI_Shape::SOLID) { - aTools.splice(aTools.begin(), anObjects, anObjects.begin()); - anAlgo.reset(new GeomAlgoAPI_Boolean(anObjects, - aTools, - GeomAlgoAPI_Boolean::BOOL_FUSE)); - } else { - anAlgo.reset(new GeomAlgoAPI_UnifySameDomain(anObjects)); + bool isOk = true; + for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin(); + anObjectsIt != anObjects.End() && isOk; + ++anObjectsIt) { + GeomShapePtr anObject = *anObjectsIt; + GeomShapePtr aParent = anObjects.Parent(anObject, false); + + if (aParent && aParent->shapeType() <= GeomAPI_Shape::COMPSOLID) { + // get parent once again to mark it and the subs as processed + aParent = anObjects.Parent(anObject); + // compsolid handling + isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_FUSE, + anObjects, aParent, anEmptyList, anEmptyList, + aResultIndex, aResultBaseAlgoList, aResultShapesList, + aResultCompound); + } else { + // process object as is + isOk = processObject(GeomAlgoAPI_Tools::BOOL_FUSE, + anObject, anEmptyList, anEmptyList, + aResultIndex, aResultBaseAlgoList, aResultShapesList, + aResultCompound); + } } - // Checking that the algorithm worked properly. - GeomAlgoAPI_MakeShapeList aMakeShapeList; - GeomAPI_DataMapOfShapeShape aMapOfShapes; - if(!anAlgo->isDone()) { - setError("Error: Boolean algorithm failed."); - return; - } - if(anAlgo->shape()->isNull()) { - setError("Error: Resulting shape is Null."); - return; - } - if(!anAlgo->isValid()) { - setError("Error: Resulting shape is not valid."); - return; + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + for (std::vector::iterator + aRBAIt = aResultBaseAlgoList.begin(); + aRBAIt != aResultBaseAlgoList.end(); ++aRBAIt) { + aMakeShapeList->appendAlgo(aRBAIt->makeShape); } - GeomShapePtr aShape = anAlgo->shape(); - aMakeShapeList.appendAlgo(anAlgo); - aMapOfShapes.merge(anAlgo->mapOfSubShapes()); - - // Store original shapes for naming. - anObjects.splice(anObjects.begin(), aTools); - anObjects.insert(anObjects.end(), aShapesToAdd.begin(), aShapesToAdd.end()); - - // Combine result with not used solids from compsolid. - if(aShapesToAdd.size() > 0) { - aShapesToAdd.push_back(aShape); - std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone()) { - setError("Error: PaveFiller algorithm failed."); - return; - } - if(aFillerAlgo->shape()->isNull()) { - setError("Error: Resulting shape is Null."); - return; - } - if(!aFillerAlgo->isValid()) { - setError("Error: Resulting shape is not valid."); - return; + GeomShapePtr aShape; + GeomAPI_ShapeIterator aCIt(aResultCompound); + if (aUnionVersion < THE_UNION_VERSION_1) { + // if the compound consists of a single sub-shape, take it, + // otherwise, take the full compound + aShape = aCIt.current(); + aCIt.next(); + if (aCIt.more()) + aShape = aResultCompound; + } + else { + // merge hierarchies of compounds containing objects and tools + aShape = keepUnusedSubsOfCompound(aCIt.current(), anObjects, ObjectHierarchy(), aMakeShapeList); + for (aCIt.next(); aCIt.more(); aCIt.next()) { + std::shared_ptr aBuilder(new GeomAlgoAPI_ShapeBuilder); + aBuilder->add(aShape, aCIt.current()); + aMakeShapeList->appendAlgo(aBuilder); } - - aShape = aFillerAlgo->shape(); - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); } - // workaround: make copy to name edges correctly // Store result and naming. - const int aModifyEdgeTag = 1; - const int aModifyFaceTag = 2; - const int aDeletedTag = 3; - /// sub solids will be placed at labels 4, 5 etc. if result is compound of solids - const int aSubsolidsTag = 4; - const std::string aModEName = "Modified_Edge"; - const std::string aModFName = "Modified_Face"; - std::shared_ptr aResultBody = document()->createBody(data()); - aResultBody->storeModified(anObjects.front(), aShape, aSubsolidsTag); - - for(ListOfShape::const_iterator anIter = anObjects.begin(); anIter != anObjects.end(); ++anIter) { - aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::EDGE, - aModifyEdgeTag, aModEName, aMapOfShapes, - true, false, true); - aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, - aModifyFaceTag, aModFName, aMapOfShapes, - true, false, true); + ListOfShape anObjectsList = anObjects.Objects(); + aResultBody->storeModified(anObjectsList.front(), aShape); + + for(ListOfShape::const_iterator anIter = anObjectsList.begin(); anIter != anObjectsList.end(); ++anIter) { + aResultBody->loadModifiedShapes(aMakeShapeList, *anIter, GeomAPI_Shape::EDGE); + aResultBody->loadModifiedShapes(aMakeShapeList, *anIter, GeomAPI_Shape::FACE); //aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag); }