Salome HOME
0023450: Fields are not displayed in GEOM
[modules/geom.git] / src / GEOM / GEOM_Function.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <Standard_Stream.hxx>
24
25 #include <GEOM_Function.hxx>
26 #include <GEOM_Object.hxx>
27 #include <GEOM_Solver.hxx>
28 #include <GEOM_ISubShape.hxx>
29
30 #include "utilities.h"
31
32 #include <TDF.hxx>
33 #include <TDF_Tool.hxx>
34 #include <TDF_Data.hxx>
35 #include <TDF_ChildIterator.hxx>
36 #include <TDF_Reference.hxx>
37 #include <TDataStd_BooleanArray.hxx>
38 #include <TDataStd_ByteArray.hxx>
39 #include <TDataStd_Integer.hxx>
40 #include <TDataStd_IntegerArray.hxx>
41 #include <TDataStd_Real.hxx>
42 #include <TDataStd_RealArray.hxx>
43 #include <TDataStd_Comment.hxx>
44 #include <TDataStd_TreeNode.hxx>
45 #include <TDataStd_UAttribute.hxx>
46 #include <TDataStd_ChildNodeIterator.hxx>
47 #include <TDataStd_ExtStringArray.hxx>
48 #include <TDataStd_ExtStringList.hxx>
49 #include <TDocStd_Owner.hxx>
50 #include <TDocStd_Document.hxx>
51 #include <TFunction_Function.hxx>
52 #include <TNaming_NamedShape.hxx>
53 #include <TNaming_Builder.hxx>
54
55 #include <TColStd_ListOfInteger.hxx>
56 #include <TColStd_ListIteratorOfListOfInteger.hxx>
57 #include <TCollection_ExtendedString.hxx>
58
59 #include <cstdlib>
60
61 #include <Standard_Failure.hxx>
62 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
63
64 // This modification was introduced in frame of Mantis issue 0021251.
65 // This line allows to keep shape orientation together with the shape itself.
66 // Otherwise orientation can be lost in some cases.
67 #define KEEP_ORIENTATION_0021251
68
69 #define ARGUMENT_LABEL 1
70 #define RESULT_LABEL 2
71 #define DESCRIPTION_LABEL 3
72 #define HISTORY_LABEL 4
73 #define SUBSHAPES_LABEL 5 // 0020756: GetGroups
74 #define NAMING_LABEL 6 // 0020750: Naming during STEP import
75 #define CALLBACK_LABEL 1 // TDataStd_Comment
76
77 #ifdef KEEP_ORIENTATION_0021251
78 #define ORIENTATION_LABEL 7 // 0021251: TNaming_NamedShape doesn't store orientation
79 #endif
80
81 #define ARGUMENTS _label.FindChild((ARGUMENT_LABEL))
82 #define ARGUMENT(thePosition) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePosition))
83 #define SUB_ARGUMENT(thePos1, thePos2) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePos1)).FindChild((thePos2))
84
85 //=======================================================================
86 //function : GetFunctionTreeID
87 //purpose  :
88 //=======================================================================
89 const Standard_GUID& GEOM_Function::GetFunctionTreeID()
90 {
91   static Standard_GUID aFunctionTreeID("FF1BBB00-5D14-4df2-980B-3A668264EA16");
92   return aFunctionTreeID;
93 }
94
95
96 //=======================================================================
97 //function : GetDependencyID
98 //purpose  :
99 //=======================================================================
100 const Standard_GUID& GEOM_Function::GetDependencyID()
101 {
102   static Standard_GUID aDependencyID("E2620650-2354-41bd-8C2C-210CFCD00948");
103   return aDependencyID;
104 }
105
106 //=============================================================================
107 /*!
108  *  GetFunction:
109  */
110 //=============================================================================
111 Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry)
112 {
113   if(!theEntry.IsAttribute(TFunction_Function::GetID())) return NULL;
114
115   return new GEOM_Function(theEntry);
116 }
117
118 //=============================================================================
119 /*!
120  *  Constructor:
121  */
122 //=============================================================================
123 GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType)
124   : _label(theEntry), _isCallBackData(false)
125 {
126   TFunction_Function::Set(theEntry, theGUID);
127   TDataStd_Integer::Set(theEntry, theType);
128
129   //Add function to a function tree
130   Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theEntry.Data());
131   Handle(TDataStd_TreeNode) aRoot, aNode;
132   if(!aDoc->Main().FindAttribute(GetFunctionTreeID(), aRoot))
133     aRoot = TDataStd_TreeNode::Set(aDoc->Main(), GetFunctionTreeID());
134
135   aNode = TDataStd_TreeNode::Set(theEntry, GetFunctionTreeID());
136   aRoot->Append(aNode);
137 }
138
139 //================================================================================
140 /*!
141  * \brief 
142  * 
143  * 
144  */
145 //================================================================================
146
147 GEOM_Function::~GEOM_Function()
148 {
149   if ( _isCallBackData ) {
150     _label.FindChild( CALLBACK_LABEL ).ForgetAttribute( TDataStd_Comment::GetID() );
151   }
152 }
153
154 //================================================================================
155 /*!
156  * \brief Retuns true if this function is the last one in the study
157  */
158 //================================================================================
159
160 bool GEOM_Function::IsLastFuntion()
161 {
162   bool isLast = false;
163
164   Handle(TDataStd_TreeNode) aNode;
165   if (_label.FindAttribute(GetFunctionTreeID(), aNode))
166     isLast = !aNode->HasNext();
167
168   return isLast;
169 }
170
171 //=============================================================================
172 /*!
173  *  GetOwner
174  */
175 //=============================================================================
176 TDF_Label GEOM_Function::GetOwnerEntry()
177 {
178   TDF_Label aFather = _label.Father();
179   while(!aFather.IsRoot()) {
180     if(aFather.IsAttribute(GEOM_Object::GetObjectID())) return aFather;
181     aFather = aFather.Father();
182   }
183
184   return TDF_Label();
185 }
186
187 //=============================================================================
188 /*!
189  *  GetType
190  */
191 //=============================================================================
192 int GEOM_Function::GetType()
193 {
194   _isDone = false;
195   Handle(TDataStd_Integer) aType;
196   if(!_label.FindAttribute(TDataStd_Integer::GetID(), aType)) return 0;
197   _isDone = true;
198   return aType->Get();
199 }
200
201 //=============================================================================
202 /*!
203  *  GetValue
204  */
205 //=============================================================================
206 TopoDS_Shape GEOM_Function::GetValue()
207 {
208   _isDone = false;
209
210   TopoDS_Shape aShape;
211   TDF_Label aLabel = GetOwnerEntry();
212   if (aLabel.IsRoot()) return aShape;
213   Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
214   if (anObject.IsNull()) return aShape;
215
216   if (!anObject->IsMainShape()) {
217     bool isResult = false;
218     TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
219     if (!aResultLabel.IsNull()) {
220       Handle(TNaming_NamedShape) aNS;
221       if (aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS))
222         isResult = true;
223     }
224
225     // compare tics
226     if (isResult) {
227       // tic of this
228       Standard_Integer aTic = anObject->GetTic();
229
230       // tic of main shape
231       GEOM_ISubShape aCI (this);
232       TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
233       if (aLabelObjMainSh.IsRoot()) return aShape;
234       Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
235       if (anObjMainSh.IsNull()) return aShape;
236       Standard_Integer aTicMainSh = anObjMainSh->GetTic();
237
238       // compare
239       isResult = ((aTic == aTicMainSh) ? true : false);
240     }
241
242     if (!isResult) {
243       try {
244         OCC_CATCH_SIGNALS;
245         GEOM_Solver aSolver(GEOM_Engine::GetEngine());
246         if (!aSolver.ComputeFunction(this)) {
247           MESSAGE("GEOM_Object::GetValue Error : Can't build a sub-shape");
248           return aShape;
249         }
250       }
251       catch (Standard_Failure) {
252         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
253         MESSAGE("GEOM_Function::GetValue Error: " << aFail->GetMessageString());
254         return aShape;
255       }
256     }
257   }
258
259   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
260   Handle(TNaming_NamedShape) aNS;
261   if (!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
262
263   aShape = aNS->Get();
264
265 #ifdef KEEP_ORIENTATION_0021251
266   // 0021251: TNaming_NamedShape doesn't store orientation
267   TDF_Label anOrientationLabel = _label.FindChild(ORIENTATION_LABEL);
268   Handle(TDataStd_Integer) anInteger;
269   if (anOrientationLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) {
270     aShape.Orientation((TopAbs_Orientation)anInteger->Get());
271   }
272 #endif
273
274   _isDone = true;
275   return aShape;
276 }
277
278 //=============================================================================
279 /*!
280  *  SetValue
281  */
282 //=============================================================================
283 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
284 {
285   _isDone = false;
286   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
287   TNaming_Builder aBuilder (aResultLabel);
288
289   aBuilder.Generated(theShape);
290
291 #ifdef KEEP_ORIENTATION_0021251
292   // 0021251: TNaming_NamedShape doesn't store orientation
293   TDF_Label anOrientationLabel = _label.FindChild(ORIENTATION_LABEL);
294   TDataStd_Integer::Set(anOrientationLabel, (int)theShape.Orientation());
295 #endif
296
297   // synchronisation between main shape and its sub-shapes
298   TDF_Label aLabel = GetOwnerEntry();
299   if (aLabel.IsRoot()) return;
300   Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
301   if (anObject.IsNull()) return;
302   if (anObject->IsMainShape()) {
303     // increase modifications counter of this (main) shape
304     anObject->IncrementTic();
305   }
306   else {
307     // update modifications counter of this (sub-) shape to be the same as on main shape
308     GEOM_ISubShape aCI (this);
309     TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
310     if (aLabelObjMainSh.IsRoot()) return;
311     Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
312     if (anObjMainSh.IsNull()) return;
313
314     anObject->SetTic(anObjMainSh->GetTic());
315   }
316
317   _isDone = true;
318 }
319
320 //=============================================================================
321 /*!
322  *  GetDriverGUID
323  */
324 //=============================================================================
325 Standard_GUID GEOM_Function::GetDriverGUID()
326 {
327   Handle(TFunction_Function) aFunction;
328   if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
329     return TDF::LowestID();
330   }
331
332   return aFunction->GetDriverGUID();
333 }
334
335 //=============================================================================
336 /*!
337  *  GetDescription
338  */
339 //=============================================================================
340 TCollection_AsciiString GEOM_Function::GetDescription()
341 {
342   Handle(TDataStd_Comment) aComment;
343   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
344   if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
345   TCollection_AsciiString aDescr(aComment->Get());
346   return aDescr;
347 }
348
349 //=============================================================================
350 /*!
351  *  SetDescription
352  */
353 //=============================================================================
354 void GEOM_Function::SetDescription(const TCollection_AsciiString& theDescription)
355 {
356   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
357   Handle(TDataStd_Comment) aComment =
358     TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
359 }
360
361 //=============================================================================
362 /*!
363  *  SetReal
364  */
365 //=============================================================================
366 void GEOM_Function::SetReal(int thePosition, double theValue)
367 {
368   _isDone = false;
369   if(thePosition <= 0) return;
370   TDF_Label anArgLabel = ARGUMENT(thePosition);
371   TDataStd_Real::Set(anArgLabel, theValue);
372   _isDone = true;
373 }
374
375 //=============================================================================
376 /*!
377  *  SetRealArray
378  */
379 //=============================================================================
380 void GEOM_Function::SetRealArray (int thePosition,
381                                   const Handle(TColStd_HArray1OfReal)& theArray)
382 {
383   _isDone = false;
384   if(thePosition <= 0) return;
385   TDF_Label anArgLabel = ARGUMENT(thePosition);
386   Handle(TDataStd_RealArray) anAttr =
387     TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
388   anAttr->ChangeArray(theArray);
389   _isDone = true;
390 }
391
392 //=============================================================================
393 /*!
394  *  GetReal
395  */
396 //=============================================================================
397 double GEOM_Function::GetReal(int thePosition)
398 {
399   _isDone = false;
400   if(thePosition <= 0) return 0.0;
401   Handle(TDataStd_Real) aReal;
402   TDF_Label anArgLabel = ARGUMENT(thePosition);
403   if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
404
405   _isDone = true;
406   return aReal->Get();
407 }
408
409 //=============================================================================
410 /*!
411  *  GetRealArray
412  */
413 //=============================================================================
414 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
415 {
416   _isDone = false;
417   if(thePosition <= 0) return NULL;
418   Handle(TDataStd_RealArray) aRealArray;
419   TDF_Label anArgLabel = ARGUMENT(thePosition);
420   if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
421
422   _isDone = true;
423   return aRealArray->Array();
424 }
425
426 //=============================================================================
427 /*!
428  *  SetInteger
429  */
430 //=============================================================================
431 void GEOM_Function::SetInteger(int thePosition, int theValue)
432 {
433   _isDone = false;
434   if(thePosition <= 0) return;
435   TDF_Label anArgLabel = ARGUMENT(thePosition);
436   TDataStd_Integer::Set(anArgLabel, theValue);
437   _isDone = true;
438 }
439
440 //=============================================================================
441 /*!
442  *  SetIntegerArray
443  */
444 //=============================================================================
445 void GEOM_Function::SetIntegerArray (int thePosition,
446                                      const Handle(TColStd_HArray1OfInteger)& theArray)
447 {
448   _isDone = false;
449   if(thePosition <= 0) return;
450   TDF_Label anArgLabel = ARGUMENT(thePosition);
451   Handle(TDataStd_IntegerArray) anAttr =
452     TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
453   anAttr->ChangeArray(theArray);
454   _isDone = true;
455 }
456
457 //=============================================================================
458 /*!
459  *  GetInteger
460  */
461 //=============================================================================
462 int GEOM_Function::GetInteger(int thePosition)
463 {
464   _isDone = false;
465   if(thePosition <= 0) return 0;
466   Handle(TDataStd_Integer) anInteger;
467   TDF_Label anArgLabel = ARGUMENT(thePosition);
468   if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
469
470   _isDone = true;
471   return anInteger->Get();
472 }
473
474 //=============================================================================
475 /*!
476  *  GetIntegerArray
477  */
478 //=============================================================================
479 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
480 {
481   _isDone = false;
482   if(thePosition <= 0) return 0;
483   Handle(TDataStd_IntegerArray) anIntegerArray;
484   TDF_Label anArgLabel = ARGUMENT(thePosition);
485   if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
486
487   _isDone = true;
488   return anIntegerArray->Array();
489 }
490
491 //=============================================================================
492 /*!
493  *  SetByteArray
494  */
495 //=============================================================================
496 void GEOM_Function::SetByteArray (int thePosition,
497                                   const Handle(TColStd_HArray1OfByte)& theArray)
498 {
499   _isDone = false;
500   if(thePosition <= 0) return;
501   TDF_Label anArgLabel = ARGUMENT(thePosition);
502   Handle(TDataStd_ByteArray) anAttr =
503     TDataStd_ByteArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
504   anAttr->ChangeArray(theArray);
505   _isDone = true;
506 }
507
508 //=============================================================================
509 /*!
510  *  GetByteArray
511  */
512 //=============================================================================
513 Handle(TColStd_HArray1OfByte) GEOM_Function::GetByteArray(int thePosition)
514 {
515   _isDone = false;
516   if(thePosition <= 0) return 0;
517   Handle(TDataStd_ByteArray) aByteArray;
518   TDF_Label anArgLabel = ARGUMENT(thePosition);
519   if(!anArgLabel.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray)) return 0;
520
521   _isDone = true;
522   return aByteArray->InternalArray();
523 }
524
525 //=============================================================================
526 /*!
527  *  SetBooleanArray
528  */
529 //=============================================================================
530 void GEOM_Function::SetBooleanArray (int thePosition,
531                                      const Handle(TColStd_HArray1OfByte)& theArray)
532 {
533   _isDone = false;
534   if(thePosition <= 0) return;
535   TDF_Label anArgLabel = ARGUMENT(thePosition);
536   Handle(TDataStd_BooleanArray) anAttr =
537     TDataStd_BooleanArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
538   anAttr->SetInternalArray(theArray);
539   _isDone = true;
540 }
541
542 //=============================================================================
543 /*!
544  *  GetBooleanArray
545  */
546 //=============================================================================
547 Handle(TColStd_HArray1OfByte) GEOM_Function::GetBooleanArray(int thePosition)
548 {
549   _isDone = false;
550   if(thePosition <= 0) return 0;
551   Handle(TDataStd_BooleanArray) aBooleanArray;
552   TDF_Label anArgLabel = ARGUMENT(thePosition);
553   if(!anArgLabel.FindAttribute(TDataStd_BooleanArray::GetID(), aBooleanArray)) return 0;
554
555   _isDone = true;
556   return aBooleanArray->InternalArray();
557 }
558
559 //=============================================================================
560 /*!
561  *  SetString
562  */
563 //=============================================================================
564 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
565 {
566   _isDone = false;
567   if(thePosition <= 0) return;
568   TDF_Label anArgLabel = ARGUMENT(thePosition);
569   TDataStd_Comment::Set(anArgLabel, theValue);
570   _isDone = true;
571 }
572
573 //=============================================================================
574 /*!
575  *  GetString
576  */
577 //=============================================================================
578 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
579 {
580   _isDone = false;
581   TCollection_AsciiString aRes;
582   if(thePosition <= 0) return aRes;
583   Handle(TDataStd_Comment) aString;
584   TDF_Label anArgLabel = ARGUMENT(thePosition);
585   if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
586   char *str = new char[aString->Get().LengthOfCString()+1];
587   aString->Get().ToUTF8CString(str);
588   aRes = TCollection_AsciiString(str);
589   _isDone = true;
590   return aRes;
591 }
592
593 //=============================================================================
594 /*!
595  *  SetReference
596  */
597 //=============================================================================
598 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
599 {
600   _isDone = false;
601   if (thePosition <= 0) return;
602   if (theReference.IsNull()) return;
603   TDF_Label anArgLabel = ARGUMENT(thePosition);
604   TDF_Reference::Set(anArgLabel, theReference->GetEntry());
605   TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
606   _isDone = true;
607   return;
608 }
609
610 //=============================================================================
611 /*!
612  *  GetReference
613  */
614 //=============================================================================
615 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition)
616 {
617   _isDone = false;
618   if(thePosition <= 0) return NULL;
619   TDF_Label anArgLabel = ARGUMENT(thePosition);
620   Handle(TDF_Reference) aRef;
621   if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
622
623   _isDone = true;
624   return GetFunction(aRef->Get());
625 }
626
627
628 //=============================================================================
629 /*!
630  *  SetStringArray
631  */
632 //=============================================================================
633 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
634 {
635   _isDone = false;
636   if(thePosition <= 0 || theArray.IsNull()) return;
637   TDF_Label anArgLabel = ARGUMENT(thePosition);
638
639   Handle(TDataStd_ExtStringArray) anArray =
640     TDataStd_ExtStringArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
641   anArray->ChangeArray(theArray);
642
643   _isDone = true;
644 }
645
646
647 //=============================================================================
648 /*!
649  *  GetStringArray
650  */
651 //=============================================================================
652 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
653 {
654   _isDone = false;
655   if(thePosition <= 0) return NULL;
656   TDF_Label anArgLabel = ARGUMENT(thePosition);
657   Handle(TDataStd_ExtStringArray) anArray;
658   if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
659
660   _isDone = true;
661   return anArray->Array();
662 }
663
664 //=======================================================================
665 //function : HasData
666 //purpose  : Returns true if data of given type already exists
667 //=======================================================================
668
669 bool GEOM_Function::HasData(int thePosition, const Standard_GUID& dataID)
670 {
671   if(thePosition <= 0) return false;
672   TDF_Label anArgLabel = ARGUMENT(thePosition);
673   return anArgLabel.IsAttribute( dataID );
674 }
675
676 //=======================================================================
677 //function : GetReferencesTreeID
678 //purpose  :
679 //=======================================================================
680 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
681 {
682   static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
683   return aReferencesTreeID;
684 }
685
686 //=============================================================================
687 /*!
688  *  SetReferenceList
689  */
690 //=============================================================================
691 void GEOM_Function::SetReferenceList (int thePosition,
692                                       const Handle(TColStd_HSequenceOfTransient)& theRefList)
693 {
694   _isDone = false;
695   if(thePosition <= 0) return;
696
697   // parent label for the list of references
698   TDF_Label anArgLabel = ARGUMENT(thePosition);
699   anArgLabel.ForgetAllAttributes();
700
701   // set TreeNode on the parent label
702   Handle(TDataStd_TreeNode) aRoot, aNode;
703   aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
704
705   // store references on sub-labels of the parent label
706   Handle(GEOM_Function) aFunc;
707   Standard_Integer ind, len = theRefList->Length();
708   for (ind = 1; ind <= len; ind++) {
709     aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
710     if (aFunc.IsNull()) continue;
711     TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
712     TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
713     TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
714
715     // set TreeNode on the child label
716     aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
717     aRoot->Append(aNode);
718   }
719
720   _isDone = true;
721   return;
722 }
723
724 //=============================================================================
725 /*!
726  *  GetReferenceList
727  */
728 //=============================================================================
729 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition)
730 {
731   Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
732   _isDone = false;
733   if(thePosition <= 0) return aResult;
734
735   // parent label for the list of references
736   TDF_Label anArgLabel = ARGUMENT(thePosition);
737   Handle(TDF_Reference) aRef;
738
739   // get TreeNode on the parent label
740   Handle(TDataStd_TreeNode) aRoot, aNode;
741   if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
742     return aResult;
743
744   // get references, stored on sub-labels of the parent label
745   TDF_Label aLabel_i;
746   TDataStd_ChildNodeIterator anIter (aRoot);
747   for (; anIter.More(); anIter.Next()) {
748     aNode = anIter.Value();
749     aLabel_i = aNode->Label();
750     if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
751     Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
752     if (aFunc_i.IsNull()) continue;
753     aResult->Append(aFunc_i);
754   }
755
756   _isDone = true;
757   return aResult;
758 }
759
760 //=============================================================================
761 /*!
762  *  SetShape
763  */
764 //=============================================================================
765 //void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
766 //{
767 //  _isDone = false;
768 //  if(thePosition <= 0 || theShape.IsNull()) return;
769 //
770 //  TDF_Label anArgLabel = ARGUMENT(thePosition);
771 //  TNaming_Builder aBuilder(anArgLabel);
772 //  aBuilder.Generated(theShape);
773 //
774 //  _isDone = true;
775 //  return;
776 //}
777 //
778 //=============================================================================
779 /*!
780  *  GetShape
781  */
782 //=============================================================================
783 //TopoDS_Shape GEOM_Function::GetShape(int thePosition)
784 //{
785 //  _isDone = false;
786 //  TopoDS_Shape aShape;
787 //  if(thePosition <= 0) return aShape;
788 //
789 //  TDF_Label anArgLabel = ARGUMENT(thePosition);
790 //  Handle(TNaming_NamedShape) aNS;
791 //  if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
792 //
793 //  aShape = aNS->Get();
794 //  _isDone = true;
795 //  return aShape;
796 //}
797
798
799 //=============================================================================
800 /*!
801  *  GetDependency
802  */
803 //=============================================================================
804 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
805 {
806   TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
807   for(; anIterator.More(); anIterator.Next()) {
808     if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
809   }
810 }
811
812 //=============================================================================
813 /*!
814  *  AddSubShapeReference
815  */
816 //=============================================================================
817 void GEOM_Function::AddSubShapeReference(Handle(GEOM_Function) theSubShape)
818 {
819   _isDone = false;
820
821   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
822
823   Handle(TDataStd_ExtStringList) aList = TDataStd_ExtStringList::Set( aSubShapesLabel );
824   TCollection_AsciiString anEntry;
825   TDF_Tool::Entry(theSubShape->GetOwnerEntry(), anEntry);
826   aList->Append(anEntry);
827
828   _isDone = true;
829 }
830
831 //=============================================================================
832 /*!
833  *  RemoveSubShapeReference
834  */
835 //=============================================================================
836 void GEOM_Function::RemoveSubShapeReference(Handle(GEOM_Function) theSubShape)
837 {
838   _isDone = false;
839
840   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
841
842   Handle(TDataStd_ExtStringList) aList;
843   if (aSubShapesLabel.FindAttribute(TDataStd_ExtStringList::GetID(), aList)) {
844     TCollection_AsciiString anEntry;
845     TDF_Tool::Entry(theSubShape->GetOwnerEntry(), anEntry);
846     aList->Remove(anEntry);
847   }
848
849   _isDone = true;
850 }
851
852 //=============================================================================
853 /*!
854  *  HasSubShapeReferences
855  */
856 //=============================================================================
857 bool GEOM_Function::HasSubShapeReferences()
858 {
859   _isDone = true;
860
861   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
862   return aSubShapesLabel.IsAttribute(TDataStd_ExtStringList::GetID());
863 }
864
865 //=============================================================================
866 /*!
867  *  GetSubShapeReferences
868  */
869 //=============================================================================
870 const TDataStd_ListOfExtendedString& GEOM_Function::GetSubShapeReferences()
871 {
872   _isDone = false;
873
874   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
875
876   Handle(TDataStd_ExtStringList) aList = TDataStd_ExtStringList::Set( aSubShapesLabel );
877
878   _isDone = true;
879   return aList->List();
880 }
881
882 //=============================================================================
883 /*!
884  *  GetHistoryEntry
885  */
886 //=============================================================================
887 TDF_Label GEOM_Function::GetHistoryEntry (const Standard_Boolean create)
888 {
889   return _label.FindChild(HISTORY_LABEL, create);
890 }
891
892 //=============================================================================
893 /*!
894  *  GetArgumentHistoryEntry
895  */
896 //=============================================================================
897 TDF_Label GEOM_Function::GetArgumentHistoryEntry (const TDF_Label&       theArgumentRefEntry,
898                                                   const Standard_Boolean create)
899 {
900   TColStd_ListOfInteger anArgumentRefTags;
901   TDF_Tool::TagList(theArgumentRefEntry, anArgumentRefTags);
902   Standard_Integer anArgumentRefLabelPos = anArgumentRefTags.Extent();
903
904   TDF_Label aHistoryLabel = GetHistoryEntry(create);
905   if (aHistoryLabel.IsNull())
906     return aHistoryLabel;
907   Standard_Integer aHistoryLabelPos = aHistoryLabel.Depth() + 1;
908
909   Standard_Integer itag;
910   TDF_Label aHistoryCurLabel = aHistoryLabel;
911   TColStd_ListIteratorOfListOfInteger aListIter (anArgumentRefTags);
912   for (itag = 1; itag <= aHistoryLabelPos; itag++) {
913     aListIter.Next();
914   }
915   for (; itag <= anArgumentRefLabelPos; itag++) {
916     aHistoryCurLabel = aHistoryCurLabel.FindChild(aListIter.Value(), create);
917     if (aHistoryCurLabel.IsNull())
918       return aHistoryCurLabel;
919     aListIter.Next();
920   }
921
922   return aHistoryCurLabel;
923 }
924
925 //=============================================================================
926 /*!
927  *  GetNamingEntry
928  */
929 //=============================================================================
930 TDF_Label GEOM_Function::GetNamingEntry (const Standard_Boolean create)
931 {
932   return _label.FindChild(NAMING_LABEL, create);
933 }
934
935 //================================================================================
936 /*!
937  * Save a pointer to a data holder intended to pass temporary data Driver -> Operation.
938  * This method should be called by Operation to set the data holder.
939  * An instance of GEOM_Function that sets the data holder will remove the
940  * corresponding OCAF attribute at it's destruction
941  */
942 //================================================================================
943
944 void GEOM_Function::SetCallBackData( void* data )
945 {
946   std::ostringstream strm;
947   strm << (long long) data;
948   TCollection_ExtendedString string( strm.str().c_str() );
949
950   TDF_Label aChild = _label.FindChild(CALLBACK_LABEL);
951   TDataStd_Comment::Set(aChild, string);
952
953   _isCallBackData = true; // I will remove TDataStd_Comment at destruction
954 }
955
956 //================================================================================
957 /*!
958  * Returns a pointer to a data holder intended to pass data Driver -> Operation.
959  * This method should be called by Driver to get the data holder to fill it in.
960  * Returns NULL if the Operation have not set the data holder.
961  */
962 //================================================================================
963
964 void* GEOM_Function::GetCallBackData()
965 {
966   Handle(TDataStd_Comment) aComment;
967   TDF_Label aChild = _label.FindChild( CALLBACK_LABEL );
968   if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return NULL;
969   TCollection_AsciiString string( aComment->Get() );
970
971   long long address;
972 #ifndef WIN32
973   address = atoll ( string.ToCString() );
974 #else
975   address = _strtoi64 ( string.ToCString(), NULL, 10 );
976 #endif
977
978   return reinterpret_cast<void*> ( address );
979 }
980
981 IMPLEMENT_STANDARD_RTTIEXT(GEOM_Function, Standard_Transient );