Salome HOME
59a73a2f5c1141ce1d95c7eaff51ea4cab026954
[modules/geom.git] / src / GEOM / GEOM_Function.cxx
1 // Copyright (C) 2007-2023  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 Returns 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& aFail) {
252         MESSAGE("GEOM_Function::GetValue Error: " << aFail.GetMessageString());
253         return aShape;
254       }
255     }
256   }
257
258   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
259   Handle(TNaming_NamedShape) aNS;
260   if (!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
261
262   aShape = aNS->Get();
263
264 #ifdef KEEP_ORIENTATION_0021251
265   // 0021251: TNaming_NamedShape doesn't store orientation
266   TDF_Label anOrientationLabel = _label.FindChild(ORIENTATION_LABEL);
267   Handle(TDataStd_Integer) anInteger;
268   if (anOrientationLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) {
269     aShape.Orientation((TopAbs_Orientation)anInteger->Get());
270   }
271 #endif
272
273   _isDone = true;
274   return aShape;
275 }
276
277 //=============================================================================
278 /*!
279  *  SetValue
280  */
281 //=============================================================================
282 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
283 {
284   _isDone = false;
285   TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
286   TNaming_Builder aBuilder (aResultLabel);
287
288   aBuilder.Generated(theShape);
289
290 #ifdef KEEP_ORIENTATION_0021251
291   // 0021251: TNaming_NamedShape doesn't store orientation
292   TDF_Label anOrientationLabel = _label.FindChild(ORIENTATION_LABEL);
293   TDataStd_Integer::Set(anOrientationLabel, (int)theShape.Orientation());
294 #endif
295
296   // synchronisation between main shape and its sub-shapes
297   TDF_Label aLabel = GetOwnerEntry();
298   if (aLabel.IsRoot()) return;
299   Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
300   if (anObject.IsNull()) return;
301   if (anObject->IsMainShape()) {
302     // increase modifications counter of this (main) shape
303     anObject->IncrementTic();
304   }
305   else {
306     // update modifications counter of this (sub-) shape to be the same as on main shape
307     GEOM_ISubShape aCI (this);
308     TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
309     if (aLabelObjMainSh.IsRoot()) return;
310     Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
311     if (anObjMainSh.IsNull()) return;
312
313     anObject->SetTic(anObjMainSh->GetTic());
314   }
315
316   _isDone = true;
317 }
318
319 //=============================================================================
320 /*!
321  *  GetDriverGUID
322  */
323 //=============================================================================
324 Standard_GUID GEOM_Function::GetDriverGUID()
325 {
326   Handle(TFunction_Function) aFunction;
327   if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
328     return TDF::LowestID();
329   }
330
331   return aFunction->GetDriverGUID();
332 }
333
334 //=============================================================================
335 /*!
336  *  GetDescription
337  */
338 //=============================================================================
339 TCollection_AsciiString GEOM_Function::GetDescription()
340 {
341   Handle(TDataStd_Comment) aComment;
342   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
343   if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
344   TCollection_AsciiString aDescr(aComment->Get());
345   return aDescr;
346 }
347
348 //=============================================================================
349 /*!
350  *  SetDescription
351  */
352 //=============================================================================
353 void GEOM_Function::SetDescription(const TCollection_AsciiString& theDescription)
354 {
355   TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
356   Handle(TDataStd_Comment) aComment =
357     TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
358 }
359
360 //=============================================================================
361 /*!
362  *  SetReal
363  */
364 //=============================================================================
365 void GEOM_Function::SetReal(int thePosition, double theValue)
366 {
367   _isDone = false;
368   if(thePosition <= 0) return;
369   TDF_Label anArgLabel = ARGUMENT(thePosition);
370   TDataStd_Real::Set(anArgLabel, theValue);
371   _isDone = true;
372 }
373
374 //=============================================================================
375 /*!
376  *  SetRealArray
377  */
378 //=============================================================================
379 void GEOM_Function::SetRealArray (int thePosition,
380                                   const Handle(TColStd_HArray1OfReal)& theArray)
381 {
382   _isDone = false;
383   if(thePosition <= 0) return;
384   TDF_Label anArgLabel = ARGUMENT(thePosition);
385   Handle(TDataStd_RealArray) anAttr =
386     TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
387   anAttr->ChangeArray(theArray);
388   _isDone = true;
389 }
390
391 //=============================================================================
392 /*!
393  *  GetReal
394  */
395 //=============================================================================
396 double GEOM_Function::GetReal(int thePosition)
397 {
398   _isDone = false;
399   if(thePosition <= 0) return 0.0;
400   Handle(TDataStd_Real) aReal;
401   TDF_Label anArgLabel = ARGUMENT(thePosition);
402   if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
403
404   _isDone = true;
405   return aReal->Get();
406 }
407
408 //=============================================================================
409 /*!
410  *  GetRealArray
411  */
412 //=============================================================================
413 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
414 {
415   _isDone = false;
416   if(thePosition <= 0) return NULL;
417   Handle(TDataStd_RealArray) aRealArray;
418   TDF_Label anArgLabel = ARGUMENT(thePosition);
419   if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
420
421   _isDone = true;
422   return aRealArray->Array();
423 }
424
425 //=============================================================================
426 /*!
427  *  SetInteger
428  */
429 //=============================================================================
430 void GEOM_Function::SetInteger(int thePosition, int theValue)
431 {
432   _isDone = false;
433   if(thePosition <= 0) return;
434   TDF_Label anArgLabel = ARGUMENT(thePosition);
435   TDataStd_Integer::Set(anArgLabel, theValue);
436   _isDone = true;
437 }
438
439 //=============================================================================
440 /*!
441  *  SetIntegerArray
442  */
443 //=============================================================================
444 void GEOM_Function::SetIntegerArray (int thePosition,
445                                      const Handle(TColStd_HArray1OfInteger)& theArray)
446 {
447   _isDone = false;
448   if(thePosition <= 0) return;
449   TDF_Label anArgLabel = ARGUMENT(thePosition);
450   Handle(TDataStd_IntegerArray) anAttr =
451     TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
452   anAttr->ChangeArray(theArray);
453   _isDone = true;
454 }
455
456 //=============================================================================
457 /*!
458  *  GetInteger
459  */
460 //=============================================================================
461 int GEOM_Function::GetInteger(int thePosition)
462 {
463   _isDone = false;
464   if(thePosition <= 0) return 0;
465   Handle(TDataStd_Integer) anInteger;
466   TDF_Label anArgLabel = ARGUMENT(thePosition);
467   if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
468
469   _isDone = true;
470   return anInteger->Get();
471 }
472
473 //=============================================================================
474 /*!
475  *  GetIntegerArray
476  */
477 //=============================================================================
478 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
479 {
480   _isDone = false;
481   if(thePosition <= 0) return 0;
482   Handle(TDataStd_IntegerArray) anIntegerArray;
483   TDF_Label anArgLabel = ARGUMENT(thePosition);
484   if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
485
486   _isDone = true;
487   return anIntegerArray->Array();
488 }
489
490 //=============================================================================
491 /*!
492  *  SetByteArray
493  */
494 //=============================================================================
495 void GEOM_Function::SetByteArray (int thePosition,
496                                   const Handle(TColStd_HArray1OfByte)& theArray)
497 {
498   _isDone = false;
499   if(thePosition <= 0) return;
500   TDF_Label anArgLabel = ARGUMENT(thePosition);
501   Handle(TDataStd_ByteArray) anAttr =
502     TDataStd_ByteArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
503   anAttr->ChangeArray(theArray);
504   _isDone = true;
505 }
506
507 //=============================================================================
508 /*!
509  *  GetByteArray
510  */
511 //=============================================================================
512 Handle(TColStd_HArray1OfByte) GEOM_Function::GetByteArray(int thePosition)
513 {
514   _isDone = false;
515   if(thePosition <= 0) return 0;
516   Handle(TDataStd_ByteArray) aByteArray;
517   TDF_Label anArgLabel = ARGUMENT(thePosition);
518   if(!anArgLabel.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray)) return 0;
519
520   _isDone = true;
521   return aByteArray->InternalArray();
522 }
523
524 //=============================================================================
525 /*!
526  *  SetBooleanArray
527  */
528 //=============================================================================
529 void GEOM_Function::SetBooleanArray (int thePosition,
530                                      const Handle(TColStd_HArray1OfByte)& theArray)
531 {
532   _isDone = false;
533   if(thePosition <= 0) return;
534   TDF_Label anArgLabel = ARGUMENT(thePosition);
535   Handle(TDataStd_BooleanArray) anAttr =
536     TDataStd_BooleanArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
537   anAttr->SetInternalArray(theArray);
538   _isDone = true;
539 }
540
541 //=============================================================================
542 /*!
543  *  GetBooleanArray
544  */
545 //=============================================================================
546 Handle(TColStd_HArray1OfByte) GEOM_Function::GetBooleanArray(int thePosition)
547 {
548   _isDone = false;
549   if(thePosition <= 0) return 0;
550   Handle(TDataStd_BooleanArray) aBooleanArray;
551   TDF_Label anArgLabel = ARGUMENT(thePosition);
552   if(!anArgLabel.FindAttribute(TDataStd_BooleanArray::GetID(), aBooleanArray)) return 0;
553
554   _isDone = true;
555   return aBooleanArray->InternalArray();
556 }
557
558 //=============================================================================
559 /*!
560  *  SetString
561  */
562 //=============================================================================
563 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
564 {
565   _isDone = false;
566   if(thePosition <= 0) return;
567   TDF_Label anArgLabel = ARGUMENT(thePosition);
568   TDataStd_Comment::Set(anArgLabel, theValue);
569   _isDone = true;
570 }
571
572 //=============================================================================
573 /*!
574  *  GetString
575  */
576 //=============================================================================
577 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
578 {
579   _isDone = false;
580   TCollection_AsciiString aRes;
581   if(thePosition <= 0) return aRes;
582   Handle(TDataStd_Comment) aString;
583   TDF_Label anArgLabel = ARGUMENT(thePosition);
584   if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
585   char *str = new char[aString->Get().LengthOfCString()+1];
586   aString->Get().ToUTF8CString(str);
587   aRes = TCollection_AsciiString(str);
588   _isDone = true;
589   return aRes;
590 }
591
592 //=============================================================================
593 /*!
594  *  SetReference
595  */
596 //=============================================================================
597 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
598 {
599   _isDone = false;
600   if (thePosition <= 0) return;
601   if (theReference.IsNull()) return;
602   TDF_Label anArgLabel = ARGUMENT(thePosition);
603   TDF_Reference::Set(anArgLabel, theReference->GetEntry());
604   TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
605   _isDone = true;
606   return;
607 }
608
609 //=============================================================================
610 /*!
611  *  GetReference
612  */
613 //=============================================================================
614 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition)
615 {
616   _isDone = false;
617   if(thePosition <= 0) return NULL;
618   TDF_Label anArgLabel = ARGUMENT(thePosition);
619   Handle(TDF_Reference) aRef;
620   if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
621
622   _isDone = true;
623   return GetFunction(aRef->Get());
624 }
625
626
627 //=============================================================================
628 /*!
629  *  SetStringArray
630  */
631 //=============================================================================
632 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
633 {
634   _isDone = false;
635   if(thePosition <= 0 || theArray.IsNull()) return;
636   TDF_Label anArgLabel = ARGUMENT(thePosition);
637
638   Handle(TDataStd_ExtStringArray) anArray =
639     TDataStd_ExtStringArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
640   anArray->ChangeArray(theArray);
641
642   _isDone = true;
643 }
644
645
646 //=============================================================================
647 /*!
648  *  GetStringArray
649  */
650 //=============================================================================
651 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
652 {
653   _isDone = false;
654   if(thePosition <= 0) return NULL;
655   TDF_Label anArgLabel = ARGUMENT(thePosition);
656   Handle(TDataStd_ExtStringArray) anArray;
657   if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
658
659   _isDone = true;
660   return anArray->Array();
661 }
662
663 //=======================================================================
664 //function : HasData
665 //purpose  : Returns true if data of given type already exists
666 //=======================================================================
667
668 bool GEOM_Function::HasData(int thePosition, const Standard_GUID& dataID)
669 {
670   if(thePosition <= 0) return false;
671   TDF_Label anArgLabel = ARGUMENT(thePosition);
672   return anArgLabel.IsAttribute( dataID );
673 }
674
675 //=======================================================================
676 //function : GetReferencesTreeID
677 //purpose  :
678 //=======================================================================
679 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
680 {
681   static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
682   return aReferencesTreeID;
683 }
684
685 //=============================================================================
686 /*!
687  *  SetReferenceList
688  */
689 //=============================================================================
690 void GEOM_Function::SetReferenceList (int thePosition,
691                                       const Handle(TColStd_HSequenceOfTransient)& theRefList)
692 {
693   _isDone = false;
694   if(thePosition <= 0) return;
695
696   // parent label for the list of references
697   TDF_Label anArgLabel = ARGUMENT(thePosition);
698   anArgLabel.ForgetAllAttributes();
699
700   // set TreeNode on the parent label
701   Handle(TDataStd_TreeNode) aRoot, aNode;
702   aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
703
704   // store references on sub-labels of the parent label
705   Handle(GEOM_Function) aFunc;
706   Standard_Integer ind, len = theRefList->Length();
707   for (ind = 1; ind <= len; ind++) {
708     aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
709     if (aFunc.IsNull()) continue;
710     TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
711     TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
712     TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
713
714     // set TreeNode on the child label
715     aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
716     aRoot->Append(aNode);
717   }
718
719   _isDone = true;
720   return;
721 }
722
723 //=============================================================================
724 /*!
725  *  GetReferenceList
726  */
727 //=============================================================================
728 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition)
729 {
730   Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
731   _isDone = false;
732   if(thePosition <= 0) return aResult;
733
734   // parent label for the list of references
735   TDF_Label anArgLabel = ARGUMENT(thePosition);
736   Handle(TDF_Reference) aRef;
737
738   // get TreeNode on the parent label
739   Handle(TDataStd_TreeNode) aRoot, aNode;
740   if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
741     return aResult;
742
743   // get references, stored on sub-labels of the parent label
744   TDF_Label aLabel_i;
745   TDataStd_ChildNodeIterator anIter (aRoot);
746   for (; anIter.More(); anIter.Next()) {
747     aNode = anIter.Value();
748     aLabel_i = aNode->Label();
749     if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
750     Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
751     if (aFunc_i.IsNull()) continue;
752     aResult->Append(aFunc_i);
753   }
754
755   _isDone = true;
756   return aResult;
757 }
758
759 //=============================================================================
760 /*!
761  *  SetShape
762  */
763 //=============================================================================
764 //void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
765 //{
766 //  _isDone = false;
767 //  if(thePosition <= 0 || theShape.IsNull()) return;
768 //
769 //  TDF_Label anArgLabel = ARGUMENT(thePosition);
770 //  TNaming_Builder aBuilder(anArgLabel);
771 //  aBuilder.Generated(theShape);
772 //
773 //  _isDone = true;
774 //  return;
775 //}
776 //
777 //=============================================================================
778 /*!
779  *  GetShape
780  */
781 //=============================================================================
782 //TopoDS_Shape GEOM_Function::GetShape(int thePosition)
783 //{
784 //  _isDone = false;
785 //  TopoDS_Shape aShape;
786 //  if(thePosition <= 0) return aShape;
787 //
788 //  TDF_Label anArgLabel = ARGUMENT(thePosition);
789 //  Handle(TNaming_NamedShape) aNS;
790 //  if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
791 //
792 //  aShape = aNS->Get();
793 //  _isDone = true;
794 //  return aShape;
795 //}
796
797
798 //=============================================================================
799 /*!
800  *  GetDependency
801  */
802 //=============================================================================
803 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
804 {
805   TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
806   for(; anIterator.More(); anIterator.Next()) {
807     if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
808   }
809 }
810
811 //=============================================================================
812 /*!
813  *  AddSubShapeReference
814  */
815 //=============================================================================
816 void GEOM_Function::AddSubShapeReference(Handle(GEOM_Function) theSubShape)
817 {
818   _isDone = false;
819
820   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
821
822   Handle(TDataStd_ExtStringList) aList = TDataStd_ExtStringList::Set( aSubShapesLabel );
823   TCollection_AsciiString anEntry;
824   TDF_Tool::Entry(theSubShape->GetOwnerEntry(), anEntry);
825   aList->Append(anEntry);
826
827   _isDone = true;
828 }
829
830 //=============================================================================
831 /*!
832  *  RemoveSubShapeReference
833  */
834 //=============================================================================
835 void GEOM_Function::RemoveSubShapeReference(Handle(GEOM_Function) theSubShape)
836 {
837   _isDone = false;
838
839   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
840
841   Handle(TDataStd_ExtStringList) aList;
842   if (aSubShapesLabel.FindAttribute(TDataStd_ExtStringList::GetID(), aList)) {
843     TCollection_AsciiString anEntry;
844     TDF_Tool::Entry(theSubShape->GetOwnerEntry(), anEntry);
845     aList->Remove(anEntry);
846   }
847
848   _isDone = true;
849 }
850
851 //=============================================================================
852 /*!
853  *  HasSubShapeReferences
854  */
855 //=============================================================================
856 bool GEOM_Function::HasSubShapeReferences()
857 {
858   _isDone = true;
859
860   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
861   return aSubShapesLabel.IsAttribute(TDataStd_ExtStringList::GetID());
862 }
863
864 //=============================================================================
865 /*!
866  *  GetSubShapeReferences
867  */
868 //=============================================================================
869 const TDataStd_ListOfExtendedString& GEOM_Function::GetSubShapeReferences()
870 {
871   _isDone = false;
872
873   TDF_Label aSubShapesLabel = _label.FindChild(SUBSHAPES_LABEL);
874
875   Handle(TDataStd_ExtStringList) aList = TDataStd_ExtStringList::Set( aSubShapesLabel );
876
877   _isDone = true;
878   return aList->List();
879 }
880
881 //=============================================================================
882 /*!
883  *  GetHistoryEntry
884  */
885 //=============================================================================
886 TDF_Label GEOM_Function::GetHistoryEntry (const Standard_Boolean create)
887 {
888   return _label.FindChild(HISTORY_LABEL, create);
889 }
890
891 //=============================================================================
892 /*!
893  *  GetArgumentHistoryEntry
894  */
895 //=============================================================================
896 TDF_Label GEOM_Function::GetArgumentHistoryEntry (const TDF_Label&       theArgumentRefEntry,
897                                                   const Standard_Boolean create)
898 {
899   TColStd_ListOfInteger anArgumentRefTags;
900   TDF_Tool::TagList(theArgumentRefEntry, anArgumentRefTags);
901   Standard_Integer anArgumentRefLabelPos = anArgumentRefTags.Extent();
902
903   TDF_Label aHistoryLabel = GetHistoryEntry(create);
904   if (aHistoryLabel.IsNull())
905     return aHistoryLabel;
906   Standard_Integer aHistoryLabelPos = aHistoryLabel.Depth() + 1;
907
908   Standard_Integer itag;
909   TDF_Label aHistoryCurLabel = aHistoryLabel;
910   TColStd_ListIteratorOfListOfInteger aListIter (anArgumentRefTags);
911   for (itag = 1; itag <= aHistoryLabelPos; itag++) {
912     aListIter.Next();
913   }
914   for (; itag <= anArgumentRefLabelPos; itag++) {
915     aHistoryCurLabel = aHistoryCurLabel.FindChild(aListIter.Value(), create);
916     if (aHistoryCurLabel.IsNull())
917       return aHistoryCurLabel;
918     aListIter.Next();
919   }
920
921   return aHistoryCurLabel;
922 }
923
924 //=============================================================================
925 /*!
926  *  GetNamingEntry
927  */
928 //=============================================================================
929 TDF_Label GEOM_Function::GetNamingEntry (const Standard_Boolean create)
930 {
931   return _label.FindChild(NAMING_LABEL, create);
932 }
933
934 //================================================================================
935 /*!
936  * Save a pointer to a data holder intended to pass temporary data Driver -> Operation.
937  * This method should be called by Operation to set the data holder.
938  * An instance of GEOM_Function that sets the data holder will remove the
939  * corresponding OCAF attribute at it's destruction
940  */
941 //================================================================================
942
943 void GEOM_Function::SetCallBackData( void* data )
944 {
945   std::ostringstream strm;
946   strm << (long long) data;
947   TCollection_ExtendedString string( strm.str().c_str() );
948
949   TDF_Label aChild = _label.FindChild(CALLBACK_LABEL);
950   TDataStd_Comment::Set(aChild, string);
951
952   _isCallBackData = true; // I will remove TDataStd_Comment at destruction
953 }
954
955 //================================================================================
956 /*!
957  * Returns a pointer to a data holder intended to pass data Driver -> Operation.
958  * This method should be called by Driver to get the data holder to fill it in.
959  * Returns NULL if the Operation have not set the data holder.
960  */
961 //================================================================================
962
963 void* GEOM_Function::GetCallBackData()
964 {
965   Handle(TDataStd_Comment) aComment;
966   TDF_Label aChild = _label.FindChild( CALLBACK_LABEL );
967   if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return NULL;
968   TCollection_AsciiString string( aComment->Get() );
969
970   long long address;
971 #ifndef WIN32
972   address = atoll ( string.ToCString() );
973 #else
974   address = _strtoi64 ( string.ToCString(), NULL, 10 );
975 #endif
976
977   return reinterpret_cast<void*> ( address );
978 }
979
980 IMPLEMENT_STANDARD_RTTIEXT(GEOM_Function, Standard_Transient )