Salome HOME
61c70febb240c32b68535463f8b99313516a7da4
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_PassKey.cxx
1 // File:        GEOMAlgo_PassKey.cxx
2 // Created:     
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <GEOMAlgo_PassKey.ixx>
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <TColStd_ListIteratorOfListOfInteger.hxx>
12
13 #ifdef WNT
14 #pragma warning( disable : 4101) 
15 #endif
16
17 static 
18   void SortShell(const int n, int* a); 
19 static
20   Standard_Integer NormalizedId(const Standard_Integer aId,
21                                 const Standard_Integer aDiv);
22
23 //=======================================================================
24 //function :
25 //purpose  : 
26 //=======================================================================
27   GEOMAlgo_PassKey::GEOMAlgo_PassKey()
28 {
29   Clear();
30 }
31 //=======================================================================
32 //function :Assign
33 //purpose  : 
34 //=======================================================================
35   GEOMAlgo_PassKey& GEOMAlgo_PassKey::Assign(const GEOMAlgo_PassKey& anOther)
36 {
37   myNbIds=anOther.myNbIds;
38   myNbMax=anOther.myNbMax;
39   mySum=anOther.mySum;
40   memcpy(myIds, anOther.myIds, sizeof(myIds));
41   return *this;
42 }
43 //=======================================================================
44 //function :Clear
45 //purpose  : 
46 //=======================================================================
47   void GEOMAlgo_PassKey::Clear()
48 {
49   Standard_Integer i;
50   //
51   myNbIds=0;
52   myNbMax=8;
53   mySum=0;
54   for (i=0; i<myNbMax; ++i) {
55     myIds[i]=0;
56   }
57 }
58 //=======================================================================
59 //function :SetIds
60 //purpose  : 
61 //=======================================================================
62   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1)
63                                
64 {
65   myNbIds=1;
66   myIds[myNbMax-1]=anId1;
67   mySum=anId1;
68 }
69 //=======================================================================
70 //function :SetIds
71 //purpose  : 
72 //=======================================================================
73   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
74                                 const Standard_Integer anId2)
75 {
76   Standard_Integer aIdN1, aIdN2;
77   //
78   myNbIds=2;
79   aIdN1=NormalizedId(anId1, myNbIds);
80   aIdN2=NormalizedId(anId2, myNbIds);
81   mySum=aIdN1+aIdN2;
82   //
83   if (anId1<anId2) {
84     myIds[myNbMax-2]=anId1;
85     myIds[myNbMax-1]=anId2;
86     return;
87   }
88   myIds[myNbMax-2]=anId2;
89   myIds[myNbMax-1]=anId1;
90 }
91
92 //=======================================================================
93 //function :SetIds
94 //purpose  : 
95 //=======================================================================
96   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
97                                 const Standard_Integer anId2,
98                                 const Standard_Integer anId3)
99 {
100   Standard_Integer aIdN1, aIdN2, aIdN3;
101   //
102   myNbIds=3;
103   aIdN1=NormalizedId(anId1, myNbIds);
104   aIdN2=NormalizedId(anId2, myNbIds);
105   aIdN3=NormalizedId(anId3, myNbIds);
106   mySum=aIdN1+aIdN2+aIdN3;
107   //
108   myIds[myNbMax-3]=anId1;
109   myIds[myNbMax-2]=anId2;
110   myIds[myNbMax-1]=anId3;
111   //
112   Compute();
113 }
114 //=======================================================================
115 //function :SetIds
116 //purpose  : 
117 //=======================================================================
118   void GEOMAlgo_PassKey::SetIds(const Standard_Integer anId1,
119                                 const Standard_Integer anId2,
120                                 const Standard_Integer anId3,
121                                 const Standard_Integer anId4)
122 {
123   Standard_Integer aIdN1, aIdN2, aIdN3, aIdN4;
124   //
125   myNbIds=4;
126   aIdN1=NormalizedId(anId1, myNbIds);
127   aIdN2=NormalizedId(anId2, myNbIds);
128   aIdN3=NormalizedId(anId3, myNbIds);
129   aIdN4=NormalizedId(anId4, myNbIds);
130   mySum=aIdN1+aIdN2+aIdN3+aIdN4;
131   //
132   myIds[myNbMax-4]=anId1;
133   myIds[myNbMax-3]=anId2;
134   myIds[myNbMax-2]=anId3;
135   myIds[myNbMax-1]=anId4;
136   //
137   Compute();
138 }
139 //=======================================================================
140 //function :SetIds
141 //purpose  : 
142 //=======================================================================
143   void GEOMAlgo_PassKey::SetIds(const TColStd_ListOfInteger& aLI)
144 {
145   Standard_Integer aNb, i, anId, aIdN;
146   TColStd_ListIteratorOfListOfInteger aIt;
147   //
148   aNb=aLI.Extent();
149   if (!aNb || aNb > myNbMax) {
150     return;
151   }
152   //
153   myNbIds=aNb;
154   mySum=0;
155   i=myNbMax-myNbIds;
156   aIt.Initialize(aLI);
157   for (; aIt.More(); aIt.Next(), ++i) {
158     anId=aIt.Value();
159     myIds[i]=anId;
160     aIdN=NormalizedId(anId, myNbIds);
161     mySum+=aIdN;
162   }
163   //
164   Compute();
165 }
166 //=======================================================================
167 //function :Id
168 //purpose  : 
169 //=======================================================================
170   Standard_Integer GEOMAlgo_PassKey::Id(const Standard_Integer aIndex)const
171 {
172   if (aIndex < 0 || aIndex >= myNbMax) {
173     return 0;
174   }
175   return myIds[aIndex];
176 }
177 //=======================================================================
178 //function :NbMax
179 //purpose  : 
180 //=======================================================================
181   Standard_Integer GEOMAlgo_PassKey::NbMax()const
182 {
183   return myNbMax;
184 }
185 //=======================================================================
186 //function :Compute
187 //purpose  : 
188 //=======================================================================
189   void GEOMAlgo_PassKey::Compute()
190 {
191   SortShell(myNbIds, myIds+myNbMax-myNbIds);
192 }
193 //=======================================================================
194 //function :IsEqual
195 //purpose  : 
196 //=======================================================================
197   Standard_Boolean GEOMAlgo_PassKey::IsEqual(const GEOMAlgo_PassKey& anOther) const
198 {
199   Standard_Integer iIsEqual;
200   Standard_Boolean bIsEqual;
201   //
202   iIsEqual=memcmp(myIds, anOther.myIds, sizeof(myIds));
203   bIsEqual=Standard_False;
204   if (!iIsEqual) {
205     bIsEqual=!bIsEqual;
206   }
207   return bIsEqual;
208 }
209 //=======================================================================
210 //function :Key
211 //purpose  : 
212 //=======================================================================
213   Standard_Address GEOMAlgo_PassKey::Key()const
214 {
215   return (Standard_Address)myIds;
216 }
217 //=======================================================================
218 //function : HashCode
219 //purpose  : 
220 //=======================================================================
221   Standard_Integer GEOMAlgo_PassKey::HashCode(const Standard_Integer Upper) const
222 {
223   //return (mySum % Upper);
224   return ::HashCode(mySum, Upper);
225 }
226 //=======================================================================
227 //function : Dump
228 //purpose  : 
229 //=======================================================================
230   void GEOMAlgo_PassKey::Dump()const
231 {
232   Standard_Integer i;
233   //
234   printf(" PassKey: {");
235   for (i=0; i<myNbMax; ++i) {
236     printf(" %d", myIds[i]);
237   }
238   printf(" }");
239 }
240 //=======================================================================
241 // function: NormalizedId
242 // purpose : 
243 //=======================================================================
244 Standard_Integer NormalizedId(const Standard_Integer aId,
245                               const Standard_Integer aDiv)
246 {
247   Standard_Integer aMax, aTresh, aIdRet;
248   //
249   aIdRet=aId;
250   aMax=::IntegerLast();
251   aTresh=aMax/aDiv;
252   if (aId>aTresh) {
253     aIdRet=aId%aTresh;
254   }
255   return aIdRet;
256 }
257 //=======================================================================
258 // function: SortShell
259 // purpose : 
260 //=======================================================================
261 void SortShell(const int n, int* a) 
262 {
263   int  x, nd, i, j, l, d=1;
264   //
265   while(d<=n) {
266     d*=2;
267   }
268   //
269   while (d) {
270     d=(d-1)/2;
271     //
272     nd=n-d;
273     for (i=0; i<nd; ++i) {
274       j=i;
275     m30:;
276       l=j+d;
277       if (a[l] < a[j]){
278         x=a[j];
279         a[j]=a[l];
280         a[l]=x;
281         j-=d;
282         if (j > -1) goto m30;
283       }//if (a[l] < a[j]){
284     }//for (i=0; i<nd; ++i) 
285   }//while (1)
286 }