X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Document.cpp;h=f61edd015f2185fbc9351c3be3533ab2ccf27a79;hb=72b9423caaa48805589d6ab87d366f79ecde5bfe;hp=10d4605f2f9ba6a1c271912defe25b7826e42f41;hpb=a8c38afe7673aa74f9ab67c21c3244a7bd080f03;p=modules%2Fshaper.git diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 10d4605f2..f61edd015 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: Model_Document.cxx -// Created: 28 Feb 2014 -// Author: Mikhail PONIKAROV +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include #include @@ -590,6 +604,8 @@ bool Model_Document::finishOperation() Events_Loop::loop()->send(aFinishMsg); } + // for open of document with primitive box inside (finish transaction in initAttributes) + bool aWasActivatedFlushes = aLoop->activateFlushes(true); while(aLoop->hasGrouppedEvent(kCreatedEvent) || aLoop->hasGrouppedEvent(kUpdatedEvent) || aLoop->hasGrouppedEvent(kRedispEvent) || aLoop->hasGrouppedEvent(kDeletedEvent)) { aLoop->flush(kCreatedEvent); @@ -597,6 +613,7 @@ bool Model_Document::finishOperation() aLoop->flush(kRedispEvent); aLoop->flush(kDeletedEvent); } + aLoop->activateFlushes(aWasActivatedFlushes); // to avoid "updated" message appearance by updater //aLoop->clear(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); @@ -908,7 +925,7 @@ FeaturePtr Model_Document::addFeature(std::string theID, const bool theMakeCurre int aSubs = aComp->numberOfSubs(false); for(int a = 0; a < aSubs; a++) { FeaturePtr aSub = aComp->subFeature(a, false); - if (myObjs->isLater(aSub, aCurrent)) { + if (aSub && myObjs->isLater(aSub, aCurrent)) { isModified = true; aCurrent = aSub; } @@ -1014,9 +1031,11 @@ std::shared_ptr Model_Document::subDoc(int theDocID) Model_Application::getApplication()->document(theDocID)); } -ObjectPtr Model_Document::object(const std::string& theGroupID, const int theIndex) +ObjectPtr Model_Document::object(const std::string& theGroupID, + const int theIndex, + const bool theAllowFolder) { - return myObjs->object(theGroupID, theIndex); + return myObjs->object(theGroupID, theIndex, theAllowFolder); } std::shared_ptr Model_Document::objectByName( @@ -1030,11 +1049,11 @@ const int Model_Document::index(std::shared_ptr theObject) return myObjs->index(theObject); } -int Model_Document::size(const std::string& theGroupID) +int Model_Document::size(const std::string& theGroupID, const bool theAllowFolder) { if (myObjs == 0) // may be on close return 0; - return myObjs->size(theGroupID); + return myObjs->size(theGroupID, theAllowFolder); } std::shared_ptr Model_Document::currentFeature(const bool theVisible) @@ -1238,6 +1257,43 @@ std::shared_ptr Model_Document::createParameter( return myObjs->createParameter(theFeatureData, theIndex); } +std::shared_ptr Model_Document::addFolder( + std::shared_ptr theAddBefore) +{ + return myObjs->createFolder(theAddBefore); +} + +void Model_Document::removeFolder(std::shared_ptr theFolder) +{ + if (theFolder) + myObjs->removeFolder(theFolder); +} + +std::shared_ptr Model_Document::findFolderAbove( + const std::list >& theFeatures) +{ + return myObjs->findFolder(theFeatures, false); +} + +std::shared_ptr Model_Document::findFolderBelow( + const std::list >& theFeatures) +{ + return myObjs->findFolder(theFeatures, true); +} + +bool Model_Document::moveToFolder( + const std::list >& theFeatures, + const std::shared_ptr& theFolder) +{ + return myObjs->moveToFolder(theFeatures, theFolder); +} + +bool Model_Document::removeFromFolder( + const std::list >& theFeatures) +{ + return myObjs->removeFromFolder(theFeatures); +} + std::shared_ptr Model_Document::feature( const std::shared_ptr& theResult) { @@ -1254,25 +1310,82 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2) return TDF_LabelMapHasher::IsEqual(theLab1, theLab2); } +// searches in this document feature that contains this label +FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) { + TDF_Label aCurrentLab = theLab; + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + return myObjs->feature(aCurrentLab); +} + void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName) { - myNamingNames[theName] = theLabel; + std::map >::iterator aFind = myNamingNames.find(theName); + + if (aFind != myNamingNames.end()) { // to avoid duplicate-labels + // to keep correct order inspite of history line management + std::list::iterator anAddAfterThis = aFind->second.end(); + FeaturePtr anAddedFeature = featureByLab(theLabel); + std::list::iterator aLabIter = aFind->second.begin(); + while(aLabIter != aFind->second.end()) { + if (theLabel.IsEqual(*aLabIter)) { + std::list::iterator aTmpIter = aLabIter; + aLabIter++; + aFind->second.erase(aTmpIter); + } else { + FeaturePtr aCurFeature = featureByLab(*aLabIter); + if (aCurFeature.get() && anAddedFeature.get() && + myObjs->isLater(anAddedFeature, aCurFeature)) + anAddAfterThis = aLabIter; + + aLabIter++; + } + } + if (anAddAfterThis != aFind->second.end()) { + anAddAfterThis++; + if (anAddAfterThis != aFind->second.end()) { + myNamingNames[theName].insert(anAddAfterThis, theLabel); // inserts before anAddAfterThis + return; + } + } + } + myNamingNames[theName].push_back(theLabel); } -void Model_Document::changeNamingName(const std::string theOldName, const std::string theNewName) +void Model_Document::changeNamingName(const std::string theOldName, + const std::string theNewName, + const TDF_Label& theLabel) { - std::map::iterator aFind = myNamingNames.find(theOldName); + std::map >::iterator aFind = myNamingNames.find(theOldName); if (aFind != myNamingNames.end()) { - myNamingNames[theNewName] = aFind->second; - myNamingNames.erase(theOldName); + std::list::iterator aLabIter = aFind->second.begin(); + for(; aLabIter != aFind->second.end(); aLabIter++) { + if (theLabel.IsEqual(*aLabIter)) { // found the label + myNamingNames[theNewName].push_back(theLabel); + if (aFind->second.size() == 1) { // only one element, so, just change the name + myNamingNames.erase(theOldName); + } else { // remove from the list + aFind->second.erase(aLabIter); + } + return; + } + } } } -TDF_Label Model_Document::findNamingName(std::string theName) +TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theContext) { - std::map::iterator aFind = myNamingNames.find(theName); + std::map >::iterator aFind = myNamingNames.find(theName); if (aFind != myNamingNames.end()) { - return aFind->second; + std::list::reverse_iterator aLabIter = aFind->second.rbegin(); + for(; aLabIter != aFind->second.rend(); aLabIter++) { + if (theContext.get()) { + // context is defined and not like this, so, skip + if (theContext == myObjs->object(aLabIter->Father())) + return *aLabIter; + } + } + return *(aFind->second.rbegin()); // no more variannts, so, return the last } // not found exact name, try to find by sub-components std::string::size_type aSlash = theName.rfind('/'); @@ -1281,24 +1394,33 @@ TDF_Label Model_Document::findNamingName(std::string theName) aFind = myNamingNames.find(anObjName); if (aFind != myNamingNames.end()) { TCollection_ExtendedString aSubName(theName.substr(aSlash + 1).c_str()); - // searching sub-labels with this name - TDF_ChildIDIterator aNamesIter(aFind->second, TDataStd_Name::GetID(), Standard_True); - for(; aNamesIter.More(); aNamesIter.Next()) { - Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value()); - if (aName->Get() == aSubName) - return aName->Label(); - } - // If not found child label with the exact sub-name, then try to find compound with - // such sub-name without suffix. - Standard_Integer aSuffixPos = aSubName.SearchFromEnd('_'); - if (aSuffixPos != -1) { - TCollection_ExtendedString anIndexStr = aSubName.Split(aSuffixPos); - aSubName.Remove(aSuffixPos); - aNamesIter.Initialize(aFind->second, TDataStd_Name::GetID(), Standard_True); + // iterate all possible same-named labels starting from the last one (the recent) + std::list::reverse_iterator aLabIter = aFind->second.rbegin(); + for(; aLabIter != aFind->second.rend(); aLabIter++) { + if (theContext.get()) { + // context is defined and not like this, so, skip + if (theContext != myObjs->object(aLabIter->Father())) + continue; + } + // searching sub-labels with this name + TDF_ChildIDIterator aNamesIter(*aLabIter, TDataStd_Name::GetID(), Standard_True); for(; aNamesIter.More(); aNamesIter.Next()) { Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value()); - if (aName->Get() == aSubName) { + if (aName->Get() == aSubName) return aName->Label(); + } + // If not found child label with the exact sub-name, then try to find compound with + // such sub-name without suffix. + Standard_Integer aSuffixPos = aSubName.SearchFromEnd('_'); + if (aSuffixPos != -1 && aSuffixPos != aSubName.Length()) { + TCollection_ExtendedString anIndexStr = aSubName.Split(aSuffixPos); + aSubName.Remove(aSuffixPos); + aNamesIter.Initialize(*aLabIter, TDataStd_Name::GetID(), Standard_True); + for(; aNamesIter.More(); aNamesIter.Next()) { + Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value()); + if (aName->Get() == aSubName) { + return aName->Label(); + } } } } @@ -1307,9 +1429,98 @@ TDF_Label Model_Document::findNamingName(std::string theName) return TDF_Label(); // not found } -ResultPtr Model_Document::findByName(const std::string theName) +bool Model_Document::isLaterByDep(FeaturePtr theThis, FeaturePtr theOther) { + // check dependencies first: if theOther depends on theThis, theThis is not later + std::list > > > aRefs; + theOther->data()->referencesToObjects(aRefs); + std::list > > >::iterator + aRefIt = aRefs.begin(); + for(; aRefIt != aRefs.end(); aRefIt++) { + std::list::iterator aRefObjIt = aRefIt->second.begin(); + for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) { + ObjectPtr aRefObj = *aRefObjIt; + if (aRefObj.get()) { + FeaturePtr aRefFeat = std::dynamic_pointer_cast(aRefObj); + if (!aRefFeat.get()) { // take feature of the result + aRefFeat = feature(std::dynamic_pointer_cast(aRefObj)); + } + if (aRefFeat.get() && aRefFeat == theThis) { + return false; // other references to this, so this later than other + } + } + } + } + return myObjs->isLater(theThis, theOther); +} + +int Model_Document::numberOfNameInHistory( + const ObjectPtr& theNameObject, const TDF_Label& theStartFrom) { - return myObjs->findByName(theName); + std::map >::iterator aFind = + myNamingNames.find(theNameObject->data()->name()); + if (aFind == myNamingNames.end() || aFind->second.size() < 2) { + return 1; // no need to specify the name by additional identifiers + } + // get the feature of the object for relative compare + FeaturePtr aStart = myObjs->feature(theStartFrom); + if (!aStart.get()) // strange, but can not find feature by the label + return 1; + // feature that contain result with this name + FeaturePtr aNameFeature; + ResultPtr aNameResult = std::dynamic_pointer_cast(theNameObject); + if (aNameResult) + aNameFeature = myObjs->feature(aNameResult); + else + aNameFeature = std::dynamic_pointer_cast(theNameObject); + // iterate all labels with this name to find the nearest just before or equal relative + std::list::reverse_iterator aLabIter = aFind->second.rbegin(); + for(; aLabIter != aFind->second.rend(); aLabIter++) { + FeaturePtr aLabFeat = featureByLab(*aLabIter); + if (!aLabFeat.get()) + continue; + if (isLaterByDep(aStart, aLabFeat)) // skip also start: its result don't used + break; + } + int aResIndex = 1; + for(; aLabIter != aFind->second.rend(); aLabIter++) { + FeaturePtr aLabFeat = featureByLab(*aLabIter); + if (!aLabFeat.get()) + continue; + if (aLabFeat == aNameFeature || isLaterByDep(aNameFeature, aLabFeat)) + return aResIndex; + aResIndex++; + } + return aResIndex; // strange +} + +ResultPtr Model_Document::findByName( + std::string& theName, std::string& theSubShapeName, bool& theUniqueContext) +{ + int aNumInHistory = 0; + std::string aName = theName; + ResultPtr aRes = myObjs->findByName(aName); + theUniqueContext = !(aRes.get() && myNamingNames.find(aName) != myNamingNames.end()); + while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index + aNumInHistory++; + aName = aName.substr(1); + aRes = myObjs->findByName(aName); + } + if (aNumInHistory) { + std::map >::iterator aFind = myNamingNames.find(aName); + if (aFind != myNamingNames.end() && aFind->second.size() > aNumInHistory) { + std::list::reverse_iterator aLibIt = aFind->second.rbegin(); + for(; aNumInHistory != 0; aNumInHistory--) + aLibIt++; + const TDF_Label& aResultLab = *aLibIt; + aRes = std::dynamic_pointer_cast(myObjs->object(aResultLab.Father())); + if (aRes) { // modify the incoming names + if (!theSubShapeName.empty()) + theSubShapeName = theSubShapeName.substr(theName.size() - aName.size()); + theName = aName; + } + } + } + return aRes; } std::list > Model_Document::allFeatures() @@ -1317,6 +1528,11 @@ std::list > Model_Document::allFeatures() return myObjs->allFeatures(); } +std::list > Model_Document::allObjects() +{ + return myObjs->allObjects(); +} + void Model_Document::setActive(const bool theFlag) { if (theFlag != myIsActive) {