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