X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeRefList.cpp;h=b6b2c42f29e8288f60294740b2258dfbe516a6b3;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=4d77a91f7f2e68663c1be1a7d18c866ab7d1a0a7;hpb=87b6a30a3afb8fb32e7e43ade8d9c947d9eb1684;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 4d77a91f7..b6b2c42f2 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // 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_AttributeRefList.h" @@ -44,6 +43,12 @@ void Model_AttributeRefList::append(ObjectPtr theObject) myExtDocRef->Append(anEntry); } else return; // something is wrong + if (myHashUsed) { + myHashObjects.insert(theObject); + myHashIndex[myRef->Extent() - 1] = theObject; + myHashIndexNoEmpty[int(myHashIndexNoEmpty.size())] = theObject; + } + // do it before the transaction finish to make just created/removed objects know dependencies // and reference from composite feature is removed automatically ADD_BACK_REF(theObject); @@ -52,6 +57,7 @@ void Model_AttributeRefList::append(ObjectPtr theObject) void Model_AttributeRefList::remove(ObjectPtr theObject) { + eraseHash(); if (theObject.get() != NULL) { if (owner()->document() == theObject->document()) { std::shared_ptr aData; @@ -60,6 +66,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) REMOVE_BACK_REF(theObject); owner()->data()->sendAttributeUpdated(this); } else { + // LCOV_EXCL_START // create new lists because for the current moment remove one of the duplicated elements // from the list is buggy TDF_LabelList anOldList = myRef->List(); @@ -79,7 +86,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) if (anExtIter.Value() == anIdString.str().c_str()) { TDataStd_ListIteratorOfListOfExtendedString anExtIter2 = anExtIter; anExtIter2.Next(); - if (anExtIter2.Value() == anEntry) { // fully maches, so, remove(don't copy) + if (anExtIter2.Value() == anEntry) { // fully matches, so, remove(don't copy) aFound = true; continue; } @@ -95,6 +102,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) REMOVE_BACK_REF(theObject); owner()->data()->sendAttributeUpdated(this); } + // LCOV_EXCL_STOP } } else { // in case of empty object remove, the first empty object is removed from the list @@ -124,6 +132,7 @@ void Model_AttributeRefList::clear() REMOVE_BACK_REF((*anOldIter)); } myExtDocRef->Clear(); + eraseHash(); owner()->data()->sendAttributeUpdated(this); } @@ -131,6 +140,10 @@ int Model_AttributeRefList::size(const bool theWithEmpty) const { if (theWithEmpty) return myRef->Extent(); + + if (myHashUsed) + return int(myHashIndexNoEmpty.size()); + int aResult = 0; const TDF_LabelList& aList = myRef->List(); for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { @@ -169,7 +182,9 @@ ObjectPtr Model_AttributeRefList::iteratedObject(TDF_ListIteratorOfLabelList& th } theExtIter.Next(); } else { // internal document object - anObj = theDoc->objects()->object(theLIter.Value()); + TDF_Label aLab = theLIter.Value(); + if (!aLab.IsNull()) + anObj = theDoc->objects()->object(theLIter.Value()); } } return anObj; @@ -177,15 +192,11 @@ ObjectPtr Model_AttributeRefList::iteratedObject(TDF_ListIteratorOfLabelList& th std::list Model_AttributeRefList::list() { + createHash(); std::list aResult; - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { - const TDF_LabelList& aList = myRef->List(); - TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); - for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - aResult.push_back(iteratedObject(aLIter, anExtIter, aDoc)); - } + std::map::iterator aHashIter = myHashIndex.begin(); + for(; aHashIter != myHashIndex.end(); aHashIter++) { + aResult.push_back(aHashIter->second); } return aResult; } @@ -195,65 +206,24 @@ bool Model_AttributeRefList::isInList(const ObjectPtr& theObj) if(!theObj.get()) { return false; } - if (theObj->document() == owner()->document()) { // this document object - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { - std::shared_ptr aData = std::dynamic_pointer_cast(theObj->data()); - if (aData.get() && aData->isValid()) { - TDF_Label anObjLab = aData->label().Father(); - const TDF_LabelList& aList = myRef->List(); - for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - if (aLIter.Value().IsEqual(anObjLab)) { - return true; - } - } - } - } - } else { // external document object - // create new lists because for the current moment remove one of the duplicated elements - // from the list is buggy - std::ostringstream anIdString; // string with document Id - anIdString<document()->id(); - std::shared_ptr aData = std::dynamic_pointer_cast(theObj->data()); - TCollection_AsciiString anEntry; - TDF_Tool::Entry(aData->label().Father(), anEntry); - bool aFound = false; - TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); - for (; anExtIter.More(); anExtIter.Next()) { - if (anExtIter.Value() == anIdString.str().c_str()) { - anExtIter.Next(); - if (anExtIter.Value() == anEntry) { // fully maches - return true; - } - } else { - anExtIter.Next(); - } - } - } - return false; + createHash(); + return myHashObjects.count(theObj) != 0; } -ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) const +ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) { - std::shared_ptr aDoc = - std::dynamic_pointer_cast(owner()->document()); - if (aDoc) { - int anIndex = -1; - TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); - for (TDF_ListIteratorOfLabelList aLIter(myRef->List()); aLIter.More(); aLIter.Next()) { - if (theWithEmpty || (!aLIter.Value().IsNull() && !aLIter.Value().IsRoot())) - anIndex++; - if (anIndex == theIndex) { - return iteratedObject(aLIter, anExtIter, aDoc); - } - if (aLIter.Value() == myRef->Label()) { - anExtIter.Next(); - anExtIter.Next(); - } - } + createHash(); + std::map::iterator aFind; + if (theWithEmpty) { + aFind = myHashIndex.find(theIndex); + if (aFind == myHashIndex.end()) + return ObjectPtr(); + } else { + aFind = myHashIndexNoEmpty.find(theIndex); + if (aFind == myHashIndexNoEmpty.end()) + return ObjectPtr(); } - return ObjectPtr(); + return aFind->second; } void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew) @@ -273,6 +243,7 @@ void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const Objec aNewLab = aCurrentLab.Root(); // root means null object } // do the substitution + eraseHash(); ADD_BACK_REF(theNew); if (myRef->InsertAfter(aNewLab, aCurrentLab)) { myRef->Remove(aCurrentLab); @@ -283,37 +254,6 @@ void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const Objec } } -void Model_AttributeRefList::exchange(const ObjectPtr& theObject1, const ObjectPtr& theObject2) -{ - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { - std::shared_ptr aData1 = std::dynamic_pointer_cast(theObject1->data()); - if (aData1.get() && aData1->isValid()) { - TDF_Label aLab1 = aData1->label().Father(); - if (theObject2.get() && theObject2->data()->isValid()) { // the new may be null - std::shared_ptr aData2 = - std::dynamic_pointer_cast(theObject2->data()); - if (aData2.get() && aData2->isValid()) { - TDF_Label aLab2 = aData2->label().Father(); - // do the substitution: use the temporary label, as usually in exchange - TDF_Label aTmpLab = aLab1.Root(); - if (myRef->InsertAfter(aTmpLab, aLab1)) { - myRef->Remove(aLab1); - } - if (myRef->InsertAfter(aLab1, aLab2)) { - myRef->Remove(aLab2); - } - if (myRef->InsertAfter(aLab2, aTmpLab)) { - myRef->Remove(aTmpLab); - } - owner()->data()->sendAttributeUpdated(this); - } - } - } - } -} - void Model_AttributeRefList::removeLast() { std::shared_ptr aDoc = std::dynamic_pointer_cast( @@ -321,6 +261,7 @@ void Model_AttributeRefList::removeLast() if (aDoc && !myRef->IsEmpty()) { ObjectPtr anObj = aDoc->objects()->object(myRef->Last()); if (anObj.get()) { + eraseHash(); myRef->Remove(myRef->Last()); REMOVE_BACK_REF(anObj); owner()->data()->sendAttributeUpdated(this); @@ -333,7 +274,7 @@ void Model_AttributeRefList::remove(const std::set& theIndices) std::shared_ptr aDoc = std::dynamic_pointer_cast( owner()->document()); if (aDoc && !myRef->IsEmpty()) { - // collet labels that will be removed + // collect labels that will be removed TDF_LabelList aLabelsToRemove; TDF_ListIteratorOfLabelList aLabIter(myRef->List()); for(int aCurrent = 0; aLabIter.More(); aLabIter.Next(), aCurrent++) { @@ -349,6 +290,7 @@ void Model_AttributeRefList::remove(const std::set& theIndices) } } if (!aLabelsToRemove.IsEmpty()) { + eraseHash(); owner()->data()->sendAttributeUpdated(this); } } @@ -369,4 +311,36 @@ void Model_AttributeRefList::reinit() if (!myLab.FindAttribute(TDataStd_ExtStringList::GetID(), myExtDocRef)) { myExtDocRef = TDataStd_ExtStringList::Set(myLab); } + eraseHash(); +} + +void Model_AttributeRefList::createHash() +{ + if (myHashUsed) + return; + eraseHash(); + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + const TDF_LabelList& aList = myRef->List(); + TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { + ObjectPtr anObj = iteratedObject(aLIter, anExtIter, aDoc); + myHashIndex[int(myHashIndex.size())] = anObj; + if (anObj.get()) { + myHashIndexNoEmpty[int(myHashIndexNoEmpty.size())] = anObj; + myHashObjects.insert(anObj); + } + } + } + if (!myHashObjects.empty()) // on open document with multi-rotation referenced have no results + myHashUsed = true; +} + +void Model_AttributeRefList::eraseHash() +{ + myHashObjects.clear(); + myHashIndex.clear(); + myHashIndexNoEmpty.clear(); + myHashUsed = false; }