0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / TDataStd / TDataStd_ReferenceList.cxx
1 // Created on: 2007-05-29
2 // Created by: Vlad Romashko
3 // Copyright (c) 2007-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 <TDataStd_ReferenceList.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_ListIteratorOfLabelList.hxx>
25 #include <TDF_RelocationTable.hxx>
26 #include <TDF_Tool.hxx>
27
28 IMPLEMENT_STANDARD_RTTIEXT(TDataStd_ReferenceList,TDF_Attribute)
29
30 //=======================================================================
31 //function : GetID
32 //purpose  : 
33 //=======================================================================
34 const Standard_GUID& TDataStd_ReferenceList::GetID() 
35
36   static Standard_GUID TDataStd_ReferenceListID ("FCC1A658-59FF-4218-931B-0320A2B469A7");
37   return TDataStd_ReferenceListID; 
38 }
39
40 //=======================================================================
41 //function : SetAttr
42 //purpose  : Implements Set functionality
43 //=======================================================================
44 static Handle(TDataStd_ReferenceList) SetAttr(const TDF_Label&       label,
45                                               const Standard_GUID&   theGuid) 
46 {
47   Handle(TDataStd_ReferenceList) A;
48   if (!label.FindAttribute (theGuid, A)) 
49   {
50     A = new TDataStd_ReferenceList;
51     A->SetID(theGuid);
52     label.AddAttribute(A);
53   }
54   return A;
55 }
56
57 //=======================================================================
58 //function : TDataStd_ReferenceList
59 //purpose  : Empty Constructor
60 //=======================================================================
61 TDataStd_ReferenceList::TDataStd_ReferenceList() : myID(GetID())
62 {}
63
64 //=======================================================================
65 //function : Set
66 //purpose  : 
67 //=======================================================================
68 Handle(TDataStd_ReferenceList) TDataStd_ReferenceList::Set(const TDF_Label& label) 
69 {
70   return SetAttr(label, GetID());
71 }
72
73 //=======================================================================
74 //function : Set
75 //purpose  : Set user defined attribute with specific ID
76 //=======================================================================
77 Handle(TDataStd_ReferenceList) TDataStd_ReferenceList::Set(const TDF_Label& label,
78                                                            const Standard_GUID&   theGuid) 
79 {
80   return SetAttr(label, theGuid);
81 }
82
83 //=======================================================================
84 //function : IsEmpty
85 //purpose  : 
86 //=======================================================================
87 Standard_Boolean TDataStd_ReferenceList::IsEmpty() const
88 {
89   return myList.IsEmpty();
90 }
91
92 //=======================================================================
93 //function : Extent
94 //purpose  : 
95 //=======================================================================
96 Standard_Integer TDataStd_ReferenceList::Extent() const
97 {
98   return myList.Extent();
99 }
100
101 //=======================================================================
102 //function : Prepend
103 //purpose  : 
104 //=======================================================================
105 void TDataStd_ReferenceList::Prepend(const TDF_Label& value)
106 {
107   Backup();
108   myList.Prepend(value);
109 }
110
111 //=======================================================================
112 //function : Append
113 //purpose  : 
114 //=======================================================================
115 void TDataStd_ReferenceList::Append(const TDF_Label& value)
116 {
117   Backup();
118   myList.Append(value);
119 }
120
121 //=======================================================================
122 //function : InsertBefore
123 //purpose  : 
124 //=======================================================================
125 Standard_Boolean TDataStd_ReferenceList::InsertBefore(const TDF_Label& value,
126                                                       const TDF_Label& before_value)
127 {
128   TDF_ListIteratorOfLabelList itr(myList);
129   for (; itr.More(); itr.Next())
130   {
131     if (itr.Value() == before_value)
132     {
133       Backup();
134       myList.InsertBefore(value, itr);
135       return Standard_True;
136     }
137   }
138   return Standard_False;
139 }
140
141 // Inserts the label before the <index> position.
142 // The indices start with 1 .. Extent().
143 Standard_Boolean TDataStd_ReferenceList::InsertBefore (const Standard_Integer index,
144                                                        const TDF_Label& before_value)
145 {
146   Standard_Integer i(1);
147   Standard_Boolean found(Standard_False);
148   TDF_ListIteratorOfLabelList itr(myList);
149   for (; itr.More(); itr.Next(), ++i)
150   {
151     if (i == index)
152     {
153       Backup();
154       myList.InsertBefore(before_value, itr);
155       found = Standard_True;
156       break;
157     }
158   }
159   return found;
160 }
161
162 //=======================================================================
163 //function : InsertAfter
164 //purpose  : 
165 //=======================================================================
166 Standard_Boolean TDataStd_ReferenceList::InsertAfter(const TDF_Label& value,
167                                                      const TDF_Label& after_value)
168 {
169   TDF_ListIteratorOfLabelList itr(myList);
170   for (; itr.More(); itr.Next())
171   {
172     if (itr.Value() == after_value)
173     {
174       Backup();
175       myList.InsertAfter(value, itr);
176       return Standard_True;
177     }
178   }
179   return Standard_False;
180 }
181
182 // Inserts the label after the <index> position.
183 // The indices start with 1 .. Extent().
184 Standard_Boolean TDataStd_ReferenceList::InsertAfter (const Standard_Integer index,
185                                                       const TDF_Label& after_value)
186 {
187   Standard_Integer i(1);
188   Standard_Boolean found(Standard_False);
189   TDF_ListIteratorOfLabelList itr(myList);
190   for (; itr.More(); itr.Next(), ++i)
191   {
192     if (i == index)
193     {
194       Backup();
195       myList.InsertAfter(after_value, itr);
196       found = Standard_True;
197       break;
198     }
199   }
200   return found;
201 }
202
203 //=======================================================================
204 //function : Remove
205 //purpose  : 
206 //=======================================================================
207 Standard_Boolean TDataStd_ReferenceList::Remove(const TDF_Label& value)
208 {
209   TDF_ListIteratorOfLabelList itr(myList);
210   for (; itr.More(); itr.Next())
211   {
212     if (itr.Value() == value)
213     {
214       Backup();
215       myList.Remove(itr);
216       return Standard_True;
217     }
218   }
219   return Standard_False;
220 }
221
222 //=======================================================================
223 //function : Remove
224 //purpose  : Removes a label at the <index> position.
225 //=======================================================================
226 Standard_Boolean TDataStd_ReferenceList::Remove (const Standard_Integer index)
227 {
228   Standard_Integer i(1);
229   Standard_Boolean found(Standard_False);
230   TDF_ListIteratorOfLabelList itr(myList);
231   for (; itr.More(); itr.Next(), ++i)
232   {
233     if (i == index)
234     {
235       Backup();
236       myList.Remove(itr);
237       found = Standard_True;
238       break;
239     }
240   }
241   return found;
242 }
243
244 //=======================================================================
245 //function : Clear
246 //purpose  : 
247 //=======================================================================
248 void TDataStd_ReferenceList::Clear()
249 {
250   Backup();
251   myList.Clear();
252 }
253
254 //=======================================================================
255 //function : First
256 //purpose  : 
257 //=======================================================================
258 const TDF_Label& TDataStd_ReferenceList::First() const
259 {
260   return myList.First();
261 }
262
263 //=======================================================================
264 //function : Last
265 //purpose  : 
266 //=======================================================================
267 const TDF_Label& TDataStd_ReferenceList::Last() const
268 {
269   return myList.Last();
270 }
271
272 //=======================================================================
273 //function : List
274 //purpose  : 
275 //=======================================================================
276 const TDF_LabelList& TDataStd_ReferenceList::List() const
277 {
278   return myList;
279 }
280
281 //=======================================================================
282 //function : ID
283 //purpose  : 
284 //=======================================================================
285 const Standard_GUID& TDataStd_ReferenceList::ID () const 
286
287   return myID; 
288 }
289
290 //=======================================================================
291 //function : SetID
292 //purpose  :
293 //=======================================================================
294 void TDataStd_ReferenceList::SetID( const Standard_GUID&  theGuid)
295 {  
296   if(myID == theGuid) return;
297   Backup();
298   myID = theGuid;
299 }
300
301 //=======================================================================
302 //function : SetID
303 //purpose  : sets default ID
304 //=======================================================================
305 void TDataStd_ReferenceList::SetID()
306 {  
307   Backup();
308   myID = GetID();
309 }
310
311 //=======================================================================
312 //function : NewEmpty
313 //purpose  : 
314 //=======================================================================
315 Handle(TDF_Attribute) TDataStd_ReferenceList::NewEmpty () const
316 {
317   return new TDataStd_ReferenceList(); 
318 }
319
320 //=======================================================================
321 //function : Restore
322 //purpose  : 
323 //=======================================================================
324 void TDataStd_ReferenceList::Restore(const Handle(TDF_Attribute)& With) 
325 {
326   myList.Clear();
327   Handle(TDataStd_ReferenceList) aList = Handle(TDataStd_ReferenceList)::DownCast(With);
328   TDF_ListIteratorOfLabelList itr(aList->List());
329   for (; itr.More(); itr.Next())
330   {
331     myList.Append(itr.Value());
332   }
333   myID = aList->ID();
334 }
335
336 //=======================================================================
337 //function : Paste
338 //purpose  : 
339 //=======================================================================
340 void TDataStd_ReferenceList::Paste (const Handle(TDF_Attribute)& Into,
341                                     const Handle(TDF_RelocationTable)& RT) const
342 {
343   Handle(TDataStd_ReferenceList) aList = Handle(TDataStd_ReferenceList)::DownCast(Into);
344   aList->Clear();
345   TDF_ListIteratorOfLabelList itr(myList);
346   for (; itr.More(); itr.Next())
347   {
348     TDF_Label L = itr.Value(), rL;
349     if (!L.IsNull())
350     {
351       if (!RT->HasRelocation(L, rL))
352         rL = L;
353       aList->Append(rL);
354     }
355   }
356   aList->SetID(myID);
357 }
358
359 //=======================================================================
360 //function : References
361 //purpose  : Adds the referenced attributes or labels.
362 //=======================================================================
363 void TDataStd_ReferenceList::References(const Handle(TDF_DataSet)& aDataSet) const
364 {
365   if (!Label().IsImported()) 
366   {
367     TDF_ListIteratorOfLabelList itr(myList);
368     for (; itr.More(); itr.Next())
369     {
370       aDataSet->AddLabel(itr.Value());
371     }
372   }
373 }
374
375 //=======================================================================
376 //function : Dump
377 //purpose  : 
378 //=======================================================================
379 Standard_OStream& TDataStd_ReferenceList::Dump (Standard_OStream& anOS) const
380 {  
381   anOS << "\nReferenceList: ";
382   Standard_Character sguid[Standard_GUID_SIZE_ALLOC];
383   myID.ToCString(sguid);
384   anOS << sguid;
385   anOS << std::endl;
386   return anOS;
387 }
388
389 //=======================================================================
390 //function : DumpJson
391 //purpose  : 
392 //=======================================================================
393 void TDataStd_ReferenceList::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
394 {
395   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
396
397   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
398
399   TCollection_AsciiString aLabel;
400   for (TDF_LabelList::Iterator aListIt (myList); aListIt.More(); aListIt.Next())
401   {
402     aLabel.Clear();
403     TDF_Tool::Entry (aListIt.Value(), aLabel);
404     OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aLabel)
405   }
406
407   OCCT_DUMP_FIELD_VALUE_GUID (theOStream, myID)
408 }