X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Document.cpp;h=4d4207648740649aec6d7da1fdad57830da3701d;hb=b0196aeefbaa53754b1052fab904386707caad87;hp=2272a8f33c4efa51896d4058f30e66a88e507d99;hpb=6e23ad2aa4923a49f5f04feed5cae513a1e403db;p=modules%2Fshaper.git diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 2272a8f33..4d4207648 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -53,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -85,14 +85,15 @@ static const int TAG_GENERAL = 1; // general properties tag // general sub-labels /// where the reference to the current feature label is located (or no attribute if null feature) static const int TAG_CURRENT_FEATURE = 1; ///< reference to the current feature -static const int TAG_CURRENT_TRANSACTION = 2; ///< integer, index of the transaction +/// integer, index of the transaction + GUID for auto recomutation blocking +static const int TAG_CURRENT_TRANSACTION = 2; static const int TAG_SELECTION_FEATURE = 3; ///< integer, tag of the selection feature label static const int TAG_NODES_STATE = 4; ///< array, tag of the Object Browser nodes states ///< naming structures constructions selected from other document static const int TAG_EXTERNAL_CONSTRUCTIONS = 5; Model_Document::Model_Document(const int theID, const std::string theKind) - : myID(theID), myKind(theKind), myIsActive(false), + : myID(theID), myKind(theKind), myIsActive(false), myIsSetCurrentFeature(false), myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format { #ifdef TINSPECTOR @@ -146,10 +147,9 @@ bool Model_Document::load(const char* theDirName, const char* theFileName, Docum Handle(TDocStd_Document) aLoaded; try { aStatus = anApp->Open(aPath, aLoaded); - } catch (Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + } catch (Standard_Failure const& anException) { Events_InfoMessage("Model_Document", - "Exception in opening of document: %1").arg(aFail->GetMessageString()).send(); + "Exception in opening of document: %1").arg(anException.GetMessageString()).send(); return false; } bool isError = aStatus != PCDM_RS_OK; @@ -274,7 +274,7 @@ bool Model_Document::save( Handle(Model_Application) anApp = Model_Application::getApplication(); if (isRoot()) { #ifdef WIN32 - CreateDirectory(theDirName, NULL); + CreateDirectory((LPTSTR) theDirName, NULL); #else mkdir(theDirName, 0x1ff); #endif @@ -284,10 +284,9 @@ bool Model_Document::save( PCDM_StoreStatus aStatus; try { aStatus = anApp->SaveAs(myDoc, aPath); - } catch (Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + } catch (Standard_Failure const& anException) { Events_InfoMessage("Model_Document", - "Exception in saving of document: %1").arg(aFail->GetMessageString()).send(); + "Exception in saving of document: %1").arg(anException.GetMessageString()).send(); if (aWasCurrent.get()) { // return the current feature to the initial position setCurrentFeature(aWasCurrent, false); aSession->setCheckTransactions(true); @@ -925,7 +924,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; } @@ -1001,12 +1000,14 @@ void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis) void Model_Document::updateHistory(const std::shared_ptr theObject) { - myObjs->updateHistory(theObject); + if (myObjs) + myObjs->updateHistory(theObject); } void Model_Document::updateHistory(const std::string theGroup) { - myObjs->updateHistory(theGroup); + if (myObjs) + myObjs->updateHistory(theGroup); } const std::set Model_Document::subDocuments() const @@ -1031,9 +1032,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( @@ -1042,16 +1045,25 @@ std::shared_ptr Model_Document::objectByName( return myObjs->objectByName(theGroupID, theName); } -const int Model_Document::index(std::shared_ptr theObject) +const int Model_Document::index(std::shared_ptr theObject, + const bool theAllowFolder) { - return myObjs->index(theObject); + return myObjs->index(theObject, theAllowFolder); } -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::parent( + const std::shared_ptr theChild) +{ + if(myObjs == 0) // may be on close + return ObjectPtr(); + return myObjs->parent(theChild); } std::shared_ptr Model_Document::currentFeature(const bool theVisible) @@ -1076,6 +1088,9 @@ std::shared_ptr Model_Document::currentFeature(const bool theV void Model_Document::setCurrentFeature( std::shared_ptr theCurrent, const bool theVisible) { + if (myIsSetCurrentFeature) + return; + myIsSetCurrentFeature = true; // blocks the flush signals to avoid each objects visualization in the viewer // they should not be shown once after all modifications are performed Events_Loop* aLoop = Events_Loop::loop(); @@ -1112,6 +1127,7 @@ void Model_Document::setCurrentFeature( std::shared_ptr aData = std::static_pointer_cast(theCurrent->data()); if (!aData.get() || !aData->isValid()) { aLoop->activateFlushes(isActive); + myIsSetCurrentFeature = false; return; } TDF_Label aFeatureLabel = aData->label().Father(); @@ -1143,7 +1159,8 @@ void Model_Document::setCurrentFeature( aDisabledFlag = false; else if (anOwners.find(anIter) != anOwners.end()) // disable the higher-level feature if the nested is the current - aDisabledFlag = true; + if (aMain->getKind() != "Import") // exception for the import XAO feature with Group (2430) + aDisabledFlag = true; } if (anIter->getKind() == "Parameter") { @@ -1183,6 +1200,7 @@ void Model_Document::setCurrentFeature( } } } + myIsSetCurrentFeature = false; // unblock the flush signals and up them after this aLoop->activateFlushes(isActive); } @@ -1255,9 +1273,56 @@ 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); +} + +std::shared_ptr Model_Document::findContainingFolder( + const std::shared_ptr& theFeature, + int& theIndexInFolder) +{ + return myObjs->findContainingFolder(theFeature, theIndexInFolder); +} + +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, + const bool theBefore) +{ + return myObjs->removeFromFolder(theFeatures, theBefore); +} + std::shared_ptr Model_Document::feature( const std::shared_ptr& theResult) { + if (myObjs == 0) // may be on close + return std::shared_ptr(); return myObjs->feature(theResult); } @@ -1271,10 +1336,35 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2) return TDF_LabelMapHasher::IsEqual(theLab1, theLab2); } +FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) { + TDF_Label aCurrentLab = theLab; + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + return myObjs->feature(aCurrentLab); +} + +ResultPtr Model_Document::resultByLab(const TDF_Label& theLab) +{ + TDF_Label aCurrentLab = theLab; + while(aCurrentLab.Depth() > 3) { + ObjectPtr aResultObj = myObjs->object(aCurrentLab); + if (aResultObj.get()) { + return std::dynamic_pointer_cast(aResultObj); // this may be null if feature + } + aCurrentLab = aCurrentLab.Father(); + } + return ResultPtr(); // not found +} + + void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName) { 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)) { @@ -1282,9 +1372,21 @@ void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName 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); } @@ -1339,33 +1441,74 @@ TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theConte if (theContext != myObjs->object(aLabIter->Father())) continue; } + // copy aSubName to avoid incorrect further processing after its suffix cutting + TCollection_ExtendedString aSubNameCopy(aSubName); // 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() == aSubNameCopy) 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); + Standard_Integer aSuffixPos = aSubNameCopy.SearchFromEnd('_'); + if (aSuffixPos != -1 && aSuffixPos != aSubNameCopy.Length()) { + TCollection_ExtendedString anIndexStr = aSubNameCopy.Split(aSuffixPos); + aSubNameCopy.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) { + if (aName->Get() == aSubNameCopy) { + return aName->Label(); + } + } + // check also "this" label + Handle(TDataStd_Name) aName; + if (aLabIter->FindAttribute(TDataStd_Name::GetID(), aName)) { + if (aName->Get() == aSubNameCopy) { return aName->Label(); } } } } + // verify context's name is same as sub-component's and use context's label + if (aSubName.IsEqual(anObjName.c_str())) + return *(aFind->second.rbegin()); } } return TDF_Label(); // not found } +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()) { + if (aRefFeat == theThis) + return false; // other references to this, so other later than this + if (std::dynamic_pointer_cast(aRefFeat)) { + if (!isLaterByDep(theThis, aRefFeat)) // nested composites: recursion + return false; + } + } + } + } + } + return myObjs->isLater(theThis, theOther); +} + int Model_Document::numberOfNameInHistory( const ObjectPtr& theNameObject, const TDF_Label& theStartFrom) { @@ -1388,36 +1531,32 @@ int Model_Document::numberOfNameInHistory( // 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++) { - TDF_Label aCurrentLab = *aLabIter; - while(aCurrentLab.Depth() > 3) - aCurrentLab = aCurrentLab.Father(); - FeaturePtr aLabFeat = myObjs->feature(aCurrentLab); + FeaturePtr aLabFeat = featureByLab(*aLabIter); if (!aLabFeat.get()) continue; - if (aLabFeat == aStart || myObjs->isLater(aStart, aLabFeat)) + if (isLaterByDep(aStart, aLabFeat)) // skip also start: its result don't used break; } int aResIndex = 1; for(; aLabIter != aFind->second.rend(); aLabIter++) { - TDF_Label aCurrentLab = *aLabIter; - while(aCurrentLab.Depth() > 3) - aCurrentLab = aCurrentLab.Father(); - FeaturePtr aLabFeat = myObjs->feature(aCurrentLab); + FeaturePtr aLabFeat = featureByLab(*aLabIter); if (!aLabFeat.get()) continue; - if (aLabFeat == aNameFeature || myObjs->isLater(aNameFeature, aLabFeat)) + if (aLabFeat == aNameFeature || isLaterByDep(aNameFeature, aLabFeat)) return aResIndex; aResIndex++; } return aResIndex; // strange } -ResultPtr Model_Document::findByName(std::string& theName, std::string& theSubShapeName) +ResultPtr Model_Document::findByName( + std::string& theName, std::string& theSubShapeName, bool& theUniqueContext) { int aNumInHistory = 0; std::string aName = theName; ResultPtr aRes = myObjs->findByName(aName); - while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index + 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); @@ -1445,6 +1584,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) { @@ -1457,21 +1601,11 @@ void Model_Document::setActive(const bool theFlag) FeaturePtr aFeature = std::dynamic_pointer_cast( object(ModelAPI_Feature::group(), a)); if (aFeature.get() && aFeature->data()->isValid()) { - const std::list >& aResList = aFeature->results(); - std::list >::const_iterator aRes = aResList.begin(); - for(; aRes != aResList.end(); aRes++) { + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + for (std::list::iterator aRes = aResults.begin(); + aRes != aResults.end(); aRes++) { ModelAPI_EventCreator::get()->sendUpdated(*aRes, aRedispEvent); - // #issue 1048: sub-compsolids also - ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast(*aRes); - if (aCompRes.get()) { - int aNumSubs = aCompRes->numberOfSubs(); - for(int a = 0; a < aNumSubs; a++) { - ResultPtr aSub = aCompRes->subResult(a); - if (aSub.get()) { - ModelAPI_EventCreator::get()->sendUpdated(aSub, aRedispEvent); - } - } - } } } } @@ -1645,9 +1779,15 @@ std::shared_ptr Model_Document::producedByFeature( if (aShape.IsNull()) return FeaturePtr(); - // for comsolids and compounds all the naming is located in the main object, so, try to use + // for compsolids and compounds all the naming is located in the main object, so, try to use // it first - ResultCompSolidPtr aMain = ModelAPI_Tools::compSolidOwner(theResult); + ResultBodyPtr aMain = ModelAPI_Tools::bodyOwner(theResult); + while (aMain.get()) { // get the top-most main + ResultBodyPtr aNextMain = ModelAPI_Tools::bodyOwner(aMain); + if (aNextMain.get()) + aMain = aNextMain; + else break; + } if (aMain.get()) { FeaturePtr aMainRes = producedByFeature(aMain, theShape); if (aMainRes) @@ -1773,3 +1913,46 @@ void Model_Document::eraseAllFeatures() if (myObjs) myObjs->eraseAllFeatures(); } + +void Model_Document::setExecuteFeatures(const bool theFlag) +{ + myExecuteFeatures = theFlag; + const std::set aSubs = subDocuments(); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) { + if (!subDoc(*aSubIter)->myObjs) + continue; + subDoc(*aSubIter)->setExecuteFeatures(theFlag); + } +} + +void Model_Document::appendTransactionToPrevious() +{ + Transaction anAppended = myTransactions.back(); + myTransactions.pop_back(); + if (!myTransactions.empty()) { // if it is empty, just forget the appended + myTransactions.back().myOCAFNum += anAppended.myOCAFNum; + } + // propagate the same action to sub-documents + const std::set aSubs = subDocuments(); + for (std::set::iterator aSubIter = aSubs.begin(); aSubIter != aSubs.end(); aSubIter++) { + subDoc(*aSubIter)->appendTransactionToPrevious(); + } +} + +/// GUID for keeping information about the auto-recomputation state +static const Standard_GUID kAutoRecomputationID("8493fb74-0674-4912-a100-1cf46c7cfab3"); + +void Model_Document::setAutoRecomutationState(const bool theState) +{ + if (theState) + generalLabel().FindChild(TAG_CURRENT_TRANSACTION).ForgetAttribute(kAutoRecomputationID); + else + TDataStd_UAttribute::Set( + generalLabel().FindChild(TAG_CURRENT_TRANSACTION), kAutoRecomputationID); +} + +bool Model_Document::autoRecomutationState() const +{ + return !generalLabel().FindChild(TAG_CURRENT_TRANSACTION).IsAttribute(kAutoRecomputationID); +}