From ed165fd07e71c11885fdc5f475a8522a5914e00d Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 27 Oct 2014 11:09:36 +0300 Subject: [PATCH] Initial iteration for storage the back references and making concealment only on Apply --- src/Model/Model_AttributeReference.cpp | 5 - src/Model/Model_AttributeSelection.cpp | 16 +-- src/Model/Model_AttributeSelection.h | 4 + src/Model/Model_AttributeSelectionList.cpp | 1 + src/Model/Model_Data.cpp | 45 +++++++++ src/Model/Model_Data.h | 13 +++ src/Model/Model_Document.cpp | 108 +++++++++++---------- src/Model/Model_Document.h | 17 +--- src/Model/Model_ResultBody.cpp | 1 + src/Model/Model_ResultConstruction.cpp | 1 + src/Model/Model_ResultPart.cpp | 1 + src/Model/Model_Session.cpp | 2 +- src/Model/Model_Update.cpp | 78 +++------------ src/ModelAPI/ModelAPI_Document.h | 3 - src/ModelAPI/ModelAPI_Object.h | 1 + src/ModelAPI/ModelAPI_Result.h | 15 ++- src/ModelAPI/ModelAPI_ResultBody.h | 10 -- src/XGUI/XGUI_Workshop.cpp | 10 +- 18 files changed, 169 insertions(+), 162 deletions(-) diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index 134516972..3781fb2a2 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -20,9 +20,7 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get())); myRef->Set(aData->label().Father()); // references to the feature label - boost::shared_dynamic_cast(owner()->document())->objectIsReferenced(theObject); owner()->data()->sendAttributeUpdated(this); } @@ -51,7 +49,6 @@ Model_AttributeReference::Model_AttributeReference(TDF_Label& theLabel) if (owner()) { boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get())); } } } @@ -62,7 +59,6 @@ void Model_AttributeReference::setObject(const boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get())); } } @@ -71,5 +67,4 @@ Model_AttributeReference::~Model_AttributeReference() boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); TDF_Label aLab = myRef->Get(); - if (aDoc && !aLab.IsNull()) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get())); } diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 9c71730a0..5c1793d84 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -56,7 +56,7 @@ boost::shared_ptr Model_AttributeSelection::value() boost::shared_ptr aResult; if (myIsInitialized) { Handle(TNaming_NamedShape) aSelection; - if (myRef.myRef->Label().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { + if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { TopoDS_Shape aSelShape = aSelection->Get(); aResult = boost::shared_ptr(new GeomAPI_Shape); aResult->setImpl(new TopoDS_Shape(aSelShape)); @@ -88,7 +88,7 @@ bool Model_AttributeSelection::update() if (!aContext) return false; if (aContext->groupName() == ModelAPI_ResultBody::group()) { // body: just a named shape, use selection mechanism from OCCT - TNaming_Selector aSelector(myRef.myRef->Label()); + TNaming_Selector aSelector(selectionLabel()); TDF_LabelMap aScope; // empty means the whole document return aSelector.Solve(aScope) == Standard_True; @@ -182,7 +182,7 @@ void Model_AttributeSelection::selectBody( const ResultPtr& theContext, const boost::shared_ptr& theSubShape) { // perform the selection - TNaming_Selector aSel(myRef.myRef->Label()); + TNaming_Selector aSel(selectionLabel()); TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : TopoDS_Shape(); TopoDS_Shape aContext; @@ -196,9 +196,6 @@ void Model_AttributeSelection::selectBody( else throw std::invalid_argument("a result with shape is expected"); } - Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aNewShape, myRef.myRef->Label()); - TDF_Label aLab = aNS->Label(); - aSel.Select(aNewShape, aContext); } @@ -249,6 +246,11 @@ void Model_AttributeSelection::selectConstruction( } } // store the selected as primitive - TNaming_Builder aBuilder(myRef.myRef->Label()); + TNaming_Builder aBuilder(selectionLabel()); aBuilder.Generated(aSubShape); } + +TDF_Label Model_AttributeSelection::selectionLabel() +{ + return myRef.myRef->Label().FindChild(1); +} diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 79ce151da..150847679 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -47,6 +47,10 @@ protected: virtual void selectConstruction( const ResultPtr& theContext, const boost::shared_ptr& theSubShape); + /// Returns the label where TNaming_Selection results are stored + /// Note: there must be no attributes stored at the same label because Selector clears this lab + TDF_Label selectionLabel(); + friend class Model_Data; friend class Model_AttributeSelectionList; }; diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index 31a2e6473..a95510118 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -43,6 +43,7 @@ boost::shared_ptr void Model_AttributeSelectionList::clear() { if (!mySubs.empty()) { + mySize->Set(0); mySubs.clear(); TDF_ChildIterator aSubIter(mySize->Label()); for(; aSubIter.More(); aSubIter.Next()) { diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index b293bd3f9..c33f682a1 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -392,3 +392,48 @@ int Model_Data::featureId() const { return myLab.Father().Tag(); // tag of the feature label } + +void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID) +{ + // TODO: the concealment state update + myRefsToMe.insert(theFeature->data()->attribute(theAttrID)); +} + +void Model_Data::referencesToObjects( + std::list > >& theRefs) +{ + std::map >::iterator anAttr = myAttrs.begin(); + std::list aReferenced; // not inside of cycle to avoid excess memory menagement + for(; anAttr != myAttrs.end(); anAttr++) { + std::string aType = anAttr->second->attributeType(); + if (aType == ModelAPI_AttributeReference::type()) { // reference to object + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeReference>(anAttr->second); + aReferenced.push_back(aRef->value()); + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + } else if (aType == ModelAPI_AttributeRefAttr::type()) { // reference to attribute or object + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(anAttr->second); + aReferenced.push_back(aRef->isObject() ? aRef->object() : aRef->attr()->owner()); + } else if (aType == ModelAPI_AttributeRefList::type()) { // list of references + aReferenced = boost::dynamic_pointer_cast(anAttr->second)->list(); + } else if (aType == ModelAPI_AttributeSelection::type()) { // selection attribute + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeSelection>(anAttr->second); + aReferenced.push_back(aRef->context()); + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + } else if (aType == ModelAPI_AttributeSelectionList::type()) { // list of selection attributes + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeSelectionList>(anAttr->second); + for(int a = aRef->size() - 1; a >= 0; a--) { + aReferenced.push_back(aRef->value(a)->context()); + } + } else + continue; // nothing to do, not reference + + if (!aReferenced.empty()) { + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + aReferenced.clear(); + } + } +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index d61ddd6c2..f2de09385 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -26,6 +26,7 @@ #include #include #include +#include class ModelAPI_Attribute; @@ -44,6 +45,9 @@ class Model_Data : public ModelAPI_Data /// needed here to emit signal that object changed on change of the attribute ObjectPtr myObject; + /// List of attributes referenced to owner (updated only during the transaction change) + std::set myRefsToMe; + Model_Data(); /// Returns label of this feature @@ -53,6 +57,7 @@ class Model_Data : public ModelAPI_Data } friend class Model_Document; + friend class Model_Update; friend class Model_AttributeReference; friend class Model_AttributeRefAttr; friend class Model_AttributeRefList; @@ -150,6 +155,14 @@ class Model_Data : public ModelAPI_Data /// Returns the identifier of feature-owner, unique in this document MODEL_EXPORT virtual int featureId() const; +private: + // removes all information about back references + inline void eraseBackReferences() {myRefsToMe.clear();} + // adds a back reference (with identifier which attribute references to this object + void addBackReference(FeaturePtr theFeature, std::string theAttrID); + // returns all references by attributes of this data + // \param the returned list of pairs: id of referenced attribute and list of referenced objects + void referencesToObjects(std::list > >& theRefs); }; #endif diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 59ebd2fb0..509d94e6a 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -146,7 +147,7 @@ bool Model_Document::load(const char* theFileName) myDoc->SetUndoLimit(UNDO_LIMIT); // to avoid the problem that feature is created in the current, not this, document Model_Session::get()->setActiveDocument(anApp->getDocument(myID)); - synchronizeFeatures(); + synchronizeFeatures(false, true); } return !isError; } @@ -304,7 +305,7 @@ void Model_Document::abortOperation() myNestedNum = -1; myDoc->AbortCommand(); } - synchronizeFeatures(true); + synchronizeFeatures(true, false); // references were not changed since transaction start // abort for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -343,7 +344,7 @@ void Model_Document::undo() myNestedNum--; if (!myIsEmptyTr[myTransactionsAfterSave]) myDoc->Undo(); - synchronizeFeatures(true); + synchronizeFeatures(true, true); // undo for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -369,7 +370,7 @@ void Model_Document::redo() if (!myIsEmptyTr[myTransactionsAfterSave]) myDoc->Redo(); myTransactionsAfterSave++; - synchronizeFeatures(true); + synchronizeFeatures(true, true); // redo for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -467,10 +468,12 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) // check the feature: it must have no depended objects on it std::list::const_iterator aResIter = theFeature->results().cbegin(); for(; aResIter != theFeature->results().cend(); aResIter++) { + /* if (myConcealedResults.find(*aResIter) != myConcealedResults.end()) { Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); return; } + */ } NCollection_DataMap::Iterator anObjIter(myObjs); for(; anObjIter.More(); anObjIter.Next()) { @@ -590,9 +593,9 @@ ObjectPtr Model_Document::object(const std::string& theGroupID, const int theInd std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { if ((*aRIter)->groupName() != theGroupID) continue; - bool isIn = theHidden; + bool isIn = theHidden && (*aRIter)->isInHistory(); if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result - isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); + isIn = !(*aRIter)->isConcealed(); } if (isIn) { if (anIndex == theIndex) @@ -629,7 +632,7 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden) if ((*aRIter)->groupName() != theGroupID) continue; bool isIn = theHidden; if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result - isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); + isIn = !(*aRIter)->isConcealed(); } if (isIn) aResult++; @@ -664,12 +667,12 @@ void Model_Document::setUniqueName(FeaturePtr theFeature) // check this is unique, if not, increase index by 1 for (aFIter.Initialize(myObjs); aFIter.More();) { FeaturePtr aFeature = aFIter.Value(); - bool isSameName = aFeature->isInHistory() && aFeature->data()->name() == aName; + bool isSameName = aFeature->data()->name() == aName; if (!isSameName) { // check also results to avoid same results names (actual for Parts) const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { - isSameName = (*aRIter)->isInHistory() && (*aRIter)->data()->name() == aName; + isSameName = (*aRIter)->data()->name() == aName; } } if (isSameName) { @@ -701,7 +704,7 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT } } -void Model_Document::synchronizeFeatures(const bool theMarkUpdated) +void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences) { boost::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); @@ -785,6 +788,49 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated) aFIter.Next(); } + if (theUpdateReferences) { + // first cycle: erase all data about back-references + NCollection_DataMap::Iterator aFeatures(myObjs); + for(; aFeatures.More(); aFeatures.Next()) { + FeaturePtr aFeature = aFeatures.Value(); + boost::shared_ptr aFData = + boost::dynamic_pointer_cast(aFeature->data()); + if (aFData) { + aFData->eraseBackReferences(); + } + const std::list >& aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + boost::shared_ptr aResData = + boost::dynamic_pointer_cast((*aRIter)->data()); + if (aResData) { + aResData->eraseBackReferences(); + } + } + } + + // second cycle: set new back-references: only features may have reference, iterate only them + ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); + for(aFeatures.Initialize(myObjs); aFeatures.More(); aFeatures.Next()) { + FeaturePtr aFeature = aFeatures.Value(); + boost::shared_ptr aFData = + boost::dynamic_pointer_cast(aFeature->data()); + if (aFData) { + std::list > > aRefs; + aFData->referencesToObjects(aRefs); + std::list > >::iterator aRefsIter = aRefs.begin(); + for(; aRefsIter != aRefs.end(); aRefsIter++) { + std::list::iterator aReferenced = aRefsIter->second.begin(); + for(; aReferenced != aRefsIter->second.end(); aReferenced++) { + boost::shared_ptr aRefData = + boost::dynamic_pointer_cast((*aReferenced)->data()); + aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated + } + } + } + } + } + myExecuteFeatures = false; aLoop->activateFlushes(true); @@ -928,48 +974,6 @@ void Model_Document::updateResults(FeaturePtr theFeature) } } -void Model_Document::objectIsReferenced(const ObjectPtr& theObject) -{ - // only bodies are concealed now - ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); - if (aResult) { - if (myConcealedResults.find(aResult) != myConcealedResults.end()) { - Events_Error::send(std::string("The object '") + aResult->data()->name() + - "' is already referenced"); - } else { - myConcealedResults.insert(aResult); - boost::shared_ptr aThis = - Model_Application::getApplication()->getDocument(myID); - ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_ResultBody::group()); - - static Events_Loop* aLoop = Events_Loop::loop(); - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); - aECreator->sendUpdated(aResult, EVENT_DISP); - } - } -} - -void Model_Document::objectIsNotReferenced(const ObjectPtr& theObject) -{ - // only bodies are concealed now - ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); - if (aResult) { - std::set::iterator aFind = myConcealedResults.find(aResult); - if (aFind != myConcealedResults.end()) { - ResultPtr aFeature = *aFind; - myConcealedResults.erase(aFind); - boost::shared_ptr aThis = - Model_Application::getApplication()->getDocument(myID); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent, false); - } else { - Events_Error::send(std::string("The object '") + aResult->data()->name() + - "' was not referenced '"); - } - } -} - Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper) { return TDF_LabelMapHasher::HashCode(theLab, theUpper); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 6f813bd23..2446cbf7c 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -130,12 +130,6 @@ class Model_Document : public ModelAPI_Document ///! On abort, undo or redo it is not necessary: results in document are updated automatically bool executeFeatures() {return myExecuteFeatures;} - ///! Reutrns true is result was conecaled because of usage it by other object - virtual bool isConcealed(const boost::shared_ptr& theResult) { - return myConcealedResults.find(boost::dynamic_pointer_cast(theResult)) - != myConcealedResults.end(); - } - protected: //! Returns (creates if needed) the features label @@ -146,7 +140,9 @@ class Model_Document : public ModelAPI_Document void setUniqueName(FeaturePtr theFeature); //! Synchronizes myFeatures list with the updated document - void synchronizeFeatures(const bool theMarkUpdated = false); + //! \param theMarkUpdated causes the "update" event for all features + //! \param theUpdateReferences causes the update of back-references + void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences); //! Creates new document with binary file format Model_Document(const std::string theID, const std::string theKind); @@ -174,11 +170,6 @@ class Model_Document : public ModelAPI_Document //! Updates the results list of the feature basing on the current data tree void updateResults(FeaturePtr theFeature); - //! Stores information that there is a reference to this object - void objectIsReferenced(const ObjectPtr& theObject); - //! Removes information that there is a reference to this object - void objectIsNotReferenced(const ObjectPtr& theObject); - //! Returns all sub documents const std::set& subDocuments() const {return mySubs;} @@ -198,8 +189,6 @@ class Model_Document : public ModelAPI_Document /// All features managed by this document (not only in history of OB) /// For optimization mapped by labels NCollection_DataMap myObjs; - /// Results that are referenced and must be concealed for object browser - std::set myConcealedResults; ///< set of identifiers of sub-documents of this document std::set mySubs; diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index f5c8cb223..1fad264d8 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -12,6 +12,7 @@ Model_ResultBody::Model_ResultBody() { + setIsConcealed(false); } void Model_ResultBody::store(const boost::shared_ptr& theShape) diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 0b6d56612..8af38252d 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -17,6 +17,7 @@ boost::shared_ptr& Model_ResultConstruction::shape() Model_ResultConstruction::Model_ResultConstruction() { myIsInHistory = true; + setIsConcealed(false); } void Model_ResultConstruction::setIsInHistory(const bool isInHistory) diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 98319c474..a1fb09b01 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -19,6 +19,7 @@ boost::shared_ptr Model_ResultPart::owner() Model_ResultPart::Model_ResultPart() { + setIsConcealed(false); } void Model_ResultPart::setData(boost::shared_ptr theData) diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 6a3cf53cc..37b020eee 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -191,7 +191,7 @@ boost::shared_ptr Model_Session::copy( aRT->SetRelocation(aSourceRoot, aTargetRoot); TDF_CopyTool::Copy(aDS, aRT); - aNew->synchronizeFeatures(); + aNew->synchronizeFeatures(false, true); return aNew; } diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 5ef4a8f09..ccdd45e77 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -137,67 +138,16 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) aMustbeUpdated = true; } } - - // references - list > aRefs = theFeature->data()->attributes( - ModelAPI_AttributeReference::type()); - list >::iterator aRefsIter = aRefs.begin(); - for (; aRefsIter != aRefs.end(); aRefsIter++) { - boost::shared_ptr aSub = boost::dynamic_pointer_cast< - ModelAPI_AttributeReference>(*aRefsIter)->value(); - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } - // reference to attribute or object - list > aRefAttrs = theFeature->data()->attributes( - ModelAPI_AttributeRefAttr::type()); - for (aRefsIter = aRefAttrs.begin(); aRefsIter != aRefAttrs.end(); aRefsIter++) { - boost::shared_ptr aRef = - boost::dynamic_pointer_cast(*aRefsIter); - if (!aRef) continue; - if (aRef->isObject()) { - boost::shared_ptr aSub = aRef->object(); - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } else if (aRef->attr()) { // reference to the attribute - boost::shared_ptr aSub = aRef->attr()->owner(); - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } - } - // lists of references - aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type()); - for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { - list aListRef = boost::dynamic_pointer_cast(*aRefsIter) - ->list(); - list::iterator aListIter = aListRef.begin(); - for (; aListIter != aListRef.end(); aListIter++) { - boost::shared_ptr aSub = *aListIter; - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } - } - // selection attributes: must be called "update" methods if needed - aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); - for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { - boost::shared_ptr aSel = - boost::dynamic_pointer_cast(*aRefsIter); - if (updateObject(aSel->context())) { - aMustbeUpdated = true; - // aSel->update(); // this must be done on execution since it may be long operation - } - } - // lists of selection attributes: must be called "update" methods if needed - aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelectionList::type()); - for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { - boost::shared_ptr aSel = - boost::dynamic_pointer_cast(*aRefsIter); - for(int a = aSel->size() - 1; a >= 0; a--) { - if (updateObject(aSel->value(a)->context())) { + // check all references: if referenced objects are updated, this object also must be updated + std::list > > aRefs; + boost::shared_ptr aData = + boost::dynamic_pointer_cast(theFeature->data()); + aData->referencesToObjects(aRefs); + std::list > >::iterator aRef = aRefs.begin(); + for(; aRef != aRefs.end(); aRef++) { + std::list::iterator aRefObj = aRef->second.begin(); + for(; aRefObj != aRef->second.end(); aRefObj++) { + if (updateObject(*aRefObj)) { aMustbeUpdated = true; } } @@ -214,8 +164,10 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) !theFeature->isPersistentResult() /* execute quick, not persistent results */) { // before execution update the selection attributes if any - aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); - for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { + list aRefs = + theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); + list::iterator aRefsIter = aRefs.begin(); + for (; aRefsIter != aRefs.end(); aRefsIter++) { boost::shared_ptr aSel = boost::dynamic_pointer_cast(*aRefsIter); aSel->update(); // this must be done on execution since it may be long operation diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 773ec389c..cdfa1d75e 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -81,9 +81,6 @@ public: virtual boost::shared_ptr feature( const boost::shared_ptr& theResult) = 0; - ///! Reutrns true is result was conecaled because of usage it by other object - virtual bool isConcealed(const boost::shared_ptr& theResult) = 0; - protected: /// Only for SWIG wrapping it is here MODELAPI_EXPORT ModelAPI_Document() diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index 7c539d7d5..f6e3c6c32 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -56,6 +56,7 @@ class ModelAPI_Object /// To use virtuality for destructors virtual ~ModelAPI_Object() {} + protected: /// Sets the data manager of an object (document does) virtual void setData(boost::shared_ptr theData) diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index af9e7ce87..eb664ec22 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -17,12 +17,19 @@ class ModelAPI_Feature; */ class ModelAPI_Result : public ModelAPI_Object { + bool myIsConcealed; ///< the result is concealed from the data tree (referenced by other objects) public: - /// Returns the source feature of this result - //virtual boost::shared_ptr owner() = 0; + /// Returns true if the result is concealed from the data tree (referenced by other objects) + inline bool isConcealed() {return myIsConcealed;} + + /// Returns true if the result is concealed from the data tree (referenced by other objects) + inline void setIsConcealed(const bool theValue) {myIsConcealed = theValue;} + + /// To virtually destroy the fields of successors + virtual ~ModelAPI_Result() + { + } - /// Returns the group identifier of this result - //virtual std::string groupName() = 0; }; //! Pointer on feature object diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index bcd45b354..db329c1fc 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -39,11 +39,6 @@ public: /// Returns the shape-result produced by this feature virtual boost::shared_ptr shape() = 0; - /// To virtually destroy the fields of successors - virtual ~ModelAPI_ResultBody() - { - } - /// Records the subshape newShape which was generated during a topological construction. /// As an example, consider the case of a face generated in construction of a box. virtual void generated( @@ -66,11 +61,6 @@ public: const boost::shared_ptr& theOldShape, const int theTag = 1) = 0; protected: - /// Use plugin manager for features creation: this method is - /// defined here only for SWIG-wrapping - ModelAPI_ResultBody() - { - } }; //! Pointer on feature object diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 8ca4729a3..7746a3c56 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -419,7 +419,12 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptrdata() || !aObj->data()->isValid() || aObj->document()->isConcealed(aObj)) + bool aHide = !aObj->data() || !aObj->data()->isValid(); + if (!aHide) { // check that this is not hidden result + ResultPtr aRes = boost::dynamic_pointer_cast(aObj); + aHide = aRes && aRes->isConcealed(); + } + if (aHide) myDisplayer->erase(aObj, false); else { if (myDisplayer->isVisible(aObj)) { @@ -463,8 +468,7 @@ void XGUI_Workshop::onFeatureCreatedMsg(const boost::shared_ptrhasOperation()) { ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - if (!(*aIt)->document()->isConcealed(*aIt) && - aOperation->hasObject(*aIt)) { // Display only current operation results + if (aOperation->hasObject(*aIt)) { // Display only current operation results myDisplayer->display(*aIt, false); isDisplayed = true; } -- 2.39.2