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