0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / XCAFDoc / XCAFDoc_GraphNode.cxx
1 // Created on: 2000-09-27
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <XCAFDoc_GraphNode.hxx>
17
18 #include <Standard_Dump.hxx>
19 #include <Standard_GUID.hxx>
20 #include <Standard_Type.hxx>
21 #include <TDF_Attribute.hxx>
22 #include <TDF_DataSet.hxx>
23 #include <TDF_Label.hxx>
24 #include <TDF_RelocationTable.hxx>
25
26 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_GraphNode,TDF_Attribute)
27
28 //     class  methods working on the node:
29 //     ===================================
30 //=======================================================================
31 //function : Find
32 //purpose  : 
33 //=======================================================================
34 Standard_Boolean XCAFDoc_GraphNode::Find(const TDF_Label& L,
35                                          Handle(XCAFDoc_GraphNode)& G)
36 {
37   return L.FindAttribute(XCAFDoc_GraphNode::GetDefaultGraphID(), G);
38 }
39
40 //=======================================================================
41 //GraphNode : GetDefaultGraphID
42 //purpose  : Static method to get the default ID of a GraphNode
43 //=======================================================================
44
45 const Standard_GUID&  XCAFDoc_GraphNode::GetDefaultGraphID() 
46 {
47   static Standard_GUID XCAFDoc_GraphNodeID ("efd212f5-6dfd-11d4-b9c8-0060b0ee281b");
48   return XCAFDoc_GraphNodeID; 
49 }
50
51 //=======================================================================
52 //GraphNode : Set
53 //purpose  : Finds or creates a GraphNode attribute with default ID
54 //=======================================================================
55
56 Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::Set(const TDF_Label& L)
57 {
58   Handle(XCAFDoc_GraphNode) GN;
59   if (!L.FindAttribute(XCAFDoc_GraphNode::GetDefaultGraphID(), GN)) {
60     GN = new XCAFDoc_GraphNode();
61     GN->SetGraphID(XCAFDoc_GraphNode::GetDefaultGraphID());
62     L.AddAttribute(GN);
63   }
64   return GN;
65 }
66
67 //=======================================================================
68 //function : Set
69 //purpose  : Finds or creates a GraphNode  attribute with explicit ID
70 //         : a driver for it
71 //=======================================================================
72
73 Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::Set (const TDF_Label& L, 
74                                                   const Standard_GUID& explicitID)
75 {
76   Handle(XCAFDoc_GraphNode) GN;
77   if (!L.FindAttribute(explicitID, GN)) {
78     GN = new XCAFDoc_GraphNode ();    
79     GN->SetGraphID( explicitID );
80     L.AddAttribute( GN );
81   }
82   return GN;
83 }
84
85 //     Instance methods: 
86 //     ================ 
87
88 //=======================================================================
89 //function : XCAFDoc_GraphNode
90 //purpose  : 
91 //=======================================================================
92
93 XCAFDoc_GraphNode::XCAFDoc_GraphNode () 
94
95 }  
96
97
98 //=======================================================================
99 //function : SetGraphID
100 //purpose  : 
101 //=======================================================================
102
103 void XCAFDoc_GraphNode::SetGraphID (const Standard_GUID& explicitID)
104 {
105   Backup();
106   myGraphID = explicitID;
107 }
108
109
110
111 //=======================================================================
112 //function : SetFather
113 //purpose  : 
114 //=======================================================================
115
116 Standard_Integer XCAFDoc_GraphNode::SetFather(const Handle(XCAFDoc_GraphNode)& F) 
117 {
118   Backup();
119   Standard_Integer Findex = myFathers.Length();
120   myFathers.Append(F);
121   return ++Findex;
122 }
123
124 //=======================================================================
125 //function : SetChild
126 //purpose  : 
127 //=======================================================================
128
129 Standard_Integer XCAFDoc_GraphNode::SetChild(const Handle(XCAFDoc_GraphNode)& Ch) 
130 {
131   Backup();
132   Standard_Integer Chindex = myChildren.Length();
133   myChildren.Append(Ch);
134   return ++Chindex;
135 }
136
137 //=======================================================================
138 //function : UnSetFather
139 //purpose  : 
140 //=======================================================================
141
142 void XCAFDoc_GraphNode::UnSetFather(const Handle(XCAFDoc_GraphNode)& F) 
143 {
144   Standard_Integer Findex = FatherIndex(F);
145   if (Findex != 0)
146   {
147     F->UnSetChildlink (this);
148     UnSetFatherlink (F);
149   }
150 }
151
152
153 //=======================================================================
154 //function : UnSetFather
155 //purpose  : 
156 //=======================================================================
157
158 void XCAFDoc_GraphNode::UnSetFather(const Standard_Integer Findex) 
159 {
160   if (Findex != 0)
161   {
162     UnSetFather (GetFather (Findex));
163   }
164 }
165
166
167 //=======================================================================
168 //function : UnSetFatherlink
169 //purpose  : Remove link finily
170 //=======================================================================
171
172 void XCAFDoc_GraphNode::UnSetFatherlink(const Handle(XCAFDoc_GraphNode)& F) 
173 {
174   Backup();
175   Standard_Integer Findex = FatherIndex (F);
176   if (Findex != 0)
177   {
178     myFathers.Remove( Findex );
179   }
180 }
181
182 //=======================================================================
183 //function : UnSetChild
184 //purpose  : 
185 //=======================================================================
186
187 void XCAFDoc_GraphNode::UnSetChild(const Handle(XCAFDoc_GraphNode)& Ch) 
188 {
189   Standard_Integer Chindex = ChildIndex(Ch);
190   if (Chindex != 0)
191   {
192     Ch->UnSetFatherlink (this);
193     UnSetChildlink (Ch);
194   }
195 }
196
197
198 //=======================================================================
199 //function : UnSetChild
200 //purpose  : 
201 //=======================================================================
202
203  void XCAFDoc_GraphNode::UnSetChild(const Standard_Integer Chindex) 
204 {
205   if (Chindex != 0)
206   {
207     UnSetChild (GetChild (Chindex));
208   }
209 }
210
211
212 //=======================================================================
213 //function : UnSetChildlink
214 //purpose  : Remove link finily
215 //=======================================================================
216
217 void XCAFDoc_GraphNode::UnSetChildlink(const Handle(XCAFDoc_GraphNode)& Ch) 
218 {
219   Backup();
220   Standard_Integer Chindex = ChildIndex (Ch);
221   if (Chindex != 0)
222   {
223     myChildren.Remove (Chindex);
224   }
225 }
226
227 //=======================================================================
228 //function : GetFather
229 //purpose  : 
230 //=======================================================================
231
232  Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::GetFather(const Standard_Integer Findex) const
233 {
234   Handle(XCAFDoc_GraphNode) F = myFathers.Value(Findex);
235   return F;
236 }
237
238 //=======================================================================
239 //function : GetChild
240 //purpose  : 
241 //=======================================================================
242
243  Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::GetChild(const Standard_Integer Chindex) const
244 {
245   Handle(XCAFDoc_GraphNode) Ch = myChildren.Value(Chindex);
246   return Ch;
247 }
248
249 //=======================================================================
250 //function : FatherIndex
251 //purpose  : 
252 //=======================================================================
253
254 Standard_Integer XCAFDoc_GraphNode::FatherIndex(const Handle(XCAFDoc_GraphNode)& F) const
255 {
256   Standard_Integer Findex = 0;
257   if (NbFathers() != 0)
258   {
259     for (Findex = 1 ; Findex <= NbFathers(); Findex++)
260     {
261       if (F == myFathers.Value (Findex))
262       {
263         return Findex;
264       }
265     }
266   }
267   return 0;
268 }
269
270 //=======================================================================
271 //function : ChildIndex
272 //purpose  : 
273 //=======================================================================
274
275  Standard_Integer XCAFDoc_GraphNode::ChildIndex(const Handle(XCAFDoc_GraphNode)& Ch) const
276 {
277   Standard_Integer Chindex;
278   if (NbChildren() != 0)
279   {
280     for (Chindex = 1; Chindex <= NbChildren(); Chindex++)
281     {
282       if (Ch == myChildren.Value (Chindex))
283       {
284         return Chindex;
285       }
286     }
287   }
288   return 0;
289 }
290
291 //=======================================================================
292 //function : IsFather
293 //purpose  : 
294 //=======================================================================
295
296  Standard_Boolean XCAFDoc_GraphNode::IsFather(const Handle(XCAFDoc_GraphNode)& Ch) const
297 {
298   if ( ChildIndex(Ch) ) return Standard_True;
299   return Standard_False;
300 }
301
302 //=======================================================================
303 //function : IsChild
304 //purpose  : 
305 //=======================================================================
306
307  Standard_Boolean XCAFDoc_GraphNode::IsChild(const Handle(XCAFDoc_GraphNode)& F) const
308 {
309   if ( FatherIndex(F) ) return Standard_True;
310   return Standard_False;
311 }
312
313 //=======================================================================
314 //function : NbFathers
315 //purpose  : 
316 //=======================================================================
317
318  Standard_Integer XCAFDoc_GraphNode::NbFathers() const
319 {
320   return myFathers.Length();
321 }
322
323 //=======================================================================
324 //function : NbChildren
325 //purpose  : 
326 //=======================================================================
327
328  Standard_Integer XCAFDoc_GraphNode::NbChildren() const
329 {
330   return myChildren.Length();
331 }
332
333
334
335 //     Implementation of Attribute methods:  
336 //     ===================================  
337
338 //=======================================================================
339 //function : ID
340 //purpose  : 
341 //=======================================================================
342
343 const Standard_GUID& XCAFDoc_GraphNode::ID() const
344 {
345   return myGraphID;
346 }
347
348
349 //=======================================================================
350 //function : Restore
351 //purpose  : 
352 //=======================================================================
353
354 void XCAFDoc_GraphNode::Restore(const Handle(TDF_Attribute)& other) 
355 {
356   Handle(XCAFDoc_GraphNode) F =  Handle(XCAFDoc_GraphNode)::DownCast(other);
357   myFathers     = F->myFathers;
358   myChildren    = F->myChildren;
359   myGraphID     = F->myGraphID;
360 }
361
362
363 //=======================================================================
364 //function : Paste
365 //purpose  : 
366 //=======================================================================
367
368 void XCAFDoc_GraphNode::Paste(const Handle(TDF_Attribute)& into,
369                               const Handle(TDF_RelocationTable)& RT) const
370 {
371   Handle(XCAFDoc_GraphNode) intof = Handle(XCAFDoc_GraphNode)::DownCast(into);
372   Handle(XCAFDoc_GraphNode) func;
373   Standard_Integer i = 1;
374   for (; i <= NbFathers(); i++) {
375     if (!RT->HasRelocation(myFathers(i), func) && RT->AfterRelocate())
376     {
377       func.Nullify();
378     }
379     if (!func.IsNull())
380     {
381       intof->SetFather(func);
382     }
383   }
384
385   i = 1;
386   for (; i <= NbChildren(); i++)
387   {
388     if (!RT->HasRelocation(myChildren(i), func) && RT->AfterRelocate())
389     {
390       func.Nullify();
391     }
392     if (!func.IsNull())
393     {
394       intof->SetChild(func);
395     }
396   }
397   intof->SetGraphID(myGraphID);
398 }
399
400
401 //=======================================================================
402 //function : NewEmpty
403 //purpose  : 
404 //=======================================================================
405
406 Handle(TDF_Attribute) XCAFDoc_GraphNode::NewEmpty() const
407 {
408   Handle(XCAFDoc_GraphNode) G = new XCAFDoc_GraphNode();
409   G->SetGraphID(myGraphID);
410   return G;
411 }
412
413
414 //=======================================================================
415 //function : References
416 //purpose  : 
417 //=======================================================================
418
419 void XCAFDoc_GraphNode::References(const Handle(TDF_DataSet)& aDataSet) const
420 {
421   Standard_Integer i;
422   Handle(XCAFDoc_GraphNode) fct;
423   for ( i = 1; i <= NbChildren(); i++ ) {
424     fct = myChildren(i);
425     if (!fct.IsNull()) {
426       aDataSet->AddAttribute(fct);
427     }
428   }
429   for ( i = 1; i <= NbFathers(); i++ ) {
430     fct = myFathers(i);
431     if ( !fct.IsNull()) {
432       aDataSet->AddAttribute(fct);
433     }
434   }
435  
436 }
437
438 //=======================================================================
439 //function : Dump
440 //purpose  : 
441 //=======================================================================
442
443 Standard_OStream& XCAFDoc_GraphNode::Dump (Standard_OStream& anOS) const
444 {
445   TDF_Attribute::Dump (anOS);
446   Standard_Integer i = 1;
447   if ( myFathers.Length()!= 0 ) {
448     anOS<<"  Fathers=";
449     for (; i <= NbFathers(); i++) {
450       if ( !myFathers(i)->Label().IsNull() ) 
451         myFathers(i)->Label().EntryDump(anOS);
452       anOS<<std::endl;
453     }
454   }
455   i = 1;
456   if ( myChildren.Length()!= 0 ) {
457     anOS<<"  Children=";
458     for (; i <= NbChildren(); i++) {
459       if ( !myChildren(i)->Label().IsNull() )
460         myChildren(i)->Label().EntryDump(anOS);
461       anOS<<std::endl;
462     }
463   }
464 //  anOS<<std::endl;
465   return anOS;
466 }
467
468 //=======================================================================
469 //function : BeforeForget
470 //purpose  : 
471 //=======================================================================
472
473 void XCAFDoc_GraphNode::BeforeForget()
474 {
475   while (myFathers.Length () > 0)
476   {
477     UnSetFather (1);
478   }
479   while (myChildren.Length () > 0)
480   {
481     UnSetChild (1);
482   }
483 }
484
485 //=======================================================================
486 //function : DumpJson
487 //purpose  : 
488 //=======================================================================
489 void XCAFDoc_GraphNode::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
490 {
491   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
492
493   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
494
495   for (XCAFDoc_GraphNodeSequence::Iterator anIteratorFather (myFathers); anIteratorFather.More(); anIteratorFather.Next())
496   {
497     const Handle(XCAFDoc_GraphNode)& aFather = anIteratorFather.Value();
498     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aFather.get())
499   }
500   
501   for (XCAFDoc_GraphNodeSequence::Iterator anIteratorChild (myChildren); anIteratorChild.More(); anIteratorChild.Next())
502   {
503     const Handle(XCAFDoc_GraphNode)& aChild = anIteratorChild.Value();
504     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aChild.get())
505   }
506
507   OCCT_DUMP_FIELD_VALUE_GUID (theOStream, myGraphID)
508 }