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>
26 #include <GEOM_ISubShape.hxx>
28 #include "utilities.h"
31 #include <TDF_Tool.hxx>
32 #include <TDF_Data.hxx>
33 #include <TDF_ChildIterator.hxx>
34 #include <TDF_Reference.hxx>
35 #include <TDataStd_Integer.hxx>
36 #include <TDataStd_IntegerArray.hxx>
37 #include <TDataStd_Real.hxx>
38 #include <TDataStd_RealArray.hxx>
39 #include <TDataStd_Comment.hxx>
40 #include <TDataStd_TreeNode.hxx>
41 #include <TDataStd_UAttribute.hxx>
42 #include <TDataStd_ChildNodeIterator.hxx>
43 #include <TDataStd_ExtStringArray.hxx>
44 #include <TDocStd_Owner.hxx>
45 #include <TDocStd_Document.hxx>
46 #include <TFunction_Function.hxx>
47 #include <TNaming_NamedShape.hxx>
48 #include <TNaming_Builder.hxx>
50 #include <TColStd_ListOfInteger.hxx>
51 #include <TColStd_ListIteratorOfListOfInteger.hxx>
52 #include <TColStd_HArray1OfReal.hxx>
53 #include <TColStd_HArray1OfInteger.hxx>
54 #include <TColStd_HSequenceOfTransient.hxx>
55 #include <TCollection_AsciiString.hxx>
56 #include <TCollection_ExtendedString.hxx>
58 #include <Standard_Failure.hxx>
59 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
61 #define ARGUMENT_LABEL 1
62 #define RESULT_LABEL 2
63 #define DESCRIPTION_LABEL 3
64 #define HISTORY_LABEL 4
66 #define ARGUMENTS _label.FindChild((ARGUMENT_LABEL))
67 #define ARGUMENT(thePosition) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePosition))
68 #define SUB_ARGUMENT(thePos1, thePos2) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePos1)).FindChild((thePos2))
70 //=======================================================================
71 //function : GetFunctionTreeID
73 //=======================================================================
74 const Standard_GUID& GEOM_Function::GetFunctionTreeID()
76 static Standard_GUID aFunctionTreeID("FF1BBB00-5D14-4df2-980B-3A668264EA16");
77 return aFunctionTreeID;
81 //=======================================================================
82 //function : GetDependencyID
84 //=======================================================================
85 const Standard_GUID& GEOM_Function::GetDependencyID()
87 static Standard_GUID aDependencyID("E2620650-2354-41bd-8C2C-210CFCD00948");
91 //=============================================================================
95 //=============================================================================
96 Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry)
98 if(!theEntry.IsAttribute(TFunction_Function::GetID())) return NULL;
100 return new GEOM_Function(theEntry);
103 //=============================================================================
107 //=============================================================================
108 GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType)
111 TFunction_Function::Set(theEntry, theGUID);
112 TDataStd_Integer::Set(theEntry, theType);
114 //Add function to a function tree
115 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theEntry.Data());
116 Handle(TDataStd_TreeNode) aRoot, aNode;
117 if(!aDoc->Main().FindAttribute(GetFunctionTreeID(), aRoot))
118 aRoot = TDataStd_TreeNode::Set(aDoc->Main(), GetFunctionTreeID());
120 aNode = TDataStd_TreeNode::Set(theEntry, GetFunctionTreeID());
121 aRoot->Append(aNode);
124 //=============================================================================
128 //=============================================================================
129 TDF_Label GEOM_Function::GetOwnerEntry()
131 TDF_Label aFather = _label.Father();
132 while(!aFather.IsRoot()) {
133 if(aFather.IsAttribute(GEOM_Object::GetObjectID())) return aFather;
134 aFather = aFather.Father();
140 //=============================================================================
144 //=============================================================================
145 int GEOM_Function::GetType()
148 Handle(TDataStd_Integer) aType;
149 if(!_label.FindAttribute(TDataStd_Integer::GetID(), aType)) return 0;
154 //=============================================================================
158 //=============================================================================
159 TopoDS_Shape GEOM_Function::GetValue()
164 TDF_Label aLabel = GetOwnerEntry();
165 if (aLabel.IsRoot()) return aShape;
166 Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
167 if (anObject.IsNull()) return aShape;
169 if (!anObject->IsMainShape()) {
170 bool isResult = false;
171 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
172 if (!aResultLabel.IsNull()) {
173 Handle(TNaming_NamedShape) aNS;
174 if (aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS))
181 Standard_Integer aTic = anObject->GetTic();
184 GEOM_ISubShape aCI (this);
185 TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
186 if (aLabelObjMainSh.IsRoot()) return aShape;
187 Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
188 if (anObjMainSh.IsNull()) return aShape;
189 Standard_Integer aTicMainSh = anObjMainSh->GetTic();
192 isResult = ((aTic == aTicMainSh) ? true : false);
197 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
200 GEOM_Solver aSolver(GEOM_Engine::GetEngine());
201 if (!aSolver.ComputeFunction(this)) {
202 MESSAGE("GEOM_Object::GetValue Error : Can't build a sub shape");
206 catch (Standard_Failure) {
207 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
208 MESSAGE("GEOM_Function::GetValue Error: " << aFail->GetMessageString());
214 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
215 Handle(TNaming_NamedShape) aNS;
216 if (!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
224 //=============================================================================
228 //=============================================================================
229 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
232 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
233 TNaming_Builder aBuilder(aResultLabel);
235 aBuilder.Generated(theShape);
237 // synchronisation between main shape and its sub-shapes
238 TDF_Label aLabel = GetOwnerEntry();
239 if (aLabel.IsRoot()) return;
240 Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
241 if (anObject.IsNull()) return;
242 if (anObject->IsMainShape()) {
243 // increase modifications counter of this (main) shape
244 anObject->IncrementTic();
247 // update modifications counter of this (sub-) shape to be the same as on main shape
248 GEOM_ISubShape aCI (this);
249 TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
250 if (aLabelObjMainSh.IsRoot()) return;
251 Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
252 if (anObjMainSh.IsNull()) return;
254 anObject->SetTic(anObjMainSh->GetTic());
260 //=============================================================================
264 //=============================================================================
265 Standard_GUID GEOM_Function::GetDriverGUID()
267 Handle(TFunction_Function) aFunction;
268 if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
269 return TDF::LowestID();
272 return aFunction->GetDriverGUID();
275 //=============================================================================
279 //=============================================================================
280 TCollection_AsciiString GEOM_Function::GetDescription()
282 Handle(TDataStd_Comment) aComment;
283 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
284 if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
285 TCollection_AsciiString aDescr(aComment->Get());
289 //=============================================================================
293 //=============================================================================
294 void GEOM_Function::SetDescription(const TCollection_AsciiString& theDescription)
296 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
297 Handle(TDataStd_Comment) aComment =
298 TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
301 //=============================================================================
305 //=============================================================================
306 void GEOM_Function::SetReal(int thePosition, double theValue)
309 if(thePosition <= 0) return;
310 TDF_Label anArgLabel = ARGUMENT(thePosition);
311 TDataStd_Real::Set(anArgLabel, theValue);
315 //=============================================================================
319 //=============================================================================
320 void GEOM_Function::SetRealArray (int thePosition,
321 const Handle(TColStd_HArray1OfReal)& theArray)
324 if(thePosition <= 0) return;
325 TDF_Label anArgLabel = ARGUMENT(thePosition);
326 Handle(TDataStd_RealArray) anAttr =
327 TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
328 anAttr->ChangeArray(theArray);
332 //=============================================================================
336 //=============================================================================
337 double GEOM_Function::GetReal(int thePosition)
340 if(thePosition <= 0) return 0.0;
341 Handle(TDataStd_Real) aReal;
342 TDF_Label anArgLabel = ARGUMENT(thePosition);
343 if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
349 //=============================================================================
353 //=============================================================================
354 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
357 if(thePosition <= 0) return NULL;
358 Handle(TDataStd_RealArray) aRealArray;
359 TDF_Label anArgLabel = ARGUMENT(thePosition);
360 if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
363 return aRealArray->Array();
366 //=============================================================================
370 //=============================================================================
371 void GEOM_Function::SetInteger(int thePosition, int theValue)
374 if(thePosition <= 0) return;
375 TDF_Label anArgLabel = ARGUMENT(thePosition);
376 TDataStd_Integer::Set(anArgLabel, theValue);
380 //=============================================================================
384 //=============================================================================
385 void GEOM_Function::SetIntegerArray (int thePosition,
386 const Handle(TColStd_HArray1OfInteger)& theArray)
389 if(thePosition <= 0) return;
390 TDF_Label anArgLabel = ARGUMENT(thePosition);
391 Handle(TDataStd_IntegerArray) anAttr =
392 TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
393 anAttr->ChangeArray(theArray);
397 //=============================================================================
401 //=============================================================================
402 int GEOM_Function::GetInteger(int thePosition)
405 if(thePosition <= 0) return 0;
406 Handle(TDataStd_Integer) anInteger;
407 TDF_Label anArgLabel = ARGUMENT(thePosition);
408 if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
411 return anInteger->Get();
414 //=============================================================================
418 //=============================================================================
419 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
422 if(thePosition <= 0) return 0;
423 Handle(TDataStd_IntegerArray) anIntegerArray;
424 TDF_Label anArgLabel = ARGUMENT(thePosition);
425 if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
428 return anIntegerArray->Array();
431 //=============================================================================
435 //=============================================================================
436 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
439 if(thePosition <= 0) return;
440 TDF_Label anArgLabel = ARGUMENT(thePosition);
441 TDataStd_Comment::Set(anArgLabel, theValue);
445 //=============================================================================
449 //=============================================================================
450 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
453 TCollection_AsciiString aRes;
454 if(thePosition <= 0) return aRes;
455 Handle(TDataStd_Comment) aString;
456 TDF_Label anArgLabel = ARGUMENT(thePosition);
457 if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
460 aRes = TCollection_AsciiString(aString->Get());
464 //=============================================================================
468 //=============================================================================
469 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
472 if(thePosition <= 0) return;
473 if(theReference.IsNull()) return;
474 TDF_Label anArgLabel = ARGUMENT(thePosition);
475 TDF_Reference::Set(anArgLabel, theReference->GetEntry());
476 TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
481 //=============================================================================
485 //=============================================================================
486 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition)
489 if(thePosition <= 0) return NULL;
490 TDF_Label anArgLabel = ARGUMENT(thePosition);
491 Handle(TDF_Reference) aRef;
492 if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
495 return GetFunction(aRef->Get());
499 //=============================================================================
503 //=============================================================================
504 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
507 if(thePosition <= 0 || theArray.IsNull()) return;
508 TDF_Label anArgLabel = ARGUMENT(thePosition);
510 Handle(TDataStd_ExtStringArray) anArray = new TDataStd_ExtStringArray;
511 anArray->ChangeArray(theArray);
512 anArgLabel.AddAttribute(anArray);
518 //=============================================================================
522 //=============================================================================
523 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
526 if(thePosition <= 0) return NULL;
527 TDF_Label anArgLabel = ARGUMENT(thePosition);
528 Handle(TDataStd_ExtStringArray) anArray;
529 if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
532 return anArray->Array();
535 //=======================================================================
536 //function : GetReferencesTreeID
538 //=======================================================================
539 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
541 static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
542 return aReferencesTreeID;
545 //=============================================================================
549 //=============================================================================
550 void GEOM_Function::SetReferenceList (int thePosition,
551 const Handle(TColStd_HSequenceOfTransient)& theRefList)
554 if(thePosition <= 0) return;
556 // parent label for the list of references
557 TDF_Label anArgLabel = ARGUMENT(thePosition);
558 anArgLabel.ForgetAllAttributes();
560 // set TreeNode on the parent label
561 Handle(TDataStd_TreeNode) aRoot, aNode;
562 aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
564 // store references on sub-labels of the parent label
565 Handle(GEOM_Function) aFunc;
566 Standard_Integer ind, len = theRefList->Length();
567 for (ind = 1; ind <= len; ind++) {
568 aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
569 if (aFunc.IsNull()) continue;
570 TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
571 TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
572 TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
574 // set TreeNode on the child label
575 aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
576 aRoot->Append(aNode);
583 //=============================================================================
587 //=============================================================================
588 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition)
590 Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
592 if(thePosition <= 0) return aResult;
594 // parent label for the list of references
595 TDF_Label anArgLabel = ARGUMENT(thePosition);
596 Handle(TDF_Reference) aRef;
598 // get TreeNode on the parent label
599 Handle(TDataStd_TreeNode) aRoot, aNode;
600 if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
603 // get references, stored on sub-labels of the parent label
605 TDataStd_ChildNodeIterator anIter (aRoot);
606 for (; anIter.More(); anIter.Next()) {
607 aNode = anIter.Value();
608 aLabel_i = aNode->Label();
609 if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
610 Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
611 if (aFunc_i.IsNull()) continue;
612 aResult->Append(aFunc_i);
619 //=============================================================================
623 //=============================================================================
624 //void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
627 // if(thePosition <= 0 || theShape.IsNull()) return;
629 // TDF_Label anArgLabel = ARGUMENT(thePosition);
630 // TNaming_Builder aBuilder(anArgLabel);
631 // aBuilder.Generated(theShape);
637 //=============================================================================
641 //=============================================================================
642 //TopoDS_Shape GEOM_Function::GetShape(int thePosition)
645 // TopoDS_Shape aShape;
646 // if(thePosition <= 0) return aShape;
648 // TDF_Label anArgLabel = ARGUMENT(thePosition);
649 // Handle(TNaming_NamedShape) aNS;
650 // if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
652 // aShape = aNS->Get();
658 //=============================================================================
662 //=============================================================================
663 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
665 TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
666 for(; anIterator.More(); anIterator.Next()) {
667 if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
671 //=============================================================================
675 //=============================================================================
676 TDF_Label GEOM_Function::GetHistoryEntry (const Standard_Boolean create)
678 return _label.FindChild(HISTORY_LABEL, create);
681 //=============================================================================
683 * GetArgumentHistoryEntry
685 //=============================================================================
686 TDF_Label GEOM_Function::GetArgumentHistoryEntry (const TDF_Label& theArgumentRefEntry,
687 const Standard_Boolean create)
689 TColStd_ListOfInteger anArgumentRefTags;
690 TDF_Tool::TagList(theArgumentRefEntry, anArgumentRefTags);
691 Standard_Integer anArgumentRefLabelPos = anArgumentRefTags.Extent();
693 TDF_Label aHistoryLabel = GetHistoryEntry(create);
694 if (aHistoryLabel.IsNull())
695 return aHistoryLabel;
696 Standard_Integer aHistoryLabelPos = aHistoryLabel.Depth() + 1;
698 Standard_Integer itag;
699 TDF_Label aHistoryCurLabel = aHistoryLabel;
700 TColStd_ListIteratorOfListOfInteger aListIter (anArgumentRefTags);
701 for (itag = 1; itag <= aHistoryLabelPos; itag++) {
704 for (; itag <= anArgumentRefLabelPos; itag++) {
705 aHistoryCurLabel = aHistoryCurLabel.FindChild(aListIter.Value(), create);
706 if (aHistoryCurLabel.IsNull())
707 return aHistoryCurLabel;
711 return aHistoryCurLabel;
714 //=======================================================================
715 //function : GEOM_Function_Type_
717 //=======================================================================
718 Standard_EXPORT Handle_Standard_Type& GEOM_Function_Type_()
721 static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
722 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared);
723 static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
724 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
727 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
728 static Handle_Standard_Type _aType = new Standard_Type("GEOM_Function",
729 sizeof(GEOM_Function),
731 (Standard_Address)_Ancestors,
732 (Standard_Address)NULL);
737 //=======================================================================
738 //function : DownCast
740 //=======================================================================
742 const Handle(GEOM_Function) Handle(GEOM_Function)::DownCast(const Handle(Standard_Transient)& AnObject)
744 Handle(GEOM_Function) _anOtherObject;
746 if (!AnObject.IsNull()) {
747 if (AnObject->IsKind(STANDARD_TYPE(GEOM_Function))) {
748 _anOtherObject = Handle(GEOM_Function)((Handle(GEOM_Function)&)AnObject);
752 return _anOtherObject ;