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