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