X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelectionList.cpp;h=0ef7aeff351e869d8975bff2aff5d56d7d9ba7b1;hb=97917d3698f5a2f7fc9596e7c755ff8f6751e373;hp=e091a6e9e6fa09505864ebea062e9e3bc702d11e;hpb=87b6a30a3afb8fb32e7e43ade8d9c947d9eb1684;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index e091a6e9e..0ef7aeff3 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.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 "Model_AttributeSelectionList.h" @@ -24,12 +23,15 @@ #include "Model_Events.h" #include "Model_Data.h" +#include #include +#include #include #include #include #include +#include #include #include #include @@ -40,8 +42,12 @@ #include #include +/// GUID for UAttribute that indicates the list has "To add all elements that share the same +/// topology" flag enabled +static const Standard_GUID kIS_GEOMETRICAL_SELECTION("f16987b6-e6c8-435c-99fa-03a7e0b06e83"); + void Model_AttributeSelectionList::append( - const ResultPtr& theContext, const std::shared_ptr& theSubShape, + const ObjectPtr& theContext, const std::shared_ptr& theSubShape, const bool theTemporarily) { // do not use the degenerated edge as a shape, a list is not incremented in this case @@ -53,7 +59,9 @@ void Model_AttributeSelectionList::append( } if (myIsCashed && !theTemporarily) { - myCash[theContext].push_back(theSubShape); + ResultPtr aResContext = std::dynamic_pointer_cast(theContext); + if (aResContext.get()) + myCash[aResContext].push_back(theSubShape); } int aNewTag = mySize->Get() + 1; @@ -76,7 +84,7 @@ void Model_AttributeSelectionList::append( } void Model_AttributeSelectionList::append( - const std::string theNamingName, const std::string& theType) + const std::string& theNamingName, const std::string& theType) { int aNewTag = mySize->Get() + 1; TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); @@ -93,6 +101,41 @@ void Model_AttributeSelectionList::append( owner()->data()->sendAttributeUpdated(this); } +void Model_AttributeSelectionList::append(const GeomPointPtr& thePoint, const std::string& theType) +{ + int aNewTag = mySize->Get() + 1; + TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); + + std::shared_ptr aNewAttr = + std::shared_ptr(new Model_AttributeSelection(aNewLab)); + if (owner()) { + aNewAttr->setObject(owner()); + aNewAttr->setParent(this); + } + aNewAttr->setID(id()); + mySize->Set(aNewTag); + aNewAttr->selectSubShape(theType, thePoint); + owner()->data()->sendAttributeUpdated(this); +} + +void Model_AttributeSelectionList::append(const std::string& theType, + const std::string& theContextName, const int theIndex) +{ + int aNewTag = mySize->Get() + 1; + TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); + + std::shared_ptr aNewAttr = + std::shared_ptr(new Model_AttributeSelection(aNewLab)); + if (owner()) { + aNewAttr->setObject(owner()); + aNewAttr->setParent(this); + } + aNewAttr->setID(id()); + mySize->Set(aNewTag); + aNewAttr->selectSubShape(theType, theContextName, theIndex); + owner()->data()->sendAttributeUpdated(this); +} + void Model_AttributeSelectionList::removeTemporaryValues() { if (myTmpAttr.get()) { @@ -193,7 +236,7 @@ void Model_AttributeSelectionList::remove(const std::set& theIndices) { int anOldSize = mySize->Get(); int aRemoved = 0; - // iterate one by one and shifting the removed indicies + // iterate one by one and shifting the removed indices for(int aCurrent = 0; aCurrent < anOldSize; aCurrent++) { if (theIndices.find(aCurrent) == theIndices.end()) { // not removed if (aRemoved) { // but must be shifted to the removed position @@ -225,28 +268,46 @@ int Model_AttributeSelectionList::size() return mySize->Get(); } -bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, +// LCOV_EXCL_START + +// returns true if theShape is same with theInList or is contained in it (a compound) +static bool isIn(GeomShapePtr theInList, GeomShapePtr theShape) { + if (theShape->isSame(theInList)) + return true; + if (theInList.get() && theInList->shapeType() == GeomAPI_Shape::COMPOUND) { + for(GeomAPI_ShapeIterator anIter(theInList); anIter.more(); anIter.next()) { + if (!anIter.current()->isNull() && anIter.current()->isSame(theShape)) + return true; + } + } + return false; +} + +bool Model_AttributeSelectionList::isInList(const ObjectPtr& theContext, const std::shared_ptr& theSubShape, const bool theTemporarily) { + ResultPtr aResCont = std::dynamic_pointer_cast(theContext); if (myIsCashed) { // the cashing is active - std::map > >::iterator aContext = - myCash.find(theContext); - if (aContext != myCash.end()) { - // iterate shapes because "isSame" method must be called for each shape - std::list >::iterator aShapes = aContext->second.begin(); - for(; aShapes != aContext->second.end(); aShapes++) { - if (!theSubShape.get()) { - if (!aShapes->get()) - return true; - } else { - // we need to call here isSame instead of isEqual to do not check shapes orientation - if (theSubShape->isSame(*aShapes)) - return true; + if (aResCont.get()) { + std::map > >::iterator aContext = + myCash.find(aResCont); + if (aContext != myCash.end()) { + // iterate shapes because "isSame" method must be called for each shape + std::list >::iterator aShapes = aContext->second.begin(); + for(; aShapes != aContext->second.end(); aShapes++) { + if (!theSubShape.get()) { + if (!aShapes->get() || (*aShapes)->isSame(aContext->first->shape())) + return true; + } else { + // we need to call here isSame instead of isEqual to do not check shapes orientation + if (isIn(*aShapes, theSubShape)) + return true; + } } } + return false; } - return false; } // no-cash method for(int anIndex = size() - 1; anIndex >= 0; anIndex--) { @@ -254,13 +315,13 @@ bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, if (anAttr.get()) { if (anAttr->context() == theContext) { // contexts are equal, so, check that values are also std::shared_ptr aValue = anAttr->value(); - if (!aValue.get()) { - if (!theSubShape.get()) { // both are null + if (!theSubShape.get()) { + if (!aValue.get() || (aResCont.get() && aValue->isSame(aResCont->shape()))) {// both null return true; } } else { // we need to call here isSame instead of isEqual to do not check shapes orientation - if (aValue->isSame(theSubShape)) // shapes are equal + if (isIn(aValue, theSubShape)) // shapes are equal return true; } } @@ -268,6 +329,7 @@ bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, } return false; } +// LCOV_EXCL_STOP const std::string Model_AttributeSelectionList::selectionType() const { @@ -287,15 +349,15 @@ std::shared_ptr } TDF_Label aLabel = mySize->Label().FindChild(theIndex + 1); // create a new attribute each time, by demand - // supporting of old attributes is too slow (synch each time) and buggy on redo - // (if attribute is deleted and created, the abort updates attriute and makes the Attr invalid) + // supporting of old attributes is too slow (sync each time) and buggy on redo + // (if attribute is deleted and created, the abort updates attribute and makes the Attr invalid) std::shared_ptr aNewAttr = std::shared_ptr(new Model_AttributeSelection(aLabel)); - aNewAttr->setID(id()); if (owner()) { aNewAttr->setObject(owner()); aNewAttr->setParent(this); } + aNewAttr->setID(id()); return aNewAttr; } @@ -330,8 +392,8 @@ bool Model_AttributeSelectionList::isInitialized() } Model_AttributeSelectionList::Model_AttributeSelectionList(TDF_Label& theLabel) +: myLab(theLabel) { - myLab = theLabel; reinit(); } @@ -347,7 +409,7 @@ void Model_AttributeSelectionList::reinit() myIsCashed = false; } - +// LCOV_EXCL_START void Model_AttributeSelectionList::cashValues(const bool theEnabled) { myIsCashed = theEnabled; @@ -361,3 +423,60 @@ void Model_AttributeSelectionList::cashValues(const bool theEnabled) } } } +// LCOV_EXCL_STOP + +bool Model_AttributeSelectionList::isGeometricalSelection() const +{ + return myLab.IsAttribute(kIS_GEOMETRICAL_SELECTION); +} + +void Model_AttributeSelectionList::setGeometricalSelection(const bool theIsGeometricalSelection) +{ + if (isGeometricalSelection() == theIsGeometricalSelection) + return; // nothing to do + if (theIsGeometricalSelection) // store the state + TDataStd_UAttribute::Set(myLab, kIS_GEOMETRICAL_SELECTION); + else + myLab.ForgetAttribute(kIS_GEOMETRICAL_SELECTION); + std::set anIndiciesToRemove; // Update list according to the flag + if (theIsGeometricalSelection) { // all objects with same geometry must be combined into single + std::list anAttributes; // collect attributes with geometrical compounds + for(int anIndex = 0; anIndex < size(); anIndex++) { + AttributeSelectionPtr anAttr = value(anIndex); + if (!anAttr.get() || !anAttr->context().get()) + continue; + anAttr->combineGeometrical(); + if (!anAttr->value().get() || anAttr->value()->shapeType() != GeomAPI_Shape::COMPOUND) + continue; + // check it is equal to some other attribute already presented in the list + std::list::iterator anAttrIter = anAttributes.begin(); + for(; anAttrIter != anAttributes.end(); anAttrIter++) { + if (anAttr->context() == (*anAttrIter)->context() && + anAttr->namingName() == (*anAttrIter)->namingName()) { + anIndiciesToRemove.insert(anIndex); + break; + } + } + if (anAttrIter == anAttributes.end()) // not removed, so, add to the compare-list + anAttributes.push_back(anAttr); + } + } else { // all objects with same geometry must be divided into separated sub-attributes + int anInitialSize = size(); + for(int anIndex = 0; anIndex < anInitialSize; anIndex++) { + AttributeSelectionPtr anAttr = value(anIndex); + if (!anAttr.get() || !anAttr->context().get()) + continue; + GeomShapePtr aValue = anAttr->value(); + if (!aValue.get() || aValue->shapeType() != GeomAPI_Shape::COMPOUND) + continue; + for(GeomAPI_ShapeIterator anIter(aValue); anIter.more(); anIter.next()) { + append(anAttr->context(), anIter.current()); + } + anIndiciesToRemove.insert(anIndex); + } + } + remove(anIndiciesToRemove); + myIsCashed = false; + myCash.clear(); // empty list as indicator that cash is not used + owner()->data()->sendAttributeUpdated(this); +}