Salome HOME
Merge branch 'Dev_0.7.1' of newgeom:newgeom into Dev_0.7.1
[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::eraseResults()
93 {
94   if (!myResults.empty()) {
95     static Events_Loop* aLoop = Events_Loop::loop();
96     static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
97     static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
98
99     std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
100     for(; aResIter != myResults.end(); aResIter++) {
101       (*aResIter)->data()->erase();
102       ModelAPI_EventCreator::get()->sendDeleted(document(), (*aResIter)->groupName());
103       aECreator->sendUpdated(*aResIter, EVENT_DISP);
104     }
105     myResults.clear();
106     // flush it to avoid left presentations after input of invalid arguments (radius=0)
107     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
108     Events_Loop::loop()->flush(anEvent);
109   }
110 }
111
112 std::shared_ptr<ModelAPI_Document> ModelAPI_Feature::documentToAdd()
113 {
114   return ModelAPI_Session::get()->activeDocument();
115 }
116
117 void ModelAPI_Feature::erase()
118 {
119   static Events_Loop* aLoop = Events_Loop::loop();
120   static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
121   static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
122
123   while (!myResults.empty()) {  // remove one by one with messages
124     std::shared_ptr<ModelAPI_Result> aRes = *(myResults.begin());
125     myResults.erase(myResults.begin());
126     aECreator->sendDeleted(aRes->document(), aRes->groupName());
127     aECreator->sendUpdated(aRes, EVENT_DISP);
128   }
129   ModelAPI_Object::erase();
130 }
131
132 ModelAPI_Feature::~ModelAPI_Feature()
133 {
134   erase();
135 }
136
137 FeaturePtr ModelAPI_Feature::feature(ObjectPtr theObject)
138 {
139   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
140   if (!aFeature) {
141     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
142     if (aResult) {
143       DocumentPtr aDoc = aResult->document();
144       return aDoc->feature(aResult);
145     }
146   }
147   return aFeature;
148 }