From f4bc7ecc3d09e89184b789ca346515c6a28e88a0 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 1 Aug 2018 11:04:01 +0300 Subject: [PATCH] Debug of "Concealment" behavior in multiple hierarchy case. --- src/Model/Model_Objects.cpp | 7 +-- src/Model/Model_ResultBody.cpp | 98 +++++++++++++++++----------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 199b249c3..f02468717 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -682,8 +682,8 @@ std::shared_ptr Model_Objects::parent( if (theChild.get()) { std::shared_ptr aData = std::dynamic_pointer_cast(theChild->data()); TDF_Label aLab = aData->label(); - if (!aLab.IsNull() && aLab.Depth() > 1) { - ObjectPtr anObj = object(aLab.Father().Father()); + if (!aLab.IsNull() && aLab.Depth() > 2) { + ObjectPtr anObj = object(aLab.Father().Father().Father()); return anObj; } } @@ -1180,7 +1180,8 @@ bool Model_Objects::hasCustomName(DataPtr theFeatureData, std::string& theParentName) const { ResultBodyPtr aBodyRes = std::dynamic_pointer_cast(theFeatureData->owner()); - if(aBodyRes) { + if (aBodyRes && std::dynamic_pointer_cast(theFeatureData)->label().Depth() < 7) { + // only for top-results (works for the cases when results are not yet added to the feature) FeaturePtr anOwner = ModelAPI_Feature::feature(theResult); // names of sub-solids in CompSolid should be default (for example, diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 2a82cc445..e22a0f38e 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -136,58 +136,52 @@ void Model_ResultBody::setIsConcealed(const bool theValue) } } +// recursively check all subs for concealment flag, returns true if everybody have "flag" state, +// in theAll returns results with "flag" state +static bool checkAllSubs(ResultBodyPtr theParent, bool theFlag, std::list& theAll) +{ + if (theParent->isConcealed() != theFlag) + theAll.push_back(theParent); + bool aResult = theParent->ModelAPI_ResultBody::isConcealed() == theFlag; + for(int a = 0; a < theParent->numberOfSubs(); a++) { + bool aSubRes = checkAllSubs(theParent->subResult(a), theFlag, theAll); + if (theFlag) + aResult = aResult || aSubRes; // concealed: one makes concealed everyone + else + aResult = aResult && aSubRes; // not concealed: all must be not concealed + } + return aResult; +} + void Model_ResultBody::updateConcealment() { if (myLastConcealed != ModelAPI_ResultBody::isConcealed()) { - ResultPtr anOwner = std::dynamic_pointer_cast(data()->owner()); - std::shared_ptr aParent = std::dynamic_pointer_cast( - ModelAPI_Tools::bodyOwner(anOwner)); - - myLastConcealed = ModelAPI_ResultBody::isConcealed(); // set new value and check parent - if (myLastConcealed) { // this becomes concealed, so, update all: parent and children - if (aParent.get()) - aParent->updateConcealment(); - static Events_ID EVENT_DISP = - Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendDeleted(document(), groupName()); - ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), EVENT_DISP); - std::vector::const_iterator aSubIter = mySubs.cbegin(); - for (; aSubIter != mySubs.cend(); aSubIter++) { - std::dynamic_pointer_cast(*aSubIter)->updateConcealment(); - } - } else { - // ask parent: if it is still concealed, nothing is changed - if (aParent.get()) { - aParent->updateConcealment(); - if (aParent->isConcealed()) { - myLastConcealed = true; - return; - } - } - // iterate children: if they are concealed, nothing is changed - bool aChildConcealed = false; - std::vector::const_iterator aSubIter = mySubs.cbegin(); - for (; aSubIter != mySubs.cend(); aSubIter++) { - std::dynamic_pointer_cast(*aSubIter)->updateConcealment(); - if ((*aSubIter)->isConcealed()) { - aChildConcealed = true; - break; - } - } - if (aChildConcealed) { // some child is concealed, so, update back - myLastConcealed = true; - if (aParent.get()) - aParent->updateConcealment(); - std::vector::const_iterator aSubIter = mySubs.cbegin(); - for (; aSubIter != mySubs.cend(); aSubIter++) { - std::dynamic_pointer_cast(*aSubIter)->updateConcealment(); + // check the whole tree of results: if one is concealed, everybody are concealed + ResultBodyPtr anOwner = std::dynamic_pointer_cast(data()->owner()); + ResultBodyPtr aParent = ModelAPI_Tools::bodyOwner(anOwner); + while(aParent.get()) { + anOwner = aParent; + aParent = ModelAPI_Tools::bodyOwner(anOwner); + } + // iterate all results and collect all results whose state may be updated + std::list anUpdated; + bool aNewFlag = !myLastConcealed; + if (checkAllSubs(anOwner, aNewFlag, anUpdated)) { // state of everyone must be updated + std::list::iterator aRes = anUpdated.begin(); + for(; aRes != anUpdated.end(); aRes++) { + bool aLastConcealed = (*aRes)->isConcealed(); + if (aNewFlag != aLastConcealed) { + std::dynamic_pointer_cast(*aRes)->myLastConcealed = aNewFlag; + if (aNewFlag) { // become concealed, behaves like removed + ModelAPI_EventCreator::get()->sendDeleted(document(), groupName()); + } else { // become not-concealed, behaves like created + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); + ModelAPI_EventCreator::get()->sendUpdated(*aRes, anEvent); + } + static Events_ID EVENT_DISP = // must be redisplayed in any case + Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(*aRes, EVENT_DISP); } - } else { // so, it becomes unconcealed - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent); - static Events_ID EVENT_DISP = - Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), EVENT_DISP); } } } @@ -229,8 +223,10 @@ void Model_ResultBody::updateSubs(const std::shared_ptr& theThisS // erase left, unused results while(mySubs.size() > aSubIndex) { ResultBodyPtr anErased = *(mySubs.rbegin()); - if (anErased->ModelAPI_ResultBody::isConcealed()) + if (anErased->ModelAPI_ResultBody::isConcealed()) { + anErased->ModelAPI_ResultBody::setIsConcealed(false); std::dynamic_pointer_cast(anErased)->updateConcealment(); + } anErased->setDisabled(anErased, true); mySubsMap.erase(anErased); mySubs.pop_back(); @@ -242,8 +238,10 @@ void Model_ResultBody::updateSubs(const std::shared_ptr& theThisS } else if (!mySubs.empty()) { // erase all subs while(!mySubs.empty()) { ResultBodyPtr anErased = *(mySubs.rbegin()); - if (anErased->ModelAPI_ResultBody::isConcealed()) + if (anErased->ModelAPI_ResultBody::isConcealed()) { + anErased->ModelAPI_ResultBody::setIsConcealed(false); std::dynamic_pointer_cast(anErased)->updateConcealment(); + } anErased->setDisabled(anErased, true); // even if it is invalid (to erase subs on abort/undo) mySubs.pop_back(); } -- 2.39.2