0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / Interface / Interface_EntityCluster.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Interface_EntityCluster.ixx>
15 #include <Standard_OutOfRange.hxx>
16 #include <Standard_NullObject.hxx>
17
18 // Un Cluster, ce sont 4 entites qui se suivent (dans le principe, nombre fixe,
19 // meme si pas 4). Elles sont remplies depuis 0. Il y a donc autant d Entites
20 // que de Handles non Nuls, plus le fait qu ils sont remplis dans l ordre
21
22 // Ainsi (avec Next), on consomme 5 Handles pour 4 Entites, avec une pointe
23 // pour 1 et 2 Entites (on reste a 5 Handles)
24
25 // Suppression : On retasse le Cluster pour que les Nulls soient tjrs a la fin
26
27 //  ....                        CONSTRUCTEURS                        ....
28
29 Interface_EntityCluster::Interface_EntityCluster ()    {  }
30
31     Interface_EntityCluster::Interface_EntityCluster
32   (const Handle(Standard_Transient)& ent)
33       {  theents[0] = ent;  }
34
35     Interface_EntityCluster::Interface_EntityCluster
36   (const Handle(Interface_EntityCluster)& ec)
37       {  thenext = ec;  }
38
39     Interface_EntityCluster::Interface_EntityCluster
40   (const Handle(Standard_Transient)& ent,
41    const Handle(Interface_EntityCluster)& ec)
42       {  theents[0] = ent;  thenext = ec;  }
43
44 //  ....                        AJOUT - SUPPRESSION                        ....
45
46     void  Interface_EntityCluster::Append
47   (const Handle(Standard_Transient)& ent)
48 {
49   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityCluster Append");
50   if      (theents[0].IsNull()) theents[0] = ent;
51   else if (theents[1].IsNull()) theents[1] = ent;
52   else if (theents[2].IsNull()) theents[2] = ent;
53   else if (theents[3].IsNull()) theents[3] = ent;
54   else {                                // Si celui-ci est plein ...
55     if (thenext.IsNull()) thenext = new Interface_EntityCluster(ent);
56     else thenext->Append(ent);
57   }
58 }
59
60     Standard_Boolean  Interface_EntityCluster::Remove
61   (const Handle(Standard_Transient)& ent)
62 {
63   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityCluster Remove");
64   Standard_Integer i;
65 //  <ent> est-il ici ? si oui, on a son rang
66   if      (ent == theents[0]) i = 1;
67   else if (ent == theents[1]) i = 2;
68   else if (ent == theents[2]) i = 3;
69   else if (ent == theents[3]) i = 4;
70
71 //  Sinon, passer au suivant, qui peut du coup devenir vide ->
72 //  On enleve le cluster vide de la liste (en principe cest le dernier)
73   else {                                // Pas trouve dans celui-ci ...
74     if (thenext.IsNull()) return Standard_False;
75     Standard_Integer res = thenext->Remove(ent);
76     if (res) thenext = thenext->Next();
77     return Standard_False;
78   }
79   return Remove(i);
80 }
81
82     Standard_Boolean  Interface_EntityCluster::Remove
83   (const Standard_Integer num)
84 {
85   if (num < 1) Standard_OutOfRange::Raise("EntityCluster : Remove");
86   Standard_Integer n = NbLocal();
87   if (num > n) {
88     if (thenext.IsNull()) Standard_OutOfRange::Raise("EntityCluster : Remove");
89     Standard_Boolean res = thenext->Remove (num-n);
90     if (res) thenext = thenext->Next();
91     return Standard_False;
92   }
93   for (Standard_Integer j = num; j < n; j --) theents[j-1] = theents[j];
94   theents[3].Nullify();     // On Nullify par la fin
95   return (n == 1);          // Ancien NbLocal == 1  -> devient nul
96 }
97
98 //  ....                        ACCES AUX DONNEES                        ....
99
100     Standard_Integer  Interface_EntityCluster::NbEntities() const 
101 {
102   Standard_Integer nb = NbLocal();
103   if (!thenext.IsNull()) nb += thenext->NbEntities();
104   return nb;
105 }
106
107     const Handle(Standard_Transient)&  Interface_EntityCluster::Value
108   (const Standard_Integer num) const
109 {
110   Standard_Integer nb = NbLocal();
111   if (num <= 0) Standard_OutOfRange::Raise("Interface EntityCluster : Value");
112   if (num > nb) {
113     if (thenext.IsNull()) Standard_OutOfRange::Raise
114       ("Interface EntityCluster : Value");
115     return thenext->Value(num-nb);
116   }
117   return theents[num-1];  // numerotation a partir de 0
118 }
119
120     void  Interface_EntityCluster::SetValue
121   (const Standard_Integer num, const Handle(Standard_Transient)& ent)
122 {
123   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityCluster SetValue");
124   Standard_Integer nb = NbLocal();
125   if (num <= 0) Standard_OutOfRange::Raise("Interface EntityCluster : SetValue");
126   if (num > nb) {
127     if (thenext.IsNull()) Standard_OutOfRange::Raise
128       ("Interface EntityCluster : SetValue");
129     thenext->SetValue(num-nb,ent);
130   }
131   else theents[num-1] = ent;  // numerotation a partir de 0
132 }
133
134     void  Interface_EntityCluster::FillIterator
135   (Interface_EntityIterator& iter) const 
136 {
137   if (!theents[0].IsNull()) iter.GetOneItem(theents[0]);
138   if (!theents[1].IsNull()) iter.GetOneItem(theents[1]);
139   if (!theents[2].IsNull()) iter.GetOneItem(theents[2]);
140   if (!theents[3].IsNull()) iter.GetOneItem(theents[3]);
141   if (!thenext.IsNull()) thenext->FillIterator(iter);
142 }
143
144 //  ....                    Actions atomiques internes                    ....
145
146 Standard_Boolean  Interface_EntityCluster::IsLocalFull () const 
147 {
148   // Solaris Forte C++ compiler insisted it couldn't cast this,
149   // even though it seems to do so elsewhere
150   Handle(Standard_Transient) tmp = Handle(Standard_Transient)(theents[3]);
151   return ( !tmp.IsNull() );
152 }
153
154     Standard_Integer  Interface_EntityCluster::NbLocal () const
155 {
156   Standard_Integer nb;
157   if      (!theents[3].IsNull()) nb = 4;
158   else if (!theents[2].IsNull()) nb = 3;
159   else if (!theents[1].IsNull()) nb = 2;
160   else if (!theents[0].IsNull()) nb = 1;
161   else                           nb = 0;
162   return nb;
163 }
164
165     Standard_Boolean  Interface_EntityCluster::HasNext () const 
166       {  return (!thenext.IsNull());  }
167
168     Handle(Interface_EntityCluster)  Interface_EntityCluster::Next () const 
169       {  return thenext;  }