1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include <Standard_Stream.hxx>
23 #include <GEOM_Function.hxx>
24 #include <GEOM_Object.hxx>
25 #include <GEOM_Solver.hxx>
27 #include "utilities.h"
30 #include <TDF_Tool.hxx>
31 #include <TDF_Data.hxx>
32 #include <TDF_ChildIterator.hxx>
33 #include <TDF_Reference.hxx>
34 #include <TDataStd_Integer.hxx>
35 #include <TDataStd_IntegerArray.hxx>
36 #include <TDataStd_Real.hxx>
37 #include <TDataStd_RealArray.hxx>
38 #include <TDataStd_Comment.hxx>
39 #include <TDataStd_TreeNode.hxx>
40 #include <TDataStd_UAttribute.hxx>
41 #include <TDataStd_ChildNodeIterator.hxx>
42 #include <TDataStd_ExtStringArray.hxx>
43 #include <TDocStd_Owner.hxx>
44 #include <TDocStd_Document.hxx>
45 #include <TFunction_Function.hxx>
46 #include <TNaming_NamedShape.hxx>
47 #include <TNaming_Builder.hxx>
49 #include <TColStd_ListOfInteger.hxx>
50 #include <TColStd_ListIteratorOfListOfInteger.hxx>
51 #include <TColStd_HArray1OfReal.hxx>
52 #include <TColStd_HArray1OfInteger.hxx>
53 #include <TColStd_HSequenceOfTransient.hxx>
54 #include <TCollection_AsciiString.hxx>
55 #include <TCollection_ExtendedString.hxx>
57 #include <Standard_Failure.hxx>
58 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
60 #define ARGUMENT_LABEL 1
61 #define RESULT_LABEL 2
62 #define DESCRIPTION_LABEL 3
63 #define HISTORY_LABEL 4
65 #define ARGUMENTS _label.FindChild((ARGUMENT_LABEL))
66 #define ARGUMENT(thePosition) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePosition))
67 #define SUB_ARGUMENT(thePos1, thePos2) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePos1)).FindChild((thePos2))
69 //=======================================================================
70 //function : GetFunctionTreeID
72 //=======================================================================
73 const Standard_GUID& GEOM_Function::GetFunctionTreeID()
75 static Standard_GUID aFunctionTreeID("FF1BBB00-5D14-4df2-980B-3A668264EA16");
76 return aFunctionTreeID;
80 //=======================================================================
81 //function : GetDependencyID
83 //=======================================================================
84 const Standard_GUID& GEOM_Function::GetDependencyID()
86 static Standard_GUID aDependencyID("E2620650-2354-41bd-8C2C-210CFCD00948");
90 //=============================================================================
94 //=============================================================================
95 Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry)
97 if(!theEntry.IsAttribute(TFunction_Function::GetID())) return NULL;
99 return new GEOM_Function(theEntry);
102 //=============================================================================
106 //=============================================================================
107 GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType)
110 TFunction_Function::Set(theEntry, theGUID);
111 TDataStd_Integer::Set(theEntry, theType);
113 //Add function to a function tree
114 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theEntry.Data());
115 Handle(TDataStd_TreeNode) aRoot, aNode;
116 if(!aDoc->Main().FindAttribute(GetFunctionTreeID(), aRoot))
117 aRoot = TDataStd_TreeNode::Set(aDoc->Main(), GetFunctionTreeID());
119 aNode = TDataStd_TreeNode::Set(theEntry, GetFunctionTreeID());
120 aRoot->Append(aNode);
123 //=============================================================================
127 //=============================================================================
128 TDF_Label GEOM_Function::GetOwnerEntry()
130 TDF_Label aFather = _label.Father();
131 while(!aFather.IsRoot()) {
132 if(aFather.IsAttribute(GEOM_Object::GetObjectID())) return aFather;
133 aFather = aFather.Father();
139 //=============================================================================
143 //=============================================================================
144 int GEOM_Function::GetType()
147 Handle(TDataStd_Integer) aType;
148 if(!_label.FindAttribute(TDataStd_Integer::GetID(), aType)) return 0;
153 //=============================================================================
157 //=============================================================================
158 TopoDS_Shape GEOM_Function::GetValue()
163 TDF_Label aLabel = GetOwnerEntry();
164 if(aLabel.IsRoot()) return aShape;
165 Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
166 if(anObject.IsNull()) return aShape;
167 if(!anObject->IsMainShape()) {
169 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
172 GEOM_Solver aSolver(GEOM_Engine::GetEngine());
173 if (!aSolver.ComputeFunction(this)) {
174 MESSAGE("GEOM_Object::GetValue Error : Can't build a sub shape");
178 catch (Standard_Failure) {
179 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
180 MESSAGE("GEOM_Function::GetValue Error: " << aFail->GetMessageString());
185 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
186 Handle(TNaming_NamedShape) aNS;
187 if(!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
195 //=============================================================================
199 //=============================================================================
200 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
203 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
204 TNaming_Builder aBuilder(aResultLabel);
206 aBuilder.Generated(theShape);
211 //=============================================================================
215 //=============================================================================
216 Standard_GUID GEOM_Function::GetDriverGUID()
218 Handle(TFunction_Function) aFunction;
219 if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
220 return TDF::LowestID();
223 return aFunction->GetDriverGUID();
226 //=============================================================================
230 //=============================================================================
231 TCollection_AsciiString GEOM_Function::GetDescription()
233 Handle(TDataStd_Comment) aComment;
234 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
235 if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
236 TCollection_AsciiString aDescr(aComment->Get());
240 //=============================================================================
244 //=============================================================================
245 void GEOM_Function::SetDescription(const TCollection_AsciiString& theDescription)
247 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
248 Handle(TDataStd_Comment) aComment =
249 TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
252 //=============================================================================
256 //=============================================================================
257 void GEOM_Function::SetReal(int thePosition, double theValue)
260 if(thePosition <= 0) return;
261 TDF_Label anArgLabel = ARGUMENT(thePosition);
262 TDataStd_Real::Set(anArgLabel, theValue);
266 //=============================================================================
270 //=============================================================================
271 void GEOM_Function::SetRealArray (int thePosition,
272 const Handle(TColStd_HArray1OfReal)& theArray)
275 if(thePosition <= 0) return;
276 TDF_Label anArgLabel = ARGUMENT(thePosition);
277 Handle(TDataStd_RealArray) anAttr =
278 TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
279 anAttr->ChangeArray(theArray);
283 //=============================================================================
287 //=============================================================================
288 double GEOM_Function::GetReal(int thePosition)
291 if(thePosition <= 0) return 0.0;
292 Handle(TDataStd_Real) aReal;
293 TDF_Label anArgLabel = ARGUMENT(thePosition);
294 if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
300 //=============================================================================
304 //=============================================================================
305 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
308 if(thePosition <= 0) return NULL;
309 Handle(TDataStd_RealArray) aRealArray;
310 TDF_Label anArgLabel = ARGUMENT(thePosition);
311 if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
314 return aRealArray->Array();
317 //=============================================================================
321 //=============================================================================
322 void GEOM_Function::SetInteger(int thePosition, int theValue)
325 if(thePosition <= 0) return;
326 TDF_Label anArgLabel = ARGUMENT(thePosition);
327 TDataStd_Integer::Set(anArgLabel, theValue);
331 //=============================================================================
335 //=============================================================================
336 void GEOM_Function::SetIntegerArray (int thePosition,
337 const Handle(TColStd_HArray1OfInteger)& theArray)
340 if(thePosition <= 0) return;
341 TDF_Label anArgLabel = ARGUMENT(thePosition);
342 Handle(TDataStd_IntegerArray) anAttr =
343 TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
344 anAttr->ChangeArray(theArray);
348 //=============================================================================
352 //=============================================================================
353 int GEOM_Function::GetInteger(int thePosition)
356 if(thePosition <= 0) return 0;
357 Handle(TDataStd_Integer) anInteger;
358 TDF_Label anArgLabel = ARGUMENT(thePosition);
359 if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
362 return anInteger->Get();
365 //=============================================================================
369 //=============================================================================
370 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
373 if(thePosition <= 0) return 0;
374 Handle(TDataStd_IntegerArray) anIntegerArray;
375 TDF_Label anArgLabel = ARGUMENT(thePosition);
376 if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
379 return anIntegerArray->Array();
382 //=============================================================================
386 //=============================================================================
387 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
390 if(thePosition <= 0) return;
391 TDF_Label anArgLabel = ARGUMENT(thePosition);
392 TDataStd_Comment::Set(anArgLabel, theValue);
396 //=============================================================================
400 //=============================================================================
401 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
404 TCollection_AsciiString aRes;
405 if(thePosition <= 0) return aRes;
406 Handle(TDataStd_Comment) aString;
407 TDF_Label anArgLabel = ARGUMENT(thePosition);
408 if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
411 aRes = TCollection_AsciiString(aString->Get());
415 //=============================================================================
419 //=============================================================================
420 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
423 if(thePosition <= 0) return;
424 if(theReference.IsNull()) return;
425 TDF_Label anArgLabel = ARGUMENT(thePosition);
426 TDF_Reference::Set(anArgLabel, theReference->GetEntry());
427 TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
432 //=============================================================================
436 //=============================================================================
437 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition)
440 if(thePosition <= 0) return NULL;
441 TDF_Label anArgLabel = ARGUMENT(thePosition);
442 Handle(TDF_Reference) aRef;
443 if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
446 return GetFunction(aRef->Get());
450 //=============================================================================
454 //=============================================================================
455 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
458 if(thePosition <= 0 || theArray.IsNull()) return;
459 TDF_Label anArgLabel = ARGUMENT(thePosition);
461 Handle(TDataStd_ExtStringArray) anArray = new TDataStd_ExtStringArray;
462 anArray->ChangeArray(theArray);
463 anArgLabel.AddAttribute(anArray);
469 //=============================================================================
473 //=============================================================================
474 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
477 if(thePosition <= 0) return NULL;
478 TDF_Label anArgLabel = ARGUMENT(thePosition);
479 Handle(TDataStd_ExtStringArray) anArray;
480 if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
483 return anArray->Array();
486 //=======================================================================
487 //function : GetReferencesTreeID
489 //=======================================================================
490 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
492 static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
493 return aReferencesTreeID;
496 //=============================================================================
500 //=============================================================================
501 void GEOM_Function::SetReferenceList (int thePosition,
502 const Handle(TColStd_HSequenceOfTransient)& theRefList)
505 if(thePosition <= 0) return;
507 // parent label for the list of references
508 TDF_Label anArgLabel = ARGUMENT(thePosition);
509 anArgLabel.ForgetAllAttributes();
511 // set TreeNode on the parent label
512 Handle(TDataStd_TreeNode) aRoot, aNode;
513 aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
515 // store references on sub-labels of the parent label
516 Handle(GEOM_Function) aFunc;
517 Standard_Integer ind, len = theRefList->Length();
518 for (ind = 1; ind <= len; ind++) {
519 aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
520 if (aFunc.IsNull()) continue;
521 TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
522 TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
523 TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
525 // set TreeNode on the child label
526 aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
527 aRoot->Append(aNode);
534 //=============================================================================
538 //=============================================================================
539 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition)
541 Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
543 if(thePosition <= 0) return aResult;
545 // parent label for the list of references
546 TDF_Label anArgLabel = ARGUMENT(thePosition);
547 Handle(TDF_Reference) aRef;
549 // get TreeNode on the parent label
550 Handle(TDataStd_TreeNode) aRoot, aNode;
551 if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
554 // get references, stored on sub-labels of the parent label
556 TDataStd_ChildNodeIterator anIter (aRoot);
557 for (; anIter.More(); anIter.Next()) {
558 aNode = anIter.Value();
559 aLabel_i = aNode->Label();
560 if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
561 Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
562 if (aFunc_i.IsNull()) continue;
563 aResult->Append(aFunc_i);
570 //=============================================================================
574 //=============================================================================
575 //void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
578 // if(thePosition <= 0 || theShape.IsNull()) return;
580 // TDF_Label anArgLabel = ARGUMENT(thePosition);
581 // TNaming_Builder aBuilder(anArgLabel);
582 // aBuilder.Generated(theShape);
588 //=============================================================================
592 //=============================================================================
593 //TopoDS_Shape GEOM_Function::GetShape(int thePosition)
596 // TopoDS_Shape aShape;
597 // if(thePosition <= 0) return aShape;
599 // TDF_Label anArgLabel = ARGUMENT(thePosition);
600 // Handle(TNaming_NamedShape) aNS;
601 // if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
603 // aShape = aNS->Get();
609 //=============================================================================
613 //=============================================================================
614 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
616 TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
617 for(; anIterator.More(); anIterator.Next()) {
618 if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
622 //=============================================================================
626 //=============================================================================
627 TDF_Label GEOM_Function::GetHistoryEntry (const Standard_Boolean create)
629 return _label.FindChild(HISTORY_LABEL, create);
632 //=============================================================================
634 * GetArgumentHistoryEntry
636 //=============================================================================
637 TDF_Label GEOM_Function::GetArgumentHistoryEntry (const TDF_Label& theArgumentRefEntry,
638 const Standard_Boolean create)
640 TColStd_ListOfInteger anArgumentRefTags;
641 TDF_Tool::TagList(theArgumentRefEntry, anArgumentRefTags);
642 Standard_Integer anArgumentRefLabelPos = anArgumentRefTags.Extent();
644 TDF_Label aHistoryLabel = GetHistoryEntry(create);
645 if (aHistoryLabel.IsNull())
646 return aHistoryLabel;
647 Standard_Integer aHistoryLabelPos = aHistoryLabel.Depth() + 1;
649 Standard_Integer itag;
650 TDF_Label aHistoryCurLabel = aHistoryLabel;
651 TColStd_ListIteratorOfListOfInteger aListIter (anArgumentRefTags);
652 for (itag = 1; itag <= aHistoryLabelPos; itag++) {
655 for (; itag <= anArgumentRefLabelPos; itag++) {
656 aHistoryCurLabel = aHistoryCurLabel.FindChild(aListIter.Value(), create);
657 if (aHistoryCurLabel.IsNull())
658 return aHistoryCurLabel;
662 return aHistoryCurLabel;
665 //=======================================================================
666 //function : GEOM_Function_Type_
668 //=======================================================================
669 Standard_EXPORT Handle_Standard_Type& GEOM_Function_Type_()
672 static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
673 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared);
674 static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
675 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
678 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
679 static Handle_Standard_Type _aType = new Standard_Type("GEOM_Function",
680 sizeof(GEOM_Function),
682 (Standard_Address)_Ancestors,
683 (Standard_Address)NULL);
688 //=======================================================================
689 //function : DownCast
691 //=======================================================================
693 const Handle(GEOM_Function) Handle(GEOM_Function)::DownCast(const Handle(Standard_Transient)& AnObject)
695 Handle(GEOM_Function) _anOtherObject;
697 if (!AnObject.IsNull()) {
698 if (AnObject->IsKind(STANDARD_TYPE(GEOM_Function))) {
699 _anOtherObject = Handle(GEOM_Function)((Handle(GEOM_Function)&)AnObject);
703 return _anOtherObject ;