Salome HOME
Merge from V6_main 01/04/2013
[modules/geom.git] / src / GEOM / GEOM_Object.cxx
1 // Copyright (C) 2007-2013  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.
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 "utilities.h"
26
27 #include <GEOM_Object.hxx>
28 #include <GEOM_Engine.hxx>
29 #include <GEOM_Solver.hxx>
30 #include <TDF_Tool.hxx>
31 #include <TDF_Data.hxx>
32 #include <TDF_Reference.hxx>
33 #include <TDF_LabelSequence.hxx>
34 #include <TDocStd_Owner.hxx>
35 #include <TDocStd_Document.hxx>
36 #include <TDataStd_Integer.hxx>
37 #include <TDataStd_Real.hxx>
38 #include <TDataStd_ChildNodeIterator.hxx>
39 #include <TDataStd_UAttribute.hxx>
40 #include <TDataStd_Name.hxx>
41 #include <TDataStd_Comment.hxx>
42 #include <TDataStd_RealArray.hxx>
43 #include <TDataStd_ByteArray.hxx>
44 #include <TColStd_HArray1OfReal.hxx>
45 #include <TCollection_AsciiString.hxx>
46 #include <TCollection_ExtendedString.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <TopExp.hxx>
49
50 #define FUNCTION_LABEL(theNb) (_label.FindChild(1).FindChild((theNb)))
51 #define TYPE_LABEL       2
52 #define FREE_LABEL       3
53 #define TIC_LABEL        4
54 #define COLOR_LABEL      5
55 #define AUTO_COLOR_LABEL 6
56 #define MARKER_LABEL     7
57
58 #define MARKER_LABEL_TYPE 1
59 #define MARKER_LABEL_SIZE 2
60 #define MARKER_LABEL_ID   3
61
62 //=======================================================================
63 //function : GetObjectID
64 //purpose  :
65 //=======================================================================
66 const Standard_GUID& GEOM_Object::GetObjectID()
67 {
68   static Standard_GUID anObjectID("FF1BBB01-5D14-4df2-980B-3A668264EA16");
69   return anObjectID;
70 }
71
72 //=======================================================================
73 //function : GetSubShapeID
74 //purpose  :
75 //=======================================================================
76 const Standard_GUID& GEOM_Object::GetSubShapeID()
77 {
78   static Standard_GUID anObjectID("FF1BBB68-5D14-4df2-980B-3A668264EA16");
79   return anObjectID;
80 }
81
82 //=============================================================================
83 /*!
84  *  GetObject
85  */
86 //=============================================================================
87 Handle(GEOM_Object) GEOM_Object::GetObject(TDF_Label& theLabel)
88 {
89   if (!theLabel.IsAttribute(GetObjectID())) return NULL;
90
91   TCollection_AsciiString anEntry;
92   TDF_Tool::Entry(theLabel, anEntry);
93
94   Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(theLabel.Data());
95   if(aDoc.IsNull()) return NULL;
96
97   Handle(TDataStd_Integer) anID;
98   if(!aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) return NULL;
99
100
101   GEOM_Engine* anEngine=  GEOM_Engine::GetEngine();
102   if(anEngine == NULL) return NULL;
103   return anEngine->GetObject(anID->Get(), (char*) anEntry.ToCString());
104
105
106 }
107
108 //=============================================================================
109 /*!
110  *  GetReferencedObject
111  */
112 //=============================================================================
113 Handle(GEOM_Object) GEOM_Object::GetReferencedObject(TDF_Label& theLabel)
114 {
115   Handle(TDF_Reference) aRef;
116   if (!theLabel.FindAttribute(TDF_Reference::GetID(), aRef)) {
117     return NULL;
118   }
119   
120   if(aRef.IsNull() || aRef->Get().IsNull()) {
121     return NULL;
122   }
123
124
125   // Get TreeNode of a referenced function
126   Handle(TDataStd_TreeNode) aT, aFather;
127   if (!TDataStd_TreeNode::Find(aRef->Get(), aT)) {
128     return NULL;
129   }
130
131
132   // Get TreeNode of Object of the referenced function
133   aFather = aT->Father();
134   if (aFather.IsNull()) {
135     return NULL;
136   }
137
138   // Get label of the referenced object
139   TDF_Label aLabel = aFather->Label();
140   
141
142   return GEOM_Object::GetObject(aLabel);
143 }
144
145 //=============================================================================
146 /*!
147  *  Constructor: private
148  */
149 //=============================================================================
150 GEOM_Object::GEOM_Object(TDF_Label& theEntry)
151   : _label(theEntry), _ior(""), _docID(-1)
152 {
153   Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(_label.Data());
154   if(!aDoc.IsNull()) {
155     Handle(TDataStd_Integer) anID;
156     if(aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) _docID = anID->Get();
157   }
158
159   if(!theEntry.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), _root))
160     _root = TDataStd_TreeNode::Set(theEntry);
161 }
162
163 //=============================================================================
164 /*!
165  *  Constructor: public
166  */
167 //=============================================================================
168 GEOM_Object::GEOM_Object(TDF_Label& theEntry, int theType)
169 : _label(theEntry), _ior(""), _docID(-1)
170 {
171   Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(_label.Data());
172   if(!aDoc.IsNull()) {
173     Handle(TDataStd_Integer) anID;
174     if(aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) _docID = anID->Get();
175   }
176
177   theEntry.ForgetAllAttributes(Standard_True);
178
179   if(!theEntry.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), _root))
180     _root = TDataStd_TreeNode::Set(theEntry);
181
182   TDataStd_Integer::Set(theEntry.FindChild(TYPE_LABEL), theType);
183
184   TDataStd_UAttribute::Set(theEntry, GetObjectID());
185 }
186
187 //=============================================================================
188 /*!
189  *  Destructor
190  */
191 //=============================================================================
192 GEOM_Object::~GEOM_Object()
193 {
194   MESSAGE("GEOM_Object::~GEOM_Object()");
195 }
196
197 //=============================================================================
198 /*!
199  *  GetType
200  */
201 //=============================================================================
202 int GEOM_Object::GetType()
203 {
204   Handle(TDataStd_Integer) aType;
205   if(!_label.FindChild(TYPE_LABEL).FindAttribute(TDataStd_Integer::GetID(), aType)) return -1;
206
207   return aType->Get();
208 }
209
210 //=============================================================================
211 /*!
212  *  SetType
213  */
214 //=============================================================================
215 void GEOM_Object::SetType(int theType)
216 {
217   TDataStd_Integer::Set(_label.FindChild(TYPE_LABEL), theType);
218 }
219
220
221 //=============================================================================
222 /*!
223  *  Returns modifications counter of this object.
224  *  Comparing this value with modifications counters of argument objects
225  *  (on which this object depends) we decide whether this object needs to be updated.
226  */
227 //=============================================================================
228 int GEOM_Object::GetTic()
229 {
230   Handle(TDataStd_Integer) aTicAttr;
231   if (!_label.FindChild(TIC_LABEL).FindAttribute(TDataStd_Integer::GetID(), aTicAttr))
232     return 0;
233
234   return aTicAttr->Get();
235 }
236
237 //=============================================================================
238 /*!
239  *  Set another value of modifications counter.
240  *
241  *  Use this method to update modifications counter of dependent object
242  *  to be equal to modifications counter of its argument.
243  *  This is commonly done in GEOM_Function::GetValue()
244  */
245 //=============================================================================
246 void GEOM_Object::SetTic(int theTic)
247 {
248   TDataStd_Integer::Set(_label.FindChild(TIC_LABEL), theTic);
249 }
250
251 //=============================================================================
252 /*!
253  *  Increment modifications counter to mark this object as modified.
254  *
255  *  Commonly called from GEOM_Function::SetValue()
256  */
257 //=============================================================================
258 void GEOM_Object::IncrementTic()
259 {
260   TDF_Label aTicLabel = _label.FindChild(TIC_LABEL);
261
262   Standard_Integer aTic = 0;
263   Handle(TDataStd_Integer) aTicAttr;
264   if (aTicLabel.FindAttribute(TDataStd_Integer::GetID(), aTicAttr))
265     aTic = aTicAttr->Get();
266
267   TDataStd_Integer::Set(aTicLabel, aTic + 1);
268 }
269
270
271 //=============================================================================
272 /*!
273  *  GetDocID
274  */
275 //=============================================================================
276 int GEOM_Object::GetDocID()
277 {
278   return _docID;
279 }
280
281
282 //=============================================================================
283 /*!
284  *  GetValue
285  */
286 //=============================================================================
287 TopoDS_Shape GEOM_Object::GetValue()
288 {
289   TopoDS_Shape aShape;
290
291   Handle(GEOM_Function) aFunction = GetLastFunction();
292
293   if (!aFunction.IsNull())
294     aShape = aFunction->GetValue();
295
296   return aShape;
297 }
298
299 //=============================================================================
300 /*!
301  *  SetName
302  */
303 //=============================================================================
304 void GEOM_Object::SetName(const char* theName)
305 {
306   TDataStd_Name::Set(_label, (char*)theName);
307 }
308
309 //=============================================================================
310 /*!
311  *  GetName
312  */
313 //=============================================================================
314 char* GEOM_Object::GetName()
315 {
316   Handle(TDataStd_Name) aNameAttr;
317   if(!_label.FindAttribute(TDataStd_Name::GetID(), aNameAttr)) return NULL;
318
319   TCollection_AsciiString aName(aNameAttr->Get());
320   // do not return pointer of local variable
321   // return aName.ToCString();
322   // the following code could lead to memory leak, so take care about recieved pointer
323   return strdup(aName.ToCString());
324 }
325
326 //=============================================================================
327 /*!
328  *  SetColor
329  */
330 //=============================================================================
331 void GEOM_Object::SetColor(const GEOM_Object::Color& theColor)
332 {
333   Handle(TDataStd_RealArray) anArray = new TDataStd_RealArray();
334   anArray->Init( 1, 3 );
335   anArray->SetValue( 1, theColor.R );
336   anArray->SetValue( 2, theColor.G );
337   anArray->SetValue( 3, theColor.B );
338
339   Handle(TDataStd_RealArray) anAttr =
340     TDataStd_RealArray::Set(_label.FindChild(COLOR_LABEL), anArray->Lower(), anArray->Upper());
341   anAttr->ChangeArray(anArray->Array());
342 }
343
344 //=============================================================================
345 /*!
346  *  GetColor
347  */
348 //=============================================================================
349 GEOM_Object::Color GEOM_Object::GetColor()
350 {
351   Handle(TDataStd_RealArray) anArray;
352   bool isFound = _label.FindChild(COLOR_LABEL).FindAttribute(TDataStd_RealArray::GetID(), anArray);
353
354   GEOM_Object::Color aColor;
355   aColor.R = isFound ? anArray->Value( 1 ) : -1;
356   aColor.G = isFound ? anArray->Value( 2 ) : -1;
357   aColor.B = isFound ? anArray->Value( 3 ) : -1;
358
359   return aColor;
360 }
361
362 //=============================================================================
363 /*!
364  *  SetAutoColor
365  */
366 //=============================================================================
367 void GEOM_Object::SetAutoColor(bool theAutoColor)
368 {
369   TDataStd_Integer::Set(_label.FindChild(AUTO_COLOR_LABEL), (int)theAutoColor);
370 }
371
372 //=============================================================================
373 /*!
374  *  GetAutoColor
375  */
376 //=============================================================================
377 bool GEOM_Object::GetAutoColor()
378 {
379   Handle(TDataStd_Integer) anAutoColor;
380   if(!_label.FindChild(AUTO_COLOR_LABEL).FindAttribute(TDataStd_Integer::GetID(), anAutoColor)) return false;
381
382   return bool(anAutoColor->Get());
383 }
384
385 //=============================================================================
386 /*!
387  *  SetMarkerStd
388  */
389 //=============================================================================
390 void GEOM_Object::SetMarkerStd(const Aspect_TypeOfMarker theType, double theSize)
391 {
392   TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL);
393   TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_TYPE), (int)theType);
394   TDataStd_Real::Set(aMarkerLabel.FindChild(MARKER_LABEL_SIZE), theSize);
395 }
396   
397 //=============================================================================
398 /*!
399  *  SetMarkerTexture
400  */
401 //=============================================================================
402 void GEOM_Object::SetMarkerTexture(int theTextureId)
403 {
404   TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL);
405   TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_TYPE), (int)Aspect_TOM_USERDEFINED);
406   TDataStd_Integer::Set(aMarkerLabel.FindChild(MARKER_LABEL_ID),   theTextureId);
407 }
408
409 //=============================================================================
410 /*!
411  *  GetMarkerType
412  */
413 //=============================================================================
414 Aspect_TypeOfMarker GEOM_Object::GetMarkerType()
415 {
416   Standard_Integer aType = -1;
417   TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
418   if(!aMarkerLabel.IsNull()) {
419     TDF_Label aTypeLabel = aMarkerLabel.FindChild(MARKER_LABEL_TYPE, Standard_False);
420     Handle(TDataStd_Integer) aTypeAttr;
421     if (!aTypeLabel.IsNull() && aTypeLabel.FindAttribute(TDataStd_Integer::GetID(), aTypeAttr))
422       aType = aTypeAttr->Get();
423   }
424   return (Aspect_TypeOfMarker)aType;
425 }
426
427 //=============================================================================
428 /*!
429  *  GetMarkerSize
430  */
431 //=============================================================================
432 double GEOM_Object::GetMarkerSize()
433 {
434   Standard_Real aSize = 0.;
435   TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
436   if(!aMarkerLabel.IsNull()) {
437     TDF_Label aSizeLabel = aMarkerLabel.FindChild(MARKER_LABEL_SIZE, Standard_False);
438     Handle(TDataStd_Real) aSizeAttr;
439     if (!aSizeLabel.IsNull() && aSizeLabel.FindAttribute(TDataStd_Real::GetID(), aSizeAttr))
440       aSize = aSizeAttr->Get();
441   }
442   return aSize;
443 }
444
445 //=============================================================================
446 /*!
447  *  GetMarkerTexture
448  */
449 //=============================================================================
450 int GEOM_Object::GetMarkerTexture()
451 {
452   Standard_Integer anId = 0;
453   if ( GetMarkerType() == Aspect_TOM_USERDEFINED) {
454     TDF_Label aMarkerLabel = _label.FindChild(MARKER_LABEL, Standard_False);
455     if(!aMarkerLabel.IsNull()) {
456       TDF_Label aTypeLabel = aMarkerLabel.FindChild(MARKER_LABEL_ID, Standard_False);
457       Handle(TDataStd_Integer) anIdAttr;
458       if (!aTypeLabel.IsNull() && aTypeLabel.FindAttribute(TDataStd_Integer::GetID(), anIdAttr))
459         anId = anIdAttr->Get();
460     }
461   }
462   return anId;
463 }
464
465 //=============================================================================
466 /*!
467  *  SetAuxData
468  */
469 //=============================================================================
470 void GEOM_Object::UnsetMarker()
471 {
472   SetMarkerStd((Aspect_TypeOfMarker)-1, 0.);
473 }
474
475 //=============================================================================
476 /*!
477  *  SetAuxData
478  */
479 //=============================================================================
480 void GEOM_Object::SetAuxData(const char* theData)
481 {
482   TDataStd_Comment::Set(_label, (char*)theData);
483 }
484
485 //=============================================================================
486 /*!
487  *  GetAuxData
488  */
489 //=============================================================================
490 TCollection_AsciiString GEOM_Object::GetAuxData()
491 {
492   TCollection_AsciiString aData;
493
494   Handle(TDataStd_Comment) aCommentAttr;
495   if (_label.FindAttribute(TDataStd_Comment::GetID(), aCommentAttr))
496     aData = aCommentAttr->Get();
497
498   return aData;
499 }
500
501 //=============================================================================
502 /*!
503  *  SetParameters
504  */
505 //=============================================================================
506 void GEOM_Object::SetParameters(const TCollection_AsciiString& theParameters)
507 {
508   if( _parameters.IsEmpty() )
509     _parameters = theParameters;
510   else {
511     _parameters += "|";
512     _parameters += theParameters;
513   }
514 }
515
516 //=============================================================================
517 /*!
518  *  GetParameters
519  */
520 //=============================================================================
521 TCollection_AsciiString GEOM_Object::GetParameters() const
522 {
523   return _parameters;
524 }
525
526
527 //=============================================================================
528 /*!
529  *  IsSubShape
530  */
531 //=============================================================================
532 bool GEOM_Object::IsMainShape()
533 {
534   Handle(GEOM_Function) aFunction = GetFunction(1);
535   if(aFunction.IsNull() || aFunction->GetDriverGUID() != GetSubShapeID()) return true; // mkr : IPAL9921
536   return false;
537 }
538
539
540 //=============================================================================
541 /*!
542  *  AddFunction
543  */
544 //=============================================================================
545 Handle(GEOM_Function) GEOM_Object::AddFunction(const Standard_GUID& theGUID,
546                                                int                  theFunctionType,
547                                                bool                 allowSubShape)
548 {
549   Standard_Integer nb = GetNbFunctions();
550   if(!allowSubShape && nb == 1 && theGUID == GetSubShapeID()) return NULL; //It's impossible to add a function to sub-shape
551   nb++;
552   TDF_Label aChild = FUNCTION_LABEL(nb);
553
554   Handle(TDataStd_TreeNode) aNode = TDataStd_TreeNode::Set(aChild);
555   _root->Append(aNode);
556
557   Handle(GEOM_Function) aFunction = new GEOM_Function(aChild, theGUID, theFunctionType);
558
559   return aFunction;
560
561 }
562
563 //=============================================================================
564 /*!
565  *  GetNbFunctions
566  */
567 //=============================================================================
568 int GEOM_Object::GetNbFunctions()
569 {
570   Standard_Integer nb = 0;
571   for(TDataStd_ChildNodeIterator CI(_root); CI.More(); CI.Next()) nb++;
572   return nb;
573 }
574
575 //=============================================================================
576 /*!
577  *  GetFunction
578  */
579 //=============================================================================
580 Handle(GEOM_Function) GEOM_Object::GetFunction(int theFunctionNumber)
581 {
582   TDF_Label aChild = FUNCTION_LABEL(theFunctionNumber);
583   return GEOM_Function::GetFunction(aChild);
584 }
585
586 //=============================================================================
587 /*!
588  *  GetlastFunction
589  */
590 //=============================================================================
591 Handle(GEOM_Function) GEOM_Object::GetLastFunction()
592 {
593   Standard_Integer nb = GetNbFunctions();
594   if(nb) return GetFunction(nb);
595
596   return NULL;
597 }
598
599
600 //=============================================================================
601 /*!
602  *  GetAllDependency
603  */
604 //=============================================================================
605 Handle(TColStd_HSequenceOfTransient) GEOM_Object::GetAllDependency()
606 {
607   Handle(TColStd_HSequenceOfTransient) anArray;
608   TDF_LabelSequence aSeq;
609   Standard_Integer nb = GetNbFunctions();
610   if(nb == 0) return anArray;
611   for(Standard_Integer i=1; i<=nb; i++) {
612     Handle(GEOM_Function) aFunction = GetFunction(i);
613     if(aFunction.IsNull()) continue;
614     aFunction->GetDependency(aSeq);
615   }
616
617   Standard_Integer aLength = aSeq.Length();
618   if(aLength > 0) {
619     anArray = new TColStd_HSequenceOfTransient;
620     for(Standard_Integer j =1; j<=aLength; j++) {
621       Handle(GEOM_Object) aRefObj = GetReferencedObject(aSeq(j));
622       if(!aRefObj.IsNull()) anArray->Append(aRefObj);
623     }
624   }
625
626   return anArray;
627 }
628
629 //=============================================================================
630 /*!
631  *  GetLastDependency
632  */
633 //=============================================================================
634 Handle(TColStd_HSequenceOfTransient) GEOM_Object::GetLastDependency()
635 {
636   Handle(TColStd_HSequenceOfTransient) anArray;
637   Handle(GEOM_Function) aFunction = GetLastFunction();
638   if (aFunction.IsNull()) return anArray;
639
640   TDF_LabelSequence aSeq;
641   aFunction->GetDependency(aSeq);
642   Standard_Integer aLength = aSeq.Length();
643   if (aLength > 0) {
644     anArray = new TColStd_HSequenceOfTransient;
645     for (Standard_Integer i = 1; i <= aLength; i++)
646       anArray->Append(GetReferencedObject(aSeq(i)));
647   }
648
649   return anArray;
650 }
651
652 //=============================================================================
653 /*!
654  *  GetFreeLabel
655  */
656 //=============================================================================
657 TDF_Label GEOM_Object::GetFreeLabel()
658 {
659   return _label.FindChild(FREE_LABEL);
660 }
661
662 //=======================================================================
663 //function :  GEOM_Object_Type_
664 //purpose  :
665 //=======================================================================
666 Standard_EXPORT Handle_Standard_Type& GEOM_Object_Type_()
667 {
668
669   static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared);
670   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared);
671   static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient);
672   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient);
673
674
675   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL};
676   static Handle_Standard_Type _aType = new Standard_Type("GEOM_Object",
677                                                          sizeof(GEOM_Object),
678                                                          1,
679                                                          (Standard_Address)_Ancestors,
680                                                          (Standard_Address)NULL);
681   return _aType;
682 }
683
684 //=======================================================================
685 //function : DownCast
686 //purpose  :
687 //=======================================================================
688
689 const Handle(GEOM_Object) Handle(GEOM_Object)::DownCast(const Handle(Standard_Transient)& AnObject)
690 {
691   Handle(GEOM_Object) _anOtherObject;
692
693   if (!AnObject.IsNull()) {
694      if (AnObject->IsKind(STANDARD_TYPE(GEOM_Object))) {
695        _anOtherObject = Handle(GEOM_Object)((Handle(GEOM_Object)&)AnObject);
696      }
697   }
698
699   return _anOtherObject ;
700 }
701
702