0023047: Behaviour of XDE sample is non-stable
[occt.git] / src / XCAFDoc / XCAFDoc_GraphNode.cxx
1 // Created on: 2000-09-27
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21
22 #include <XCAFDoc_GraphNode.ixx>
23
24 //     class  methods working on the node:
25 //     ===================================
26
27 //=======================================================================
28 //function : Find
29 //purpose  : 
30 //=======================================================================
31
32 Standard_Boolean XCAFDoc_GraphNode::Find(const TDF_Label& L,
33                                          Handle(XCAFDoc_GraphNode)& G)
34 {
35   return L.FindAttribute(XCAFDoc_GraphNode::GetDefaultGraphID(), G);
36 }
37
38 //=======================================================================
39 //GraphNode : GetDefaultGraphID
40 //purpose  : Static method to get the default ID of a GraphNode
41 //=======================================================================
42
43 const Standard_GUID&  XCAFDoc_GraphNode::GetDefaultGraphID() 
44 {
45   static Standard_GUID XCAFDoc_GraphNodeID ("efd212f5-6dfd-11d4-b9c8-0060b0ee281b");
46   return XCAFDoc_GraphNodeID; 
47 }
48
49 //=======================================================================
50 //GraphNode : Set
51 //purpose  : Finds or creates a GraphNode attribute with default ID
52 //=======================================================================
53
54 Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::Set(const TDF_Label& L)
55 {
56   Handle(XCAFDoc_GraphNode) GN;
57   if (!L.FindAttribute(XCAFDoc_GraphNode::GetDefaultGraphID(), GN)) {
58     GN = new XCAFDoc_GraphNode();
59     GN->SetGraphID(XCAFDoc_GraphNode::GetDefaultGraphID());
60     L.AddAttribute(GN);
61   }
62   return GN;
63 }
64
65 //=======================================================================
66 //function : Set
67 //purpose  : Finds or creates a GraphNode  attribute with explicit ID
68 //         : a driver for it
69 //=======================================================================
70
71 Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::Set (const TDF_Label& L, 
72                                                   const Standard_GUID& explicitID)
73 {
74   Handle(XCAFDoc_GraphNode) GN;
75   if (!L.FindAttribute(explicitID, GN)) {
76     GN = new XCAFDoc_GraphNode ();    
77     GN->SetGraphID( explicitID );
78     L.AddAttribute( GN );
79   }
80   return GN;
81 }
82
83 //     Instance methods: 
84 //     ================ 
85
86 //=======================================================================
87 //function : XCAFDoc_GraphNode
88 //purpose  : 
89 //=======================================================================
90
91 XCAFDoc_GraphNode::XCAFDoc_GraphNode () 
92
93 }  
94
95
96 //=======================================================================
97 //function : SetGraphID
98 //purpose  : 
99 //=======================================================================
100
101 void XCAFDoc_GraphNode::SetGraphID (const Standard_GUID& explicitID)
102 {
103   Backup();
104   myGraphID = explicitID;
105 }
106
107
108
109 //=======================================================================
110 //function : SetFather
111 //purpose  : 
112 //=======================================================================
113
114 Standard_Integer XCAFDoc_GraphNode::SetFather(const Handle(XCAFDoc_GraphNode)& F) 
115 {
116   Backup();
117   Standard_Integer Findex = myFathers.Length();
118   myFathers.Append(F);
119   return ++Findex;
120 }
121
122 //=======================================================================
123 //function : SetChild
124 //purpose  : 
125 //=======================================================================
126
127 Standard_Integer XCAFDoc_GraphNode::SetChild(const Handle(XCAFDoc_GraphNode)& Ch) 
128 {
129   Backup();
130   Standard_Integer Chindex = myChildren.Length();
131   myChildren.Append(Ch);
132   return ++Chindex;
133 }
134
135 //=======================================================================
136 //function : UnSetFather
137 //purpose  : 
138 //=======================================================================
139
140 void XCAFDoc_GraphNode::UnSetFather(const Handle(XCAFDoc_GraphNode)& F) 
141 {
142   Backup();
143   Standard_Integer Findex = FatherIndex(F);
144   if (Findex != 0)
145   F->UnSetChildlink(this);
146   UnSetFatherlink(F);
147 }
148
149
150 //=======================================================================
151 //function : UnSetFather
152 //purpose  : 
153 //=======================================================================
154
155 void XCAFDoc_GraphNode::UnSetFather(const Standard_Integer Findex) 
156 {
157   if (Findex != 0)
158   UnSetFather( GetFather(Findex) );
159 }
160
161
162 //=======================================================================
163 //function : UnSetFatherlink
164 //purpose  : Remove link finily
165 //=======================================================================
166
167 void XCAFDoc_GraphNode::UnSetFatherlink(const Handle(XCAFDoc_GraphNode)& F) 
168 {
169   myFathers.Remove( FatherIndex(F) );
170 }
171
172 //=======================================================================
173 //function : UnSetChild
174 //purpose  : 
175 //=======================================================================
176
177 void XCAFDoc_GraphNode::UnSetChild(const Handle(XCAFDoc_GraphNode)& Ch) 
178 {
179   Backup();
180   Standard_Integer Chindex = ChildIndex(Ch);
181   if (Chindex != 0) 
182   Ch->UnSetFatherlink(this);
183   UnSetChildlink(Ch);
184 }
185
186
187 //=======================================================================
188 //function : UnSetChild
189 //purpose  : 
190 //=======================================================================
191
192  void XCAFDoc_GraphNode::UnSetChild(const Standard_Integer Chindex) 
193 {
194   if (Chindex != 0 )
195   UnSetChild( GetChild(Chindex) );
196 }
197
198
199 //=======================================================================
200 //function : UnSetChildlink
201 //purpose  : Remove link finily
202 //=======================================================================
203
204 void XCAFDoc_GraphNode::UnSetChildlink(const Handle(XCAFDoc_GraphNode)& Ch) 
205 {
206   myChildren.Remove( ChildIndex(Ch) );
207 }
208
209 //=======================================================================
210 //function : GetFather
211 //purpose  : 
212 //=======================================================================
213
214  Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::GetFather(const Standard_Integer Findex) const
215 {
216   Handle(XCAFDoc_GraphNode) F = myFathers.Value(Findex);
217   return F;
218 }
219
220 //=======================================================================
221 //function : GetChild
222 //purpose  : 
223 //=======================================================================
224
225  Handle(XCAFDoc_GraphNode) XCAFDoc_GraphNode::GetChild(const Standard_Integer Chindex) const
226 {
227   Handle(XCAFDoc_GraphNode) Ch = myChildren.Value(Chindex);
228   return Ch;
229 }
230
231 //=======================================================================
232 //function : FatherIndex
233 //purpose  : 
234 //=======================================================================
235
236 Standard_Integer XCAFDoc_GraphNode::FatherIndex(const Handle(XCAFDoc_GraphNode)& F) const
237 {
238   Standard_Integer Findex = 0;
239   if (NbFathers()!=0) {
240     for (Findex = 1 ; Findex <= NbFathers(); Findex++) {
241       if ( F == myFathers.Value(Findex)) return Findex;
242     }
243   }
244   return 0;
245 }
246
247 //=======================================================================
248 //function : ChildIndex
249 //purpose  : 
250 //=======================================================================
251
252  Standard_Integer XCAFDoc_GraphNode::ChildIndex(const Handle(XCAFDoc_GraphNode)& Ch) const
253 {
254   Standard_Integer Chindex;
255   if (NbChildren()!=0) {
256     for (Chindex = 1; Chindex <= NbChildren(); Chindex++) {
257       if ( Ch == myChildren.Value(Chindex)) return Chindex;
258     }
259   }
260   return 0;
261 }
262
263 //=======================================================================
264 //function : IsFather
265 //purpose  : 
266 //=======================================================================
267
268  Standard_Boolean XCAFDoc_GraphNode::IsFather(const Handle(XCAFDoc_GraphNode)& Ch) const
269 {
270   if ( ChildIndex(Ch) ) return Standard_True;
271   return Standard_False;
272 }
273
274 //=======================================================================
275 //function : IsChild
276 //purpose  : 
277 //=======================================================================
278
279  Standard_Boolean XCAFDoc_GraphNode::IsChild(const Handle(XCAFDoc_GraphNode)& F) const
280 {
281   if ( FatherIndex(F) ) return Standard_True;
282   return Standard_False;
283 }
284
285 //=======================================================================
286 //function : NbFathers
287 //purpose  : 
288 //=======================================================================
289
290  Standard_Integer XCAFDoc_GraphNode::NbFathers() const
291 {
292   return myFathers.Length();
293 }
294
295 //=======================================================================
296 //function : NbChildren
297 //purpose  : 
298 //=======================================================================
299
300  Standard_Integer XCAFDoc_GraphNode::NbChildren() const
301 {
302   return myChildren.Length();
303 }
304
305
306
307 //     Implementation of Attribute methods:  
308 //     ===================================  
309
310 //=======================================================================
311 //function : ID
312 //purpose  : 
313 //=======================================================================
314
315 const Standard_GUID& XCAFDoc_GraphNode::ID() const
316 {
317   return myGraphID;
318 }
319
320
321 //=======================================================================
322 //function : Restore
323 //purpose  : 
324 //=======================================================================
325
326 void XCAFDoc_GraphNode::Restore(const Handle(TDF_Attribute)& other) 
327 {
328   Handle(XCAFDoc_GraphNode) F =  Handle(XCAFDoc_GraphNode)::DownCast(other);
329   myFathers     = F->myFathers;
330   myChildren    = F->myChildren;
331   myGraphID     = F->myGraphID;
332 }
333
334
335 //=======================================================================
336 //function : Paste
337 //purpose  : 
338 //=======================================================================
339
340 void XCAFDoc_GraphNode::Paste(const Handle(TDF_Attribute)& into,
341                               const Handle(TDF_RelocationTable)& RT) const
342 {
343   Handle(XCAFDoc_GraphNode) intof = Handle(XCAFDoc_GraphNode)::DownCast(into);
344   Handle(XCAFDoc_GraphNode) func;
345   Standard_Integer i = 1;
346   for (; i <= NbFathers(); i++) {
347     if (!RT->HasRelocation(myFathers(i), func) && RT->AfterRelocate()) {
348       func.Nullify();
349     }
350     intof->SetFather(func);
351   }
352
353   i = 1;
354   for (; i <= NbChildren(); i++) {
355     if (!RT->HasRelocation(myChildren(i), func) && RT->AfterRelocate()) {
356       func.Nullify();
357     }
358     intof->SetFather(func);
359   }
360   intof->SetGraphID(myGraphID);
361 }
362
363
364 //=======================================================================
365 //function : NewEmpty
366 //purpose  : 
367 //=======================================================================
368
369 Handle(TDF_Attribute) XCAFDoc_GraphNode::NewEmpty() const
370 {
371   Handle(XCAFDoc_GraphNode) G = new XCAFDoc_GraphNode();
372   G->SetGraphID(myGraphID);
373   return G;
374 }
375
376
377 //=======================================================================
378 //function : References
379 //purpose  : 
380 //=======================================================================
381
382 void XCAFDoc_GraphNode::References(const Handle(TDF_DataSet)& aDataSet) const
383 {
384   Standard_Integer i;
385   Handle(XCAFDoc_GraphNode) fct;
386   for ( i = 1; i <= NbChildren(); i++ ) {
387     fct = myChildren(i);
388     if (!fct.IsNull()) {
389       aDataSet->AddAttribute(fct);
390     }
391   }
392   for ( i = 1; i <= NbFathers(); i++ ) {
393     fct = myFathers(i);
394     if ( !fct.IsNull()) {
395       aDataSet->AddAttribute(fct);
396     }
397   }
398  
399 }
400
401 //=======================================================================
402 //function : Dump
403 //purpose  : 
404 //=======================================================================
405
406 Standard_OStream& XCAFDoc_GraphNode::Dump (Standard_OStream& anOS) const
407 {
408   TDF_Attribute::Dump (anOS);
409   Standard_Integer i = 1;
410   if ( myFathers.Length()!= 0 ) {
411     anOS<<"  Fathers=";
412     for (; i <= NbFathers(); i++) {
413       if ( !myFathers(i)->Label().IsNull() ) 
414         myFathers(i)->Label().EntryDump(anOS);
415       anOS<<endl;
416     }
417   }
418   i = 1;
419   if ( myChildren.Length()!= 0 ) {
420     anOS<<"  Children=";
421     for (; i <= NbChildren(); i++) {
422       if ( !myChildren(i)->Label().IsNull() )
423         myChildren(i)->Label().EntryDump(anOS);
424       anOS<<endl;
425     }
426   }
427 //  anOS<<endl;
428   return anOS;
429 }
430
431 //=======================================================================
432 //function : BeforeForget
433 //purpose  : 
434 //=======================================================================
435
436 void XCAFDoc_GraphNode::BeforeForget()
437 {
438   while ( myFathers.Length() > 0 ) 
439     UnSetFather(1);
440   while ( myChildren.Length() > 0 )
441     UnSetChild(1);
442 }