956a415ea8b34ff8f0451b3fee0825ece4f91841
[occt.git] / src / TDF / TDF_LabelNode.cxx
1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-1999 Matra Datavision
3 // Copyright (c) 1999-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 // Version:     0.0
23 //Version Date            Purpose
24 //              0.0     Feb  6 1997     Creation
25 //              MSV 21.03.2003: protect against stack overflow in destructor
26
27
28 #include <TDF_LabelNode.hxx>
29
30 #include <TDF_Data.hxx>
31 #include <TDF_Label.hxx>
32
33 //=======================================================================
34 //function : TDF_LabelNode
35 //purpose  : Constructor with TDF_Data*, only used for root node.
36 //=======================================================================
37
38 TDF_LabelNode::TDF_LabelNode
39 (TDF_Data* aDataPtr)
40 : myFather          (NULL), // The sign it is the root.
41 #ifdef KEEP_LOCAL_ROOT
42   myBrother         (NULL),
43 #else
44   myBrother         ((TDF_LabelNode *)aDataPtr),
45 #endif
46   myFirstChild      (NULL),
47   myLastFoundChild  (NULL), //jfa 10.01.2003
48   myTag             (0), // Always 0 for root.
49   myFlags           (0),
50 #ifdef KEEP_LOCAL_ROOT
51   myData            (aDataPtr)
52 #endif
53 {
54 #ifdef DEB
55   myDebugEntry = '0';
56 #endif
57 }
58
59
60 //=======================================================================
61 //function : TDF_LabelNode
62 //purpose  : Constructor
63 //=======================================================================
64
65 TDF_LabelNode::TDF_LabelNode
66 (const Standard_Integer aTag, TDF_LabelNode* aFather)
67 : myFather          (aFather),
68   myBrother         (NULL),
69   myFirstChild      (NULL),
70   myLastFoundChild  (NULL), //jfa 10.01.2003
71   myTag             (aTag),
72   myFlags           (0),
73 #ifdef KEEP_LOCAL_ROOT
74   myData            (NULL)
75 #endif
76 {
77   if (aFather != NULL) {
78     Depth(aFather->Depth() + 1);
79 #ifdef KEEP_LOCAL_ROOT
80     myData = aFather -> Data();
81 #endif
82   }
83 #ifdef DEB
84   myDebugEntry = myFather->myDebugEntry;
85   myDebugEntry += ':';
86   myDebugEntry += aTag;
87 #endif
88 }
89
90 //=======================================================================
91 //function : ~TDF_LabelNode
92 //purpose  : 
93 //=======================================================================
94
95 TDF_LabelNode::~TDF_LabelNode()
96 {
97   // MSV 21.03.2003: do not delete brother, rather delete all children in a loop
98   //                 to avoid stack overflow
99   while (myFirstChild != NULL) {
100     TDF_LabelNode* aSecondChild = myFirstChild->Brother();
101     delete myFirstChild;
102     myFirstChild = aSecondChild;
103   }
104   myFirstAttribute.Nullify();
105   myLastFoundChild = NULL;      //jfa 10.01.2003
106 }
107
108 //=======================================================================
109 //function : AddAttribute
110 //purpose  : Adds an attribute at the first or the specified position.
111 //=======================================================================
112
113 void TDF_LabelNode::AddAttribute
114 (const Handle(TDF_Attribute)& afterAtt,
115  const Handle(TDF_Attribute)& newAtt)
116 {
117   newAtt->myFlags = 1; // Valid.
118   newAtt->myLabelNode  = this;
119   if (afterAtt.IsNull()) { // Inserts at beginning.
120     newAtt->myNext   = myFirstAttribute;
121     myFirstAttribute = newAtt;
122   }
123   else { // Inserts at specified place.
124     newAtt->myNext   = afterAtt->myNext;
125     afterAtt->myNext = newAtt;
126   }
127 }
128
129
130 //=======================================================================
131 //function : RemoveAttribute
132 //purpose  : Removes an attribute from the first or the specified position.
133 //=======================================================================
134
135 void TDF_LabelNode::RemoveAttribute
136 (const Handle(TDF_Attribute)& afterAtt,
137  const Handle(TDF_Attribute)& oldAtt)
138 {
139   oldAtt->myFlags = 0; // Unvalid.
140   oldAtt->myLabelNode  = NULL;
141   if (afterAtt.IsNull()) { // Removes from beginning.
142     myFirstAttribute = oldAtt->myNext;
143   }
144   else { // Removes from specified place.
145     afterAtt->myNext = oldAtt->myNext;
146   }
147   // Nullifier le next induit l'iterateur d'attribut en erreur.
148   //oldAtt->myNext.Nullify();
149 }
150
151
152 //=======================================================================
153 //function : RootNode
154 //purpose  : used for non const object.
155 //=======================================================================
156
157 TDF_LabelNode* TDF_LabelNode::RootNode ()
158 {
159 #ifdef KEEP_LOCAL_ROOT
160   return myData? myData -> myRoot: 0L;
161 #else
162   TDF_LabelNode* lp = this;
163   while (lp->myFather != NULL) lp = lp->myFather;
164   return lp;
165 #endif
166 }
167
168
169 //=======================================================================
170 //function : RootNode
171 //purpose  : used for const object.
172 //=======================================================================
173
174 const TDF_LabelNode* TDF_LabelNode::RootNode () const
175 {
176 #ifdef KEEP_LOCAL_ROOT
177   return myData? myData -> myRoot: 0L;
178 #else
179   const TDF_LabelNode* lp = this;
180   while (lp->myFather != NULL) lp = lp->myFather;
181   return lp;
182 #endif
183 }
184
185
186 //=======================================================================
187 //function : Data
188 //purpose  : 
189 //=======================================================================
190
191 TDF_Data * TDF_LabelNode::Data () const
192 {
193 #ifdef KEEP_LOCAL_ROOT
194   return myData;
195 #else
196   const TDF_LabelNode* ln = RootNode()->myBrother;
197   return ((TDF_Data*) ln);
198 #endif
199 }
200
201
202 //=======================================================================
203 //function : AllMayBeModified
204 //purpose  : 
205 //=======================================================================
206
207 void TDF_LabelNode::AllMayBeModified()
208 {
209   MayBeModified(Standard_True);
210   if (myFather && !myFather->MayBeModified()) myFather->AllMayBeModified();
211 }