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