+
+void Model_Update::updateStability(void* theSender)
+{
+ ModelAPI_Object* aSender = static_cast<ModelAPI_Object*>(theSender);
+ if (aSender && aSender->document()) {
+ Model_Objects* aDocObjects =
+ std::dynamic_pointer_cast<Model_Document>(aSender->document())->objects();
+ if (aDocObjects) {
+ aDocObjects->synchronizeBackRefs();
+ }
+ }
+}
+
+///////////////// Updated items iterator ////////////////////////
+Model_Update::IterationItem::IterationItem(std::shared_ptr<ModelAPI_CompositeFeature> theFeature)
+{
+ myBreaked = false;
+ myIsVirtual = false;
+ myMain = theFeature;
+ myObjects = NULL;
+ if (!myMain.get() && ModelAPI_Session::get()->hasModuleDocument()) { // no document => nothing to do
+ DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+ myObjects = std::dynamic_pointer_cast<Model_Document>(aRootDoc)->objects();
+ }
+ mySkipNext = false;
+}
+
+void Model_Update::IterationItem::next()
+{
+ if (mySkipNext) { // ignore one next
+ mySkipNext = false;
+ return;
+ }
+ if (!myBreaked) {
+ if (myMain.get()) {
+ myIndex++;
+ int aNumSubs = myMain->numberOfSubs();
+ if (myIndex == aNumSubs)
+ return;
+ // skip sub-objects, that are subs not only for this: sketch elements relatively to Part
+ for(FeaturePtr aSub = myMain->subFeature(myIndex); aSub.get();
+ aSub = myMain->subFeature(myIndex)) {
+ aSub = myMain->subFeature(myIndex);
+ CompositeFeaturePtr anOwner = ModelAPI_Tools::compositeOwner(aSub);
+ if (!anOwner.get() || anOwner == myMain) {
+ break;
+ }
+ myIndex++;
+ if (myIndex == aNumSubs)
+ break;
+ }
+ } else if (mySub.get()) {
+ while(mySub.get()) {
+ mySub = myObjects->nextFeature(mySub);
+ CompositeFeaturePtr anOwner = ModelAPI_Tools::compositeOwner(mySub);
+ // skip sub-objects, that are subs not only for this: sketch elements relatively to PartSet
+ if (!anOwner.get()) {
+ break;
+ }
+ }
+ }
+ }
+}
+
+bool Model_Update::IterationItem::more()
+{
+ if (myBreaked)
+ return false;
+ if (myMain.get())
+ return myIndex < myMain->numberOfSubs();
+ return mySub.get() != NULL;
+}
+
+FeaturePtr Model_Update::IterationItem::current()
+{
+ if (myMain.get())
+ return myMain->subFeature(myIndex);
+ return mySub;
+}
+
+void Model_Update::IterationItem::setBreaked()
+{
+ if (!myIsVirtual)
+ myBreaked = true;
+}
+
+void Model_Update::IterationItem::startIteration(const bool theVirtual)
+{
+ myIsVirtual = theVirtual;
+ if (myMain.get()) {
+ myIndex = 0;
+ } else if (myObjects) {
+ mySub = myObjects->firstFeature();
+ }
+}
+
+bool Model_Update::IterationItem::isIterated(FeaturePtr theFeature)
+{
+ if (myMain.get()) {
+ if (myMain->isSub(theFeature)) {
+ CompositeFeaturePtr anOwner = ModelAPI_Tools::compositeOwner(theFeature);
+ if (!anOwner.get() || anOwner == myMain)
+ return true;
+ }
+ return false;
+ }
+ // for the root document just check that this feature in this document and it is not sub
+ return myObjects->owner() == theFeature->document() &&
+ !ModelAPI_Tools::compositeOwner(theFeature).get();
+}
+
+bool Model_Update::IterationItem::isEarlierThanCurrent(FeaturePtr theFeature)
+{
+ if (myMain.get()) {
+ for(int a = 0; a < myIndex; a++) {
+ if (myMain->subFeature(a) == theFeature)
+ return true;
+ }
+ } else {
+ return !mySub.get() && !myObjects->isLater(theFeature, mySub);
+ }
+ return false;
+}
+
+void Model_Update::IterationItem::setCurrentBefore(FeaturePtr theFeature)
+{
+ if (myMain.get()) {
+ for(int a = 0; a < myIndex; a++) {
+ if (myMain->subFeature(a) == theFeature) {
+ myIndex = a;
+ break;
+ }
+ }
+ } else {
+ mySub = theFeature;
+ }
+ mySkipNext = true;
+}