Salome HOME
Resolve batch runtime errors on debian squeeze
[modules/shaper.git] / src / Model / Model_Data.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        Model_Data.hxx
4 // Created:     21 Mar 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include <Model_Data.h>
8 #include <Model_AttributeDocRef.h>
9 #include <Model_AttributeInteger.h>
10 #include <Model_AttributeDouble.h>
11 #include <Model_AttributeReference.h>
12 #include <Model_AttributeRefAttr.h>
13 #include <Model_AttributeRefList.h>
14 #include <Model_AttributeBoolean.h>
15 #include <Model_AttributeString.h>
16 #include <Model_AttributeSelection.h>
17 #include <Model_AttributeSelectionList.h>
18 #include <Model_Events.h>
19 #include <ModelAPI_Feature.h>
20 #include <ModelAPI_Result.h>
21 #include <ModelAPI_Validator.h>
22 #include <ModelAPI_Session.h>
23
24 #include <GeomData_Point.h>
25 #include <GeomData_Point2D.h>
26 #include <GeomData_Dir.h>
27 #include <Events_Loop.h>
28 #include <Events_Error.h>
29
30 #include <TDataStd_Name.hxx>
31
32 #include <string>
33
34 // myLab contains:
35 // TDataStd_Name - name of the object
36 // TDataStd_Integer - state of the object execution
37
38 Model_Data::Model_Data() : mySendAttributeUpdated(true)
39 {
40 }
41
42 void Model_Data::setLabel(TDF_Label theLab)
43 {
44   myLab = theLab;
45 }
46
47 std::string Model_Data::name()
48 {
49   Handle(TDataStd_Name) aName;
50   if (myLab.FindAttribute(TDataStd_Name::GetID(), aName))
51     return std::string(TCollection_AsciiString(aName->Get()).ToCString());
52   return "";  // not defined
53 }
54
55 void Model_Data::setName(const std::string& theName)
56 {
57   bool isModified = false;
58   Handle(TDataStd_Name) aName;
59   if (!myLab.FindAttribute(TDataStd_Name::GetID(), aName)) {
60     TDataStd_Name::Set(myLab, theName.c_str());
61     isModified = true;
62   } else {
63     isModified = !aName->Get().IsEqual(theName.c_str());
64     if (isModified)
65       aName->Set(theName.c_str());
66   }
67 }
68
69 void Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
70 {
71   TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
72   ModelAPI_Attribute* anAttr = 0;
73   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
74     anAttr = new Model_AttributeDocRef(anAttrLab);
75   } else if (theAttrType == Model_AttributeInteger::typeId()) {
76     anAttr = new Model_AttributeInteger(anAttrLab);
77   } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) {
78     anAttr = new Model_AttributeDouble(anAttrLab);
79   } else if (theAttrType == Model_AttributeBoolean::typeId()) {
80     anAttr = new Model_AttributeBoolean(anAttrLab);
81   } else if (theAttrType == Model_AttributeString::typeId()) {
82     anAttr = new Model_AttributeString(anAttrLab);
83   } else if (theAttrType == ModelAPI_AttributeReference::typeId()) {
84     anAttr = new Model_AttributeReference(anAttrLab);
85   } else if (theAttrType == ModelAPI_AttributeSelection::typeId()) {
86     anAttr = new Model_AttributeSelection(anAttrLab);
87   } else if (theAttrType == ModelAPI_AttributeSelectionList::typeId()) {
88     anAttr = new Model_AttributeSelectionList(anAttrLab);
89   } else if (theAttrType == ModelAPI_AttributeRefAttr::typeId()) {
90     anAttr = new Model_AttributeRefAttr(anAttrLab);
91   } else if (theAttrType == ModelAPI_AttributeRefList::typeId()) {
92     anAttr = new Model_AttributeRefList(anAttrLab);
93   } 
94   // create also GeomData attributes here because only here the OCAF strucure is known
95   else if (theAttrType == GeomData_Point::typeId()) {
96     anAttr = new GeomData_Point(anAttrLab);
97   } else if (theAttrType == GeomData_Dir::typeId()) {
98     anAttr = new GeomData_Dir(anAttrLab);
99   } else if (theAttrType == GeomData_Point2D::typeId()) {
100     anAttr = new GeomData_Point2D(anAttrLab);
101   }
102   if (anAttr) {
103     myAttrs[theID] = std::shared_ptr<ModelAPI_Attribute>(anAttr);
104     anAttr->setObject(myObject);
105     anAttr->setID(theID);
106   } else {
107     Events_Error::send("Can not create unknown type of attribute " + theAttrType);
108   }
109 }
110
111 // macro for gthe generic returning of the attribute by the ID
112 #define GET_ATTRIBUTE_BY_ID(ATTR_TYPE, METHOD_NAME) \
113   std::shared_ptr<ATTR_TYPE> Model_Data::METHOD_NAME(const std::string& theID) { \
114     std::shared_ptr<ATTR_TYPE> aRes; \
115     std::map<std::string, AttributePtr >::iterator aFound = \
116       myAttrs.find(theID); \
117     if (aFound != myAttrs.end()) { \
118       aRes = std::dynamic_pointer_cast<ATTR_TYPE>(aFound->second); \
119     } \
120     return aRes; \
121   }
122 // implement nice getting methods for all ModelAPI attributes
123 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeDocRef, document);
124 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeDouble, real);
125 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeInteger, integer);
126 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeBoolean, boolean);
127 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeString, string);
128 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeReference, reference);
129 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeSelection, selection);
130 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeSelectionList, selectionList);
131 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeRefAttr, refattr);
132 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeRefList, reflist);
133
134 std::shared_ptr<ModelAPI_Attribute> Model_Data::attribute(const std::string& theID)
135 {
136   std::shared_ptr<ModelAPI_Attribute> aResult;
137   if (myAttrs.find(theID) == myAttrs.end())  // no such attribute
138     return aResult;
139   return myAttrs[theID];
140 }
141
142 const std::string& Model_Data::id(const std::shared_ptr<ModelAPI_Attribute>& theAttr)
143 {
144   std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = 
145     myAttrs.begin();
146   for (; anAttr != myAttrs.end(); anAttr++) {
147     if (anAttr->second == theAttr)
148       return anAttr->first;
149   }
150   // not found
151   static std::string anEmpty;
152   return anEmpty;
153 }
154
155 bool Model_Data::isEqual(const std::shared_ptr<ModelAPI_Data>& theData)
156 {
157   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theData);
158   if (aData)
159     return myLab.IsEqual(aData->myLab) == Standard_True ;
160   return false;
161 }
162
163 bool Model_Data::isValid()
164 {
165   return !myLab.IsNull() && myLab.HasAttribute();
166 }
167
168 std::list<std::shared_ptr<ModelAPI_Attribute> > Model_Data::attributes(const std::string& theType)
169 {
170   std::list<std::shared_ptr<ModelAPI_Attribute> > aResult;
171   std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
172     myAttrs.begin();
173   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
174     if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
175       aResult.push_back(anAttrsIter->second);
176     }
177   }
178   return aResult;
179 }
180
181 std::list<std::string> Model_Data::attributesIDs(const std::string& theType) 
182 {
183   std::list<std::string> aResult;
184   std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
185     myAttrs.begin();
186   for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
187     if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
188       aResult.push_back(anAttrsIter->first);
189     }
190   }
191   return aResult;
192 }
193
194 void Model_Data::sendAttributeUpdated(ModelAPI_Attribute* theAttr)
195 {
196   theAttr->setInitialized();
197   if (theAttr->isArgument()) {
198     static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
199     ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
200     if (mySendAttributeUpdated && myObject) {
201       myObject->attributeChanged(theAttr->id());
202     }
203   }
204 }
205
206 void Model_Data::blockSendAttributeUpdated(const bool theBlock)
207 {
208   mySendAttributeUpdated = !theBlock;
209 }
210
211 void Model_Data::erase()
212 {
213   if (!myLab.IsNull())
214     myLab.ForgetAllAttributes();
215 }
216
217 void Model_Data::execState(const ModelAPI_ExecState theState)
218 {
219   if (theState != ModelAPI_StateNothing)
220     TDataStd_Integer::Set(myLab, (int)theState);
221 }
222
223 ModelAPI_ExecState Model_Data::execState()
224 {
225   Handle(TDataStd_Integer) aStateAttr;
226   if (myLab.FindAttribute(TDataStd_Integer::GetID(), aStateAttr)) {
227     return ModelAPI_ExecState(aStateAttr->Get());
228   }
229   return ModelAPI_StateMustBeUpdated; // default value
230 }
231
232 void Model_Data::setError(const std::string& theError)
233 {
234   execState(ModelAPI_StateExecFailed);
235   Events_Error::send(theError);
236 }
237
238 int Model_Data::featureId() const
239 {
240   return myLab.Father().Tag(); // tag of the feature label
241 }
242
243 void Model_Data::eraseBackReferences()
244 {
245   myRefsToMe.clear();
246   std::shared_ptr<ModelAPI_Result> aRes = 
247     std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
248   if (aRes)
249     aRes->setIsConcealed(false);
250 }
251
252 void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID)
253 {
254   myRefsToMe.insert(theFeature->data()->attribute(theAttrID));
255   if (ModelAPI_Session::get()->validators()->isConcealed(theFeature->getKind(), theAttrID)) {
256     std::shared_ptr<ModelAPI_Result> aRes = 
257       std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
258     if (aRes) {
259       aRes->setIsConcealed(true);
260     }
261   }
262 }
263
264 void Model_Data::referencesToObjects(
265   std::list<std::pair<std::string, std::list<ObjectPtr> > >& theRefs)
266 {
267   std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = myAttrs.begin();
268   std::list<ObjectPtr> aReferenced; // not inside of cycle to avoid excess memory menagement
269   for(; anAttr != myAttrs.end(); anAttr++) {
270     std::string aType = anAttr->second->attributeType();
271     if (aType == ModelAPI_AttributeReference::typeId()) { // reference to object
272       std::shared_ptr<ModelAPI_AttributeReference> aRef = std::dynamic_pointer_cast<
273           ModelAPI_AttributeReference>(anAttr->second);
274       aReferenced.push_back(aRef->value());
275     } else if (aType == ModelAPI_AttributeRefAttr::typeId()) { // reference to attribute or object
276       std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
277           ModelAPI_AttributeRefAttr>(anAttr->second);
278       aReferenced.push_back(aRef->isObject() ? aRef->object() : aRef->attr()->owner());
279     } else if (aType == ModelAPI_AttributeRefList::typeId()) { // list of references
280       aReferenced = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr->second)->list();
281     } else if (aType == ModelAPI_AttributeSelection::typeId()) { // selection attribute
282       std::shared_ptr<ModelAPI_AttributeSelection> aRef = std::dynamic_pointer_cast<
283           ModelAPI_AttributeSelection>(anAttr->second);
284       aReferenced.push_back(aRef->context());
285     } else if (aType == ModelAPI_AttributeSelectionList::typeId()) { // list of selection attributes
286       std::shared_ptr<ModelAPI_AttributeSelectionList> aRef = std::dynamic_pointer_cast<
287           ModelAPI_AttributeSelectionList>(anAttr->second);
288       for(int a = aRef->size() - 1; a >= 0; a--) {
289         aReferenced.push_back(aRef->value(a)->context());
290       }
291     } else
292       continue; // nothing to do, not reference
293
294     if (!aReferenced.empty()) {
295       theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
296       aReferenced.clear();
297     }
298   }
299 }