]> SALOME platform Git repositories - modules/shaper.git/blob - src/Model/Model_Update.cpp
Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SketchSolver
[modules/shaper.git] / src / Model / Model_Update.cpp
1 // File:        Model_Update.cxx
2 // Created:     25 Jun 2014
3 // Author:      Mikhail PONIKAROV
4
5 #include <Model_Update.h>
6 #include <ModelAPI_Feature.h>
7 #include <ModelAPI_Data.h>
8 #include <ModelAPI_Document.h>
9 #include <Model_Events.h>
10 #include <ModelAPI_AttributeReference.h>
11 #include <ModelAPI_AttributeRefList.h>
12
13 using namespace std;
14
15 Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
16
17 Model_Update::Model_Update()
18 {
19   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
20 }
21
22 void Model_Update::processEvent(const Events_Message* theMessage)
23 {
24   const Model_FeatureUpdatedMessage* aMsg = 
25     dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
26   myInitial = aMsg->features();
27   // collect all documents involved into the update
28   set<boost::shared_ptr<ModelAPI_Document> > aDocs;
29   set<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myInitial.begin();
30   for(; aFIter != myInitial.end(); aFIter++) {
31     aDocs.insert((*aFIter)->document());
32   }
33   // iterate all features of features-documents to update them
34   set<boost::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
35   for(; aDIter != aDocs.end(); aDIter++) {
36     int aNbFeatures = (*aDIter)->size(FEATURES_GROUP);
37     for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
38       boost::shared_ptr<ModelAPI_Feature> aFeature = (*aDIter)->feature(FEATURES_GROUP, aFIndex);
39       if (aFeature)
40         updateFeature(aFeature);
41     }
42   }
43   myUpdated.clear();
44 }
45
46 bool Model_Update::updateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
47 {
48   // check it is already processed
49   if (myUpdated.find(theFeature) != myUpdated.end())
50     return myUpdated[theFeature];
51   // check all features this feature depended on (recursive call of updateFeature)
52   bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end();
53   // references
54   list<boost::shared_ptr<ModelAPI_Attribute> > aRefs = 
55     theFeature->data()->attributes(ModelAPI_AttributeReference::type());
56   list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
57   for(; aRefsIter != aRefs.end(); aRefsIter++) {
58     boost::shared_ptr<ModelAPI_Feature> aSub =
59       boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
60     if (aSub && aSub != theFeature && updateFeature(aSub))
61       aMustbeUpdated = true;
62   }
63   // lists of references
64   aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
65   for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
66     list<FeaturePtr> aListRef = 
67       boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
68     list<FeaturePtr>::iterator aListIter = aListRef.begin();
69     for(; aListIter != aListRef.end(); aListIter++) {
70       boost::shared_ptr<ModelAPI_Feature> aSub = *aListIter;
71       if (aSub && updateFeature(aSub))
72         aMustbeUpdated = true;
73     }
74   }
75   // execute feature if it must be updated
76   bool anExecute = aMustbeUpdated || myInitial.find(theFeature) != myInitial.end();
77   if (anExecute) {
78     theFeature->execute();
79   }
80   myUpdated[theFeature] = anExecute;
81   return anExecute;
82 }