bb604b88aa8064d7ed45f3ce5eca62774c51a373
[occt.git] / src / BOPDS / BOPDS_PaveBlock.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #include <BOPDS_PaveBlock.ixx>
21 #include <BOPDS_ListOfPave.hxx>
22 #include <Standard.hxx>
23 #include <NCollection_BaseAllocator.hxx>
24
25
26 #ifdef WNT
27 #pragma warning ( disable : 4291 )
28 #endif
29
30 static
31   void SortShell(const int n, BOPDS_Pave *a);
32
33 //=======================================================================
34 //function : 
35 //purpose  : 
36 //=======================================================================
37   BOPDS_PaveBlock::BOPDS_PaveBlock()
38 :
39   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
40   myExtPaves(myAllocator)
41 {
42   myEdge=-1;
43   myOriginalEdge=-1;
44   myTS1=-99.;
45   myTS2=myTS1;
46 }
47 //=======================================================================
48 //function : 
49 //purpose  : 
50 //=======================================================================
51   BOPDS_PaveBlock::BOPDS_PaveBlock(const Handle(NCollection_BaseAllocator)& theAllocator)
52 :
53   myAllocator(theAllocator),
54   myExtPaves(theAllocator),
55   myMFence(100, theAllocator)
56 {
57   myEdge=-1;
58   myOriginalEdge=-1;
59   myTS1=-99.;
60   myTS2=myTS1;
61 }
62
63 //=======================================================================
64 //function : SetEdge
65 //purpose  : 
66 //=======================================================================
67   void BOPDS_PaveBlock::SetEdge(const Standard_Integer theEdge)
68 {
69   myEdge=theEdge;
70 }
71 //=======================================================================
72 //function : Edge
73 //purpose  : 
74 //=======================================================================
75   Standard_Integer BOPDS_PaveBlock::Edge()const
76 {
77   return myEdge;
78 }
79 //=======================================================================
80 //function : HasEdge
81 //purpose  : 
82 //=======================================================================
83   Standard_Boolean BOPDS_PaveBlock::HasEdge()const
84 {
85   return (myEdge>=0);
86 }
87 //=======================================================================
88 //function : HasEdge
89 //purpose  : 
90 //=======================================================================
91   Standard_Boolean BOPDS_PaveBlock::HasEdge(Standard_Integer& theEdge)const
92 {
93   theEdge=myEdge;
94   return (myEdge>=0);
95 }
96
97 //=======================================================================
98 //function : SetOriginalEdge
99 //purpose  : 
100 //=======================================================================
101   void BOPDS_PaveBlock::SetOriginalEdge(const Standard_Integer theEdge)
102 {
103   myOriginalEdge=theEdge;
104 }
105 //=======================================================================
106 //function : OriginalEdge
107 //purpose  : 
108 //=======================================================================
109   Standard_Integer BOPDS_PaveBlock::OriginalEdge()const
110 {
111   return myOriginalEdge;
112 }
113 //=======================================================================
114 //function : IsSplitEdge
115 //purpose  : 
116 //=======================================================================
117   Standard_Boolean BOPDS_PaveBlock::IsSplitEdge()const
118 {
119   return (myEdge!=myOriginalEdge);
120 }
121 //=======================================================================
122 //function : SetPave1
123 //purpose  : 
124 //=======================================================================
125   void BOPDS_PaveBlock::SetPave1(const BOPDS_Pave& thePave)
126 {
127   myPave1=thePave;
128 }
129 //=======================================================================
130 //function : Pave1
131 //purpose  : 
132 //=======================================================================
133   const BOPDS_Pave& BOPDS_PaveBlock::Pave1()const
134 {
135   return myPave1;
136 }
137 //=======================================================================
138 //function : SetPave2
139 //purpose  : 
140 //=======================================================================
141   void BOPDS_PaveBlock::SetPave2(const BOPDS_Pave& thePave)
142 {
143   myPave2=thePave;
144 }
145 //=======================================================================
146 //function : Pave2
147 //purpose  : 
148 //=======================================================================
149   const BOPDS_Pave& BOPDS_PaveBlock::Pave2()const
150 {
151   return myPave2;
152 }
153 //=======================================================================
154 //function : Range
155 //purpose  : 
156 //=======================================================================
157   void BOPDS_PaveBlock::Range(Standard_Real& theT1,
158                               Standard_Real& theT2)const
159 {
160   theT1=myPave1.Parameter();
161   theT2=myPave2.Parameter();
162 }
163 //=======================================================================
164 //function : Indices
165 //purpose  : 
166 //=======================================================================
167   void BOPDS_PaveBlock::Indices(Standard_Integer& theIndex1,
168                                 Standard_Integer& theIndex2)const
169 {
170   theIndex1=myPave1.Index();
171   theIndex2=myPave2.Index();
172 }
173 //=======================================================================
174 //function : HasSameBounds
175 //purpose  : 
176 //=======================================================================
177   Standard_Boolean BOPDS_PaveBlock::HasSameBounds(const Handle(BOPDS_PaveBlock)& theOther)const
178 {
179   Standard_Boolean bFlag1, bFlag2;
180   Standard_Integer n11, n12, n21, n22;
181   //
182   Indices(n11, n12);
183   theOther->Indices(n21, n22);
184   //
185   bFlag1=(n11==n21) && (n12==n22);
186   bFlag2=(n11==n22) && (n12==n21);
187   //
188   return (bFlag1 || bFlag2);
189 }
190
191
192 //
193 // Extras
194 //
195 //=======================================================================
196 //function : AppendExtPave
197 //purpose  : 
198 //=======================================================================
199   void BOPDS_PaveBlock::AppendExtPave(const BOPDS_Pave& thePave)
200 {
201   if (myMFence.Add(thePave.Index())) {
202     myExtPaves.Append(thePave);
203   }
204 }
205 //=======================================================================
206 //function : AppendExtPave1
207 //purpose  : 
208 //=======================================================================
209   void BOPDS_PaveBlock::AppendExtPave1(const BOPDS_Pave& thePave)
210 {
211   myExtPaves.Append(thePave);
212 }
213 //=======================================================================
214 //function : ExtPaves
215 //purpose  : 
216 //=======================================================================
217   const BOPDS_ListOfPave& BOPDS_PaveBlock::ExtPaves()const 
218 {
219   return myExtPaves;
220 }
221 //=======================================================================
222 //function : ChangeExtPaves
223 //purpose  : 
224 //=======================================================================
225   BOPDS_ListOfPave& BOPDS_PaveBlock::ChangeExtPaves() 
226 {
227   return myExtPaves;
228 }
229 //=======================================================================
230 //function : IsToUpdate
231 //purpose  : 
232 //=======================================================================
233   Standard_Boolean BOPDS_PaveBlock::IsToUpdate()const 
234 {
235   return !myExtPaves.IsEmpty();
236 }
237 //=======================================================================
238 //function : ContainsParameter
239 //purpose  : 
240 //=======================================================================
241   Standard_Boolean BOPDS_PaveBlock::ContainsParameter(const Standard_Real theT,
242                                                       const Standard_Real theTol)const
243 {
244   Standard_Boolean bRet;
245   Standard_Real dT;
246   BOPDS_ListIteratorOfListOfPave aIt;
247   //
248   bRet=Standard_False;
249   aIt.Initialize(myExtPaves);
250   for (; aIt.More(); aIt.Next()) {
251     dT=aIt.Value().Parameter()-theT;
252     if (dT<0.) {
253       dT=-dT;
254     }
255     if (dT<theTol) {
256       bRet=!bRet;
257       break;
258     }
259   }
260   return bRet;
261 }
262 //=======================================================================
263 //function : Update
264 //purpose  : 
265 //=======================================================================
266   void BOPDS_PaveBlock::Update(BOPDS_ListOfPaveBlock& theLPB,
267                                const Standard_Boolean theFlag)
268 {
269   Standard_Integer i, aNb;
270   BOPDS_Pave *pPaves;
271   BOPDS_Pave aPave1, aPave2;
272   Handle(BOPDS_PaveBlock) aPB;
273   BOPDS_ListIteratorOfListOfPave aIt;
274   //
275   aNb=myExtPaves.Extent();
276   if (theFlag) {
277     aNb=aNb+2;
278   }
279   //
280   pPaves=(BOPDS_Pave *)myAllocator->Allocate(aNb*sizeof(BOPDS_Pave));
281   for (i=0; i<aNb; ++i) {
282     new (pPaves+i) BOPDS_Pave();
283   }
284   //
285   i=0;
286   if (theFlag) {
287     pPaves[i]=myPave1; 
288     ++i;
289     pPaves[i]=myPave2; 
290     ++i;
291   }
292   //
293   aIt.Initialize(myExtPaves);
294   for (; aIt.More(); aIt.Next()) {
295     const BOPDS_Pave& aPave=aIt.Value();
296     pPaves[i]=(aPave);
297     ++i;
298   }
299   myExtPaves.Clear();
300   myMFence.Clear();
301   //
302   SortShell(aNb, pPaves);
303   //
304   for (i=0; i<aNb; ++i) {
305     const BOPDS_Pave& aPave=pPaves[i];
306     if (!i) {
307       aPave1=aPave;
308       continue;
309     }
310     //
311     aPave2=aPave;
312     aPB=new BOPDS_PaveBlock;
313     aPB->SetOriginalEdge(myOriginalEdge);
314     aPB->SetPave1(aPave1);
315     aPB->SetPave2(aPave2);
316     //
317     theLPB.Append(aPB);
318     //
319     aPave1=aPave2;
320   }
321   //
322   for (i=0; i<aNb; ++i) {
323     pPaves[i].~BOPDS_Pave();
324   }
325   myAllocator->Free((Standard_Address&)pPaves); 
326 }
327
328 //=======================================================================
329 // function: SortShell
330 // purpose : 
331 //=======================================================================
332 void SortShell(const int n, BOPDS_Pave *a) 
333 {
334   int nd, i, j, l, d=1;
335   BOPDS_Pave x;
336   //
337   while(d<=n) {
338     d*=2;
339   }
340   //
341   while (d) {
342     d=(d-1)/2;
343     //
344     nd=n-d;
345     for (i=0; i<nd; ++i) {
346       j=i;
347     m30:;
348       l=j+d;
349       if (a[l] < a[j]){
350         x=a[j];
351         a[j]=a[l];
352         a[l]=x;
353         j-=d;
354         if (j > -1) goto m30;
355       }//if (a[l] < a[j]){
356     }//for (i=0; i<nd; ++i) 
357   }//while (1)
358 }
359 //
360 // Common block   
361 //
362 //=======================================================================
363 //function : SetCommonBlock
364 //purpose  : 
365 //=======================================================================
366   void BOPDS_PaveBlock::SetCommonBlock(const Handle(BOPDS_CommonBlock)& theCB)
367 {
368   myCommonBlock=theCB;
369 }
370 //=======================================================================
371 //function : CommonBlock
372 //purpose  : 
373 //=======================================================================
374   const Handle(BOPDS_CommonBlock)& BOPDS_PaveBlock::CommonBlock()const
375 {
376   return myCommonBlock;
377 }
378 //=======================================================================
379 //function : IsCommonBlock
380 //purpose  : 
381 //=======================================================================
382   Standard_Boolean BOPDS_PaveBlock::IsCommonBlock()const
383 {
384   return (!myCommonBlock.IsNull());
385 }
386 //=======================================================================
387 //function : IsCommonBlockOnEdge
388 //purpose  : 
389 //=======================================================================
390   Standard_Boolean BOPDS_PaveBlock::IsCommonBlockOnEdge()const
391 {
392   if (!myCommonBlock.IsNull()) {
393     return (myCommonBlock->PaveBlocks().Extent()>1);
394   }
395   return Standard_False;
396 }
397 //=======================================================================
398 //function : RealPaveBlock
399 //purpose  : 
400 //=======================================================================
401   const Handle(BOPDS_PaveBlock)& BOPDS_PaveBlock::RealPaveBlock()const
402 {
403   if (IsCommonBlock()) {
404     const Handle(BOPDS_PaveBlock)& aPB1=myCommonBlock->PaveBlock1();
405     return aPB1;
406   }
407   //
408   Handle_BOPDS_PaveBlock* pPB=(Handle_BOPDS_PaveBlock*)&myPB;
409   *pPB=this;
410   return myPB;
411 }
412 // ShrunkData
413 //=======================================================================
414 //function : HasShrunkData
415 //purpose  : 
416 //=======================================================================
417   Standard_Boolean BOPDS_PaveBlock::HasShrunkData()const
418 {
419   return (!myShrunkBox.IsVoid());
420 }
421 //=======================================================================
422 //function : SetShrunkData
423 //purpose  : 
424 //=======================================================================
425   void BOPDS_PaveBlock::SetShrunkData(const Standard_Real theT1,
426                                       const Standard_Real theT2,
427                                       const Bnd_Box& theBox)
428 {
429   myTS1=theT1;
430   myTS2=theT2;
431   myShrunkBox=theBox;
432 }
433 //=======================================================================
434 //function : ShrunkData
435 //purpose  : 
436 //=======================================================================
437   void BOPDS_PaveBlock::ShrunkData(Standard_Real& theT1,
438                                    Standard_Real& theT2,
439                                    Bnd_Box& theBox)const
440 {
441   theT1=myTS1;
442   theT2=myTS2;
443   theBox=myShrunkBox;
444 }
445 //=======================================================================
446 //function : Dump
447 //purpose  : 
448 //=======================================================================
449   void BOPDS_PaveBlock::Dump()const
450 {
451   printf(" PB:{ E:%d orE:%d", myEdge, myOriginalEdge);
452   printf(" Pave1:");
453   myPave1.Dump();
454   printf(" Pave2:");
455   myPave2.Dump();
456   printf(" }");
457 }
458