1 // Copyright (C) 2007-2013 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
23 #include "GEOM_Object.hxx"
24 #include "GEOM_Engine.hxx"
25 #include "GEOM_Solver.hxx"
27 #include <Standard_Stream.hxx>
28 #include <TColStd_HArray1OfReal.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <TCollection_ExtendedString.hxx>
31 #include <TDF_Data.hxx>
32 #include <TDF_LabelSequence.hxx>
33 #include <TDF_Reference.hxx>
34 #include <TDF_Tool.hxx>
35 #include <TDataStd_ByteArray.hxx>
36 #include <TDataStd_ChildNodeIterator.hxx>
37 #include <TDataStd_Comment.hxx>
38 #include <TDataStd_Integer.hxx>
39 #include <TDataStd_Name.hxx>
40 #include <TDataStd_Real.hxx>
41 #include <TDataStd_RealArray.hxx>
42 #include <TDataStd_UAttribute.hxx>
43 #include <TDocStd_Document.hxx>
44 #include <TDocStd_Owner.hxx>
45 #include <TFunction_Driver.hxx>
46 #include <TFunction_DriverTable.hxx>
48 #include <TopTools_IndexedMapOfShape.hxx>
50 #include "utilities.h"
53 #define FUNCTION_LABEL(theNb) (_label.FindChild(1).FindChild((theNb)))
58 #define AUTO_COLOR_LABEL 6
59 #define MARKER_LABEL 7
61 #define MARKER_LABEL_TYPE 1
62 #define MARKER_LABEL_SIZE 2
63 #define MARKER_LABEL_ID 3
65 //=======================================================================
66 //function : GetObjectID
68 //=======================================================================
69 const Standard_GUID& GEOM_Object::GetObjectID()
71 static Standard_GUID anObjectID("FF1BBB01-5D14-4df2-980B-3A668264EA16");
75 //=======================================================================
76 //function : GetSubShapeID
78 //=======================================================================
79 const Standard_GUID& GEOM_Object::GetSubShapeID()
81 static Standard_GUID anObjectID("FF1BBB68-5D14-4df2-980B-3A668264EA16");
85 //=============================================================================
89 //=============================================================================
90 Handle(GEOM_Object) GEOM_Object::GetObject(TDF_Label& theLabel)
92 if (!theLabel.IsAttribute(GetObjectID())) return NULL;
94 TCollection_AsciiString anEntry;
95 TDF_Tool::Entry(theLabel, anEntry);
97 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theLabel.Data());
98 if(aDoc.IsNull()) return NULL;
100 Handle(TDataStd_Integer) anID;
101 if(!aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) return NULL;
104 GEOM_Engine* anEngine= GEOM_Engine::GetEngine();
105 if(anEngine == NULL) return NULL;
106 return anEngine->GetObject(anID->Get(), (char*) anEntry.ToCString());
111 //=============================================================================
113 * GetReferencedObject
115 //=============================================================================
116 Handle(GEOM_Object) GEOM_Object::GetReferencedObject(TDF_Label& theLabel)
118 Handle(TDF_Reference) aRef;
119 if (!theLabel.FindAttribute(TDF_Reference::GetID(), aRef)) {
123 if(aRef.IsNull() || aRef->Get().IsNull()) {
128 // Get TreeNode of a referenced function
129 Handle(TDataStd_TreeNode) aT, aFather;
130 if (!TDataStd_TreeNode::Find(aRef->Get(), aT)) {
135 // Get TreeNode of Object of the referenced function
136 aFather = aT->Father();
137 if (aFather.IsNull()) {
141 // Get label of the referenced object
142 TDF_Label aLabel = aFather->Label();
145 return GEOM_Object::GetObject(aLabel);
148 //=============================================================================
150 * Constructor: private
152 //=============================================================================
153 GEOM_Object::GEOM_Object(TDF_Label& theEntry)
154 : _label(theEntry), _ior(""), _docID(-1)
156 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(_label.Data());
158 Handle(TDataStd_Integer) anID;
159 if(aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) _docID = anID->Get();
162 if(!theEntry.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), _root))
163 _root = TDataStd_TreeNode::Set(theEntry);
166 //=============================================================================
168 * Constructor: public
170 //=============================================================================
171 GEOM_Object::GEOM_Object(TDF_Label& theEntry, int theType)
172 : _label(theEntry), _ior(""), _docID(-1)
174 Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(_label.Data());
176 Handle(TDataStd_Integer) anID;
177 if(aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) _docID = anID->Get();
180 theEntry.ForgetAllAttributes(Standard_True);
182 if(!theEntry.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), _root))
183 _root = TDataStd_TreeNode::Set(theEntry);
185 TDataStd_Integer::Set(theEntry.FindChild(TYPE_LABEL), theType);
187 TDataStd_UAttribute::Set(theEntry, GetObjectID());
190 //=============================================================================
194 //=============================================================================
195 GEOM_Object::~GEOM_Object()
197 MESSAGE("GEOM_Object::~GEOM_Object()");
200 //=============================================================================
204 //=============================================================================
205 int GEOM_Object::GetType()
207 Handle(TDataStd_Integer) aType;
208 if(!_label.FindChild(TYPE_LABEL).FindAttribute(TDataStd_Integer::GetID(), aType)) return -1;
213 //=============================================================================
217 //=============================================================================
218 void GEOM_Object::SetType(int theType)
220 TDataStd_Integer::Set(_label.FindChild(TYPE_LABEL), theType);
224 //=============================================================================
226 * Returns modifications counter of this object.
227 * Comparing this value with modifications counters of argument objects
228 * (on which this object depends) we decide whether this object needs to be updated.
230 //=============================================================================
231 int GEOM_Object::GetTic()
233 Handle(TDataStd_Integer) aTicAttr;
234 if (!_label.FindChild(TIC_LABEL).FindAttribute(TDataStd_Integer::GetID(), aTicAttr))
237 return aTicAttr->Get();
240 //=============================================================================
242 * Set another value of modifications counter.
244 * Use this method to update modifications counter of dependent object
245 * to be equal to modifications counter of its argument.
246 * This is commonly done in GEOM_Function::GetValue()
248 //=============================================================================
249 void GEOM_Object::SetTic(int theTic)
251 TDataStd_Integer::Set(_label.FindChild(TIC_LABEL), theTic);
254 //=============================================================================
256 * Increment modifications counter to mark this object as modified.
258 * Commonly called from GEOM_Function::SetValue()
260 //=============================================================================
261 void GEOM_Object::IncrementTic()
263 TDF_Label aTicLabel = _label.FindChild(TIC_LABEL);
265 Standard_Integer aTic = 0;
266 Handle(TDataStd_Integer) aTicAttr;
267 if (aTicLabel.FindAttribute(TDataStd_Integer::GetID(), aTicAttr))
268 aTic = aTicAttr->Get();
270 TDataStd_Integer::Set(aTicLabel, aTic + 1);
274 //=============================================================================
278 //=============================================================================
279 int GEOM_Object::GetDocID()
285 //=============================================================================
289 //=============================================================================
290 TopoDS_Shape GEOM_Object::GetValue()
294 Handle(GEOM_Function) aFunction = GetLastFunction();
296 if (!aFunction.IsNull())
297 aShape = aFunction->GetValue();
302 //=============================================================================
306 //=============================================================================
307 void GEOM_Object::SetName(const char* theName)
309 TDataStd_Name::Set(_label, (char*)theName);
312 //=============================================================================
316 //=============================================================================
317 char* GEOM_Object::GetName()
319 Handle(TDataStd_Name) aNameAttr;
320 if(!_label.FindAttribute(TDataStd_Name::GetID(), aNameAttr)) return NULL;
322 TCollection_AsciiString aName(aNameAttr->Get());
323 // do not return pointer of local variable
324 // return aName.ToCString();
325 // the following code could lead to memory leak, so take care about recieved pointer
326 return strdup(aName.ToCString());
329 //=============================================================================
333 //=============================================================================
334 void GEOM_Object::SetColor(const GEOM_Object::Color& theColor)
336 Handle(TDataStd_RealArray) anArray = new TDataStd_RealArray();
337 anArray->Init( 1, 3 );
338 anArray->SetValue( 1, theColor.R );
339 anArray->SetValue( 2, theColor.G );
340 anArray->SetValue( 3, theColor.B );
342 Handle(TDataStd_RealArray) anAttr =
343 TDataStd_RealArray::Set(_label.FindChild(COLOR_LABEL), anArray->Lower(), anArray->Upper());
344 anAttr->ChangeArray(anArray->Array());
347 //=============================================================================
351 //=============================================================================
352 GEOM_Object::Color GEOM_Object::GetColor()
354 Handle(TDataStd_RealArray) anArray;
355 bool isFound = _label.FindChild(COLOR_LABEL).FindAttribute(TDataStd_RealArray::GetID(), anArray);
357 GEOM_Object::Color aColor;
358 aColor.R = isFound ? anArray->Value( 1 ) : -1;
359 aColor.G = isFound ? anArray->Value( 2 ) : -1;
360 aColor.B = isFound ? anArray->Value( 3 ) : -1;
365 //=============================================================================
369 //=============================================================================
370 void GEOM_Object::SetAutoColor(bool theAutoColor)
372 TDataStd_Integer::Set(_label.FindChild(AUTO_COLOR_LABEL), (int)theAutoColor);
375 //=============================================================================
379 //=============================================================================
380 bool GEOM_Object::GetAutoColor()
382 Handle(TDataStd_Integer) anAutoColor;
383 if(!_label.FindChild(AUTO_COLOR_LABEL).FindAttribute(TDataStd_Integer::GetID(), anAutoColor)) return false;
385 return bool(anAutoColor->Get());
388 //=============================================================================
392 //=============================================================================
393 void GEOM_Object::SetMarkerStd(const Aspect_TypeOfMarker theType, double theSize)
395 TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL);
396 TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_TYPE), (int)theType);
397 TDataStd_Real::Set(aMarkerLabel.FindChild(MARKER_LABEL_SIZE), theSize);
400 //=============================================================================
404 //=============================================================================
405 void GEOM_Object::SetMarkerTexture(int theTextureId)
407 TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL);
408 TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_TYPE), (int)Aspect_TOM_USERDEFINED);
409 TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_ID), theTextureId);
412 //=============================================================================
416 //=============================================================================
417 Aspect_TypeOfMarker GEOM_Object::GetMarkerType()
419 Standard_Integer aType = -1;
420 TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
421 if(!aMarkerLabel.IsNull()) {
422 TDF_Label aTypeLabel = aMarkerLabel.FindChild(MARKER_LABEL_TYPE, Standard_False);
423 Handle(TDataStd_Integer) aTypeAttr;
424 if (!aTypeLabel.IsNull() && aTypeLabel.FindAttribute(TDataStd_Integer::GetID(), aTypeAttr))
425 aType = aTypeAttr->Get();
427 return (Aspect_TypeOfMarker)aType;
430 //=============================================================================
434 //=============================================================================
435 double GEOM_Object::GetMarkerSize()
437 Standard_Real aSize = 0.;
438 TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
439 if(!aMarkerLabel.IsNull()) {
440 TDF_Label aSizeLabel = aMarkerLabel.FindChild(MARKER_LABEL_SIZE, Standard_False);
441 Handle(TDataStd_Real) aSizeAttr;
442 if (!aSizeLabel.IsNull() && aSizeLabel.FindAttribute(TDataStd_Real::GetID(), aSizeAttr))
443 aSize = aSizeAttr->Get();
448 //=============================================================================
452 //=============================================================================
453 int GEOM_Object::GetMarkerTexture()
455 Standard_Integer anId = 0;
456 if ( GetMarkerType() == Aspect_TOM_USERDEFINED) {
457 TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
458 if(!aMarkerLabel.IsNull()) {
459 TDF_Label aTypeLabel = aMarkerLabel.FindChild(MARKER_LABEL_ID, Standard_False);
460 Handle(TDataStd_Integer) anIdAttr;
461 if (!aTypeLabel.IsNull() && aTypeLabel.FindAttribute(TDataStd_Integer::GetID(), anIdAttr))
462 anId = anIdAttr->Get();
468 //=============================================================================
472 //=============================================================================
473 void GEOM_Object::UnsetMarker()
475 SetMarkerStd((Aspect_TypeOfMarker)-1, 0.);
478 //=============================================================================
482 //=============================================================================
483 void GEOM_Object::SetAuxData(const char* theData)
485 TDataStd_Comment::Set(_label, (char*)theData);
488 //=============================================================================
492 //=============================================================================
493 TCollection_AsciiString GEOM_Object::GetAuxData()
495 TCollection_AsciiString aData;
497 Handle(TDataStd_Comment) aCommentAttr;
498 if (_label.FindAttribute(TDataStd_Comment::GetID(), aCommentAttr))
499 aData = aCommentAttr->Get();
504 //=============================================================================
508 //=============================================================================
509 void GEOM_Object::SetParameters(const TCollection_AsciiString& theParameters)
511 if( _parameters.IsEmpty() )
512 _parameters = theParameters;
515 _parameters += theParameters;
519 //=============================================================================
523 //=============================================================================
524 TCollection_AsciiString GEOM_Object::GetParameters() const
530 //=============================================================================
534 //=============================================================================
535 bool GEOM_Object::IsMainShape()
537 Handle(GEOM_Function) aFunction = GetFunction(1);
538 if(aFunction.IsNull() || aFunction->GetDriverGUID() != GetSubShapeID()) return true; // mkr : IPAL9921
543 //=============================================================================
547 //=============================================================================
548 Handle(GEOM_Function) GEOM_Object::AddFunction(const Standard_GUID& theGUID,
552 Standard_Integer nb = GetNbFunctions();
553 if(!allowSubShape && nb == 1 && theGUID == GetSubShapeID()) return NULL; //It's impossible to add a function to sub-shape
555 TDF_Label aChild = FUNCTION_LABEL(nb);
557 Handle(TDataStd_TreeNode) aNode = TDataStd_TreeNode::Set(aChild);
558 _root->Append(aNode);
560 Handle(GEOM_Function) aFunction = new GEOM_Function(aChild, theGUID, theFunctionType);
566 //=============================================================================
570 //=============================================================================
571 int GEOM_Object::GetNbFunctions()
573 Standard_Integer nb = 0;
574 for(TDataStd_ChildNodeIterator CI(_root); CI.More(); CI.Next()) nb++;
578 //=============================================================================
582 //=============================================================================
583 Handle(GEOM_Function) GEOM_Object::GetFunction(int theFunctionNumber)
585 TDF_Label aChild = FUNCTION_LABEL(theFunctionNumber);
586 return GEOM_Function::GetFunction(aChild);
589 //=============================================================================
593 //=============================================================================
594 Handle(GEOM_Function) GEOM_Object::GetLastFunction()
596 Standard_Integer nb = GetNbFunctions();
597 if(nb) return GetFunction(nb);
603 //=============================================================================
607 //=============================================================================
608 Handle(TColStd_HSequenceOfTransient) GEOM_Object::GetAllDependency()
610 Handle(TColStd_HSequenceOfTransient) anArray;
611 TDF_LabelSequence aSeq;
612 Standard_Integer nb = GetNbFunctions();
613 if(nb == 0) return anArray;
614 for(Standard_Integer i=1; i<=nb; i++) {
615 Handle(GEOM_Function) aFunction = GetFunction(i);
616 if(aFunction.IsNull()) continue;
617 aFunction->GetDependency(aSeq);
620 Standard_Integer aLength = aSeq.Length();
622 anArray = new TColStd_HSequenceOfTransient;
623 for(Standard_Integer j =1; j<=aLength; j++) {
624 Handle(GEOM_Object) aRefObj = GetReferencedObject(aSeq(j));
625 if(!aRefObj.IsNull()) anArray->Append(aRefObj);
632 //=============================================================================
636 //=============================================================================
637 Handle(TColStd_HSequenceOfTransient) GEOM_Object::GetLastDependency()
639 Handle(TColStd_HSequenceOfTransient) anArray;
640 Handle(GEOM_Function) aFunction = GetLastFunction();
641 if (aFunction.IsNull()) return anArray;
643 TDF_LabelSequence aSeq;
644 aFunction->GetDependency(aSeq);
645 Standard_Integer aLength = aSeq.Length();
647 anArray = new TColStd_HSequenceOfTransient;
648 for (Standard_Integer i = 1; i <= aLength; i++)
649 anArray->Append(GetReferencedObject(aSeq(i)));
655 //================================================================================
657 * \brief Returns a driver creator of this object
659 //================================================================================
661 Handle(TFunction_Driver) GEOM_Object::GetCreationDriver()
663 Handle(TFunction_Driver) aDriver;
665 Handle(GEOM_Function) function = GetFunction(1);
666 if ( !function.IsNull() )
668 Standard_GUID aGUID = function->GetDriverGUID();
669 if ( TFunction_DriverTable::Get()->FindDriver(aGUID, aDriver))
670 aDriver->Init( function->GetEntry() );
675 //=============================================================================
679 //=============================================================================
680 TDF_Label GEOM_Object::GetFreeLabel()
682 return _label.FindChild(FREE_LABEL);
685 //=======================================================================
686 //function : GEOM_Object_Type_
688 //=======================================================================
689 Standard_EXPORT Handle_Standard_Type& GEOM_Object_Type_()
692 static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
693 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared);
694 static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
695 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
698 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
699 static Handle_Standard_Type _aType = new Standard_Type("GEOM_Object",
702 (Standard_Address)_Ancestors,
703 (Standard_Address)NULL);
707 //=======================================================================
708 //function : DownCast
710 //=======================================================================
712 const Handle(GEOM_Object) Handle(GEOM_Object)::DownCast(const Handle(Standard_Transient)& AnObject)
714 Handle(GEOM_Object) _anOtherObject;
716 if (!AnObject.IsNull()) {
717 if (AnObject->IsKind(STANDARD_TYPE(GEOM_Object))) {
718 _anOtherObject = Handle(GEOM_Object)((Handle(GEOM_Object)&)AnObject);
722 return _anOtherObject ;