X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_BooleanSmash.cpp;h=a46ed7409b6ca664fb177e54f286f4cd2f55565c;hb=1d369e0e18eda4bfd12518d9798fd7fbf517e852;hp=2ec4468c4ac306b50c13775c39890308746404c2;hpb=f5f2457865bf513acd090a6254aca37ab18de0c9;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp index 2ec4468c4..a46ed7409 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.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,10 +12,9 @@ // // 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_BooleanSmash.h" @@ -36,6 +35,8 @@ #include #include +static const int THE_SMASH_VERSION_1 = 20190506; + //================================================================================================== FeaturesPlugin_BooleanSmash::FeaturesPlugin_BooleanSmash() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_SMASH) @@ -47,105 +48,59 @@ void FeaturesPlugin_BooleanSmash::initAttributes() { data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); data()->addAttribute(TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + + initVersion(THE_SMASH_VERSION_1); } //================================================================================================== void FeaturesPlugin_BooleanSmash::execute() { std::string anError; - ListOfShape anObjects, aTools; - std::map, ListOfShape> aCompSolidsObjects; - - // Getting objects. - AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_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(); - ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(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); - } - } + ObjectHierarchy anObjectsHistory, aToolsHistory; + ListOfShape aPlanes; - // Getting tools. - AttributeSelectionListPtr aToolsSelList = selectionList(TOOL_LIST_ID()); - for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); - GeomShapePtr aTool = aToolAttr->value(); - if(!aTool.get()) { - return; - } - aTools.push_back(aTool); - } + // Getting objects and tools. + if (!processAttribute(OBJECT_LIST_ID(), anObjectsHistory, aPlanes) || + !processAttribute(TOOL_LIST_ID(), aToolsHistory, aPlanes)) + return; int aResultIndex = 0; - if((anObjects.empty() && aCompSolidsObjects.empty()) - || aTools.empty()) { + if (anObjectsHistory.IsEmpty() || aToolsHistory.IsEmpty()) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; } + // Collecting all shapes which will be smashed. + ListOfShape aShapesToSmash = anObjectsHistory.Objects(); + // List of original shapes for naming. ListOfShape anOriginalShapes; - anOriginalShapes.insert(anOriginalShapes.end(), anObjects.begin(), anObjects.end()); + anOriginalShapes.insert(anOriginalShapes.end(), aShapesToSmash.begin(), aShapesToSmash.end()); + ListOfShape aTools = aToolsHistory.Objects(); anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end()); - // Collecting all shapes which will be smashed. - ListOfShape aShapesToSmash; - aShapesToSmash.insert(aShapesToSmash.end(), anObjects.begin(), anObjects.end()); - // 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(); + for (ObjectHierarchy::Iterator anIt = anObjectsHistory.Begin(); + anIt != anObjectsHistory.End(); ++anIt) { - std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - anOriginalShapes.push_back(aCompSolid); - aShapesToSmash.insert(aShapesToSmash.end(), - aUsedInOperationSolids.begin(), - aUsedInOperationSolids.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()) { - aShapesToAdd.push_back(aSolidInCompSolid); - } + GeomShapePtr aParent = anObjectsHistory.Parent(*anIt, false); + if (aParent) { + anOriginalShapes.push_back(aParent); + + ListOfShape aUsed, aNotUsed; + anObjectsHistory.SplitCompound(aParent, aUsed, aNotUsed); + aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end()); + + // add unused shapes of compounds/compsolids to the history, + // to avoid treating them as unused later when constructing a compound containing + // the result of Smash and all unused sub-shapes of multi-level compounds + for (ListOfShape::iterator anIt = aNotUsed.begin(); anIt != aNotUsed.end(); ++anIt) + anObjectsHistory.AddObject(*anIt); } } @@ -155,7 +110,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr anObjectsCutAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) { aShapesToSmash.clear(); @@ -167,7 +122,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aToolsCutAlgo( new GeomAlgoAPI_Boolean(aTools, aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) { aTools.clear(); @@ -180,7 +135,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aBoolAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { @@ -213,6 +168,14 @@ void FeaturesPlugin_BooleanSmash::execute() aMakeShapeList->appendAlgo(aFillerAlgo); } + // take into account a version of SMASH feature + int aSmashVersion = version(); + if (aSmashVersion == THE_SMASH_VERSION_1) { + // merge hierarchies of compounds containing objects and tools + // and append the result of the FUSE operation + aShape = keepUnusedSubsOfCompound(aShape, anObjectsHistory, aToolsHistory, aMakeShapeList); + } + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,