Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Bnd / Bnd_BoundSortBox2d.cxx
1 // File:        Bnd_BoundSortBox2d.cxx
2 // Created:     Mon Mar  8 15:20:59 1993
3 // Author:      Didier PIFFAULT
4 //              <dpf@phylox>
5
6 #include <Bnd_BoundSortBox2d.ixx>
7 #include <Standard_NullValue.hxx>
8 #include <Bnd_Array1OfBox.hxx>
9 #include <TColStd_ListIteratorOfListOfInteger.hxx>
10 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
11 #include <TColStd_Array1OfListOfInteger.hxx>
12
13
14 //=======================================================================
15 //function : Bnd_BoundSortBox2d
16 //purpose  : 
17 //=======================================================================
18
19 Bnd_BoundSortBox2d::Bnd_BoundSortBox2d()
20      : discrX(0), discrY(0)
21 {}
22
23
24 //=======================================================================
25 //function : Initialize
26 //purpose  : 
27 //=======================================================================
28
29 void Bnd_BoundSortBox2d::Initialize(const Bnd_Box2d& CompleteBox,
30                                     const Handle(Bnd_HArray1OfBox2d)& SetOfBox)
31 {
32   myBox=CompleteBox;
33   myBndComponents=SetOfBox;
34   discrX=SetOfBox->Length();
35   discrY=discrX;
36
37   Standard_Real xmin, ymin, xmax, ymax;
38   Standard_Real middleX=0.;
39   Standard_Real middleY=0.;
40
41   const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
42
43   Standard_Integer labox;
44   for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
45     if (!taBox(labox).IsVoid()) {
46       taBox.Value(labox).Get(xmin, ymin, xmax, ymax);
47       middleX+=xmax-xmin;
48       middleY+=ymax-ymin;
49     }
50   }
51   middleX=middleX/taBox.Length();
52   middleY=middleY/taBox.Length();
53
54   Standard_Real Xmax, Ymax;
55   CompleteBox.Get(Xmin, Ymin, Xmax, Ymax);
56   deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
57   deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
58
59   if (middleX < Epsilon(100.)) {
60     discrX=1;
61     deltaX=Xmax-Xmin;
62   }
63   else if (middleX > deltaX) {
64     discrX=(Standard_Integer)((Xmax-Xmin)/middleX);
65     deltaX=middleX;
66     discrX++;
67   }
68
69   if (middleY < Epsilon(100.)) {
70     discrY=1;
71     deltaY=Ymax-Ymin;
72   }
73   else if (middleY > deltaY) {
74     discrY=(Standard_Integer)((Ymax-Ymin)/middleY + 0.1);
75     deltaY=middleY;
76     discrY++;
77   }
78
79   SortBoxes();
80 }
81
82 //=======================================================================
83 //function : Initialize
84 //purpose  : 
85 //=======================================================================
86
87 void  Bnd_BoundSortBox2d::Initialize(const Handle_Bnd_HArray1OfBox2d& SetOfBox)
88 {
89   myBndComponents=SetOfBox;
90   discrX=SetOfBox->Length();
91   discrY=discrX;
92   
93   Standard_Real xmin, ymin, xmax, ymax;
94   Standard_Real middleX=0.;
95   Standard_Real middleY=0.;
96   
97   const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
98   
99   Standard_Integer labox;
100   for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
101     if (!taBox(labox).IsVoid()) {
102       myBox.Add(taBox(labox));
103       taBox.Value(labox).Get(xmin, ymin, xmax, ymax);
104       middleX+=xmax-xmin;
105       middleY+=ymax-ymin;
106     }
107   }
108   middleX=middleX/taBox.Length();
109   middleY=middleY/taBox.Length();
110
111   Standard_Real Xmax, Ymax;
112   myBox.Get(Xmin, Ymin, Xmax, Ymax);
113   deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
114   deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
115
116   if (middleX < Epsilon(100.)) {
117     discrX=1;
118     deltaX=Xmax-Xmin;
119   }
120   else if (middleX > deltaX) {
121     discrX=(Standard_Integer)((Xmax-Xmin)/middleX);
122     deltaX=middleX;
123     discrX++;
124   }
125
126   if (middleY < Epsilon(100.)) {
127     discrY=1;
128     deltaY=Ymax-Ymin;
129   }
130   else if (middleY > deltaY) {
131     discrY=(Standard_Integer)((Ymax-Ymin)/middleY + 0.1);
132     deltaY=middleY;
133     discrY++;
134   }
135
136   SortBoxes();
137 }
138
139
140 //=======================================================================
141 //function : SortBoxes
142 //purpose  : 
143 //=======================================================================
144
145 void  Bnd_BoundSortBox2d::SortBoxes()
146 {
147   Standard_NullValue_Raise_if (discrX+discrY <=0, "BoundSortBox2d nul!");
148
149   Standard_Integer labox, lacase, firstcase, lastcase;
150   Standard_Real xmin, ymin, xmax, ymax;
151   const  Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
152
153   axisX=new TColStd_HArray1OfListOfInteger(1, discrX); 
154   TColStd_Array1OfListOfInteger & tabListX=axisX->ChangeArray1();
155
156   axisY=new TColStd_HArray1OfListOfInteger(1, discrY);
157   TColStd_Array1OfListOfInteger & tabListY=axisY->ChangeArray1();
158
159   for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
160     if (!taBox(labox).IsVoid()) {
161       taBox(labox).Get(xmin, ymin, xmax, ymax);
162
163       if (discrX>1) {
164         firstcase=(Standard_Integer ) Max(1.0, (xmin-Xmin)/deltaX);
165         lastcase=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
166         for (lacase=firstcase; lacase<=lastcase; lacase++) {
167           tabListX(lacase).Append(labox);
168         }
169       }
170
171       if (discrY >1) {
172         firstcase=(Standard_Integer ) Max(1.0, (ymin-Ymin)/deltaY);
173         lastcase=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
174         for (lacase=firstcase; lacase<=lastcase; lacase++) {
175           tabListY(lacase).Append(labox);
176         }
177       }
178     }
179   }
180 }
181
182 //=======================================================================
183 //function : Initialize
184 //purpose  : 
185 //=======================================================================
186
187 void  Bnd_BoundSortBox2d::Initialize(const Bnd_Box2d& CompleteBox,
188                                      const Standard_Integer nbComponents)
189 {
190   Standard_NullValue_Raise_if (nbComponents <=0, "BoundSortBox nul!");
191
192   myBox=CompleteBox;
193   myBndComponents=new Bnd_HArray1OfBox2d(1, nbComponents);
194
195   Bnd_Box2d emptyBox; 
196   myBndComponents->Init( emptyBox ); 
197
198   discrX=nbComponents;
199   discrY=nbComponents;
200   
201   Standard_Real Xmax, Ymax;
202   CompleteBox.Get(Xmin, Ymin, Xmax, Ymax);
203   
204   deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
205   deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
206   
207   if (deltaX < Epsilon(100.)) {
208     discrX=1;
209     deltaX=Xmax-Xmin;
210   }
211   else axisX=new TColStd_HArray1OfListOfInteger(1, discrX); 
212
213   if (deltaY < Epsilon(100.)) {
214     discrY=1;
215     deltaY=Ymax-Ymin;
216   }
217   else axisY=new TColStd_HArray1OfListOfInteger(1, discrY);
218 }
219
220 //=======================================================================
221 //function : Add
222 //purpose  : 
223 //=======================================================================
224
225 void  Bnd_BoundSortBox2d::Add(const Bnd_Box2d& theBox,
226                               const Standard_Integer boxIndex)
227 {
228   Standard_MultiplyDefined_Raise_if
229     (!(myBndComponents->Value(boxIndex).IsVoid()),
230      " This box is already defined !");
231
232   if (!theBox.IsVoid()) {
233     Bnd_Array1OfBox2d & taBox=myBndComponents->ChangeArray1();
234     Standard_Integer theGap, firstGap , lastGap;
235     Standard_Real xmin, ymin, xmax, ymax;
236     theBox.Get(xmin, ymin, xmax, ymax);
237
238     if (taBox.Lower()<=boxIndex  && boxIndex<=taBox.Upper()) 
239       taBox(boxIndex).Update(xmin, ymin, xmax, ymax);
240
241     TColStd_Array1OfListOfInteger & tabListX=axisX->ChangeArray1();
242
243     if (discrX>1) {
244       firstGap=(Standard_Integer ) Max(1.0, ((xmin-Xmin)/deltaX)+1);
245       lastGap=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
246       for (theGap=firstGap; theGap<=lastGap; theGap++) {
247         tabListX(theGap).Append(boxIndex);
248       }
249     }
250
251     TColStd_Array1OfListOfInteger & tabListY=axisY->ChangeArray1();
252
253     if (discrY >1) {
254       firstGap=(Standard_Integer ) Max(1.0, ((ymin-Ymin)/deltaY)+1);
255       lastGap=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
256       for (theGap=firstGap; theGap<=lastGap; theGap++) {
257         tabListY(theGap).Append(boxIndex);
258       }
259     }
260   }
261 }
262
263
264 //=======================================================================
265 //function : Compare
266 //purpose  : 
267 //=======================================================================
268
269
270 const TColStd_ListOfInteger& Bnd_BoundSortBox2d::Compare
271   (const Bnd_Box2d& theBox)
272 {
273   Standard_NullValue_Raise_if (discrX+discrY <=0, 
274                                "Compare sur 1 BoundSortBox2d nul!");
275
276   lastResult.Clear();
277   if (theBox.IsVoid()) return lastResult;
278   if (theBox.IsOut(myBox)) return lastResult;
279
280   Standard_Integer lacase, firstcase, lastcase;
281   Standard_Real xmin, ymin, xmax, ymax;
282   theBox.Get(xmin, ymin, xmax, ymax);
283
284   const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
285   Crible.Clear();
286   theFound=2;
287
288   Standard_Integer cardY=0;
289   if (discrY>1 && (!theBox.IsOpenYmin() || !theBox.IsOpenYmax())) {
290     const TColStd_Array1OfListOfInteger & tabList=axisY->Array1();
291     firstcase=(Standard_Integer ) Max(1.0, (ymin-Ymin)/deltaY);
292     lastcase=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
293     for (lacase=firstcase; lacase<=lastcase; lacase++) {
294       TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
295       for (; theList.More(); theList.Next()) {
296         cardY++;
297         Crible.Bind(theList.Value(), 2);
298       }
299     }
300     if (cardY==0) return lastResult;
301   }
302   else {
303     if (ymin > Ymin+deltaY || ymax < Ymin)
304       return lastResult;
305     theFound-=2;
306   }
307
308   if (discrX>1 && (!theBox.IsOpenXmin() || !theBox.IsOpenXmax())) {
309     const TColStd_Array1OfListOfInteger & tabList=axisX->Array1();
310     firstcase=(Standard_Integer ) Max(1.0, (xmin-Xmin)/deltaX);
311     lastcase=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
312     for (lacase=firstcase; lacase<=lastcase; lacase++) {
313       TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
314       for (; theList.More(); theList.Next()) {
315         if (Crible.IsBound(theList.Value())) {
316           if (Crible(theList.Value())==theFound) {
317             if (!taBox.Value(theList.Value()).IsOut(theBox)){
318               lastResult.Append(theList.Value());
319               Crible(theList.Value())=0;
320             }
321           }
322         }
323       }
324     }
325     return lastResult;
326   }
327
328   else {
329     if (xmin > Xmin+deltaX || xmax < Xmin) return lastResult;
330     else if (discrY==1)
331       {
332         lacase=1;
333         for(Standard_Integer i=taBox.Lower();i<=taBox.Upper();i++)
334           {
335             lastResult.Append(i);
336           } 
337       }
338     else{
339
340       TColStd_DataMapIteratorOfDataMapOfIntegerInteger itDM(Crible);
341       for (; itDM.More(); itDM.Next()) {
342         if (itDM.Value()==theFound) {
343           if (taBox.Lower()<=itDM.Key() && itDM.Key()<=taBox.Upper()) {
344             if (!taBox(itDM.Key()).IsOut(theBox)) 
345               lastResult.Append(itDM.Key());
346           }
347           else {
348             lastResult.Append(itDM.Key());
349           }
350         }
351       }
352     }
353   }
354   return lastResult;
355 }
356
357
358 //=======================================================================
359 //function : Dump
360 //purpose  : 
361 //=======================================================================
362
363 void Bnd_BoundSortBox2d::Dump() const
364 {
365   Standard_Integer lacase;
366
367   cout <<   "axis X : " << discrX << " intervalles de " << deltaX << endl;
368   if (discrX>1) {
369     const TColStd_Array1OfListOfInteger & tabList=axisX->Array1();
370     for (lacase=1; lacase<=discrX; lacase++) {
371       cout << "     X " << lacase << " : " ;
372       TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
373       for (; theList.More(); theList.Next()) {
374         cout << theList.Value() << " ";
375       }
376       cout << "\n";
377     }
378   }
379
380   cout <<   "axis Y : " << discrY << " intervalles de " << deltaY << endl;
381   if (discrY>1) {
382     const TColStd_Array1OfListOfInteger & tabList=axisY->Array1();
383     for (lacase=1; lacase<=discrY; lacase++) {
384       cout << "     Y " << lacase << " : " ;
385       TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
386       for (; theList.More(); theList.Next()) {
387         cout << theList.Value() << " ";
388       }
389       cout << "\n";
390     }
391   }
392 }