From 92850f45a1d8ea12d8c5f4f286076887b2c8301d Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 27 Oct 2014 14:55:00 +0300 Subject: [PATCH] Debug of selection and delete of feature --- src/Model/Model_AttributeSelection.cpp | 4 +- src/Model/Model_Data.cpp | 37 ------ src/Model/Model_Data.h | 5 +- src/Model/Model_Document.cpp | 124 ++++++++---------- src/Model/Model_Document.h | 2 + src/ModelAPI/ModelAPI_Data.h | 3 - .../ModuleBase_WidgetShapeSelector.cpp | 1 - 7 files changed, 64 insertions(+), 112 deletions(-) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 5c1793d84..3d351d413 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -129,7 +129,7 @@ bool Model_AttributeSelection::update() for(; aRes != aResults.cend(); aRes++) { ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(*aRes); - if (aConstr->shape()) { + if (aConstr->shape() && aConstr->shape()->isEdge()) { const TopoDS_Shape& aResShape = aConstr->shape()->impl(); TopoDS_Edge anEdge = TopoDS::Edge(aResShape); if (!anEdge.IsNull()) { @@ -230,7 +230,7 @@ void Model_AttributeSelection::selectConstruction( for(; aRes != aResults.cend(); aRes++) { ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(*aRes); - if (aConstr->shape()) { + if (aConstr->shape() && aConstr->shape()->isEdge()) { const TopoDS_Shape& aResShape = aConstr->shape()->impl(); TopoDS_Edge anEdge = TopoDS::Edge(aResShape); if (!anEdge.IsNull()) { diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index c33f682a1..cc3ed5ef3 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -351,43 +351,6 @@ bool Model_Data::mustBeUpdated() return myLab.IsAttribute(kMustBeUpdatedGUID) == Standard_True; } -bool Model_Data::referencesTo(const boost::shared_ptr& theFeature) -{ - // collect results of this feature first to check references quickly in the cycle - std::set aFeatureObjs; - aFeatureObjs.insert(theFeature); - std::list >::const_iterator aRIter = - theFeature->results().cbegin(); - for(; aRIter != theFeature->results().cend(); aRIter++) { - if (*aRIter) - aFeatureObjs.insert(*aRIter); - } - - std::map >::iterator anAttrsIter = - myAttrs.begin(); - for (; anAttrsIter != myAttrs.end(); anAttrsIter++) { - if (anAttrsIter->second->attributeType() == ModelAPI_AttributeRefAttr::type()) { - boost::shared_ptr aRefAttr = - boost::dynamic_pointer_cast(anAttrsIter->second); - if (aRefAttr && aRefAttr->isObject()) { // check referenced object - if (aFeatureObjs.find(aRefAttr->object()) != aFeatureObjs.end()) - return true; - } else { // check object of referenced attribute - boost::shared_ptr anAttr = aRefAttr->attr(); - if (anAttr && aFeatureObjs.find(anAttr->owner()) != aFeatureObjs.end()) - return true; - } - } else if (anAttrsIter->second->attributeType() == ModelAPI_AttributeReference::type()) { - boost::shared_ptr aRef = - boost::dynamic_pointer_cast(anAttrsIter->second); - if (aFeatureObjs.find(aRef->value()) != aFeatureObjs.end()) { - return true; - } - } - } - return false; -} - int Model_Data::featureId() const { return myLab.Father().Tag(); // tag of the feature label diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index f2de09385..46d50acc0 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -149,9 +149,6 @@ class Model_Data : public ModelAPI_Data /// Returns true if feature must be updated (re-executed) on rebuild MODEL_EXPORT virtual bool mustBeUpdated(); - /// Returns true if this data attributes are referenced to the given feature or its results - MODEL_EXPORT virtual bool referencesTo(const boost::shared_ptr& theFeature); - /// Returns the identifier of feature-owner, unique in this document MODEL_EXPORT virtual int featureId() const; @@ -160,6 +157,8 @@ private: 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 objects referenced to this + const std::set& refsToMe() {return myRefsToMe;} // 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); diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 509d94e6a..05452239c 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -265,10 +265,12 @@ void Model_Document::finishOperation() if (!myDoc->HasOpenCommand() && myNestedNum != -1) boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(false); // for nested transaction commit + synchronizeBackRefs(); Events_Loop* aLoop = Events_Loop::loop(); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); if (!myDoc->HasOpenCommand() && myNestedNum != -1) boost::static_pointer_cast(Model_Session::get()) @@ -468,18 +470,11 @@ 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()) { - DataPtr aData = anObjIter.Value()->data(); - if (aData->referencesTo(theFeature)) { - Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); + boost::shared_ptr aData = + boost::dynamic_pointer_cast((*aResIter)->data()); + if (aData && !aData->refsToMe().empty()) { + Events_Error::send( + "Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); return; } } @@ -496,22 +491,11 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) // erase all attributes under the label of feature aFeatureLabel.ForgetAllAttributes(); // remove it from the references array - RemoveFromRefArray(featuresLabel(), aFeatureLabel); - + if (theFeature->isInHistory()) { + RemoveFromRefArray(featuresLabel(), aFeatureLabel); + } // event: feature is deleted ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); - /* this is in "erase" - // results of this feature must be redisplayed - static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - const std::list >& aResults = theFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); - for (; aRIter != aResults.cend(); aRIter++) { - boost::shared_ptr aRes = *aRIter; - aRes->setData(boost::shared_ptr()); // deleted flag - ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP); - ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), aRes->groupName()); - } - */ } FeaturePtr Model_Document::feature(TDF_Label& theLabel) @@ -789,46 +773,7 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t } 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 - } - } - } - } + synchronizeBackRefs(); } myExecuteFeatures = false; @@ -840,11 +785,58 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); } aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(true); myExecuteFeatures = true; } +void Model_Document::synchronizeBackRefs() +{ + // 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 aRefTo = aRefsIter->second.begin(); + for(; aRefTo != aRefsIter->second.end(); aRefTo++) { + if (*aRefTo) { + boost::shared_ptr aRefData = + boost::dynamic_pointer_cast((*aRefTo)->data()); + aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated + } + } + } + } + } +} + TDF_Label Model_Document::resultLabel( const boost::shared_ptr& theFeatureData, const int theResultIndex) { diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 2446cbf7c..cbea4a19e 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -143,6 +143,8 @@ class Model_Document : public ModelAPI_Document //! \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); + //! Synchronizes the BackReferences list in Data of Features and Results + void synchronizeBackRefs(); //! Creates new document with binary file format Model_Document(const std::string theID, const std::string theKind); diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 85c65cbd5..2acf4fc6b 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -106,9 +106,6 @@ class MODELAPI_EXPORT ModelAPI_Data /// Returns true if feature must be updated (re-executed) on rebuild virtual bool mustBeUpdated() = 0; - /// Returns true if this data attributes are referenced to the given feature or its results - virtual bool referencesTo(const boost::shared_ptr& theFeature) = 0; - /// Returns the identifier of feature-owner, unique in this document virtual int featureId() const = 0; diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 470450070..1de73631a 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -227,7 +227,6 @@ void ModuleBase_WidgetShapeSelector::setObject(ObjectPtr theObj, boost::shared_p if (!myUseSubShapes) { static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TOHIDE); ModelAPI_EventCreator::get()->sendUpdated(mySelectedObject, anEvent); - Events_Loop::loop()->flush(anEvent); } } updateSelectionName(); -- 2.39.2