X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FFeaturesPlugin%2FFeaturesPlugin_RemoveSubShapes.cpp;h=370efa3a6d76bb3ab73850afd123e344f8f327a7;hb=4289f04d4dcda1de53b4d33f63bc13e24a0fb650;hp=53d02ab83e183e643c45c03357965aea72d51dc1;hpb=2ca2f176d8ee99adf29d119e7ca6fe658fa63e8b;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp index 53d02ab83..370efa3a6 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.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,19 +12,19 @@ // // 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_RemoveSubShapes.h" #include +#include #include -#include #include #include +#include #include #include @@ -38,6 +38,7 @@ //================================================================================================== FeaturesPlugin_RemoveSubShapes::FeaturesPlugin_RemoveSubShapes() +: myChangedInCode(false) { } @@ -46,59 +47,164 @@ void FeaturesPlugin_RemoveSubShapes::initAttributes() { data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(SUBSHAPES_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(SUBSHAPES_TO_KEEP_ID(), ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(SUBSHAPES_TO_REMOVE_ID(), ModelAPI_AttributeSelectionList::typeId()); } void FeaturesPlugin_RemoveSubShapes::attributeChanged(const std::string& theID) { ModelAPI_Feature::attributeChanged(theID); - if(theID == BASE_SHAPE_ID()) { - AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); - AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID()); - if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) { - return; - } + if (myChangedInCode) return; - aSubShapesAttrList->clear(); + AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); + AttributeSelectionListPtr aSubShapesToKeepAttrList = selectionList(SUBSHAPES_TO_KEEP_ID()); + AttributeSelectionListPtr aSubShapesToRemoveAttrList = selectionList(SUBSHAPES_TO_REMOVE_ID()); + if (!aShapeAttrSelection.get() + || !aSubShapesToKeepAttrList.get() + || !aSubShapesToRemoveAttrList.get()) + { + return; + } - ResultPtr aContext = aShapeAttrSelection->context(); - ResultCompSolidPtr aResultCompSolid = - std::dynamic_pointer_cast(aContext); - if(!aResultCompSolid.get()) { - return; - } + ResultPtr aContext = aShapeAttrSelection->context(); + ResultBodyPtr aResultBody = + std::dynamic_pointer_cast(aContext); + if (!aResultBody.get()) { + aSubShapesToKeepAttrList->clear(); + aSubShapesToRemoveAttrList->clear(); + return; + } + const bool isHasSubs = ModelAPI_Tools::hasSubResults(aResultBody); - GeomShapePtr aBaseShape = aShapeAttrSelection->value(); - if(!aBaseShape.get()) { - aBaseShape = aContext->shape(); - } - if(!aBaseShape.get()) { - return; + GeomShapePtr aBaseShape = aShapeAttrSelection->value(); + if(!aBaseShape.get()) { + aBaseShape = aContext->shape(); + } + + myChangedInCode = true; + if (theID == BASE_SHAPE_ID() || theID == SUBSHAPES_TO_KEEP_ID() || + theID == SUBSHAPES_TO_REMOVE_ID()) { + std::list anAllSubs; + ModelAPI_Tools::allSubs(aResultBody, anAllSubs); + + if(theID == BASE_SHAPE_ID()) { + aSubShapesToKeepAttrList->clear(); + aSubShapesToRemoveAttrList->clear(); + + if (!aBaseShape.get()) { + return; + } + + std::list aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape); + ListOfShape::const_iterator anIt = aSubShapes.cbegin(); + for (; anIt != aSubShapes.cend(); ++anIt) + { + GeomShapePtr aSubShape = *anIt; + if(!isHasSubs) { + aSubShapesToKeepAttrList->append(aContext, aSubShape); + } else { + std::list::iterator aSubsIt = anAllSubs.begin(); + for(; aSubsIt != anAllSubs.end(); aSubsIt++) { + ResultBodyPtr aSub = std::dynamic_pointer_cast(*aSubsIt); + if (aSub && aSub->shape().get() && aSub->shape()->isSubShape(aSubShape)) { + aSubShapesToKeepAttrList->append(aSub, aSubShape); + break; + } + } + } + } } - GeomAPI_Shape::ShapeType aShapeType = aBaseShape->shapeType(); - if(aShapeType != GeomAPI_Shape::WIRE - && aShapeType != GeomAPI_Shape::SHELL - && aShapeType != GeomAPI_Shape::COMPSOLID - && aShapeType != GeomAPI_Shape::COMPOUND) { - return; + else if (theID == SUBSHAPES_TO_KEEP_ID()) + { + aSubShapesToRemoveAttrList->clear(); + + if (!aBaseShape.get()) { + return; + } + + int anIndex; + // optimization: collect selection attribute values into a map + const int aSubsToKeepNb = aSubShapesToKeepAttrList->size(); + GeomAPI_DataMapOfShapeShape aSubShapesToKeep; + for(anIndex = 0; anIndex < aSubsToKeepNb; ++anIndex) { + AttributeSelectionPtr anAttrSelectionInList = aSubShapesToKeepAttrList->value(anIndex); + GeomShapePtr aSubShapeToKeep = anAttrSelectionInList->value(); + if (aSubShapeToKeep.get()) + aSubShapesToKeep.bind(aSubShapeToKeep, aSubShapeToKeep); + } + + std::list aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape); + ListOfShape::const_iterator anIt = aSubShapes.cbegin(); + for (; anIt != aSubShapes.cend(); ++anIt) + { + GeomShapePtr aSubShape = *anIt; + if (aSubShapesToKeep.isBound(aSubShape)) + continue; + + if(!isHasSubs) { + aSubShapesToRemoveAttrList->append(aContext, aSubShape); + } + else { + std::list::iterator aSubsIt = anAllSubs.begin(); + for (; aSubsIt != anAllSubs.end(); aSubsIt++) { + ResultBodyPtr aSub = std::dynamic_pointer_cast(*aSubsIt); + if (aSub && aSub->shape().get() && aSub->shape()->isSubShape(aSubShape)) { + aSubShapesToRemoveAttrList->append(aSub, aSubShape); + break; + } + } + } + } } - for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { - GeomShapePtr aSubShape = anIt.current(); - const int aNumOfSubs = aResultCompSolid->numberOfSubs(); - if(aNumOfSubs == 0) { - aSubShapesAttrList->append(aContext, aSubShape); - } else { - for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) { - ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex); - if(aSubResult->shape()->isEqual(aSubShape)) { - aSubShapesAttrList->append(aSubResult, aSubShape); - break; + else if (theID == SUBSHAPES_TO_REMOVE_ID()) + { + aSubShapesToKeepAttrList->clear(); + + if (!aBaseShape.get()) { + return; + } + + int anIndex; + const int aSubsToRemoveNb = aSubShapesToRemoveAttrList->size(); + GeomAPI_DataMapOfShapeShape aSubShapesToRemove; + for(anIndex = 0; anIndex < aSubsToRemoveNb; ++anIndex) { + AttributeSelectionPtr anAttrSelectionInList = aSubShapesToRemoveAttrList->value(anIndex); + GeomShapePtr aSubShapeToRemove = anAttrSelectionInList->value(); + if (aSubShapeToRemove.get()) + aSubShapesToRemove.bind(aSubShapeToRemove, aSubShapeToRemove); + } + + + std::list aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape); + ListOfShape::const_iterator anIt = aSubShapes.cbegin(); + for (; anIt != aSubShapes.cend(); ++anIt) + { + GeomShapePtr aSubShape = *anIt; + if (aSubShapesToRemove.isBound(aSubShape)) + continue; + + if (!isHasSubs) { + aSubShapesToKeepAttrList->append(aContext, aSubShape); + } + else { + std::list::iterator aSubsIt = anAllSubs.begin(); + for (; aSubsIt != anAllSubs.end(); aSubsIt++) { + ResultBodyPtr aSub = std::dynamic_pointer_cast(*aSubsIt); + if (aSub && aSub->shape().get() && aSub->shape()->isSubShape(aSubShape)) { + aSubShapesToKeepAttrList->append(aSub, aSubShape); + break; + } } } } } } + + myChangedInCode = false; } //================================================================================================== @@ -106,7 +212,7 @@ void FeaturesPlugin_RemoveSubShapes::execute() { // Get base shape and sub-shapes list. AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); - AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID()); + AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_TO_KEEP_ID()); if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) { return; } @@ -132,49 +238,74 @@ void FeaturesPlugin_RemoveSubShapes::execute() AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(0); aResultShape = anAttrSelectionInList->value(); } + // deleted and copied must be jointed to one list which keeps all the history + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); // find all removed shapes - GeomAlgoAPI_MakeShapeCustom aDeletedSubs; + std::shared_ptr aDeletedSubs(new GeomAlgoAPI_MakeShapeCustom); std::set aTypes; // types that where removed aTypes.insert(GeomAPI_Shape::FACE); - for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { - if (!anIt.current().get() || anIt.current()->isNull()) + + std::list aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape); + for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt) { + GeomShapePtr aSubShape = *anIt; + if (!aSubShape.get() || aSubShape->isNull()) continue; + int anIndex; for(anIndex = 0; anIndex < aSubsNb; ++anIndex) { AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex); GeomShapePtr aLeftShape = anAttrSelectionInList->value(); - if (anIt.current()->isEqual(aLeftShape)) { + if (aSubShape->isEqual(aLeftShape)) { break; // found in a left-list } } if (anIndex == aSubsNb) { // not found in left - aDeletedSubs.addDeleted(anIt.current()); - aTypes.insert(anIt.current()->shapeType()); - if (anIt.current()->shapeType() != GeomAPI_Shape::FACE) { - GeomAPI_ShapeExplorer aFaces(anIt.current(), GeomAPI_Shape::FACE); + aDeletedSubs->addDeleted(aSubShape); + aTypes.insert(aSubShape->shapeType()); + if (aSubShape->shapeType() != GeomAPI_Shape::FACE) { + GeomAPI_ShapeExplorer aFaces(aSubShape, GeomAPI_Shape::FACE); for(; aFaces.more(); aFaces.next()) - aDeletedSubs.addDeleted(aFaces.current()); + aDeletedSubs->addDeleted(aFaces.current()); } } } + aMakeShapeList->appendAlgo(aDeletedSubs); + std::shared_ptr aCopy(new GeomAlgoAPI_Copy(aResultShape)); + aResultShape = aCopy->shape(); + aMakeShapeList->appendAlgo(aCopy); - GeomAlgoAPI_Copy aCopy(aResultShape); - aResultShape = aCopy.shape(); + if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { + aResultShape = GeomAlgoAPI_ShapeTools::groupSharedTopology(aResultShape); + if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { + // if the result has only one sub-shape, discard the compound + GeomAPI_ShapeIterator aSubIt(aResultShape); + GeomShapePtr aSub = aSubIt.current(); + aSubIt.next(); + if (!aSubIt.more()) + aResultShape = aSub; + } + } // Store result. ResultBodyPtr aResultBody = document()->createBody(data()); - aResultBody->storeModified(aBaseShape, aResultShape, 1); - std::set::iterator aTypeIter = aTypes.begin(); - for(; aTypeIter != aTypes.end(); aTypeIter++) - aResultBody->loadDeletedShapes(&aDeletedSubs, aBaseShape, *aTypeIter, 1); - aResultBody->loadAndOrientModifiedShapes(&aCopy, - aBaseShape, - GeomAPI_Shape::FACE, - 2, - "Modified_Face", - *aCopy.mapOfSubShapes().get(), - true, false, true); + aResultBody->storeModified(aBaseShape, aResultShape); + for (std::set::iterator aTypeIter = aTypes.begin(); + aTypeIter != aTypes.end(); + ++aTypeIter) + { + aResultBody->loadDeletedShapes(aMakeShapeList, aBaseShape, *aTypeIter); + } + + aResultBody->loadModifiedShapes(aMakeShapeList, + aBaseShape, + GeomAPI_Shape::FACE); + aResultBody->loadModifiedShapes(aMakeShapeList, + aBaseShape, + GeomAPI_Shape::EDGE); + aResultBody->loadModifiedShapes(aMakeShapeList, + aBaseShape, + GeomAPI_Shape::VERTEX); setResult(aResultBody); }