Salome HOME
Merge branch 'master' into Dev_1.1.0
[modules/shaper.git] / src / ModelAPI / ModelAPI_Feature.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModelAPI_Feature.cpp
4 // Created:     17 Jul 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include "ModelAPI_Feature.h"
8 #include <ModelAPI_Events.h>
9 #include <ModelAPI_Result.h>
10 #include <ModelAPI_Data.h>
11 #include <ModelAPI_Document.h>
12 #include <ModelAPI_Session.h>
13 #include <Events_Loop.h>
14
15 const std::list<std::shared_ptr<ModelAPI_Result> >& ModelAPI_Feature::results()
16 {
17   return myResults;
18 }
19
20 std::shared_ptr<ModelAPI_Result> ModelAPI_Feature::firstResult()
21 {
22   return myResults.empty() ? std::shared_ptr<ModelAPI_Result>() : *(myResults.begin());
23 }
24
25 std::shared_ptr<ModelAPI_Result> ModelAPI_Feature::lastResult()
26 {
27   return myResults.empty() ? std::shared_ptr<ModelAPI_Result>() : *(myResults.rbegin());
28 }
29
30 void ModelAPI_Feature::setResult(const std::shared_ptr<ModelAPI_Result>& theResult)
31 {
32   if (firstResult() == theResult) {  // just updated
33     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
34     ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
35     return;
36   }
37   // created
38   while (!myResults.empty()) {  // remove one by one with messages
39     std::shared_ptr<ModelAPI_Result> aRes = *(myResults.begin());
40     myResults.erase(myResults.begin());
41     ModelAPI_EventCreator::get()->sendDeleted(aRes->document(), aRes->groupName());
42   }
43   myResults.push_back(theResult);
44   static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
45   ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
46   // Create event for first Feature 
47   Events_Loop::loop()->flush(anEvent);
48 }
49
50 void ModelAPI_Feature::setResult(const std::shared_ptr<ModelAPI_Result>& theResult,
51                                  const int theIndex)
52 {
53   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
54   for (int anIndex = 0; anIndex < theIndex; anIndex++) {
55     aResIter++;
56   }
57   if (aResIter == myResults.end()) {  // append
58     myResults.push_back(theResult);
59     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
60     ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
61     // Create event for first Feature, send it to make "created" earlier than "updated"
62     // VSV: Commenting out of this statement causes problems with circle operation for example
63     Events_Loop::loop()->flush(anEvent);
64   } else {  // update
65     *aResIter = theResult;
66     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
67     ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
68   }
69 }
70
71 void ModelAPI_Feature::removeResult(const std::shared_ptr<ModelAPI_Result>& theResult)
72 {
73   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
74   for(; aResIter != myResults.end(); aResIter++) {
75     ResultPtr aRes = *aResIter;
76     if (aRes == theResult) {
77       std::string aGroup = aRes->groupName();
78       aRes->data()->erase();
79       myResults.erase(aResIter);
80
81       static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
82       static Events_Loop* aLoop = Events_Loop::loop();
83       static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
84       static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
85       ModelAPI_EventCreator::get()->sendDeleted(document(), aGroup);
86       aECreator->sendUpdated(aRes, EVENT_DISP);
87       break;
88     }
89   }
90 }
91
92 void ModelAPI_Feature::removeResults(const int theSinceIndex)
93 {
94   if (theSinceIndex == 0) {
95     eraseResults();
96     return;
97   }
98
99   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
100   for(int anIndex = 0; anIndex < theSinceIndex && aResIter != myResults.end(); anIndex++)
101     aResIter++;
102   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aNextIter = aResIter;
103   for(; aNextIter != myResults.end(); aNextIter++) {
104     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
105     static Events_Loop* aLoop = Events_Loop::loop();
106     static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
107     static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
108     ModelAPI_EventCreator::get()->sendDeleted(document(), (*aNextIter)->groupName());
109     aECreator->sendUpdated(*aNextIter, EVENT_DISP);
110   }
111   myResults.erase(aResIter, myResults.end());
112 }
113
114 void ModelAPI_Feature::eraseResults()
115 {
116   if (!myResults.empty()) {
117     static Events_Loop* aLoop = Events_Loop::loop();
118     static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
119     static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
120
121     std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
122     for(; aResIter != myResults.end(); aResIter++) {
123       (*aResIter)->data()->erase();
124       ModelAPI_EventCreator::get()->sendDeleted(document(), (*aResIter)->groupName());
125       aECreator->sendUpdated(*aResIter, EVENT_DISP);
126     }
127     myResults.clear();
128     // flush it to avoid left presentations after input of invalid arguments (radius=0)
129     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
130     Events_Loop::loop()->flush(anEvent);
131     Events_Loop::loop()->flush(EVENT_DISP);
132   }
133 }
134
135 std::shared_ptr<ModelAPI_Document> ModelAPI_Feature::documentToAdd()
136 {
137   // null pointer t ouse the current document
138   return std::shared_ptr<ModelAPI_Document>();
139 }
140
141 void ModelAPI_Feature::erase()
142 {
143   static Events_Loop* aLoop = Events_Loop::loop();
144   static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
145   static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
146
147   while (!myResults.empty()) {  // remove one by one with messages
148     std::shared_ptr<ModelAPI_Result> aRes = *(myResults.begin());
149     myResults.erase(myResults.begin());
150     aECreator->sendDeleted(aRes->document(), aRes->groupName());
151     aECreator->sendUpdated(aRes, EVENT_DISP);
152   }
153   ModelAPI_Object::erase();
154 }
155
156 ModelAPI_Feature::~ModelAPI_Feature()
157 {
158   erase();
159 }
160
161 FeaturePtr ModelAPI_Feature::feature(ObjectPtr theObject)
162 {
163   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
164   if (!aFeature) {
165     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
166     if (aResult) {
167       DocumentPtr aDoc = aResult->document();
168       return aDoc->feature(aResult);
169     }
170   }
171   return aFeature;
172 }