-// 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<mailto:webmaster.salome@opencascade.com>
+//
#include <Model_Document.h>
#include <Model_Data.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultCompSolid.h>
#include <Events_Loop.h>
#include <Events_InfoMessage.h>
#include <TDF_ListIteratorOfLabelList.hxx>
#include <TDF_LabelMap.hxx>
#include <TDF_DeltaOnAddition.hxx>
+#include <TDataStd_UAttribute.hxx>
#include <TNaming_Builder.hxx>
#include <TNaming_SameShapeIterator.hxx>
#include <TNaming_Iterator.hxx>
// 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
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;
if (currentFeature(false) != lastFeature()) {
aSession->setCheckTransactions(false);
aWasCurrent = currentFeature(false);
- setCurrentFeature(lastFeature(), false);
+ // if last is nested into something else, make this something else as last:
+ // otherwise it will look like edition of sub-element, so, the main will be disabled
+ FeaturePtr aLast = lastFeature();
+ if (aLast.get()) {
+ CompositeFeaturePtr aMain = ModelAPI_Tools::compositeOwner(aLast);
+ while(aMain.get()) {
+ aLast = aMain;
+ aMain = ModelAPI_Tools::compositeOwner(aLast);
+ }
+ }
+ setCurrentFeature(aLast, true);
}
// create a directory in the root document if it is not yet exist
Handle(Model_Application) anApp = Model_Application::getApplication();
if (isRoot()) {
#ifdef WIN32
- CreateDirectory(theDirName, NULL);
+ CreateDirectory((LPTSTR) theDirName, NULL);
#else
mkdir(theDirName, 0x1ff);
#endif
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);
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);
aLoop->flush(kRedispEvent);
aLoop->flush(kDeletedEvent);
}
+ aLoop->activateFlushes(aWasActivatedFlushes);
// to avoid "updated" message appearance by updater
//aLoop->clear(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
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;
}
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<ModelAPI_Object> Model_Document::objectByName(
return myObjs->objectByName(theGroupID, theName);
}
-const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject)
+const int Model_Document::index(std::shared_ptr<ModelAPI_Object> 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<ModelAPI_Object> Model_Document::parent(
+ const std::shared_ptr<ModelAPI_Object> theChild)
+{
+ if(myObjs == 0) // may be on close
+ return ObjectPtr();
+ return myObjs->parent(theChild);
}
std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theVisible)
void Model_Document::setCurrentFeature(
std::shared_ptr<ModelAPI_Feature> 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();
std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
if (!aData.get() || !aData->isValid()) {
aLoop->activateFlushes(isActive);
+ myIsSetCurrentFeature = false;
return;
}
TDF_Label aFeatureLabel = aData->label().Father();
if (isSub(aMain, anIter)) // sub-elements of not-disabled feature are not disabled
aDisabledFlag = false;
else if (anOwners.find(anIter) != anOwners.end())
- // disable the higher-level feature is the nested is the current
- aDisabledFlag = true;
+ // disable the higher-level feature if the nested is the current
+ if (aMain->getKind() != "Import") // exception for the import XAO feature with Group (2430)
+ aDisabledFlag = true;
}
if (anIter->getKind() == "Parameter") {
}
}
}
+ myIsSetCurrentFeature = false;
// unblock the flush signals and up them after this
aLoop->activateFlushes(isActive);
}
return myObjs->createParameter(theFeatureData, theIndex);
}
+std::shared_ptr<ModelAPI_Folder> Model_Document::addFolder(
+ std::shared_ptr<ModelAPI_Feature> theAddBefore)
+{
+ return myObjs->createFolder(theAddBefore);
+}
+
+void Model_Document::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
+{
+ if (theFolder)
+ myObjs->removeFolder(theFolder);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderAbove(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+ return myObjs->findFolder(theFeatures, false);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderBelow(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+ return myObjs->findFolder(theFeatures, true);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findContainingFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ int& theIndexInFolder)
+{
+ return myObjs->findContainingFolder(theFeature, theIndexInFolder);
+}
+
+bool Model_Document::moveToFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder)
+{
+ return myObjs->moveToFolder(theFeatures, theFolder);
+}
+
+bool Model_Document::removeFromFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore)
+{
+ return myObjs->removeFromFolder(theFeatures, theBefore);
+}
+
std::shared_ptr<ModelAPI_Feature> Model_Document::feature(
const std::shared_ptr<ModelAPI_Result>& theResult)
{
+ if (myObjs == 0) // may be on close
+ return std::shared_ptr<ModelAPI_Feature>();
return myObjs->feature(theResult);
}
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<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+
+ if (aFind != myNamingNames.end()) { // to avoid duplicate-labels
+ // to keep correct order inspite of history line management
+ std::list<TDF_Label>::iterator anAddAfterThis = aFind->second.end();
+ FeaturePtr anAddedFeature = featureByLab(theLabel);
+ std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+ while(aLabIter != aFind->second.end()) {
+ if (theLabel.IsEqual(*aLabIter)) {
+ std::list<TDF_Label>::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<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theOldName);
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theOldName);
if (aFind != myNamingNames.end()) {
- myNamingNames[theNewName] = aFind->second;
- myNamingNames.erase(theOldName);
+ std::list<TDF_Label>::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<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theName);
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
if (aFind != myNamingNames.end()) {
- return aFind->second;
+ std::list<TDF_Label>::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('/');
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<TDF_Label>::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;
+ }
+ // 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 = 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() == 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
}
-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<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+ theOther->data()->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >::iterator
+ aRefIt = aRefs.begin();
+ for(; aRefIt != aRefs.end(); aRefIt++) {
+ std::list<ObjectPtr>::iterator aRefObjIt = aRefIt->second.begin();
+ for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) {
+ ObjectPtr aRefObj = *aRefObjIt;
+ if (aRefObj.get()) {
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObj);
+ if (!aRefFeat.get()) { // take feature of the result
+ aRefFeat = feature(std::dynamic_pointer_cast<ModelAPI_Result>(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<std::string, std::list<TDF_Label> >::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<ModelAPI_Result>(theNameObject);
+ if (aNameResult)
+ aNameFeature = myObjs->feature(aNameResult);
+ else
+ aNameFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theNameObject);
+ // iterate all labels with this name to find the nearest just before or equal relative
+ std::list<TDF_Label>::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<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(aName);
+ if (aFind != myNamingNames.end() && aFind->second.size() > aNumInHistory) {
+ std::list<TDF_Label>::reverse_iterator aLibIt = aFind->second.rbegin();
+ for(; aNumInHistory != 0; aNumInHistory--)
+ aLibIt++;
+ const TDF_Label& aResultLab = *aLibIt;
+ aRes = std::dynamic_pointer_cast<ModelAPI_Result>(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<std::shared_ptr<ModelAPI_Feature> > Model_Document::allFeatures()
return myObjs->allFeatures();
}
+std::list<std::shared_ptr<ModelAPI_Object> > Model_Document::allObjects()
+{
+ return myObjs->allObjects();
+}
+
void Model_Document::setActive(const bool theFlag)
{
if (theFlag != myIsActive) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
object(ModelAPI_Feature::group(), a));
if (aFeature.get() && aFeature->data()->isValid()) {
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResList = aFeature->results();
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResList.begin();
- for(; aRes != aResList.end(); aRes++) {
+ std::list<ResultPtr> aResults;
+ ModelAPI_Tools::allResults(aFeature, aResults);
+ for (std::list<ResultPtr>::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<ModelAPI_ResultCompSolid>(*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);
- }
- }
- }
}
}
}
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)
if (myObjs)
myObjs->eraseAllFeatures();
}
+
+void Model_Document::setExecuteFeatures(const bool theFlag)
+{
+ myExecuteFeatures = theFlag;
+ const std::set<int> aSubs = subDocuments();
+ std::set<int>::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<int> aSubs = subDocuments();
+ for (std::set<int>::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);
+}