Salome HOME
Copyrights update
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_PassKey.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 // File:        GEOMAlgo_PassKey.cxx
21 // Created:     
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <GEOMAlgo_PassKey.ixx>
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31
32 #ifdef WNT
33 #pragma warning( disable : 4101) 
34 #endif
35
36 static 
37   void SortShell(const int n, int* a); 
38 static
39   Standard_Integer NormalizedId(const Standard_Integer aId,
40                                 const Standard_Integer aDiv);
41
42 //=======================================================================
43 //function :
44 //purpose  : 
45 //=======================================================================
46   GEOMAlgo_PassKey::GEOMAlgo_PassKey()
47 {
48   Clear();
49 }
50 //=======================================================================
51 //function :Assign
52 //purpose  : 
53 //=======================================================================
54   GEOMAlgo_PassKey& GEOMAlgo_PassKey::Assign(const GEOMAlgo_PassKey& anOther)
55 {
56   myNbIds=anOther.myNbIds;
57   myNbMax=anOther.myNbMax;
58   mySum=anOther.mySum;
59   memcpy(myIds, anOther.myIds, sizeof(myIds));
60   return *this;
61 }
62 //=======================================================================
63 //function :Clear
64 //purpose  : 
65 //=======================================================================
66   void GEOMAlgo_PassKey::Clear()
67 {
68   Standard_Integer i;
69   //
70   myNbIds=0;
71   myNbMax=8;
72   mySum=0;
73   for (i=0; i<myNbMax; ++i) {
74     myIds[i]=0;
75   }
76 }
77 //=======================================================================
78 //function :SetIds
79 //purpose  : 
80 //=======================================================================
81   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1)
82                                
83 {
84   myNbIds=1;
85   myIds[myNbMax-1]=anId1;
86   mySum=anId1;
87 }
88 //=======================================================================
89 //function :SetIds
90 //purpose  : 
91 //=======================================================================
92   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
93                                 const Standard_Integer anId2)
94 {
95   Standard_Integer aIdN1, aIdN2;
96   //
97   myNbIds=2;
98   aIdN1=NormalizedId(anId1, myNbIds);
99   aIdN2=NormalizedId(anId2, myNbIds);
100   mySum=aIdN1+aIdN2;
101   //
102   if (anId1<anId2) {
103     myIds[myNbMax-2]=anId1;
104     myIds[myNbMax-1]=anId2;
105     return;
106   }
107   myIds[myNbMax-2]=anId2;
108   myIds[myNbMax-1]=anId1;
109 }
110
111 //=======================================================================
112 //function :SetIds
113 //purpose  : 
114 //=======================================================================
115   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
116                                 const Standard_Integer anId2,
117                                 const Standard_Integer anId3)
118 {
119   Standard_Integer aIdN1, aIdN2, aIdN3;
120   //
121   myNbIds=3;
122   aIdN1=NormalizedId(anId1, myNbIds);
123   aIdN2=NormalizedId(anId2, myNbIds);
124   aIdN3=NormalizedId(anId3, myNbIds);
125   mySum=aIdN1+aIdN2+aIdN3;
126   //
127   myIds[myNbMax-3]=anId1;
128   myIds[myNbMax-2]=anId2;
129   myIds[myNbMax-1]=anId3;
130   //
131   Compute();
132 }
133 //=======================================================================
134 //function :SetIds
135 //purpose  : 
136 //=======================================================================
137   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
138                                 const Standard_Integer anId2,
139                                 const Standard_Integer anId3,
140                                 const Standard_Integer anId4)
141 {
142   Standard_Integer aIdN1, aIdN2, aIdN3, aIdN4;
143   //
144   myNbIds=4;
145   aIdN1=NormalizedId(anId1, myNbIds);
146   aIdN2=NormalizedId(anId2, myNbIds);
147   aIdN3=NormalizedId(anId3, myNbIds);
148   aIdN4=NormalizedId(anId4, myNbIds);
149   mySum=aIdN1+aIdN2+aIdN3+aIdN4;
150   //
151   myIds[myNbMax-4]=anId1;
152   myIds[myNbMax-3]=anId2;
153   myIds[myNbMax-2]=anId3;
154   myIds[myNbMax-1]=anId4;
155   //
156   Compute();
157 }
158 //=======================================================================
159 //function :SetIds
160 //purpose  : 
161 //=======================================================================
162   void GEOMAlgo_PassKey::SetIds(const TColStd_ListOfInteger& aLI)
163 {
164   Standard_Integer aNb, i, anId, aIdN;
165   TColStd_ListIteratorOfListOfInteger aIt;
166   //
167   aNb=aLI.Extent();
168   if (!aNb || aNb > myNbMax) {
169     return;
170   }
171   //
172   myNbIds=aNb;
173   mySum=0;
174   i=myNbMax-myNbIds;
175   aIt.Initialize(aLI);
176   for (; aIt.More(); aIt.Next(), ++i) {
177     anId=aIt.Value();
178     myIds[i]=anId;
179     aIdN=NormalizedId(anId, myNbIds);
180     mySum+=aIdN;
181   }
182   //
183   Compute();
184 }
185 //=======================================================================
186 //function :Id
187 //purpose  : 
188 //=======================================================================
189   Standard_Integer GEOMAlgo_PassKey::Id(const Standard_Integer aIndex)const
190 {
191   if (aIndex < 0 || aIndex >= myNbMax) {
192     return 0;
193   }
194   return myIds[aIndex];
195 }
196 //=======================================================================
197 //function :NbMax
198 //purpose  : 
199 //=======================================================================
200   Standard_Integer GEOMAlgo_PassKey::NbMax()const
201 {
202   return myNbMax;
203 }
204 //=======================================================================
205 //function :Compute
206 //purpose  : 
207 //=======================================================================
208   void GEOMAlgo_PassKey::Compute()
209 {
210   SortShell(myNbIds, myIds+myNbMax-myNbIds);
211 }
212 //=======================================================================
213 //function :IsEqual
214 //purpose  : 
215 //=======================================================================
216   Standard_Boolean GEOMAlgo_PassKey::IsEqual(const GEOMAlgo_PassKey& anOther) const
217 {
218   Standard_Integer iIsEqual;
219   Standard_Boolean bIsEqual;
220   //
221   iIsEqual=memcmp(myIds, anOther.myIds, sizeof(myIds));
222   bIsEqual=Standard_False;
223   if (!iIsEqual) {
224     bIsEqual=!bIsEqual;
225   }
226   return bIsEqual;
227 }
228 //=======================================================================
229 //function :Key
230 //purpose  : 
231 //=======================================================================
232   Standard_Address GEOMAlgo_PassKey::Key()const
233 {
234   return (Standard_Address)myIds;
235 }
236 //=======================================================================
237 //function : HashCode
238 //purpose  : 
239 //=======================================================================
240   Standard_Integer GEOMAlgo_PassKey::HashCode(const Standard_Integer Upper) const
241 {
242   //return (mySum % Upper);
243   return ::HashCode(mySum, Upper);
244 }
245 //=======================================================================
246 //function : Dump
247 //purpose  : 
248 //=======================================================================
249   void GEOMAlgo_PassKey::Dump()const
250 {
251   Standard_Integer i;
252   //
253   printf(" PassKey: {");
254   for (i=0; i<myNbMax; ++i) {
255     printf(" %d", myIds[i]);
256   }
257   printf(" }");
258 }
259 //=======================================================================
260 // function: NormalizedId
261 // purpose : 
262 //=======================================================================
263 Standard_Integer NormalizedId(const Standard_Integer aId,
264                               const Standard_Integer aDiv)
265 {
266   Standard_Integer aMax, aTresh, aIdRet;
267   //
268   aIdRet=aId;
269   aMax=::IntegerLast();
270   aTresh=aMax/aDiv;
271   if (aId>aTresh) {
272     aIdRet=aId%aTresh;
273   }
274   return aIdRet;
275 }
276 //=======================================================================
277 // function: SortShell
278 // purpose : 
279 //=======================================================================
280 void SortShell(const int n, int* a) 
281 {
282   int  x, nd, i, j, l, d=1;
283   //
284   while(d<=n) {
285     d*=2;
286   }
287   //
288   while (d) {
289     d=(d-1)/2;
290     //
291     nd=n-d;
292     for (i=0; i<nd; ++i) {
293       j=i;
294     m30:;
295       l=j+d;
296       if (a[l] < a[j]){
297         x=a[j];
298         a[j]=a[l];
299         a[l]=x;
300         j-=d;
301         if (j > -1) goto m30;
302       }//if (a[l] < a[j]){
303     }//for (i=0; i<nd; ++i) 
304   }//while (1)
305 }