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