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