From: mpv Date: Mon, 24 Aug 2015 14:54:45 +0000 (+0300) Subject: Fix for #767: correct the internal history structure for nested features X-Git-Tag: V_1.4.0_beta4~272 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5303dd1fa6ad4411e38f8d36103c72109957e05c;p=modules%2Fshaper.git Fix for #767: correct the internal history structure for nested features --- diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 5d33e78ba..fe3d061bb 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -615,7 +615,24 @@ FeaturePtr Model_Document::addFeature(std::string theID, const bool theMakeCurre aDocToAdd = this; } if (aFeature) { - aDocToAdd->myObjs->addFeature(aFeature, aDocToAdd->currentFeature(false)); + // searching for feature after which must be added the next feature: this is the current feature + // but also all sub-features of this feature + FeaturePtr aCurrent = aDocToAdd->currentFeature(false); + bool isModified = true; + for(CompositeFeaturePtr aComp = std::dynamic_pointer_cast(aCurrent); + aComp.get() && isModified; + aComp = std::dynamic_pointer_cast(aCurrent)) { + isModified = false; + int aSubs = aComp->numberOfSubs(false); + for(int a = 0; a < aSubs; a++) { + FeaturePtr aSub = aComp->subFeature(a, false); + if (myObjs->isLater(aSub, aCurrent)) { + isModified = true; + aCurrent = aSub; + } + } + } + aDocToAdd->myObjs->addFeature(aFeature, aCurrent); if (!aFeature->isAction()) { // do not add action to the data model if (theMakeCurrent) // after all this feature stays in the document, so make it current aDocToAdd->setCurrentFeature(aFeature, false); diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 8e1354f36..49bc5dfb7 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -1011,7 +1011,8 @@ FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theRever Handle(TDataStd_ReferenceArray) aRefs; if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features - if (aRefs->Value(a).IsEqual(aFeatureLabel)) { + TDF_Label aCurLab = aRefs->Value(a); + if (aCurLab.IsEqual(aFeatureLabel)) { a += theReverse ? -1 : 1; if (a >= aRefs->Lower() && a <= aRefs->Upper()) return feature(aRefs->Value(a)); @@ -1041,6 +1042,31 @@ FeaturePtr Model_Objects::lastFeature() return FeaturePtr(); // no features at all } +bool Model_Objects::isLater(FeaturePtr theLater, FeaturePtr theCurrent) const +{ + std::shared_ptr aLaterD = std::static_pointer_cast(theLater->data()); + std::shared_ptr aCurrentD = std::static_pointer_cast(theCurrent->data()); + if (aLaterD && aLaterD->isValid() && aCurrentD && aCurrentD->isValid()) { + TDF_Label aLaterL = aLaterD->label().Father(); + TDF_Label aCurrentL = aCurrentD->label().Father(); + int aLaterI = -1, aCurentI = -1; // not found yet state + Handle(TDataStd_ReferenceArray) aRefs; + if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features + TDF_Label aCurLab = aRefs->Value(a); + if (aCurLab.IsEqual(aLaterL)) { + aLaterI = a; + } else if (aCurLab.IsEqual(aCurrentL)) { + aCurentI = a; + } else continue; + if (aLaterI != -1 && aCurentI != -1) // both are found + return aLaterI > aCurentI; + } + } + } + return false; // not found, or something is wrong +} + std::list > Model_Objects::allFeatures() { std::list > aResult; diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index 114be09df..0b11f4436 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -182,6 +182,8 @@ class Model_Objects FeaturePtr firstFeature(); /// Returns to the last (from the history point of view) feature, any: invisible or disabled FeaturePtr lastFeature(); + /// Returns true if theLater is in history of features creation later than theCurrent + bool isLater(FeaturePtr theLater, FeaturePtr theCurrent) const; /// Returns the result group identifier of the given feature (for this at least one result must /// be created before)