1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include <Standard_Stream.hxx>
24 #include <GEOM_Function.hxx>
25 #include <GEOM_Object.hxx>
26 #include <GEOM_Solver.hxx>
27 #include <GEOM_ISubShape.hxx>
29 #include "utilities.h"
32 #include <TDF_Tool.hxx>
33 #include <TDF_Data.hxx>
34 #include <TDF_ChildIterator.hxx>
35 #include <TDF_Reference.hxx>
36 #include <TDataStd_Integer.hxx>
37 #include <TDataStd_IntegerArray.hxx>
38 #include <TDataStd_Real.hxx>
39 #include <TDataStd_RealArray.hxx>
40 #include <TDataStd_Comment.hxx>
41 #include <TDataStd_TreeNode.hxx>
42 #include <TDataStd_UAttribute.hxx>
43 #include <TDataStd_ChildNodeIterator.hxx>
44 #include <TDataStd_ExtStringArray.hxx>
45 #include <TDocStd_Owner.hxx>
46 #include <TDocStd_Document.hxx>
47 #include <TFunction_Function.hxx>
48 #include <TNaming_NamedShape.hxx>
49 #include <TNaming_Builder.hxx>
51 #include <TColStd_ListOfInteger.hxx>
52 #include <TColStd_ListIteratorOfListOfInteger.hxx>
53 #include <TColStd_HArray1OfReal.hxx>
54 #include <TColStd_HArray1OfInteger.hxx>
55 #include <TColStd_HSequenceOfTransient.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #include <TCollection_ExtendedString.hxx>
59 #include <Standard_Failure.hxx>
60 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
62 #define ARGUMENT_LABEL 1
63 #define RESULT_LABEL 2
64 #define DESCRIPTION_LABEL 3
65 #define HISTORY_LABEL 4
67 #define ARGUMENTS _label.FindChild((ARGUMENT_LABEL))
68 #define ARGUMENT(thePosition) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePosition))
69 #define SUB_ARGUMENT(thePos1, thePos2) _label.FindChild((ARGUMENT_LABEL)).FindChild((thePos1)).FindChild((thePos2))
71 //=======================================================================
72 //function : GetFunctionTreeID
74 //=======================================================================
75 const Standard_GUID& GEOM_Function::GetFunctionTreeID()
77 static Standard_GUID aFunctionTreeID("FF1BBB00-5D14-4df2-980B-3A668264EA16");
78 return aFunctionTreeID;
82 //=======================================================================
83 //function : GetDependencyID
85 //=======================================================================
86 const Standard_GUID& GEOM_Function::GetDependencyID()
88 static Standard_GUID aDependencyID("E2620650-2354-41bd-8C2C-210CFCD00948");
92 //=============================================================================
96 //=============================================================================
97 Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry)
99 if(!theEntry.IsAttribute(TFunction_Function::GetID())) return NULL;
101 return new GEOM_Function(theEntry);
104 //=============================================================================
108 //=============================================================================
109 GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType)
112 TFunction_Function::Set(theEntry, theGUID);
113 TDataStd_Integer::Set(theEntry, theType);
115 //Add function to a function tree
116 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theEntry.Data());
117 Handle(TDataStd_TreeNode) aRoot, aNode;
118 if(!aDoc->Main().FindAttribute(GetFunctionTreeID(), aRoot))
119 aRoot = TDataStd_TreeNode::Set(aDoc->Main(), GetFunctionTreeID());
121 aNode = TDataStd_TreeNode::Set(theEntry, GetFunctionTreeID());
122 aRoot->Append(aNode);
125 //=============================================================================
129 //=============================================================================
130 TDF_Label GEOM_Function::GetOwnerEntry()
132 TDF_Label aFather = _label.Father();
133 while(!aFather.IsRoot()) {
134 if(aFather.IsAttribute(GEOM_Object::GetObjectID())) return aFather;
135 aFather = aFather.Father();
141 //=============================================================================
145 //=============================================================================
146 int GEOM_Function::GetType()
149 Handle(TDataStd_Integer) aType;
150 if(!_label.FindAttribute(TDataStd_Integer::GetID(), aType)) return 0;
155 //=============================================================================
159 //=============================================================================
160 TopoDS_Shape GEOM_Function::GetValue()
165 TDF_Label aLabel = GetOwnerEntry();
166 if (aLabel.IsRoot()) return aShape;
167 Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
168 if (anObject.IsNull()) return aShape;
170 if (!anObject->IsMainShape()) {
171 bool isResult = false;
172 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
173 if (!aResultLabel.IsNull()) {
174 Handle(TNaming_NamedShape) aNS;
175 if (aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS))
182 Standard_Integer aTic = anObject->GetTic();
185 GEOM_ISubShape aCI (this);
186 TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
187 if (aLabelObjMainSh.IsRoot()) return aShape;
188 Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
189 if (anObjMainSh.IsNull()) return aShape;
190 Standard_Integer aTicMainSh = anObjMainSh->GetTic();
193 isResult = ((aTic == aTicMainSh) ? true : false);
198 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
201 GEOM_Solver aSolver(GEOM_Engine::GetEngine());
202 if (!aSolver.ComputeFunction(this)) {
203 MESSAGE("GEOM_Object::GetValue Error : Can't build a sub shape");
207 catch (Standard_Failure) {
208 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
209 MESSAGE("GEOM_Function::GetValue Error: " << aFail->GetMessageString());
215 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
216 Handle(TNaming_NamedShape) aNS;
217 if (!aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
225 //=============================================================================
229 //=============================================================================
230 void GEOM_Function::SetValue(TopoDS_Shape& theShape)
233 TDF_Label aResultLabel = _label.FindChild(RESULT_LABEL);
234 TNaming_Builder aBuilder(aResultLabel);
236 aBuilder.Generated(theShape);
238 // synchronisation between main shape and its sub-shapes
239 TDF_Label aLabel = GetOwnerEntry();
240 if (aLabel.IsRoot()) return;
241 Handle(GEOM_Object) anObject = GEOM_Object::GetObject(aLabel);
242 if (anObject.IsNull()) return;
243 if (anObject->IsMainShape()) {
244 // increase modifications counter of this (main) shape
245 anObject->IncrementTic();
248 // update modifications counter of this (sub-) shape to be the same as on main shape
249 GEOM_ISubShape aCI (this);
250 TDF_Label aLabelObjMainSh = aCI.GetMainShape()->GetOwnerEntry();
251 if (aLabelObjMainSh.IsRoot()) return;
252 Handle(GEOM_Object) anObjMainSh = GEOM_Object::GetObject(aLabelObjMainSh);
253 if (anObjMainSh.IsNull()) return;
255 anObject->SetTic(anObjMainSh->GetTic());
261 //=============================================================================
265 //=============================================================================
266 Standard_GUID GEOM_Function::GetDriverGUID()
268 Handle(TFunction_Function) aFunction;
269 if(!_label.FindAttribute(TFunction_Function::GetID(), aFunction)) {
270 return TDF::LowestID();
273 return aFunction->GetDriverGUID();
276 //=============================================================================
280 //=============================================================================
281 TCollection_AsciiString GEOM_Function::GetDescription()
283 Handle(TDataStd_Comment) aComment;
284 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
285 if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return TCollection_AsciiString();
286 TCollection_AsciiString aDescr(aComment->Get());
290 //=============================================================================
294 //=============================================================================
295 void GEOM_Function::SetDescription(const TCollection_AsciiString& theDescription)
297 TDF_Label aChild = _label.FindChild(DESCRIPTION_LABEL);
298 Handle(TDataStd_Comment) aComment =
299 TDataStd_Comment::Set(aChild, TCollection_ExtendedString(theDescription));
302 //=============================================================================
306 //=============================================================================
307 void GEOM_Function::SetReal(int thePosition, double theValue)
310 if(thePosition <= 0) return;
311 TDF_Label anArgLabel = ARGUMENT(thePosition);
312 TDataStd_Real::Set(anArgLabel, theValue);
316 //=============================================================================
320 //=============================================================================
321 void GEOM_Function::SetRealArray (int thePosition,
322 const Handle(TColStd_HArray1OfReal)& theArray)
325 if(thePosition <= 0) return;
326 TDF_Label anArgLabel = ARGUMENT(thePosition);
327 Handle(TDataStd_RealArray) anAttr =
328 TDataStd_RealArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
329 anAttr->ChangeArray(theArray);
333 //=============================================================================
337 //=============================================================================
338 double GEOM_Function::GetReal(int thePosition)
341 if(thePosition <= 0) return 0.0;
342 Handle(TDataStd_Real) aReal;
343 TDF_Label anArgLabel = ARGUMENT(thePosition);
344 if(!anArgLabel.FindAttribute(TDataStd_Real::GetID(), aReal)) return 0.0;
350 //=============================================================================
354 //=============================================================================
355 Handle(TColStd_HArray1OfReal) GEOM_Function::GetRealArray(int thePosition)
358 if(thePosition <= 0) return NULL;
359 Handle(TDataStd_RealArray) aRealArray;
360 TDF_Label anArgLabel = ARGUMENT(thePosition);
361 if(!anArgLabel.FindAttribute(TDataStd_RealArray::GetID(), aRealArray)) return NULL;
364 return aRealArray->Array();
367 //=============================================================================
371 //=============================================================================
372 void GEOM_Function::SetInteger(int thePosition, int theValue)
375 if(thePosition <= 0) return;
376 TDF_Label anArgLabel = ARGUMENT(thePosition);
377 TDataStd_Integer::Set(anArgLabel, theValue);
381 //=============================================================================
385 //=============================================================================
386 void GEOM_Function::SetIntegerArray (int thePosition,
387 const Handle(TColStd_HArray1OfInteger)& theArray)
390 if(thePosition <= 0) return;
391 TDF_Label anArgLabel = ARGUMENT(thePosition);
392 Handle(TDataStd_IntegerArray) anAttr =
393 TDataStd_IntegerArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
394 anAttr->ChangeArray(theArray);
398 //=============================================================================
402 //=============================================================================
403 int GEOM_Function::GetInteger(int thePosition)
406 if(thePosition <= 0) return 0;
407 Handle(TDataStd_Integer) anInteger;
408 TDF_Label anArgLabel = ARGUMENT(thePosition);
409 if(!anArgLabel.FindAttribute(TDataStd_Integer::GetID(), anInteger)) return 0;
412 return anInteger->Get();
415 //=============================================================================
419 //=============================================================================
420 Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
423 if(thePosition <= 0) return 0;
424 Handle(TDataStd_IntegerArray) anIntegerArray;
425 TDF_Label anArgLabel = ARGUMENT(thePosition);
426 if(!anArgLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) return 0;
429 return anIntegerArray->Array();
432 //=============================================================================
436 //=============================================================================
437 void GEOM_Function::SetString(int thePosition, const TCollection_AsciiString& theValue)
440 if(thePosition <= 0) return;
441 TDF_Label anArgLabel = ARGUMENT(thePosition);
442 TDataStd_Comment::Set(anArgLabel, theValue);
446 //=============================================================================
450 //=============================================================================
451 TCollection_AsciiString GEOM_Function::GetString(int thePosition)
454 TCollection_AsciiString aRes;
455 if(thePosition <= 0) return aRes;
456 Handle(TDataStd_Comment) aString;
457 TDF_Label anArgLabel = ARGUMENT(thePosition);
458 if(!anArgLabel.FindAttribute(TDataStd_Comment::GetID(), aString)) return aRes;
461 aRes = TCollection_AsciiString(aString->Get());
465 //=============================================================================
469 //=============================================================================
470 void GEOM_Function::SetReference(int thePosition, Handle(GEOM_Function) theReference)
473 if(thePosition <= 0) return;
474 if(theReference.IsNull()) return;
475 TDF_Label anArgLabel = ARGUMENT(thePosition);
476 TDF_Reference::Set(anArgLabel, theReference->GetEntry());
477 TDataStd_UAttribute::Set(anArgLabel, GetDependencyID());
482 //=============================================================================
486 //=============================================================================
487 Handle(GEOM_Function) GEOM_Function::GetReference(int thePosition)
490 if(thePosition <= 0) return NULL;
491 TDF_Label anArgLabel = ARGUMENT(thePosition);
492 Handle(TDF_Reference) aRef;
493 if(!anArgLabel.FindAttribute(TDF_Reference::GetID(), aRef)) return NULL;
496 return GetFunction(aRef->Get());
500 //=============================================================================
504 //=============================================================================
505 void GEOM_Function::SetStringArray(int thePosition, const Handle(TColStd_HArray1OfExtendedString)& theArray)
508 if(thePosition <= 0 || theArray.IsNull()) return;
509 TDF_Label anArgLabel = ARGUMENT(thePosition);
511 Handle(TDataStd_ExtStringArray) anArray = new TDataStd_ExtStringArray;
512 anArray->ChangeArray(theArray);
513 anArgLabel.AddAttribute(anArray);
519 //=============================================================================
523 //=============================================================================
524 Handle(TColStd_HArray1OfExtendedString) GEOM_Function::GetStringArray(int thePosition)
527 if(thePosition <= 0) return NULL;
528 TDF_Label anArgLabel = ARGUMENT(thePosition);
529 Handle(TDataStd_ExtStringArray) anArray;
530 if(!anArgLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArray)) return NULL;
533 return anArray->Array();
536 //=======================================================================
537 //function : GetReferencesTreeID
539 //=======================================================================
540 const Standard_GUID& GEOM_Function::GetReferencesTreeID()
542 static Standard_GUID aReferencesTreeID("FF1BBB10-5D14-4df2-980B-3A668264EA16");
543 return aReferencesTreeID;
546 //=============================================================================
550 //=============================================================================
551 void GEOM_Function::SetReferenceList (int thePosition,
552 const Handle(TColStd_HSequenceOfTransient)& theRefList)
555 if(thePosition <= 0) return;
557 // parent label for the list of references
558 TDF_Label anArgLabel = ARGUMENT(thePosition);
559 anArgLabel.ForgetAllAttributes();
561 // set TreeNode on the parent label
562 Handle(TDataStd_TreeNode) aRoot, aNode;
563 aRoot = TDataStd_TreeNode::Set(anArgLabel, GetReferencesTreeID());
565 // store references on sub-labels of the parent label
566 Handle(GEOM_Function) aFunc;
567 Standard_Integer ind, len = theRefList->Length();
568 for (ind = 1; ind <= len; ind++) {
569 aFunc = Handle(GEOM_Function)::DownCast(theRefList->Value(ind));
570 if (aFunc.IsNull()) continue;
571 TDF_Label anArgLabel_i = SUB_ARGUMENT(thePosition, ind);
572 TDF_Reference::Set(anArgLabel_i, aFunc->GetEntry());
573 TDataStd_UAttribute::Set(anArgLabel_i, GetDependencyID());
575 // set TreeNode on the child label
576 aNode = TDataStd_TreeNode::Set(anArgLabel_i, GetReferencesTreeID());
577 aRoot->Append(aNode);
584 //=============================================================================
588 //=============================================================================
589 Handle(TColStd_HSequenceOfTransient) GEOM_Function::GetReferenceList(int thePosition)
591 Handle(TColStd_HSequenceOfTransient) aResult = new TColStd_HSequenceOfTransient;
593 if(thePosition <= 0) return aResult;
595 // parent label for the list of references
596 TDF_Label anArgLabel = ARGUMENT(thePosition);
597 Handle(TDF_Reference) aRef;
599 // get TreeNode on the parent label
600 Handle(TDataStd_TreeNode) aRoot, aNode;
601 if(!anArgLabel.FindAttribute(GetReferencesTreeID(), aRoot))
604 // get references, stored on sub-labels of the parent label
606 TDataStd_ChildNodeIterator anIter (aRoot);
607 for (; anIter.More(); anIter.Next()) {
608 aNode = anIter.Value();
609 aLabel_i = aNode->Label();
610 if (!aLabel_i.FindAttribute(TDF_Reference::GetID(), aRef)) continue;
611 Handle(GEOM_Function) aFunc_i = GetFunction(aRef->Get());
612 if (aFunc_i.IsNull()) continue;
613 aResult->Append(aFunc_i);
620 //=============================================================================
624 //=============================================================================
625 //void GEOM_Function::SetShape(int thePosition, const TopoDS_Shape& theShape)
628 // if(thePosition <= 0 || theShape.IsNull()) return;
630 // TDF_Label anArgLabel = ARGUMENT(thePosition);
631 // TNaming_Builder aBuilder(anArgLabel);
632 // aBuilder.Generated(theShape);
638 //=============================================================================
642 //=============================================================================
643 //TopoDS_Shape GEOM_Function::GetShape(int thePosition)
646 // TopoDS_Shape aShape;
647 // if(thePosition <= 0) return aShape;
649 // TDF_Label anArgLabel = ARGUMENT(thePosition);
650 // Handle(TNaming_NamedShape) aNS;
651 // if(!anArgLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) return aShape;
653 // aShape = aNS->Get();
659 //=============================================================================
663 //=============================================================================
664 void GEOM_Function::GetDependency(TDF_LabelSequence& theSeq)
666 TDF_ChildIterator anIterator(ARGUMENTS, Standard_True);
667 for(; anIterator.More(); anIterator.Next()) {
668 if(anIterator.Value().IsAttribute(GetDependencyID())) theSeq.Append(anIterator.Value());
672 //=============================================================================
676 //=============================================================================
677 TDF_Label GEOM_Function::GetHistoryEntry (const Standard_Boolean create)
679 return _label.FindChild(HISTORY_LABEL, create);
682 //=============================================================================
684 * GetArgumentHistoryEntry
686 //=============================================================================
687 TDF_Label GEOM_Function::GetArgumentHistoryEntry (const TDF_Label& theArgumentRefEntry,
688 const Standard_Boolean create)
690 TColStd_ListOfInteger anArgumentRefTags;
691 TDF_Tool::TagList(theArgumentRefEntry, anArgumentRefTags);
692 Standard_Integer anArgumentRefLabelPos = anArgumentRefTags.Extent();
694 TDF_Label aHistoryLabel = GetHistoryEntry(create);
695 if (aHistoryLabel.IsNull())
696 return aHistoryLabel;
697 Standard_Integer aHistoryLabelPos = aHistoryLabel.Depth() + 1;
699 Standard_Integer itag;
700 TDF_Label aHistoryCurLabel = aHistoryLabel;
701 TColStd_ListIteratorOfListOfInteger aListIter (anArgumentRefTags);
702 for (itag = 1; itag <= aHistoryLabelPos; itag++) {
705 for (; itag <= anArgumentRefLabelPos; itag++) {
706 aHistoryCurLabel = aHistoryCurLabel.FindChild(aListIter.Value(), create);
707 if (aHistoryCurLabel.IsNull())
708 return aHistoryCurLabel;
712 return aHistoryCurLabel;
715 //=======================================================================
716 //function : GEOM_Function_Type_
718 //=======================================================================
719 Standard_EXPORT Handle_Standard_Type& GEOM_Function_Type_()
722 static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
723 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared);
724 static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
725 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
728 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
729 static Handle_Standard_Type _aType = new Standard_Type("GEOM_Function",
730 sizeof(GEOM_Function),
732 (Standard_Address)_Ancestors,
733 (Standard_Address)NULL);
738 //=======================================================================
739 //function : DownCast
741 //=======================================================================
743 const Handle(GEOM_Function) Handle(GEOM_Function)::DownCast(const Handle(Standard_Transient)& AnObject)
745 Handle(GEOM_Function) _anOtherObject;
747 if (!AnObject.IsNull()) {
748 if (AnObject->IsKind(STANDARD_TYPE(GEOM_Function))) {
749 _anOtherObject = Handle(GEOM_Function)((Handle(GEOM_Function)&)AnObject);
753 return _anOtherObject ;