0026738: Make Boolean operations safely treating arguments when running with fuzzy...
[occt.git] / src / BOPDS / BOPDS_PaveBlock.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Bnd_Box.hxx>
17 #include <BOPDS_ListOfPave.hxx>
18 #include <BOPDS_Pave.hxx>
19 #include <BOPDS_PaveBlock.hxx>
20 #include <BOPDS_VectorOfPave.hxx>
21 #include <NCollection_BaseAllocator.hxx>
22 #include <Standard.hxx>
23 #include <Standard_Type.hxx>
24
25 #include <algorithm>
26 IMPLEMENT_STANDARD_RTTIEXT(BOPDS_PaveBlock,MMgt_TShared)
27
28 #ifdef _MSC_VER
29 #pragma warning ( disable : 4291 )
30 #endif
31
32 //=======================================================================
33 //function : 
34 //purpose  : 
35 //=======================================================================
36   BOPDS_PaveBlock::BOPDS_PaveBlock()
37 :
38   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
39   myExtPaves(myAllocator)
40 {
41   myEdge=-1;
42   myOriginalEdge=-1;
43   myTS1=-99.;
44   myTS2=myTS1;
45   myIsSplittable=Standard_False;
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   myIsSplittable=Standard_False;
62 }
63
64 //=======================================================================
65 //function : SetEdge
66 //purpose  : 
67 //=======================================================================
68   void BOPDS_PaveBlock::SetEdge(const Standard_Integer theEdge)
69 {
70   myEdge=theEdge;
71 }
72 //=======================================================================
73 //function : Edge
74 //purpose  : 
75 //=======================================================================
76   Standard_Integer BOPDS_PaveBlock::Edge()const
77 {
78   return myEdge;
79 }
80 //=======================================================================
81 //function : HasEdge
82 //purpose  : 
83 //=======================================================================
84   Standard_Boolean BOPDS_PaveBlock::HasEdge()const
85 {
86   return (myEdge>=0);
87 }
88 //=======================================================================
89 //function : HasEdge
90 //purpose  : 
91 //=======================================================================
92   Standard_Boolean BOPDS_PaveBlock::HasEdge(Standard_Integer& theEdge)const
93 {
94   theEdge=myEdge;
95   return (myEdge>=0);
96 }
97
98 //=======================================================================
99 //function : SetOriginalEdge
100 //purpose  : 
101 //=======================================================================
102   void BOPDS_PaveBlock::SetOriginalEdge(const Standard_Integer theEdge)
103 {
104   myOriginalEdge=theEdge;
105 }
106 //=======================================================================
107 //function : OriginalEdge
108 //purpose  : 
109 //=======================================================================
110   Standard_Integer BOPDS_PaveBlock::OriginalEdge()const
111 {
112   return myOriginalEdge;
113 }
114 //=======================================================================
115 //function : IsSplitEdge
116 //purpose  : 
117 //=======================================================================
118   Standard_Boolean BOPDS_PaveBlock::IsSplitEdge()const
119 {
120   return (myEdge!=myOriginalEdge);
121 }
122 //=======================================================================
123 //function : SetPave1
124 //purpose  : 
125 //=======================================================================
126   void BOPDS_PaveBlock::SetPave1(const BOPDS_Pave& thePave)
127 {
128   myPave1=thePave;
129 }
130 //=======================================================================
131 //function : Pave1
132 //purpose  : 
133 //=======================================================================
134   const BOPDS_Pave& BOPDS_PaveBlock::Pave1()const
135 {
136   return myPave1;
137 }
138 //=======================================================================
139 //function : SetPave2
140 //purpose  : 
141 //=======================================================================
142   void BOPDS_PaveBlock::SetPave2(const BOPDS_Pave& thePave)
143 {
144   myPave2=thePave;
145 }
146 //=======================================================================
147 //function : Pave2
148 //purpose  : 
149 //=======================================================================
150   const BOPDS_Pave& BOPDS_PaveBlock::Pave2()const
151 {
152   return myPave2;
153 }
154 //=======================================================================
155 //function : Range
156 //purpose  : 
157 //=======================================================================
158   void BOPDS_PaveBlock::Range(Standard_Real& theT1,
159                               Standard_Real& theT2)const
160 {
161   theT1=myPave1.Parameter();
162   theT2=myPave2.Parameter();
163 }
164 //=======================================================================
165 //function : Indices
166 //purpose  : 
167 //=======================================================================
168   void BOPDS_PaveBlock::Indices(Standard_Integer& theIndex1,
169                                 Standard_Integer& theIndex2)const
170 {
171   theIndex1=myPave1.Index();
172   theIndex2=myPave2.Index();
173 }
174 //=======================================================================
175 //function : HasSameBounds
176 //purpose  : 
177 //=======================================================================
178   Standard_Boolean BOPDS_PaveBlock::HasSameBounds(const Handle(BOPDS_PaveBlock)& theOther)const
179 {
180   Standard_Boolean bFlag1, bFlag2;
181   Standard_Integer n11, n12, n21, n22;
182   //
183   Indices(n11, n12);
184   theOther->Indices(n21, n22);
185   //
186   bFlag1=(n11==n21) && (n12==n22);
187   bFlag2=(n11==n22) && (n12==n21);
188   //
189   return (bFlag1 || bFlag2);
190 }
191
192
193 //
194 // Extras
195 //
196 //=======================================================================
197 //function : AppendExtPave
198 //purpose  : 
199 //=======================================================================
200   void BOPDS_PaveBlock::AppendExtPave(const BOPDS_Pave& thePave)
201 {
202   if (myMFence.Add(thePave.Index())) {
203     myExtPaves.Append(thePave);
204   }
205 }
206 //=======================================================================
207 //function : AppendExtPave1
208 //purpose  : 
209 //=======================================================================
210   void BOPDS_PaveBlock::AppendExtPave1(const BOPDS_Pave& thePave)
211 {
212   myExtPaves.Append(thePave);
213 }
214 //=======================================================================
215 //function : RemoveExtPave
216 //purpose  : 
217 //=======================================================================
218 void BOPDS_PaveBlock::RemoveExtPave(const Standard_Integer theVertNum)
219 {
220   if (myMFence.Contains(theVertNum))
221   {
222     BOPDS_ListOfPave::Iterator itPaves(myExtPaves);
223     while (itPaves.More())
224     {
225       if (itPaves.Value().Index() == theVertNum)
226         myExtPaves.Remove(itPaves);
227       else
228         itPaves.Next();
229     }
230     myMFence.Remove(theVertNum);
231   }
232 }
233 //=======================================================================
234 //function : ExtPaves
235 //purpose  : 
236 //=======================================================================
237   const BOPDS_ListOfPave& BOPDS_PaveBlock::ExtPaves()const 
238 {
239   return myExtPaves;
240 }
241 //=======================================================================
242 //function : ChangeExtPaves
243 //purpose  : 
244 //=======================================================================
245   BOPDS_ListOfPave& BOPDS_PaveBlock::ChangeExtPaves() 
246 {
247   return myExtPaves;
248 }
249 //=======================================================================
250 //function : IsToUpdate
251 //purpose  : 
252 //=======================================================================
253   Standard_Boolean BOPDS_PaveBlock::IsToUpdate()const 
254 {
255   return !myExtPaves.IsEmpty();
256 }
257 //=======================================================================
258 //function : ContainsParameter
259 //purpose  : 
260 //=======================================================================
261   Standard_Boolean BOPDS_PaveBlock::ContainsParameter(const Standard_Real theT,
262                                                       const Standard_Real theTol,
263                                                       Standard_Integer& theInd) const
264 {
265   Standard_Boolean bRet;
266   BOPDS_ListIteratorOfListOfPave aIt;
267   //
268   bRet = Standard_False;
269   aIt.Initialize(myExtPaves);
270   for (; aIt.More(); aIt.Next()) {
271     const BOPDS_Pave& aPave = aIt.Value();
272     bRet = (Abs(aPave.Parameter() - theT) < theTol);
273     if (bRet) {
274       theInd = aPave.Index();
275       break;
276     }
277   }
278   return bRet;
279 }
280 //=======================================================================
281 //function : Update
282 //purpose  : 
283 //=======================================================================
284   void BOPDS_PaveBlock::Update(BOPDS_ListOfPaveBlock& theLPB,
285                                const Standard_Boolean theFlag)
286 {
287   Standard_Integer i, aNb;
288   BOPDS_Pave aPave1, aPave2;
289   Handle(BOPDS_PaveBlock) aPB;
290   BOPDS_ListIteratorOfListOfPave aIt;
291   //
292   aNb=myExtPaves.Extent();
293   if (theFlag) {
294     aNb=aNb+2;
295   }
296   //
297   if (aNb <= 1) {
298     myExtPaves.Clear();
299     myMFence.Clear();
300     return;
301   }
302   //
303   BOPDS_VectorOfPave pPaves(1, aNb);
304   //
305   i=1;
306   if (theFlag) {
307     pPaves(i) = myPave1; 
308     ++i;
309     pPaves(i) = myPave2; 
310     ++i;
311   }
312   //
313   aIt.Initialize(myExtPaves);
314   for (; aIt.More(); aIt.Next()) {
315     const BOPDS_Pave& aPave=aIt.Value();
316     pPaves(i) = aPave;
317     ++i;
318   }
319   myExtPaves.Clear();
320   myMFence.Clear();
321   //
322   std::sort(pPaves.begin(), pPaves.end());
323   //
324   for (i = 1; i <= aNb; ++i) {
325     const BOPDS_Pave& aPave = pPaves(i);
326     if (i == 1) {
327       aPave1 = aPave;
328       continue;
329     }
330     //
331     aPave2 = aPave;
332     aPB = new BOPDS_PaveBlock;
333     aPB->SetOriginalEdge(myOriginalEdge);
334     aPB->SetPave1(aPave1);
335     aPB->SetPave2(aPave2);
336     //
337     theLPB.Append(aPB);
338     //
339     aPave1 = aPave2;
340   }
341 }
342 // ShrunkData
343 //=======================================================================
344 //function : HasShrunkData
345 //purpose  : 
346 //=======================================================================
347   Standard_Boolean BOPDS_PaveBlock::HasShrunkData()const
348 {
349   return (!myShrunkBox.IsVoid());
350 }
351 //=======================================================================
352 //function : SetShrunkData
353 //purpose  : 
354 //=======================================================================
355   void BOPDS_PaveBlock::SetShrunkData(const Standard_Real theT1,
356                                       const Standard_Real theT2,
357                                       const Bnd_Box& theBox,
358                                       const Standard_Boolean theIsSplittable)
359 {
360   myTS1=theT1;
361   myTS2=theT2;
362   myShrunkBox=theBox;
363   myIsSplittable=theIsSplittable;
364 }
365 //=======================================================================
366 //function : ShrunkData
367 //purpose  : 
368 //=======================================================================
369   void BOPDS_PaveBlock::ShrunkData(Standard_Real& theT1,
370                                    Standard_Real& theT2,
371                                    Bnd_Box& theBox,
372                                    Standard_Boolean& theIsSplittable) const
373 {
374   theT1=myTS1;
375   theT2=myTS2;
376   theBox=myShrunkBox;
377   theIsSplittable=myIsSplittable;
378 }
379 //=======================================================================
380 //function : Dump
381 //purpose  : 
382 //=======================================================================
383   void BOPDS_PaveBlock::Dump()const
384 {
385   printf(" PB:{ E:%d orE:%d", myEdge, myOriginalEdge);
386   printf(" Pave1:");
387   myPave1.Dump();
388   printf(" Pave2:");
389   myPave2.Dump();
390   printf(" }");
391 }