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