b462d4099294551088ca037bd5195a5db80ee8c8
[occt.git] / src / Interface / Interface_EntityList.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
15 #include <Interface_EntityCluster.hxx>
16 #include <Interface_EntityIterator.hxx>
17 #include <Interface_EntityList.hxx>
18 #include <Interface_InterfaceError.hxx>
19 #include <Standard_NullObject.hxx>
20 #include <Standard_OutOfRange.hxx>
21 #include <Standard_Transient.hxx>
22
23 // Une EntityList, c est au fond un "Handle" bien entoure :
24 // S il est nul, la liste est vide
25 // Si c est une Entite, la liste comprend cette entite et rien d autre
26 // Si c est un EntityCluster, il definit (avec ses Next eventuels) le contenu
27 // de la liste
28 Interface_EntityList::Interface_EntityList ()    {  }
29
30     void  Interface_EntityList::Clear ()
31       {  theval.Nullify();  }
32
33 //  ....                EDITIONS (ajout-suppression)                ....
34
35     void  Interface_EntityList::Append
36   (const Handle(Standard_Transient)& ent)
37 {
38   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityList Append");
39   if (theval.IsNull()) {  theval = ent;  return;  }
40   Handle(Interface_EntityCluster) aValEC =
41     Handle(Interface_EntityCluster)::DownCast(theval);
42   if (!aValEC.IsNull()) aValEC->Append(ent);    // EntityCluster
43   else {                                // reste InterfaceEntity ...
44     Handle(Interface_EntityCluster) ec = new Interface_EntityCluster(theval);
45     ec->Append(ent);
46     theval = ec;
47   }
48 }
49
50 // Difference avec Append : on optimise, en evitant la recursivite
51 // En effet, quand un EntityCluster est plein, Append transmet au Next
52 // Ici, EntityList garde le controle, le temps de traitement reste le meme
53 // Moyennant quoi, l ordre n est pas garanti
54
55     void  Interface_EntityList::Add
56   (const Handle(Standard_Transient)& ent)
57 {
58   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityList Add");
59   if (theval.IsNull()) {  theval = ent;  return;  }
60   Handle(Interface_EntityCluster) aValEC =
61     Handle(Interface_EntityCluster)::DownCast(theval);
62   if (!aValEC.IsNull()) {               // EntityCluster
63     if (aValEC->IsLocalFull()) theval = new Interface_EntityCluster(ent, aValEC);
64     else aValEC->Append (ent);
65   } else {                          // reste InterfaceEntity ...
66     Handle(Interface_EntityCluster) ec = new Interface_EntityCluster(theval);
67     ec->Append(ent);
68     theval = ec;
69   }
70 }
71
72 //  Remove : Par Identification d Item a supprimer, ou par Rang
73 //  Identification : Item supprime ou qu il soit
74 //  N.B.: La liste peut devenir vide ... cf retour Remove de Cluster
75
76     void  Interface_EntityList::Remove (const Handle(Standard_Transient)& ent)
77 {
78   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityList Remove");
79   if (theval.IsNull()) return;
80   if (theval == ent) {
81     theval.Nullify();
82     return;
83   }
84   Handle(Interface_EntityCluster) ec =
85     Handle(Interface_EntityCluster)::DownCast(theval);
86   if (ec.IsNull()) return;   // Une seule Entite et pas la bonne
87   Standard_Boolean res = ec->Remove(ent);
88   if (res) theval.Nullify();
89 }
90
91 //  Remove par rang : tester OutOfRange
92
93     void  Interface_EntityList::Remove  (const Standard_Integer num)
94 {
95   if (theval.IsNull()) Standard_OutOfRange::Raise("EntityList : Remove");
96   Handle(Interface_EntityCluster) ec =
97     Handle(Interface_EntityCluster)::DownCast(theval);
98   if (ec.IsNull()) {
99     if (num != 1) Standard_OutOfRange::Raise("EntityList : Remove");
100     theval.Nullify();
101     return;
102   }
103   Standard_Boolean res = ec->Remove(num);
104   if (res) theval.Nullify();
105 }
106
107 //  ....                    ACCES Unitaire AUX DONNEES                    ....
108
109     Standard_Boolean  Interface_EntityList::IsEmpty () const 
110       {  return (theval.IsNull());  }
111
112     Standard_Integer  Interface_EntityList::NbEntities () const 
113 {
114   if (theval.IsNull()) return 0;
115   Handle(Interface_EntityCluster) ec =
116     Handle(Interface_EntityCluster)::DownCast(theval);
117   if (ec.IsNull()) return 1;   // Une seuke Entite
118   return ec->NbEntities();
119 }
120
121
122     const Handle(Standard_Transient)&  Interface_EntityList::Value
123   (const Standard_Integer num) const 
124 {
125   if (theval.IsNull()) Standard_OutOfRange::Raise("Interface EntityList : Value");
126   Handle(Interface_EntityCluster) ec =
127     Handle(Interface_EntityCluster)::DownCast(theval);
128   if (!ec.IsNull()) return ec->Value(num);  // EntityCluster
129   else if (num != 1) Standard_OutOfRange::Raise("Interface EntityList : Value");
130   return theval;
131 }
132
133     void  Interface_EntityList::SetValue
134   (const Standard_Integer num, const Handle(Standard_Transient)& ent)
135 {
136   if (ent.IsNull()) Standard_NullObject::Raise("Interface_EntityList SetValue");
137   if (theval.IsNull()) Standard_OutOfRange::Raise("Interface EntityList : SetValue");
138   Handle(Interface_EntityCluster) ec =
139     Handle(Interface_EntityCluster)::DownCast(theval);
140   if (!ec.IsNull()) ec->SetValue(num,ent);   // EntityCluster
141   else if (num != 1) Standard_OutOfRange::Raise("Interface EntityList : SetValue");
142   else theval = ent;
143
144 }
145
146 //  ....                Interrogations Generales                ....
147
148     void  Interface_EntityList::FillIterator
149   (Interface_EntityIterator& iter) const 
150 {
151   if (theval.IsNull()) return;
152   Handle(Interface_EntityCluster) ec =
153     Handle(Interface_EntityCluster)::DownCast(theval);
154   if (!ec.IsNull()) ec->FillIterator(iter);    // EntityCluster;
155   else iter.GetOneItem(theval);
156 }
157
158
159     Standard_Integer Interface_EntityList::NbTypedEntities
160   (const Handle(Standard_Type)& atype) const
161 {
162   Standard_Integer res = 0;
163   if (theval.IsNull()) return 0;
164   Handle(Interface_EntityCluster) ec =
165     Handle(Interface_EntityCluster)::DownCast(theval);
166   if (!ec.IsNull()) {                // EntityCluster
167     while (!ec.IsNull()) {
168       for (Standard_Integer i = ec->NbLocal(); i > 0; i --) {
169         if (ec->Value(i)->IsKind(atype)) res ++;
170       }
171       if (!ec->HasNext()) break;
172       ec = ec->Next();
173     }
174   } else {                           // Une seule Entite
175     if (theval->IsKind(atype)) res = 1;
176   }
177   return res;
178 }
179
180     Handle(Standard_Transient) Interface_EntityList::TypedEntity
181   (const Handle(Standard_Type)& atype, const Standard_Integer num) const
182 {
183   Standard_Integer res = 0;
184   Handle(Standard_Transient) entres;
185   if (theval.IsNull()) Interface_InterfaceError::Raise
186     ("Interface EntityList : TypedEntity , none found");
187   Handle(Interface_EntityCluster) ec =
188     Handle(Interface_EntityCluster)::DownCast(theval);
189   if (!ec.IsNull()) {                // EntityCluster
190     while (!ec.IsNull()) {
191       for (Standard_Integer i = ec->NbLocal(); i > 0; i --) {
192         if (ec->Value(i)->IsKind(atype)) {
193           res ++;
194           if (num == 0 && res > 1) Interface_InterfaceError::Raise
195             ("Interface EntityList : TypedEntity , several found");
196           entres = ec->Value(i);
197           if (res == num) return entres;
198         }
199       }
200       if (!ec->HasNext()) break;
201       ec = ec->Next();
202     }
203   } else if (num > 1) {
204     Interface_InterfaceError::Raise
205       ("Interface EntityList : TypedEntity ,out of range");
206   } else {                          // InterfaceEntity
207     if (!theval->IsKind(atype)) Interface_InterfaceError::Raise
208       ("Interface EntityList : TypedEntity , none found");
209     entres = theval;
210   }
211   return entres;
212 }