Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / Model / Model_Data.cpp
1 // File:        Model_Data.hxx
2 // Created:     21 Mar 2014
3 // Author:      Mikhail PONIKAROV
4
5 #include <Model_Data.h>
6 #include <Model_AttributeDocRef.h>
7 #include <Model_AttributeInteger.h>
8 #include <Model_AttributeDouble.h>
9 #include <Model_AttributeReference.h>
10 #include <Model_AttributeRefAttr.h>
11 #include <Model_AttributeRefList.h>
12 #include <Model_AttributeBoolean.h>
13 #include <Model_AttributeString.h>
14 #include <Model_AttributeSelection.h>
15 #include <Model_AttributeSelectionList.h>
16 #include <Model_Events.h>
17 #include <ModelAPI_Feature.h>
18 #include <ModelAPI_Result.h>
19
20 #include <GeomData_Point.h>
21 #include <GeomData_Point2D.h>
22 #include <GeomData_Dir.h>
23 #include <Events_Loop.h>
24 #include <Events_Error.h>
25
26 #include <TDataStd_Name.hxx>
27 #include <TDataStd_UAttribute.hxx>
28
29 #include <string>
30
31 Model_Data::Model_Data()
32 {
33 }
34
35 void Model_Data::setLabel(TDF_Label theLab)
36 {
37   myLab = theLab;
38 }
39
40 std::string Model_Data::name()
41 {
42   Handle(TDataStd_Name) aName;
43   if (myLab.FindAttribute(TDataStd_Name::GetID(), aName))
44     return std::string(TCollection_AsciiString(aName->Get()).ToCString());
45   return "";  // not defined
46 }
47
48 void Model_Data::setName(const std::string& theName)
49 {
50   bool isModified = false;
51   Handle(TDataStd_Name) aName;
52   if (!myLab.FindAttribute(TDataStd_Name::GetID(), aName)) {
53     TDataStd_Name::Set(myLab, theName.c_str());
54     isModified = true;
55   } else {
56     isModified = !aName->Get().IsEqual(theName.c_str());
57     if (isModified)
58       aName->Set(theName.c_str());
59   }
60 }
61
62 void Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
63 {
64   TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
65   ModelAPI_Attribute* anAttr = 0;
66   if (theAttrType == ModelAPI_AttributeDocRef::type()) {
67     anAttr = new Model_AttributeDocRef(anAttrLab);
68   } else if (theAttrType == Model_AttributeInteger::type()) {
69     anAttr = new Model_AttributeInteger(anAttrLab);
70   } else if (theAttrType == ModelAPI_AttributeDouble::type()) {
71     anAttr = new Model_AttributeDouble(anAttrLab);
72   } else if (theAttrType == Model_AttributeBoolean::type()) {
73     anAttr = new Model_AttributeBoolean(anAttrLab);
74   } else if (theAttrType == Model_AttributeString::type()) {
75     anAttr = new Model_AttributeString(anAttrLab);
76   } else if (theAttrType == ModelAPI_AttributeReference::type()) {
77     anAttr = new Model_AttributeReference(anAttrLab);
78   } else if (theAttrType == ModelAPI_AttributeSelection::type()) {
79     anAttr = new Model_AttributeSelection(anAttrLab);
80   } else if (theAttrType == ModelAPI_AttributeSelectionList::type()) {
81     anAttr = new Model_AttributeSelectionList(anAttrLab);
82   } else if (theAttrType == ModelAPI_AttributeRefAttr::type()) {
83     anAttr = new Model_AttributeRefAttr(anAttrLab);
84   } else if (theAttrType == ModelAPI_AttributeRefList::type()) {
85     anAttr = new Model_AttributeRefList(anAttrLab);
86   } else if (theAttrType == GeomData_Point::type()) {
87     anAttr = new GeomData_Point(anAttrLab);
88   } else if (theAttrType == GeomData_Dir::type()) {
89     anAttr = new GeomData_Dir(anAttrLab);
90   } else if (theAttrType == GeomData_Point2D::type()) {
91     anAttr = new GeomData_Point2D(anAttrLab);
92   }
93   if (anAttr) {
94     myAttrs[theID] = boost::shared_ptr<ModelAPI_Attribute>(anAttr);
95     anAttr->setObject(myObject);
96   } else {
97     Events_Error::send("Can not create unknown type of attribute " + theAttrType);
98   }
99 }
100
101 boost::shared_ptr<ModelAPI_AttributeDocRef> Model_Data::document(const std::string& theID)
102 {
103   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
104     myAttrs.find(theID);
105   if (aFound == myAttrs.end()) {
106     // TODO: generate error on unknown attribute request and/or add mechanism for customization
107     return boost::shared_ptr<ModelAPI_AttributeDocRef>();
108   }
109   boost::shared_ptr<ModelAPI_AttributeDocRef> aRes = boost::dynamic_pointer_cast<
110       ModelAPI_AttributeDocRef>(aFound->second);
111   if (!aRes) {
112     // TODO: generate error on invalid attribute type request
113   }
114   return aRes;
115 }
116
117 boost::shared_ptr<ModelAPI_AttributeDouble> Model_Data::real(const std::string& theID)
118 {
119   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
120     myAttrs.find(theID);
121   if (aFound == myAttrs.end()) {
122     // TODO: generate error on unknown attribute request and/or add mechanism for customization
123     return boost::shared_ptr<ModelAPI_AttributeDouble>();
124   }
125   boost::shared_ptr<ModelAPI_AttributeDouble> aRes = boost::dynamic_pointer_cast<
126       ModelAPI_AttributeDouble>(aFound->second);
127   if (!aRes) {
128     // TODO: generate error on invalid attribute type request
129   }
130   return aRes;
131 }
132
133 boost::shared_ptr<ModelAPI_AttributeInteger> Model_Data::integer(const std::string& theID)
134 {
135   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
136     myAttrs.find(theID);
137   if (aFound == myAttrs.end()) {
138     // TODO: generate error on unknown attribute request and/or add mechanism for customization
139     return boost::shared_ptr<ModelAPI_AttributeInteger>();
140   }
141   boost::shared_ptr<ModelAPI_AttributeInteger> aRes = boost::dynamic_pointer_cast<
142       ModelAPI_AttributeInteger>(aFound->second);
143   if (!aRes) {
144     // TODO: generate error on invalid attribute type request
145   }
146   return aRes;
147 }
148
149 boost::shared_ptr<ModelAPI_AttributeBoolean> Model_Data::boolean(const std::string& theID)
150 {
151   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
152     myAttrs.find(theID);
153   if (aFound == myAttrs.end()) {
154     // TODO: generate error on unknown attribute request and/or add mechanism for customization
155     return boost::shared_ptr<ModelAPI_AttributeBoolean>();
156   }
157   boost::shared_ptr<ModelAPI_AttributeBoolean> aRes = boost::dynamic_pointer_cast<
158       ModelAPI_AttributeBoolean>(aFound->second);
159   if (!aRes) {
160     // TODO: generate error on invalid attribute type request
161   }
162   return aRes;
163 }
164
165 boost::shared_ptr<ModelAPI_AttributeString> Model_Data::string(const std::string& theID)
166 {
167   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
168     myAttrs.find(theID);
169   if (aFound == myAttrs.end()) {
170     // TODO: generate error on unknown attribute request and/or add mechanism for customization
171     return boost::shared_ptr<ModelAPI_AttributeString>();
172   }
173   boost::shared_ptr<ModelAPI_AttributeString> aRes =
174       boost::dynamic_pointer_cast<ModelAPI_AttributeString>(aFound->second);
175   if (!aRes) {
176     // TODO: generate error on invalid attribute type request
177   }
178   return aRes;
179
180 }
181
182 boost::shared_ptr<ModelAPI_AttributeReference> Model_Data::reference(const std::string& theID)
183 {
184   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
185     myAttrs.find(theID);
186   if (aFound == myAttrs.end()) {
187     // TODO: generate error on unknown attribute request and/or add mechanism for customization
188     return boost::shared_ptr<ModelAPI_AttributeReference>();
189   }
190   boost::shared_ptr<ModelAPI_AttributeReference> aRes = boost::dynamic_pointer_cast<
191       ModelAPI_AttributeReference>(aFound->second);
192   if (!aRes) {
193     // TODO: generate error on invalid attribute type request
194   }
195   return aRes;
196 }
197
198 boost::shared_ptr<ModelAPI_AttributeSelection> Model_Data::selection(const std::string& theID)
199 {
200   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
201     myAttrs.find(theID);
202   if (aFound == myAttrs.end()) {
203     // TODO: generate error on unknown attribute request and/or add mechanism for customization
204     return boost::shared_ptr<ModelAPI_AttributeSelection>();
205   }
206   boost::shared_ptr<ModelAPI_AttributeSelection> aRes = 
207     boost::dynamic_pointer_cast<ModelAPI_AttributeSelection>(aFound->second);
208   if (!aRes) {
209     // TODO: generate error on invalid attribute type request
210   }
211   return aRes;
212 }
213
214 boost::shared_ptr<ModelAPI_AttributeSelectionList> 
215   Model_Data::selectionList(const std::string& theID)
216 {
217   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
218     myAttrs.find(theID);
219   if (aFound == myAttrs.end()) {
220     // TODO: generate error on unknown attribute request and/or add mechanism for customization
221     return boost::shared_ptr<ModelAPI_AttributeSelectionList>();
222   }
223   boost::shared_ptr<ModelAPI_AttributeSelectionList> aRes = 
224     boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aFound->second);
225   if (!aRes) {
226     // TODO: generate error on invalid attribute type request
227   }
228   return aRes;
229 }
230
231 boost::shared_ptr<ModelAPI_AttributeRefAttr> Model_Data::refattr(const std::string& theID)
232 {
233   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
234     myAttrs.find(theID);
235   if (aFound == myAttrs.end()) {
236     // TODO: generate error on unknown attribute request and/or add mechanism for customization
237     return boost::shared_ptr<ModelAPI_AttributeRefAttr>();
238   }
239   boost::shared_ptr<ModelAPI_AttributeRefAttr> aRes = boost::dynamic_pointer_cast<
240       ModelAPI_AttributeRefAttr>(aFound->second);
241   if (!aRes) {
242     // TODO: generate error on invalid attribute type request
243   }
244   return aRes;
245 }
246
247 boost::shared_ptr<ModelAPI_AttributeRefList> Model_Data::reflist(const std::string& theID)
248 {
249   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator aFound = 
250     myAttrs.find(theID);
251   if (aFound == myAttrs.end()) {
252     // TODO: generate error on unknown attribute request and/or add mechanism for customization
253     return boost::shared_ptr<ModelAPI_AttributeRefList>();
254   }
255   boost::shared_ptr<ModelAPI_AttributeRefList> aRes = boost::dynamic_pointer_cast<
256       ModelAPI_AttributeRefList>(aFound->second);
257   if (!aRes) {
258     // TODO: generate error on invalid attribute type request
259   }
260   return aRes;
261 }
262
263 boost::shared_ptr<ModelAPI_Attribute> Model_Data::attribute(const std::string& theID)
264 {
265   boost::shared_ptr<ModelAPI_Attribute> aResult;
266   if (myAttrs.find(theID) == myAttrs.end())  // no such attribute
267     return aResult;
268   return myAttrs[theID];
269 }
270
271 const std::string& Model_Data::id(const boost::shared_ptr<ModelAPI_Attribute>& theAttr)
272 {
273   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = 
274     myAttrs.begin();
275   for (; anAttr != myAttrs.end(); anAttr++) {
276     if (anAttr->second == theAttr)
277       return anAttr->first;
278   }
279   // not found
280   static std::string anEmpty;
281   return anEmpty;
282 }
283
284 bool Model_Data::isEqual(const boost::shared_ptr<ModelAPI_Data>& theData)
285 {
286   boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(theData);
287   if (aData)
288     return myLab.IsEqual(aData->myLab) == Standard_True ;
289   return false;
290 }
291
292 bool Model_Data::isValid()
293 {
294   return !myLab.IsNull() && myLab.HasAttribute();
295 }
296
297 std::list<boost::shared_ptr<ModelAPI_Attribute> > Model_Data::attributes(const std::string& theType)
298 {
299   std::list<boost::shared_ptr<ModelAPI_Attribute> > aResult;
300   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
301     myAttrs.begin();
302   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
303     if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
304       aResult.push_back(anAttrsIter->second);
305     }
306   }
307   return aResult;
308 }
309
310 std::list<std::string> Model_Data::attributesIDs(const std::string& theType) 
311 {
312   std::list<std::string> aResult;
313   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
314     myAttrs.begin();
315   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
316     if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
317       aResult.push_back(anAttrsIter->first);
318     }
319   }
320   return aResult;
321 }
322
323 void Model_Data::sendAttributeUpdated(ModelAPI_Attribute* theAttr)
324 {
325   theAttr->setInitialized();
326   if (theAttr->isArgument()) {
327     static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
328     ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
329   }
330 }
331
332 void Model_Data::erase()
333 {
334   if (!myLab.IsNull())
335     myLab.ForgetAllAttributes();
336 }
337
338 /// identifeir of the "must be updated" flag in the data tree
339 Standard_GUID kMustBeUpdatedGUID("baede74c-31a6-4416-9c4d-e48ce65f2005");
340
341 void Model_Data::mustBeUpdated(const bool theFlag)
342 {
343   if (theFlag)
344     TDataStd_UAttribute::Set(myLab, kMustBeUpdatedGUID);
345   else
346     myLab.ForgetAttribute(kMustBeUpdatedGUID);
347 }
348
349 bool Model_Data::mustBeUpdated()
350 {
351   return myLab.IsAttribute(kMustBeUpdatedGUID) == Standard_True;
352 }
353
354 bool Model_Data::referencesTo(const boost::shared_ptr<ModelAPI_Feature>& theFeature)
355 {
356   // collect results of this feature first to check references quickly in the cycle
357   std::set<ObjectPtr> aFeatureObjs;
358   aFeatureObjs.insert(theFeature);
359   std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter =
360     theFeature->results().cbegin();
361   for(; aRIter != theFeature->results().cend(); aRIter++) {
362     if (*aRIter)
363       aFeatureObjs.insert(*aRIter);
364   }
365
366   std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
367     myAttrs.begin();
368   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
369     if (anAttrsIter->second->attributeType() == ModelAPI_AttributeRefAttr::type()) {
370       boost::shared_ptr<ModelAPI_AttributeRefAttr> aRefAttr = 
371         boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttrsIter->second);
372       if (aRefAttr && aRefAttr->isObject()) { // check referenced object
373         if (aFeatureObjs.find(aRefAttr->object()) != aFeatureObjs.end())
374           return true;
375       } else { // check object of referenced attribute
376         boost::shared_ptr<ModelAPI_Attribute> anAttr = aRefAttr->attr();
377         if (anAttr && aFeatureObjs.find(anAttr->owner()) != aFeatureObjs.end())
378           return true;
379       }
380     } else if (anAttrsIter->second->attributeType() == ModelAPI_AttributeReference::type()) {
381       boost::shared_ptr<ModelAPI_AttributeReference> aRef = 
382         boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttrsIter->second);
383       if (aFeatureObjs.find(aRef->value()) != aFeatureObjs.end()) {
384         return true;
385       }
386     }
387   }
388   return false;
389 }