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