Salome HOME
cb4b0ebafea3bfaf8921eeebfbec267c766e50ac
[modules/geom.git] / src / GEOM / GEOM_Function.cxx
1 using namespace std; 
2
3 #include "GEOM_Function.hxx"
4 #include "GEOM_Object.hxx"
5 #include "GEOM_Solver.hxx"
6 #include <TDF.hxx>
7 #include <TDF_Data.hxx>
8 #include <TDF_ChildIterator.hxx>
9 #include <TDF_Reference.hxx>
10 #include <TDataStd_Integer.hxx>
11 #include <TDataStd_IntegerArray.hxx>
12 #include <TDataStd_Real.hxx>
13 #include <TDataStd_RealArray.hxx>
14 #include <TDataStd_Comment.hxx>
15 #include <TDataStd_TreeNode.hxx>
16 #include <TDataStd_UAttribute.hxx>
17 #include <TDataStd_ChildNodeIterator.hxx>
18 #include <TDataStd_ExtStringArray.hxx>
19 #include <TDocStd_Owner.hxx>
20 #include <TDocStd_Document.hxx>
21 #include <TFunction_Function.hxx>
22 #include <TNaming_NamedShape.hxx>
23 #include <TNaming_Builder.hxx>
24
25 #include <TColStd_HArray1OfReal.hxx>
26 #include <TColStd_HArray1OfInteger.hxx>
27 #include <TColStd_HSequenceOfTransient.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <TCollection_ExtendedString.hxx>
30
31 #include "utilities.h"
32
33 #define ARGUMENT_LABEL 1
34 #define RESULT_LABEL 2
35 #define DESCRIPTION_LABEL 3
36 #define ARGUMENTS _label.FindChild((ARGUMENT_LABEL))
37 #define ARGUMENT(thePosition) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePosition))
38 #define SUB_ARGUMENT(thePos1, thePos2) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePos1)).FindChild((thePos2))
39
40 //=======================================================================
41 //function : GetFunctionTreeID
42 //purpose  :
43 //=======================================================================
44 const Standard_GUID& GEOM_Function::GetFunctionTreeID()
45 {
46   static Standard_GUID aFunctionTreeID("FF1BBB00-5D14-4df2-980B-3A668264EA16");
47   return aFunctionTreeID;
48 }   
49
50
51 //=======================================================================
52 //function : GetDependencyID
53 //purpose  :
54 //=======================================================================
55 const Standard_GUID& GEOM_Function::GetDependencyID()
56 {
57   static Standard_GUID aDependencyID("E2620650-2354-41bd-8C2C-210CFCD00948");
58   return aDependencyID;
59 }   
60
61 //=============================================================================
62 /*!
63  *  GetFunction:
64  */
65 //=============================================================================
66 Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry)
67 {
68   if(!theEntry.IsAttribute(TFunction_Function::GetID())) return NULL;
69
70   return new GEOM_Function(theEntry);
71 }
72
73 //=============================================================================
74 /*!
75  *  Constructor:
76  */
77 //=============================================================================
78 GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType)
79 : _label(theEntry)
80 {
81   TFunction_Function::Set(theEntry, theGUID);
82   TDataStd_Integer::Set(theEntry, theType);   
83
84   //Add function to a function tree
85   Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theEntry.Data());
86   Handle(TDataStd_TreeNode) aRoot, aNode;
87   if(!aDoc->Main().FindAttribute(GetFunctionTreeID(), aRoot)) 
88     aRoot = TDataStd_TreeNode::Set(aDoc->Main(), GetFunctionTreeID());
89
90   aNode = TDataStd_TreeNode::Set(theEntry, GetFunctionTreeID());
91   aRoot->Append(aNode);
92 }
93
94 //=============================================================================
95 /*!
96  *  GetOwner
97  */
98 //============================================================================= 
99 TDF_Label GEOM_Function::GetOwnerEntry()
100 {
101   TDF_Label aFather = _label.Father();
102   while(!aFather.IsRoot()) {
103     if(aFather.IsAttribute(GEOM_Object::GetObjectID())) return aFather;
104     aFather = aFather.Father();
105   }
106   
107   return TDF_Label();    
108 }
109
110 //=============================================================================
111 /*!
112  *  GetType
113  */
114 //=============================================================================
115 int GEOM_Function::GetType()
116 {
117   _isDone = false;
118   Handle(TDataStd_Integer) aType;
119   if(!_label.FindAttribute(TDataStd_Integer::GetID(), aType)) return 0;
120   _isDone = true;
121   return aType->Get();          
122 }
123
124 //=============================================================================
125 /*!
126  *  GetValue
127  */
128 //=============================================================================
129 TopoDS_Shape GEOM_Function::GetValue()
130 {
131   _isDone = false;
132   
133   TopoDS_Shape aShape;
134   TDF_Label aLabel = GetOwnerEntry();
135   if(aLabel.IsRoot()) return aShape;
136   Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
137   if(anObject.IsNull()) return aShape;
138   if(!anObject->IsMainShape()) {
139     try {
140       GEOM_Solver aSolver(GEOM_Engine::GetEngine());
141       if (!aSolver.ComputeFunction(this)) {
142         MESSAGE("GEOM_Object::GetValue Error : Can't build a sub shape");        
143         return aShape;
144       }
145     }
146     catch (Standard_Failure) {
147       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
148       MESSAGE("GEOM_Function::GetValue Error: " << aFail->GetMessageString());
149       return aShape;
150     }
151   }
152
153   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);  
154   Handle(TNaming_NamedShape) aNS;
155   if(!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
156
157   aShape = aNS->Get();
158
159   _isDone = true;
160   return aShape;          
161 }
162
163 //=============================================================================
164 /*!
165  *  GetValue
166  */
167 //=============================================================================
168 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
169 {
170   _isDone = false;
171   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
172   TNaming_Builder aBuilder(aResultLabel);
173
174   aBuilder.Generated(theShape);
175   
176   _isDone = true;
177 }
178
179 //=============================================================================
180 /*!
181  *  GetDriverGUID
182  */
183 //=============================================================================
184 Standard_GUID GEOM_Function::GetDriverGUID()
185 {
186   Handle(TFunction_Function) aFunction;
187   if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
188     return TDF::LowestID();
189   }
190
191   return aFunction->GetDriverGUID();
192 }
193
194 //=============================================================================
195 /*!
196  *  GetDescription
197  */
198 //=============================================================================
199 TCollection_AsciiString GEOM_Function::GetDescription()
200 {
201   Handle(TDataStd_Comment) aComment;
202   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
203   if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
204   TCollection_AsciiString aDescr(aComment->Get());
205   return aDescr;
206 }
207
208 //=============================================================================
209 /*!
210  *  SetDescription
211  */
212 //=============================================================================
213 void GEOM_Function::SetDescription(TCollection_AsciiString& theDescription)
214 {
215   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
216   Handle(TDataStd_Comment) aComment = TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
217 }
218
219 //=============================================================================
220 /*!
221  *  SetReal
222  */
223 //=============================================================================
224 void GEOM_Function::SetReal(int thePosition, double theValue)
225 {
226   _isDone = false;
227   if(thePosition <= 0) return;
228   TDF_Label anArgLabel = ARGUMENT(thePosition);
229   TDataStd_Real::Set(anArgLabel, theValue);
230   _isDone = true;
231 }
232
233 //=============================================================================
234 /*!
235  *  SetRealArray
236  */
237 //=============================================================================
238 void GEOM_Function::SetRealArray (int thePosition,
239                                   const Handle(TColStd_HArray1OfReal)& theArray)
240 {
241   _isDone = false;
242   if(thePosition <= 0) return;
243   TDF_Label anArgLabel = ARGUMENT(thePosition);
244   Handle(TDataStd_RealArray) anAttr =
245     TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
246   anAttr->ChangeArray(theArray);
247   _isDone = true;
248 }
249
250 //=============================================================================
251 /*!
252  *  GetReal
253  */
254 //=============================================================================
255 double GEOM_Function::GetReal(int thePosition)
256 {
257   _isDone = false;
258   if(thePosition <= 0) return 0.0;
259   Handle(TDataStd_Real) aReal;
260   TDF_Label anArgLabel = ARGUMENT(thePosition);
261   if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
262
263   _isDone = true;
264   return aReal->Get();
265 }
266
267 //=============================================================================
268 /*!
269  *  GetRealArray
270  */
271 //=============================================================================
272 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
273 {
274   _isDone = false;
275   if(thePosition <= 0) return NULL;
276   Handle(TDataStd_RealArray) aRealArray;
277   TDF_Label anArgLabel = ARGUMENT(thePosition);
278   if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
279
280   _isDone = true;
281   return aRealArray->Array();
282 }
283
284 //=============================================================================
285 /*!
286  *  SetInteger
287  */
288 //=============================================================================
289 void GEOM_Function::SetInteger(int thePosition, int theValue)
290 {
291   _isDone = false;
292   if(thePosition <= 0) return;
293   TDF_Label anArgLabel = ARGUMENT(thePosition);
294   TDataStd_Integer::Set(anArgLabel, theValue);
295   _isDone = true;
296 }
297
298 //=============================================================================
299 /*!
300  *  SetIntegerArray
301  */
302 //=============================================================================
303 void GEOM_Function::SetIntegerArray (int thePosition,
304                                      const Handle(TColStd_HArray1OfInteger)& theArray)
305 {
306   _isDone = false;
307   if(thePosition <= 0) return;
308   TDF_Label anArgLabel = ARGUMENT(thePosition);
309   Handle(TDataStd_IntegerArray) anAttr =
310     TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
311   anAttr->ChangeArray(theArray);
312   _isDone = true;
313 }
314
315 //=============================================================================
316 /*!
317  *  GetInteger
318  */
319 //=============================================================================
320 int GEOM_Function::GetInteger(int thePosition)
321 {
322   _isDone = false;
323   if(thePosition <= 0) return 0;
324   Handle(TDataStd_Integer) anInteger;
325   TDF_Label anArgLabel = ARGUMENT(thePosition);
326   if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
327
328   _isDone = true;
329   return anInteger->Get();
330 }
331
332 //=============================================================================
333 /*!
334  *  GetIntegerArray
335  */
336 //=============================================================================
337 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
338 {
339   _isDone = false;
340   if(thePosition <= 0) return 0;
341   Handle(TDataStd_IntegerArray) anIntegerArray;
342   TDF_Label anArgLabel = ARGUMENT(thePosition);
343   if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
344
345   _isDone = true;
346   return anIntegerArray->Array();
347 }
348
349 //=============================================================================
350 /*!
351  *  SetString
352  */
353 //=============================================================================
354 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
355 {
356   _isDone = false;
357   if(thePosition <= 0) return;
358   TDF_Label anArgLabel = ARGUMENT(thePosition);
359   TDataStd_Comment::Set(anArgLabel, theValue);
360   _isDone = true;
361 }
362
363 //=============================================================================
364 /*!
365  *  GetString
366  */
367 //=============================================================================
368 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
369 {
370   _isDone = false;
371   TCollection_AsciiString aRes;
372   if(thePosition <= 0) return aRes;
373   Handle(TDataStd_Comment) aString;
374   TDF_Label anArgLabel = ARGUMENT(thePosition);
375   if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
376
377   _isDone = true;
378   aRes = TCollection_AsciiString(aString->Get());
379   return aRes;
380 }
381
382 //=============================================================================
383 /*!
384  *  SetReference
385  */
386 //=============================================================================
387 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
388 {
389   _isDone = false;
390   if(thePosition <= 0) return;
391   if(theReference.IsNull()) return;
392   TDF_Label anArgLabel = ARGUMENT(thePosition);
393   TDF_Reference::Set(anArgLabel, theReference->GetEntry());
394   TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
395   _isDone = true;
396   return;
397 }
398
399 //=============================================================================
400 /*!
401  *  GetReference
402  */
403 //=============================================================================
404 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition) 
405 {
406   _isDone = false;
407   if(thePosition <= 0) return NULL;
408   TDF_Label anArgLabel = ARGUMENT(thePosition);
409   Handle(TDF_Reference) aRef;
410   if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
411
412   _isDone = true;
413   return GetFunction(aRef->Get());
414 }
415
416
417 //=============================================================================
418 /*!
419  *  SetStringArray
420  */
421 //=============================================================================
422 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
423 {
424   _isDone = false;
425   if(thePosition <= 0 || theArray.IsNull()) return; 
426   TDF_Label anArgLabel = ARGUMENT(thePosition);
427
428   Handle(TDataStd_ExtStringArray) anArray = new TDataStd_ExtStringArray;
429   anArray->ChangeArray(theArray);
430   anArgLabel.AddAttribute(anArray);
431   
432   _isDone = true;
433 }
434
435
436 //=============================================================================
437 /*!
438  *  GetStringArray
439  */
440 //=============================================================================  
441 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
442 {
443   _isDone = false;
444   if(thePosition <= 0) return NULL;
445   TDF_Label anArgLabel = ARGUMENT(thePosition);
446   Handle(TDataStd_ExtStringArray) anArray;
447   if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
448
449   _isDone = true;
450   return anArray->Array();
451 }
452
453 //=======================================================================
454 //function : GetReferencesTreeID
455 //purpose  :
456 //=======================================================================
457 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
458 {
459   static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
460   return aReferencesTreeID;
461 }   
462
463 //=============================================================================
464 /*!
465  *  SetReferenceList
466  */
467 //=============================================================================
468 void GEOM_Function::SetReferenceList (int thePosition,
469                                       const Handle(TColStd_HSequenceOfTransient)& theRefList)
470 {
471   _isDone = false;
472   if(thePosition <= 0) return;
473
474   // parent label for the list of references
475   TDF_Label anArgLabel = ARGUMENT(thePosition);
476   anArgLabel.ForgetAllAttributes();
477
478   // set TreeNode on the parent label
479   Handle(TDataStd_TreeNode) aRoot, aNode;
480   aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
481
482   // store references on sub-labels of the parent label
483   Handle(GEOM_Function) aFunc;
484   Standard_Integer ind, len = theRefList->Length();
485   for (ind = 1; ind <= len; ind++) {
486     aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
487     if (aFunc.IsNull()) continue;
488     TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
489     TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
490     TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
491
492     // set TreeNode on the child label
493     aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
494     aRoot->Append(aNode);
495   }
496
497   _isDone = true;
498   return;
499 }
500
501 //=============================================================================
502 /*!
503  *  GetReferenceList
504  */
505 //=============================================================================
506 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition) 
507 {
508   Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
509   _isDone = false;
510   if(thePosition <= 0) return aResult;
511
512   // parent label for the list of references
513   TDF_Label anArgLabel = ARGUMENT(thePosition);
514   Handle(TDF_Reference) aRef;
515
516   // get TreeNode on the parent label
517   Handle(TDataStd_TreeNode) aRoot, aNode;
518   if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
519     return aResult;
520
521   // get references, stored on sub-labels of the parent label
522   TDF_Label aLabel_i;
523   TDataStd_ChildNodeIterator anIter (aRoot);
524   for (; anIter.More(); anIter.Next()) {
525     aNode = anIter.Value();
526     aLabel_i = aNode->Label();
527     if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
528     Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
529     if (aFunc_i.IsNull()) continue;
530     aResult->Append(aFunc_i);
531   }
532
533   _isDone = true;
534   return aResult;
535 }
536
537 //=============================================================================
538 /*!
539  *  SetShape
540  */
541 //=============================================================================
542 void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
543 {
544   _isDone = false;
545   if(thePosition <= 0 || theShape.IsNull()) return;
546
547   TDF_Label anArgLabel = ARGUMENT(thePosition);
548   TNaming_Builder aBuilder(anArgLabel);
549   aBuilder.Generated(theShape);
550
551   _isDone = true;
552   return;
553 }
554
555 //=============================================================================
556 /*!
557  *  GetShape
558  */
559 //=============================================================================  
560 TopoDS_Shape GEOM_Function::GetShape(int thePosition)
561 {
562   _isDone = false;
563   TopoDS_Shape aShape;
564   if(thePosition <= 0) return aShape;
565
566   TDF_Label anArgLabel = ARGUMENT(thePosition);
567   Handle(TNaming_NamedShape) aNS;
568   if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
569
570   aShape = aNS->Get();
571   _isDone = true;
572   return aShape;
573 }
574
575
576 //=============================================================================
577 /*!
578  *  GetDependency
579  */
580 //=============================================================================  
581 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
582 {
583   TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
584   for(; anIterator.More(); anIterator.Next()) {
585     if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
586   }
587 }
588
589 //=======================================================================
590 //function :  GEOM_Function_Type_
591 //purpose  :
592 //======================================================================= 
593 Standard_EXPORT Handle_Standard_Type& GEOM_Function_Type_()
594 {
595
596   static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
597   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared); 
598   static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
599   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
600  
601
602   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
603   static Handle_Standard_Type _aType = new Standard_Type("GEOM_Function",
604                                                          sizeof(GEOM_Function),
605                                                          1,
606                                                          (Standard_Address)_Ancestors,
607                                                          (Standard_Address)NULL);
608
609   return _aType;
610 }
611
612 //=======================================================================
613 //function : DownCast
614 //purpose  :
615 //======================================================================= 
616
617 const Handle(GEOM_Function) Handle(GEOM_Function)::DownCast(const Handle(Standard_Transient)& AnObject)
618 {
619   Handle(GEOM_Function) _anOtherObject;
620
621   if (!AnObject.IsNull()) {
622      if (AnObject->IsKind(STANDARD_TYPE(GEOM_Function))) {
623        _anOtherObject = Handle(GEOM_Function)((Handle(GEOM_Function)&)AnObject);
624      }
625   }
626
627   return _anOtherObject ;
628 }
629
630
631
632