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