0031435: Data Exchange - Problem importing STEP files
[occt.git] / src / Interface / Interface_EntityCluster.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
42cf5bc1 14
15#include <Interface_EntityCluster.hxx>
16#include <Interface_EntityIterator.hxx>
17#include <Interface_EntityList.hxx>
7fd59977 18#include <Standard_NullObject.hxx>
42cf5bc1 19#include <Standard_OutOfRange.hxx>
20#include <Standard_Transient.hxx>
21#include <Standard_Type.hxx>
e00b8ed9 22#include <NCollection_Sequence.hxx>
7fd59977 23
25e59720 24IMPLEMENT_STANDARD_RTTIEXT(Interface_EntityCluster,Standard_Transient)
92efcf78 25
7fd59977 26// Un Cluster, ce sont 4 entites qui se suivent (dans le principe, nombre fixe,
27// meme si pas 4). Elles sont remplies depuis 0. Il y a donc autant d Entites
28// que de Handles non Nuls, plus le fait qu ils sont remplis dans l ordre
7fd59977 29// Ainsi (avec Next), on consomme 5 Handles pour 4 Entites, avec une pointe
30// pour 1 et 2 Entites (on reste a 5 Handles)
7fd59977 31// Suppression : On retasse le Cluster pour que les Nulls soient tjrs a la fin
7fd59977 32// .... CONSTRUCTEURS ....
b311480e 33Interface_EntityCluster::Interface_EntityCluster () { }
7fd59977 34
35 Interface_EntityCluster::Interface_EntityCluster
36 (const Handle(Standard_Transient)& ent)
37 { theents[0] = ent; }
38
39 Interface_EntityCluster::Interface_EntityCluster
40 (const Handle(Interface_EntityCluster)& ec)
41 { thenext = ec; }
42
43 Interface_EntityCluster::Interface_EntityCluster
44 (const Handle(Standard_Transient)& ent,
45 const Handle(Interface_EntityCluster)& ec)
46 { theents[0] = ent; thenext = ec; }
47
48// .... AJOUT - SUPPRESSION ....
49
50 void Interface_EntityCluster::Append
51 (const Handle(Standard_Transient)& ent)
52{
9775fa61 53 if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster Append");
7fd59977 54 if (theents[0].IsNull()) theents[0] = ent;
55 else if (theents[1].IsNull()) theents[1] = ent;
56 else if (theents[2].IsNull()) theents[2] = ent;
57 else if (theents[3].IsNull()) theents[3] = ent;
58 else { // Si celui-ci est plein ...
59 if (thenext.IsNull()) thenext = new Interface_EntityCluster(ent);
e00b8ed9 60 else {
61 Handle(Interface_EntityCluster) aCurEntClust = thenext;
62 while (aCurEntClust->HasNext() && aCurEntClust->IsLocalFull())
63 aCurEntClust = aCurEntClust->thenext;
64 aCurEntClust->Append(ent);
65 }
7fd59977 66 }
67}
68
69 Standard_Boolean Interface_EntityCluster::Remove
70 (const Handle(Standard_Transient)& ent)
71{
9775fa61 72 if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster Remove");
7fd59977 73 Standard_Integer i;
74// <ent> est-il ici ? si oui, on a son rang
75 if (ent == theents[0]) i = 1;
76 else if (ent == theents[1]) i = 2;
77 else if (ent == theents[2]) i = 3;
78 else if (ent == theents[3]) i = 4;
79
80// Sinon, passer au suivant, qui peut du coup devenir vide ->
81// On enleve le cluster vide de la liste (en principe cest le dernier)
82 else { // Pas trouve dans celui-ci ...
83 if (thenext.IsNull()) return Standard_False;
84 Standard_Integer res = thenext->Remove(ent);
85 if (res) thenext = thenext->Next();
86 return Standard_False;
87 }
88 return Remove(i);
89}
90
91 Standard_Boolean Interface_EntityCluster::Remove
92 (const Standard_Integer num)
93{
9775fa61 94 if (num < 1) throw Standard_OutOfRange("EntityCluster : Remove");
7fd59977 95 Standard_Integer n = NbLocal();
96 if (num > n) {
9775fa61 97 if (thenext.IsNull()) throw Standard_OutOfRange("EntityCluster : Remove");
7fd59977 98 Standard_Boolean res = thenext->Remove (num-n);
99 if (res) thenext = thenext->Next();
100 return Standard_False;
101 }
102 for (Standard_Integer j = num; j < n; j --) theents[j-1] = theents[j];
103 theents[3].Nullify(); // On Nullify par la fin
104 return (n == 1); // Ancien NbLocal == 1 -> devient nul
105}
106
107// .... ACCES AUX DONNEES ....
108
109 Standard_Integer Interface_EntityCluster::NbEntities() const
110{
111 Standard_Integer nb = NbLocal();
112 if (!thenext.IsNull()) nb += thenext->NbEntities();
113 return nb;
114}
115
116 const Handle(Standard_Transient)& Interface_EntityCluster::Value
117 (const Standard_Integer num) const
118{
e00b8ed9 119 Standard_Integer nb = NbLocal(), aLocalNum=num;
9775fa61 120 if (num <= 0) throw Standard_OutOfRange("Interface EntityCluster : Value");
e00b8ed9 121 if (num > nb) {
122 Handle(Interface_EntityCluster) aCurEntClust = thenext;
123 aLocalNum -= nb;
124 while (aLocalNum>aCurEntClust->NbLocal())
125 {
126 if (!aCurEntClust->HasNext()) throw Standard_OutOfRange("Interface EntityCluster : Value");
127 aCurEntClust = aCurEntClust->thenext;
128 aLocalNum-= nb;
129 }
130 return aCurEntClust->theents[aLocalNum - 1];
7fd59977 131 }
132 return theents[num-1]; // numerotation a partir de 0
133}
134
135 void Interface_EntityCluster::SetValue
136 (const Standard_Integer num, const Handle(Standard_Transient)& ent)
e00b8ed9 137{
9775fa61 138 if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster SetValue");
e00b8ed9 139 Standard_Integer nb = NbLocal(), aLocalNum = num;
9775fa61 140 if (num <= 0) throw Standard_OutOfRange("Interface EntityCluster : SetValue");
e00b8ed9 141 if (num > nb)
142 {
143 Handle(Interface_EntityCluster) aCurEntClust = thenext;
144 aLocalNum -= nb;
145 while (aLocalNum > aCurEntClust->NbLocal())
146 {
147 if (thenext.IsNull()) throw Standard_OutOfRange("Interface EntityCluster : SetValue");
148 aCurEntClust = aCurEntClust->thenext;
149 aLocalNum -= nb;
150 }
151 aCurEntClust->theents[aLocalNum - 1] = ent;
7fd59977 152 }
153 else theents[num-1] = ent; // numerotation a partir de 0
154}
155
156 void Interface_EntityCluster::FillIterator
157 (Interface_EntityIterator& iter) const
158{
159 if (!theents[0].IsNull()) iter.GetOneItem(theents[0]);
160 if (!theents[1].IsNull()) iter.GetOneItem(theents[1]);
161 if (!theents[2].IsNull()) iter.GetOneItem(theents[2]);
162 if (!theents[3].IsNull()) iter.GetOneItem(theents[3]);
163 if (!thenext.IsNull()) thenext->FillIterator(iter);
164}
165
166// .... Actions atomiques internes ....
167
168Standard_Boolean Interface_EntityCluster::IsLocalFull () const
169{
170 // Solaris Forte C++ compiler insisted it couldn't cast this,
171 // even though it seems to do so elsewhere
857ffd5e 172 Handle(Standard_Transient) tmp = Handle(Standard_Transient)(theents[3]);
7fd59977 173 return ( !tmp.IsNull() );
174}
175
176 Standard_Integer Interface_EntityCluster::NbLocal () const
177{
178 Standard_Integer nb;
179 if (!theents[3].IsNull()) nb = 4;
180 else if (!theents[2].IsNull()) nb = 3;
181 else if (!theents[1].IsNull()) nb = 2;
182 else if (!theents[0].IsNull()) nb = 1;
183 else nb = 0;
184 return nb;
185}
186
187 Standard_Boolean Interface_EntityCluster::HasNext () const
188 { return (!thenext.IsNull()); }
189
190 Handle(Interface_EntityCluster) Interface_EntityCluster::Next () const
191 { return thenext; }
e00b8ed9 192
193Interface_EntityCluster::~Interface_EntityCluster()
194{
195 if (!thenext.IsNull())
196 {
197 //Loading entities into the collection
198 //for deletion in reverse order(avoiding the recursion)
199 NCollection_Sequence<Handle(Interface_EntityCluster)> aNColOfEntClust;
200 Handle(Interface_EntityCluster) aCurEntClust = thenext;
201 while (aCurEntClust->HasNext())
202 {
203 aNColOfEntClust.Append(aCurEntClust);
204 aCurEntClust = aCurEntClust->Next();
205 }
206 aNColOfEntClust.Append(aCurEntClust);
207 aNColOfEntClust.Reverse();
208 for (NCollection_Sequence<Handle(Interface_EntityCluster)>::Iterator anEntClustIter(aNColOfEntClust);
209 anEntClustIter.More(); anEntClustIter.Next())
210 {
211 //Nullifying and destruction all fields of each entity in the collection
212 for (Standard_Integer anInd = 0; anInd < anEntClustIter.ChangeValue()->NbLocal(); ++anInd)
213 {
214 anEntClustIter.ChangeValue()->theents[anInd].Nullify();
215 }
216 anEntClustIter.ChangeValue()->thenext.Nullify();
217 }
218 }
219 for (Standard_Integer anInd = 0; anInd < NbLocal(); ++anInd)
220 {
221 theents[anInd].Nullify();
222 }
223 thenext.Nullify();
224}
225
226