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