0028775: Code duplication removal across the BOPAlgo_PaveFiller algorithm
[occt.git] / src / BOPDS / BOPDS_DS.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 <BOPCol_DataMapOfIntegerMapOfInteger.hxx>
18 #include <BOPCol_DataMapOfShapeInteger.hxx>
19 #include <BOPCol_ListOfInteger.hxx>
20 #include <BOPCol_MapOfInteger.hxx>
21 #include <BOPDS_CommonBlock.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_FaceInfo.hxx>
24 #include <BOPDS_IndexRange.hxx>
25 #include <BOPDS_MapOfPave.hxx>
26 #include <BOPDS_MapOfPaveBlock.hxx>
27 #include <BOPDS_Pair.hxx>
28 #include <BOPDS_PaveBlock.hxx>
29 #include <BOPDS_ShapeInfo.hxx>
30 #include <BOPDS_VectorOfPave.hxx>
31 #include <BOPTools_AlgoTools.hxx>
32 #include <BRepAdaptor_Curve.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_TEdge.hxx>
35 #include <BRep_TFace.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRep_TVertex.hxx>
38 #include <BRepBndLib.hxx>
39 #include <Geom_Curve.hxx>
40 #include <GeomAPI_ProjectPointOnCurve.hxx>
41 #include <gp_Pnt.hxx>
42 #include <IntTools_Tools.hxx>
43 #include <NCollection_BaseAllocator.hxx>
44 #include <Precision.hxx>
45 #include <Standard_Assert.hxx>
46 #include <TopoDS.hxx>
47 #include <TopoDS_Edge.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Iterator.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <TopoDS_Vertex.hxx>
52 #include <BOPCol_MapOfShape.hxx>
53 #include <BOPCol_DataMapOfIntegerListOfInteger.hxx>
54
55 #include <algorithm>
56 //
57
58 static
59   void TotalShapes(const TopoDS_Shape& aS, 
60                    Standard_Integer& aNbS,
61                    BOPCol_MapOfShape& aMS);
62
63 static
64   Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
65                                  const TopoDS_Edge& aE);
66
67 //=======================================================================
68 //function : 
69 //purpose  : 
70 //=======================================================================
71 BOPDS_DS::BOPDS_DS()
72 :
73   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
74   myArguments(myAllocator),
75   myRanges(0,myAllocator),
76   myLines(0, myAllocator), 
77   myMapShapeIndex(100, myAllocator),
78   myPaveBlocksPool(0,myAllocator),
79   myMapPBCB(100, myAllocator),
80   myFaceInfoPool(0, myAllocator),
81   myShapesSD(100, myAllocator),
82   myMapVE(100, myAllocator),
83   myInterfTB(100, myAllocator),
84   myInterfVV(0, myAllocator),
85   myInterfVE(0, myAllocator),
86   myInterfVF(0, myAllocator),
87   myInterfEE(0, myAllocator),
88   myInterfEF(0, myAllocator),
89   myInterfFF(0, myAllocator),
90   myInterfVZ(0, myAllocator),
91   myInterfEZ(0, myAllocator),
92   myInterfFZ(0, myAllocator),
93   myInterfZZ(0, myAllocator)
94 {
95   myNbShapes=0;
96   myNbSourceShapes=0;
97 }
98 //=======================================================================
99 //function : 
100 //purpose  : 
101 //=======================================================================
102 BOPDS_DS::BOPDS_DS(const Handle(NCollection_BaseAllocator)& theAllocator)
103 :
104   myAllocator(theAllocator),
105   myArguments(myAllocator),
106   myRanges(0, myAllocator),
107   myLines(0, myAllocator),
108   myMapShapeIndex(100, myAllocator),
109   myPaveBlocksPool(0, myAllocator),
110   myMapPBCB(100, myAllocator),
111   myFaceInfoPool(0, myAllocator),
112   myShapesSD(100, myAllocator),
113   myMapVE(100, myAllocator),
114   myInterfTB(100, myAllocator),
115   myInterfVV(0, myAllocator),
116   myInterfVE(0, myAllocator),
117   myInterfVF(0, myAllocator),
118   myInterfEE(0, myAllocator),
119   myInterfEF(0, myAllocator),
120   myInterfFF(0, myAllocator),
121   myInterfVZ(0, myAllocator),
122   myInterfEZ(0, myAllocator),
123   myInterfFZ(0, myAllocator),
124   myInterfZZ(0, myAllocator)
125 {
126   myNbShapes=0;
127   myNbSourceShapes=0;
128 }
129 //=======================================================================
130 //function : ~
131 //purpose  : 
132 //=======================================================================
133 BOPDS_DS::~BOPDS_DS()
134 {
135   Clear();
136 }
137 //=======================================================================
138 //function : Clear
139 //purpose  : 
140 //=======================================================================
141 void BOPDS_DS::Clear()
142 {
143   myNbShapes=0;
144   myNbSourceShapes=0;
145   //
146   myArguments.Clear();
147   myRanges.Clear();
148   myLines.Clear();
149   myMapShapeIndex.Clear();
150   myPaveBlocksPool.Clear();
151   myFaceInfoPool.Clear();
152   myShapesSD.Clear();
153   myMapVE.Clear();
154   myMapPBCB.Clear();
155   myInterfTB.Clear();
156   myInterfVV.Clear();
157   myInterfVE.Clear();
158   myInterfVF.Clear();
159   myInterfEE.Clear();
160   myInterfEF.Clear();
161   myInterfFF.Clear();
162   myInterfVZ.Clear();
163   myInterfEZ.Clear();
164   myInterfFZ.Clear();
165   myInterfZZ.Clear();
166 }
167 //=======================================================================
168 //function : SetArguments
169 //purpose  : 
170 //=======================================================================
171 void BOPDS_DS::SetArguments(const BOPCol_ListOfShape& theLS)
172 {
173   myArguments=theLS;
174 }
175 //=======================================================================
176 //function : Arguments
177 //purpose  : 
178 //=======================================================================
179 const BOPCol_ListOfShape& BOPDS_DS::Arguments()const
180 {
181   return myArguments;
182 }
183 //=======================================================================
184 //function : Allocator
185 //purpose  : 
186 //=======================================================================
187 const Handle(NCollection_BaseAllocator)& BOPDS_DS::Allocator()const
188 {
189   return myAllocator;
190 }
191
192 //=======================================================================
193 //function : NbShapes
194 //purpose  : 
195 //=======================================================================
196 Standard_Integer BOPDS_DS::NbShapes()const
197 {
198   return myLines.Size();
199 }
200 //=======================================================================
201 //function : NbSourceShapes
202 //purpose  : 
203 //=======================================================================
204 Standard_Integer BOPDS_DS::NbSourceShapes()const
205 {
206   return myNbSourceShapes;
207 }
208 //=======================================================================
209 //function : NbRanges
210 //purpose  : 
211 //=======================================================================
212 Standard_Integer BOPDS_DS::NbRanges()const
213 {
214   return myRanges.Size();
215 }
216 //=======================================================================
217 //function : Range
218 //purpose  : 
219 //=======================================================================
220 const BOPDS_IndexRange& BOPDS_DS::Range(const Standard_Integer theI)const
221 {
222   return myRanges(theI);
223 }
224 //=======================================================================
225 //function : Rank
226 //purpose  : 
227 //=======================================================================
228 Standard_Integer BOPDS_DS::Rank(const Standard_Integer theI)const
229 {
230   Standard_Integer i, aNb, iErr;
231   //
232   iErr=-1;
233   aNb=NbRanges();
234   for(i=0; i<aNb; ++i) {
235     const BOPDS_IndexRange& aR=Range(i);
236     if (aR.Contains(theI)) {
237       return i;
238     }
239   }
240   return iErr;
241 }
242 //=======================================================================
243 //function : IsNewShape
244 //purpose  : 
245 //=======================================================================
246 Standard_Boolean BOPDS_DS::IsNewShape(const Standard_Integer theI)const
247 {
248   return theI>=NbSourceShapes();
249 }
250 //=======================================================================
251 //function : Append
252 //purpose  : 
253 //=======================================================================
254 Standard_Integer BOPDS_DS::Append(const BOPDS_ShapeInfo& theSI)
255 {
256   Standard_Integer iX;
257   //
258   myLines.Append1()=theSI;
259   iX=myLines.Extent()-1;
260   myMapShapeIndex.Bind(theSI.Shape(), iX);
261   //
262   return iX;
263 }
264 //=======================================================================
265 //function : Append
266 //purpose  : 
267 //=======================================================================
268 Standard_Integer BOPDS_DS::Append(const TopoDS_Shape& theS)
269 {
270   Standard_Integer iX;
271   //
272   myLines.Append1().SetShape(theS);
273   iX=myLines.Extent()-1;
274   myMapShapeIndex.Bind(theS, iX);
275   return iX;
276 }
277 //=======================================================================
278 //function : ShapeInfo
279 //purpose  : 
280 //=======================================================================
281 const BOPDS_ShapeInfo& BOPDS_DS::ShapeInfo
282   (const Standard_Integer theI)const
283 {
284   return myLines(theI);
285 }
286 //=======================================================================
287 //function : ChangeShapeInfo
288 //purpose  : 
289 //=======================================================================
290 BOPDS_ShapeInfo& BOPDS_DS::ChangeShapeInfo(const Standard_Integer theI)
291 {
292   BOPDS_ShapeInfo *pSI;
293   //
294   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI);
295   pSI=(BOPDS_ShapeInfo *)&aSI;
296   return *pSI;
297 }
298 //=======================================================================
299 //function : Shape
300 //purpose  : 
301 //=======================================================================
302 const TopoDS_Shape& BOPDS_DS::Shape(const Standard_Integer theI)const
303 {
304   
305   const TopoDS_Shape& aS=ShapeInfo(theI).Shape();
306   return aS;
307 }
308 //=======================================================================
309 //function : Index
310 //purpose  : 
311 //=======================================================================
312 Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS)const
313 {
314   Standard_Integer iRet;
315   //
316   iRet=-1;
317   if (myMapShapeIndex.IsBound(theS)) {
318     iRet=myMapShapeIndex.Find(theS);
319   }
320   return iRet;
321 }
322 //=======================================================================
323 //function : Init
324 //purpose  : 
325 //=======================================================================
326 void BOPDS_DS::Init(const Standard_Real theFuzz)
327 {
328   Standard_Integer i1, i2, j, aI, aNb, aNbS, aNbE, aNbSx;
329   Standard_Integer n1, n2, n3, nV, nW, nE, aNbF;
330   Standard_Real aTol, aTolAdd;
331   TopAbs_ShapeEnum aTS;
332   TopoDS_Iterator aItS;
333   BOPCol_ListIteratorOfListOfInteger aIt1, aIt2, aIt3;
334   BOPCol_ListIteratorOfListOfShape aIt;
335   BOPDS_IndexRange aR;
336   Handle(NCollection_BaseAllocator) aAllocator;
337   BOPCol_MapOfShape aMS;
338   //
339   // 1 Append Source Shapes
340   aNb=myArguments.Extent();
341   if (!aNb) {
342     return;
343   }
344   //
345   myRanges.SetIncrement(aNb);
346   //
347   aNbS=0;
348   aIt.Initialize(myArguments);
349   for (; aIt.More(); aIt.Next()) {
350     const TopoDS_Shape& aSx=aIt.Value();
351     //
352     aNbSx=0;
353     TotalShapes(aSx, aNbSx, aMS);
354     //
355     aNbS=aNbS+aNbSx;
356   }
357   aMS.Clear();
358   //
359   myLines.SetIncrement(2*aNbS);
360   //-----------------------------------------------------scope_1 f
361   aAllocator=
362     NCollection_BaseAllocator::CommonBaseAllocator();
363   //
364   //
365   i1=0; 
366   i2=0;
367   aIt.Initialize(myArguments);
368   for (; aIt.More(); aIt.Next()) {
369     const TopoDS_Shape& aS=aIt.Value();
370     if (myMapShapeIndex.IsBound(aS)) {
371       continue;
372     }
373     aI=Append(aS);
374     //
375     InitShape(aI, aS);
376     //
377     i2=NbShapes()-1;
378     aR.SetIndices(i1, i2);
379     myRanges.Append(aR);
380     i1=i2+1;
381   }
382   //
383   aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
384   myNbSourceShapes = NbShapes();
385   //
386   // 2 Bounding Boxes
387   //
388   // 2.1 Vertex
389   for (j=0; j<myNbSourceShapes; ++j) {
390     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
391     //
392     const TopoDS_Shape& aS=aSI.Shape();
393     //
394     aTS=aSI.ShapeType();
395     //
396     if (aTS==TopAbs_VERTEX) {
397       Bnd_Box& aBox=aSI.ChangeBox();
398       const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aS);
399       const gp_Pnt& aP=BRep_Tool::Pnt(aV);
400       aTol = BRep_Tool::Tolerance(aV);
401       aBox.SetGap(aTol + aTolAdd);
402       aBox.Add(aP);
403     }
404   }
405   // 2.2 Edge
406   aNbE=0;
407   for (j=0; j<myNbSourceShapes; ++j) {
408     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
409     //
410     aTS=aSI.ShapeType();
411     if (aTS==TopAbs_EDGE) {
412       const TopoDS_Shape& aS=aSI.Shape();
413       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
414       aTol = BRep_Tool::Tolerance(aE);
415       //
416       if (!BRep_Tool::Degenerated(aE)) {
417         Standard_Boolean bInf1, bInf2;
418         Standard_Integer aIx;
419         Standard_Real aT1, aT2;
420         gp_Pnt aPx;
421         Handle(Geom_Curve) aC3D;
422         TopoDS_Vertex aVx; 
423         TopoDS_Edge aEx;
424         BRep_Builder aBB;
425         BOPDS_ShapeInfo aSIx;
426         //
427         BOPCol_ListOfInteger& aLI=aSI.ChangeSubShapes();
428         //
429         aEx=aE;
430         aEx.Orientation(TopAbs_FORWARD);
431         //
432         aC3D=BRep_Tool::Curve (aEx, aT1, aT2);
433         bInf1=Precision::IsNegativeInfinite(aT1);
434         bInf2=Precision::IsPositiveInfinite(aT2);
435         //
436         if (bInf1) {
437           aC3D->D0(aT1, aPx);
438           aBB.MakeVertex(aVx, aPx, aTol);
439           aVx.Orientation(TopAbs_FORWARD);
440           //
441           aSIx.SetShape(aVx);
442           aSIx.SetShapeType(TopAbs_VERTEX);
443           aSIx.SetFlag(1); //infinite flag
444           //
445           aIx=Append(aSIx);
446           aLI.Append(aIx);
447         }
448         if (bInf2) {
449           aC3D->D0(aT2, aPx);
450           aBB.MakeVertex(aVx, aPx, aTol);
451           aVx.Orientation(TopAbs_REVERSED);
452           //
453           aSIx.SetShape(aVx);
454           aSIx.SetShapeType(TopAbs_VERTEX);
455           aSIx.SetFlag(1);//infinite flag
456           //
457           aIx=Append(aSIx);
458           aLI.Append(aIx);
459         }
460       } 
461       else {
462         aSI.SetFlag(j);
463       }
464       //
465       Bnd_Box& aBox=aSI.ChangeBox();
466       BRepBndLib::Add(aE, aBox);
467       //
468       const BOPCol_ListOfInteger& aLV=aSI.SubShapes(); 
469       aIt1.Initialize(aLV);
470       for (; aIt1.More(); aIt1.Next()) {
471         nV=aIt1.Value();
472         BOPDS_ShapeInfo& aSIV=ChangeShapeInfo(nV);
473         Bnd_Box& aBx=aSIV.ChangeBox();
474         aBox.Add(aBx);
475       }
476       aBox.SetGap(aBox.GetGap() + aTolAdd);
477       ++aNbE;
478     }
479   }
480   // 2.3 Face
481   BOPCol_MapOfInteger aMI(100, aAllocator);
482   BOPCol_MapIteratorOfMapOfInteger aItMI;
483   //
484   aNbF=0;
485   for (j=0; j<myNbSourceShapes; ++j) {
486     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
487     //
488     aTS=aSI.ShapeType();
489     if (aTS==TopAbs_FACE) {
490       const TopoDS_Shape& aS=aSI.Shape();
491       //
492       Bnd_Box& aBox=aSI.ChangeBox();
493       BRepBndLib::Add(aS, aBox);
494       //
495       BOPCol_ListOfInteger& aLW=aSI.ChangeSubShapes(); 
496       aIt1.Initialize(aLW);
497       for (; aIt1.More(); aIt1.Next()) {
498         nW=aIt1.Value();
499         BOPDS_ShapeInfo& aSIW=ChangeShapeInfo(nW);
500         //
501         const BOPCol_ListOfInteger& aLE=aSIW.SubShapes(); 
502         aIt2.Initialize(aLE);
503         for (; aIt2.More(); aIt2.Next()) {
504           nE=aIt2.Value();
505           BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
506           Bnd_Box& aBx=aSIE.ChangeBox();
507           aBox.Add(aBx);
508           aMI.Add(nE);
509           //
510           const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aSIE.Shape());
511           if (BRep_Tool::Degenerated(aE)) {
512             aSIE.SetFlag(j);
513           }
514           //
515           const BOPCol_ListOfInteger& aLV=aSIE.SubShapes(); 
516           aIt3.Initialize(aLV);
517           for (; aIt3.More(); aIt3.Next()) {
518             nV=aIt3.Value();
519             aMI.Add(nV);
520           }
521         }
522       }//for (; aIt1.More(); aIt1.Next()) {
523       //
524       // pure internal vertices on the face
525       aItS.Initialize(aS);
526       for (; aItS.More(); aItS.Next()) {
527         const TopoDS_Shape& aSx=aItS.Value();
528         if (aSx.ShapeType()==TopAbs_VERTEX){
529           nV=Index(aSx);
530           aMI.Add(nV);
531         }
532       }
533       //
534       //
535       // For a Face: change wires for BRep sub-shapes
536       aLW.Clear();
537       aItMI.Initialize(aMI);
538       for (; aItMI.More(); aItMI.Next()) {
539         nV=aItMI.Value();
540         aLW.Append(nV);
541       }
542       aMI.Clear();
543       aBox.SetGap(aBox.GetGap() + aTolAdd);
544       ++aNbF;
545     }//if (aTS==TopAbs_FACE) {
546   }//for (j=0; j<myNbSourceShapes; ++j) {
547   //
548   // 2.4 Solids
549   for (j=0; j<myNbSourceShapes; ++j) {
550     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
551     //
552     aTS=aSI.ShapeType();
553     if (aTS!=TopAbs_SOLID) {
554       continue;
555     }
556     Bnd_Box& aBox=aSI.ChangeBox();
557     BuildBndBoxSolid(j, aBox); 
558     //
559     //
560     // update sub-shapes by BRep comprising ones
561     aMI.Clear();
562     BOPCol_ListOfInteger& aLI1=aSI.ChangeSubShapes();
563     //
564     aIt1.Initialize(aLI1);
565     for (; aIt1.More(); aIt1.Next()) {
566       n1=aIt1.Value();
567       BOPDS_ShapeInfo& aSI1=ChangeShapeInfo(n1);
568       if (aSI1.ShapeType()!=TopAbs_SHELL) {
569         continue;
570       }
571       //
572       const BOPCol_ListOfInteger& aLI2=aSI1.SubShapes(); 
573       aIt2.Initialize(aLI2);
574       for (; aIt2.More(); aIt2.Next()) {
575         n2=aIt2.Value();
576         BOPDS_ShapeInfo& aSI2=ChangeShapeInfo(n2);
577         if (aSI2.ShapeType()!=TopAbs_FACE) {
578           continue;
579         }
580         //
581         aMI.Add(n2);
582         //
583         const BOPCol_ListOfInteger& aLI3=aSI2.SubShapes(); 
584         aIt3.Initialize(aLI3);
585         for (; aIt3.More(); aIt3.Next()) {
586           n3=aIt3.Value();
587           aMI.Add(n3);
588         }
589       }
590     }
591     //
592     aLI1.Clear();
593     aItMI.Initialize(aMI);
594     for (; aItMI.More(); aItMI.Next()) {
595       n1=aItMI.Value();
596       aLI1.Append(n1);
597     }
598     aMI.Clear();
599   }//for (j=0; j<myNbSourceShapes; ++j) {
600   //
601   aMI.Clear();
602   //-----------------------------------------------------
603   //
604   for (nE=0; nE<myNbSourceShapes; ++nE) {
605     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(nE);
606     if (aSI.ShapeType()!=TopAbs_EDGE) {
607       continue;
608     }
609     //
610     const BOPCol_ListOfInteger& aLV=aSI.SubShapes(); 
611     aIt1.Initialize(aLV);
612     for (; aIt1.More(); aIt1.Next()) {
613       nV=aIt1.Value();
614       if (myMapVE.IsBound(nV)) {
615         BOPCol_ListOfInteger& aLE=myMapVE.ChangeFind(nV);
616         aLE.Append(nE);
617       }
618       else {
619         BOPCol_ListOfInteger aLE(myAllocator);
620         //
621         aLE.Append(nE);
622         myMapVE.Bind(nV, aLE);
623       }
624     }
625   }
626   //
627   BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItDMILI; 
628   aItDMILI.Initialize(myMapVE);
629   for(; aItDMILI.More(); aItDMILI.Next()) { 
630     BOPCol_MapOfInteger aMFence;
631     BOPCol_ListOfInteger aLEx;
632     //
633     nV=aItDMILI.Key();
634     BOPCol_ListOfInteger& aLE=aItDMILI.ChangeValue();
635     aIt1.Initialize(aLE);
636     for (; aIt1.More(); aIt1.Next()) {
637       nE=aIt1.Value();
638       if(aMFence.Add(nE)) {
639         aLEx.Append(nE);
640       }
641     }
642     //
643     aLE.Clear();
644     aIt1.Initialize(aLEx);
645     for (; aIt1.More(); aIt1.Next()) {
646       nE=aIt1.Value();
647       aLE.Append(nE);
648     }
649   }
650   //-----------------------------------------------------scope_1 t
651   // 3 myPaveBlocksPool
652   // 4. myFaceInfoPool
653   myPaveBlocksPool.SetIncrement(aNbE);
654   myFaceInfoPool.SetIncrement(aNbF);
655 }
656 //=======================================================================
657 //function : InitShape
658 //purpose  : 
659 //=======================================================================
660 void BOPDS_DS::InitShape
661   (const Standard_Integer aI,
662    const TopoDS_Shape& aS)
663 {
664   Standard_Integer aIx;
665   TopoDS_Iterator aIt;
666   BOPCol_ListIteratorOfListOfInteger aIt1;
667   //
668   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(aI);
669   aSI.SetShapeType(aS.ShapeType());
670   BOPCol_ListOfInteger& aLI=aSI.ChangeSubShapes();
671   //
672   BOPCol_MapOfInteger aM;
673   //
674   aIt1.Initialize(aLI);
675   for (; aIt1.More(); aIt1.Next()) {
676     aM.Add(aIt1.Value());
677   }
678   //
679   aIt.Initialize(aS);
680   for (; aIt.More(); aIt.Next()) {
681     const TopoDS_Shape& aSx=aIt.Value();
682     const Standard_Integer* pIx = myMapShapeIndex.Seek(aSx);
683     aIx = (pIx ? *pIx : Append(aSx));
684     //
685     InitShape(aIx, aSx);
686     //
687     if (aM.Add(aIx)) {
688       aLI.Append(aIx);
689     }
690   }
691 }
692
693 //=======================================================================
694 //function : HasInterf
695 //purpose  : 
696 //=======================================================================
697 Standard_Boolean BOPDS_DS::HasInterf(const Standard_Integer theI) const
698 {
699   Standard_Integer n1, n2;
700   Standard_Boolean bRet;
701   BOPDS_MapIteratorOfMapOfPair aIt;
702   //
703   bRet = Standard_False;
704   //
705   aIt.Initialize(myInterfTB);
706   for (; aIt.More(); aIt.Next()) {
707     const BOPDS_Pair& aPK = aIt.Value();
708     aPK.Indices(n1, n2);
709     if (n1 == theI || n2 == theI) {
710       bRet = Standard_True;
711       break;
712     }
713   }
714   //
715   return bRet;
716 }
717 //=======================================================================
718 //function : HasInterfShapeSubShapes
719 //purpose  : 
720 //=======================================================================
721 Standard_Boolean BOPDS_DS::HasInterfShapeSubShapes
722   (const Standard_Integer theI1,
723    const Standard_Integer theI2,
724    const Standard_Boolean theFlag)const
725 {
726   Standard_Boolean bRet;
727   Standard_Integer n2;
728   BOPCol_ListIteratorOfListOfInteger aIt;
729   bRet = Standard_False;
730   //
731   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI2);
732   const BOPCol_ListOfInteger& aLI=aSI.SubShapes(); 
733   aIt.Initialize(aLI);
734   for (; aIt.More(); aIt.Next()) {
735     n2=aIt.Value();
736     bRet=HasInterf(theI1, n2);
737     if (theFlag) {
738       if(bRet) {
739         break;
740       }
741     }
742     else {
743       if(!bRet) {
744         break;
745       }
746     }
747   }
748   return bRet;
749 }
750 //=======================================================================
751 //function : HasInterfSubShapes
752 //purpose  : 
753 //=======================================================================
754 Standard_Boolean BOPDS_DS::HasInterfSubShapes
755   (const Standard_Integer theI1,
756    const Standard_Integer theI2)const
757 {
758   Standard_Boolean bRet;
759   Standard_Integer n1;
760   BOPCol_ListIteratorOfListOfInteger aIt;
761   bRet = Standard_False;
762   //
763   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI1);
764   const BOPCol_ListOfInteger& aLI=aSI.SubShapes(); 
765   aIt.Initialize(aLI);
766   for (; aIt.More(); aIt.Next()) {
767     n1=aIt.Value();
768     bRet=HasInterfShapeSubShapes(n1, theI2);
769     if(bRet) {
770       break;
771     }
772   }
773   return bRet;
774 }
775 //
776 // PaveBlocks
777 //=======================================================================
778 //function : PaveBlocksPool
779 //purpose  : 
780 //=======================================================================
781 const BOPDS_VectorOfListOfPaveBlock& BOPDS_DS::PaveBlocksPool()const
782 {
783   return myPaveBlocksPool;
784 }
785 //=======================================================================
786 //function : ChangePaveBlocksPool
787 //purpose  : 
788 //=======================================================================
789 BOPDS_VectorOfListOfPaveBlock& BOPDS_DS::ChangePaveBlocksPool()
790 {
791   return myPaveBlocksPool;
792 }
793 //=======================================================================
794 //function : HasPaveBlocks
795 //purpose  : 
796 //=======================================================================
797 Standard_Boolean BOPDS_DS::HasPaveBlocks(const Standard_Integer theI)const
798 {
799   return ShapeInfo(theI).HasReference();
800 }
801 //=======================================================================
802 //function : PaveBlocks
803 //purpose  : 
804 //=======================================================================
805 const BOPDS_ListOfPaveBlock& BOPDS_DS::PaveBlocks
806   (const Standard_Integer theI)const
807 {
808   static BOPDS_ListOfPaveBlock sLPB;
809   Standard_Integer aRef;
810   //
811   if (HasPaveBlocks(theI)) { 
812     aRef=ShapeInfo(theI).Reference();
813     const BOPDS_ListOfPaveBlock& aLPB=myPaveBlocksPool(aRef);
814     return aLPB;
815   }
816   return sLPB;
817 }
818
819 //=======================================================================
820 //function : ChangePaveBlocks
821 //purpose  : 
822 //=======================================================================
823 BOPDS_ListOfPaveBlock& BOPDS_DS::ChangePaveBlocks
824   (const Standard_Integer theI)
825 {
826   Standard_Boolean bHasReference;
827   Standard_Integer aRef;
828   //
829   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
830   bHasReference=aSI.HasReference();
831   if (!bHasReference) {
832     InitPaveBlocks(theI);
833   }
834   //
835   aRef=aSI.Reference();
836   return myPaveBlocksPool(aRef);
837 }
838 //=======================================================================
839 //function : InitPaveBlocks
840 //purpose  : 
841 //=======================================================================
842 void BOPDS_DS::InitPaveBlocks(const Standard_Integer theI)
843 {
844   Standard_Integer nV=0, iRef, aNbV, nVSD;
845   Standard_Real aT;
846   TopAbs_Orientation aOrE;
847   TopoDS_Vertex aV;
848   BOPCol_ListIteratorOfListOfInteger aIt;
849   BOPDS_Pave aPave;
850   Handle(BOPDS_PaveBlock) aPB;
851   //
852   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
853   const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aSI.Shape());
854   aOrE=aE.Orientation();
855   //
856   const BOPCol_ListOfInteger& aLV=aSI.SubShapes();
857   aNbV=aLV.Extent();
858   if (!aNbV) {
859     return;
860   }
861   //
862   aPB=new BOPDS_PaveBlock; 
863   aPB->SetOriginalEdge(theI);
864   //
865   if (aOrE!=TopAbs_INTERNAL) {
866     aIt.Initialize(aLV);
867     for (; aIt.More(); aIt.Next()) {
868       nV=aIt.Value();
869       //
870       const BOPDS_ShapeInfo& aSIV=ShapeInfo(nV);
871       aV=*(TopoDS_Vertex*)(&aSIV.Shape());
872       if (aSIV.HasFlag()) {
873         aT=ComputeParameter(aV, aE); 
874       }
875       else {
876         aT=BRep_Tool::Parameter(aV, aE);
877       } 
878       //
879       if (HasShapeSD(nV, nVSD)) {
880         nV=nVSD;
881       }
882       aPave.SetIndex(nV);
883       aPave.SetParameter(aT);
884       if (aSI.HasFlag())
885         // for a degenerated edge append pave unconditionally
886         aPB->AppendExtPave1(aPave);
887       else
888         aPB->AppendExtPave(aPave);
889     }
890     //
891     if (aNbV==1) {
892       aV.Reverse();
893       aT=BRep_Tool::Parameter(aV, aE);
894       aPave.SetIndex(nV);
895       aPave.SetParameter(aT);
896       aPB->AppendExtPave1(aPave);
897     }
898   }
899   //
900   else {
901     TopoDS_Iterator aItE;
902     //
903     aItE.Initialize(aE, Standard_False, Standard_True);
904     for (; aItE.More(); aItE.Next()) {
905       aV=*((TopoDS_Vertex*)&aItE.Value());
906       nV=Index(aV);
907       //
908       const BOPDS_ShapeInfo& aSIV=ShapeInfo(nV);
909       if (aSIV.HasFlag()) {
910         aT=ComputeParameter(aV, aE); 
911       }
912       else {
913         aT=BRep_Tool::Parameter(aV, aE);
914       }
915       //
916       if (HasShapeSD(nV, nVSD)) {
917         nV=nVSD;
918       }
919       aPave.SetIndex(nV);
920       aPave.SetParameter(aT);
921       aPB->AppendExtPave1(aPave);
922     }
923   }
924   //
925   BOPDS_ListOfPaveBlock &aLPB=myPaveBlocksPool.Append1();
926   iRef=myPaveBlocksPool.Extent()-1;
927   //
928   aPB->Update(aLPB, Standard_False);
929   aSI.SetReference(iRef);
930 }
931 //=======================================================================
932 //function : UpdatePaveBlocks
933 //purpose  : 
934 //=======================================================================
935 void BOPDS_DS::UpdatePaveBlocks()
936 {
937   Standard_Integer i, aNbPBP;
938   BOPDS_ListOfPaveBlock aLPBN(myAllocator);
939   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
940   //
941   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
942   //
943   aNbPBP=aPBP.Size();
944   for (i=0; i<aNbPBP; ++i) {
945     BOPDS_ListOfPaveBlock& aLPB=aPBP(i); 
946     //
947     aItPB.Initialize(aLPB);
948     for (; aItPB.More();) {
949       Handle(BOPDS_PaveBlock)& aPB=aItPB.ChangeValue();
950       //
951       if (!aPB->IsToUpdate()) {
952         aItPB.Next();
953         continue;
954       }
955       //
956       aLPBN.Clear();
957       aPB->Update(aLPBN);
958       //
959       aLPB.Remove(aItPB);
960       //
961       aLPB.Append(aLPBN);
962     }// for (; aItPB.More(); aItPB.Next()) {
963   }// for (i=0; i<aNbPBP; ++i) {
964 }
965 //=======================================================================
966 //function : UpdatePaveBlock
967 //purpose  : 
968 //=======================================================================
969 void BOPDS_DS::UpdatePaveBlock(const Handle(BOPDS_PaveBlock)& thePB)
970 {
971   if (!thePB->IsToUpdate()){
972     return;
973   }
974   //
975   Standard_Integer nE, iRef;
976   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBN;
977   BOPDS_ListOfPaveBlock aLPBN(myAllocator);
978   Handle(BOPDS_PaveBlock) aPB;
979   //
980   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
981   //
982   nE=thePB->OriginalEdge();
983   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(nE);
984   iRef=aSI.Reference();
985   BOPDS_ListOfPaveBlock& aLPB=aPBP(iRef); 
986   //
987   aItPB.Initialize(aLPB);
988   for (; aItPB.More(); aItPB.Next()) {
989     aPB=aItPB.ChangeValue();
990     if (aPB==thePB) {
991       aPB->Update(aLPBN);
992       aLPB.Append(aLPBN);
993       aLPB.Remove(aItPB);
994       break;
995     }
996   }
997 }
998 //=======================================================================
999 //function : UpdateCommonBlock
1000 //purpose  : 
1001 //=======================================================================
1002 void BOPDS_DS::UpdateCommonBlock(const Handle(BOPDS_CommonBlock)& theCB,
1003                                  const Standard_Real theFuzz)
1004 {
1005   Standard_Integer nE, iRef, n1, n2;
1006   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB, aItPBN;
1007   BOPDS_ListOfPaveBlock aLPBN;
1008   NCollection_DataMap<BOPDS_Pair, BOPDS_ListOfPaveBlock, BOPDS_PairMapHasher> aMPKLPB;
1009   NCollection_DataMap<BOPDS_Pair, BOPDS_ListOfPaveBlock, BOPDS_PairMapHasher>::Iterator aItMPKLPB;
1010   Handle(BOPDS_PaveBlock) aPB;
1011   Handle(BOPDS_CommonBlock) aCBx;
1012   BOPDS_Pair aPK;
1013   //
1014   const BOPDS_ListOfPaveBlock& aLPBCB=theCB->PaveBlocks();
1015   if (!aLPBCB.First()->IsToUpdate()){
1016     return;
1017   }
1018   //
1019   const BOPCol_ListOfInteger& aLF=theCB->Faces();
1020   //
1021   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
1022   //
1023   aItPBCB.Initialize(aLPBCB);
1024   for (; aItPBCB.More(); aItPBCB.Next()) {
1025     const Handle(BOPDS_PaveBlock)& aPBCB=aItPBCB.ChangeValue();
1026     //
1027     nE=aPBCB->OriginalEdge();
1028     iRef=ChangeShapeInfo(nE).Reference();
1029     BOPDS_ListOfPaveBlock& aLPB=aPBP(iRef); 
1030     //
1031     aItPB.Initialize(aLPB);
1032     for (; aItPB.More(); aItPB.Next()) {
1033       aPB=aItPB.ChangeValue();
1034       if (aPB==aPBCB) {
1035         //
1036         aLPBN.Clear();
1037         aPB->Update(aLPBN);
1038         //
1039         aItPBN.Initialize(aLPBN);
1040         for (; aItPBN.More(); aItPBN.Next()) {
1041           Handle(BOPDS_PaveBlock)& aPBN=aItPBN.ChangeValue();
1042           aLPB.Append(aPBN);
1043           //
1044           aPBN->Indices(n1, n2);
1045           aPK.SetIndices(n1, n2);
1046           if (aMPKLPB.IsBound(aPK)) {
1047             BOPDS_ListOfPaveBlock& aLPBx=aMPKLPB.ChangeFind(aPK);
1048             aLPBx.Append(aPBN);
1049           }
1050           else {
1051             BOPDS_ListOfPaveBlock aLPBx;
1052             aLPBx.Append(aPBN);
1053             aMPKLPB.Bind(aPK, aLPBx);
1054           }
1055         }
1056         aLPB.Remove(aItPB);
1057         break;
1058       }
1059     }
1060   }
1061   //
1062   aItMPKLPB.Initialize(aMPKLPB);
1063   for (; aItMPKLPB.More(); aItMPKLPB.Next()) {
1064     BOPDS_ListOfPaveBlock& aLPBx=aItMPKLPB.ChangeValue();
1065     //
1066     while (aLPBx.Extent()) {
1067       Standard_Boolean bCoinside;
1068       BOPDS_ListOfPaveBlock aLPBxN;
1069       //
1070       aItPB.Initialize(aLPBx);
1071       for(; aItPB.More(); ) {
1072         const Handle(BOPDS_PaveBlock)& aPBx=aItPB.Value();
1073         if (aLPBxN.Extent()) {
1074           const Handle(BOPDS_PaveBlock)& aPBCx = aLPBxN.First();
1075           bCoinside = CheckCoincidence(aPBx, aPBCx, theFuzz);
1076           if (bCoinside) {
1077             aLPBxN.Append(aPBx);
1078             aLPBx.Remove(aItPB);
1079             continue;
1080           }//if (bCoinside) {
1081         }//if (aLPBxN.Extent()) {
1082         else {
1083           aLPBxN.Append(aPBx);
1084           aLPBx.Remove(aItPB);
1085           continue;
1086         }
1087         aItPB.Next();
1088       }//for(; aItPB.More(); ) {
1089       //
1090       aCBx=new BOPDS_CommonBlock;
1091       aCBx->SetPaveBlocks(aLPBxN);
1092       aCBx->SetFaces(aLF);
1093       //
1094       aItPB.Initialize(aLPBxN);
1095       for (; aItPB.More(); aItPB.Next()) {
1096         aPB=aItPB.ChangeValue();
1097         SetCommonBlock(aPB, aCBx);
1098       }
1099     }
1100   }
1101 }
1102
1103 //=======================================================================
1104 // function: RealPaveBlock
1105 // purpose: 
1106 //=======================================================================
1107 Handle(BOPDS_PaveBlock) BOPDS_DS::RealPaveBlock
1108     (const Handle(BOPDS_PaveBlock)& thePB) const
1109 {
1110   if (IsCommonBlock(thePB)) {
1111     const Handle(BOPDS_CommonBlock)& aCB = CommonBlock(thePB);
1112     const Handle(BOPDS_PaveBlock)& aPB = aCB->PaveBlock1();
1113     return aPB;
1114   }
1115   return thePB;
1116 }
1117
1118 //=======================================================================
1119 // function: IsCommonBlockOnEdge
1120 // purpose: 
1121 //=======================================================================
1122 Standard_Boolean BOPDS_DS::IsCommonBlockOnEdge
1123     (const Handle(BOPDS_PaveBlock)& thePB) const
1124 {
1125   if (IsCommonBlock(thePB)) {
1126     const Handle(BOPDS_CommonBlock)& aCB = CommonBlock(thePB);
1127     return aCB->PaveBlocks().Extent()>1;
1128   } 
1129   return Standard_False;
1130 }
1131
1132 //=======================================================================
1133 //function : IsCommonBlock
1134 //purpose  : 
1135 //=======================================================================
1136 Standard_Boolean BOPDS_DS::IsCommonBlock
1137     (const Handle(BOPDS_PaveBlock)& thePB) const
1138 {
1139   return myMapPBCB.IsBound(thePB);
1140 }
1141
1142 //=======================================================================
1143 //function : CommonBlock
1144 //purpose  : 
1145 //=======================================================================
1146 Handle(BOPDS_CommonBlock) BOPDS_DS::CommonBlock
1147     (const Handle(BOPDS_PaveBlock)& thePB) const
1148 {
1149   return (IsCommonBlock(thePB) ? myMapPBCB.Find(thePB) : NULL);
1150 }
1151
1152 //=======================================================================
1153 //function : SetCommonBlock
1154 //purpose  : 
1155 //=======================================================================
1156 void BOPDS_DS::SetCommonBlock(const Handle(BOPDS_PaveBlock)& thePB,
1157                               const Handle(BOPDS_CommonBlock)& theCB)
1158 {
1159   if (IsCommonBlock(thePB)) {
1160     Handle(BOPDS_CommonBlock)& aCB = myMapPBCB.ChangeFind(thePB);
1161     aCB=theCB;
1162   }
1163   else {
1164     myMapPBCB.Bind(thePB, theCB);
1165   }
1166 }
1167
1168 //
1169 // FaceInfo
1170 //
1171
1172 //=======================================================================
1173 //function : FaceInfoPool
1174 //purpose  : 
1175 //=======================================================================
1176 const BOPDS_VectorOfFaceInfo& BOPDS_DS::FaceInfoPool()const
1177 {
1178   return myFaceInfoPool;
1179 }
1180 //=======================================================================
1181 //function : HasFaceInfo
1182 //purpose  : 
1183 //=======================================================================
1184 Standard_Boolean BOPDS_DS::HasFaceInfo(const Standard_Integer theI)const
1185 {
1186   return ShapeInfo(theI).HasReference();
1187 }
1188 //=======================================================================
1189 //function : FaceInfo
1190 //purpose  : 
1191 //=======================================================================
1192 const BOPDS_FaceInfo& BOPDS_DS::FaceInfo(const Standard_Integer theI)const
1193 {
1194   static BOPDS_FaceInfo sFI;
1195   Standard_Integer aRef;
1196   //
1197   if (HasFaceInfo(theI)) { 
1198     aRef=ShapeInfo(theI).Reference();
1199     const BOPDS_FaceInfo& aFI=myFaceInfoPool(aRef);
1200     return aFI;
1201   }
1202   return sFI;
1203 }
1204 //=======================================================================
1205 //function : ChangeFaceInfo
1206 //purpose  : 
1207 //=======================================================================
1208 BOPDS_FaceInfo& BOPDS_DS::ChangeFaceInfo(const Standard_Integer theI)
1209 {
1210   Standard_Boolean bHasReference;
1211   Standard_Integer aRef;
1212   BOPDS_FaceInfo* pFI;
1213   //
1214   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1215   bHasReference=aSI.HasReference();
1216   if (!bHasReference) {
1217     InitFaceInfo(theI);
1218   }
1219   //
1220   aRef=aSI.Reference();
1221   const BOPDS_FaceInfo& aFI=myFaceInfoPool(aRef);
1222   pFI=(BOPDS_FaceInfo*)&aFI;
1223   return *pFI;
1224 }
1225 //=======================================================================
1226 //function : InitFaceInfo
1227 //purpose  : 
1228 //=======================================================================
1229 void BOPDS_DS::InitFaceInfo(const Standard_Integer theI)
1230 {
1231   Standard_Integer iRef;
1232   //
1233   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1234   BOPDS_FaceInfo &aFI=myFaceInfoPool.Append1();
1235   iRef=myFaceInfoPool.Extent()-1;
1236   aSI.SetReference(iRef);
1237   //
1238   aFI.SetIndex(theI);
1239   UpdateFaceInfoIn(theI);
1240   UpdateFaceInfoOn(theI);
1241 }
1242 //=======================================================================
1243 //function : UpdateFaceInfoIn
1244 //purpose  : 
1245 //=======================================================================
1246 void BOPDS_DS::UpdateFaceInfoIn(const Standard_Integer theI)
1247 {
1248   Standard_Integer iRef;
1249   //
1250   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1251   if (aSI.HasReference()) {
1252     iRef=aSI.Reference();
1253     BOPDS_FaceInfo &aFI=myFaceInfoPool(iRef);
1254     //
1255     BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.ChangePaveBlocksIn();
1256     BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
1257     aMPBIn.Clear();
1258     aMVIn.Clear();
1259     FaceInfoIn(theI, aMPBIn, aMVIn);
1260   }
1261 }
1262 //=======================================================================
1263 //function : UpdateFaceInfoOn
1264 //purpose  : 
1265 //=======================================================================
1266 void BOPDS_DS::UpdateFaceInfoOn(const Standard_Integer theI)
1267 {
1268   Standard_Integer iRef;
1269   //
1270   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1271   if (aSI.HasReference()) {
1272     iRef=aSI.Reference();
1273     BOPDS_FaceInfo &aFI=myFaceInfoPool(iRef);
1274     //
1275     BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.ChangePaveBlocksOn();
1276     BOPCol_MapOfInteger& aMVOn=aFI.ChangeVerticesOn();
1277     aMPBOn.Clear();
1278     aMVOn.Clear();
1279     FaceInfoOn(theI, aMPBOn, aMVOn);
1280   }
1281 }
1282 //=======================================================================
1283 //function : FaceInfoOn
1284 //purpose  : 
1285 //=======================================================================
1286 void BOPDS_DS::FaceInfoOn(const Standard_Integer theF,
1287                           BOPDS_IndexedMapOfPaveBlock& theMPB,
1288                           BOPCol_MapOfInteger& theMI)
1289 {
1290   Standard_Integer nS, nSD, nV1, nV2;
1291   BOPCol_ListIteratorOfListOfInteger aIt;
1292   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
1293   //
1294   const BOPDS_ShapeInfo& aSI=ShapeInfo(theF);
1295   const BOPCol_ListOfInteger& aLI=aSI.SubShapes();
1296   aIt.Initialize(aLI);
1297   for (; aIt.More(); aIt.Next()) {
1298     nS=aIt.Value();
1299     const BOPDS_ShapeInfo& aSIE=ShapeInfo(nS);
1300     if (aSIE.ShapeType()==TopAbs_EDGE) {
1301       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nS);
1302       aItPB.Initialize(aLPB);
1303       for (; aItPB.More(); aItPB.Next()) {
1304         const Handle(BOPDS_PaveBlock)& aPB=aItPB.Value();
1305         aPB->Indices(nV1, nV2);
1306         theMI.Add(nV1);
1307         theMI.Add(nV2);
1308         Handle(BOPDS_PaveBlock) aPBR=RealPaveBlock(aPB);
1309         theMPB.Add(aPBR);
1310       }
1311     }//if (aSIE.ShapeType()==TopAbs_EDGE) 
1312     else {
1313       // nE is TopAbs_VERTEX
1314       if (HasShapeSD(nS, nSD)) {
1315         nS=nSD;
1316       }
1317       theMI.Add(nS);
1318     }
1319   }
1320 }
1321 //=======================================================================
1322 //function : FaceInfoIn
1323 //purpose  : 
1324 //=======================================================================
1325 void BOPDS_DS::FaceInfoIn(const Standard_Integer theF,
1326                           BOPDS_IndexedMapOfPaveBlock& theMPB,
1327                           BOPCol_MapOfInteger& theMI)
1328 {
1329   Standard_Integer i, aNbVF, aNbEF, nV, nE, nVSD;
1330   TopoDS_Iterator aItS;
1331   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
1332   //
1333   // 1. Pure internal vertices on the face
1334   const TopoDS_Shape& aF=Shape(theF);
1335   aItS.Initialize(aF);
1336   for (; aItS.More(); aItS.Next()) {
1337     const TopoDS_Shape& aSx=aItS.Value();
1338     if (aSx.ShapeType()==TopAbs_VERTEX){
1339       nV=Index(aSx);
1340       if (HasShapeSD(nV, nVSD)) {
1341         nV=nVSD;
1342       }
1343       theMI.Add(nV);
1344     }
1345   }
1346   //
1347   // 2. aVFs
1348   BOPDS_VectorOfInterfVF& aVFs=InterfVF();
1349   aNbVF=aVFs.Extent();
1350   for (i=0; i<aNbVF; ++i) {
1351     BOPDS_InterfVF& aVF=aVFs(i);
1352     if(aVF.Contains(theF)) {
1353       nV=aVF.OppositeIndex(theF);
1354       if (HasShapeSD(nV, nVSD)) {
1355         nV=nVSD;
1356       }
1357       theMI.Add(nV);
1358     }
1359   }
1360   //
1361   // 3. aEFs
1362   BOPDS_VectorOfInterfEF& aEFs=InterfEF();
1363   aNbEF=aEFs.Extent();
1364   for (i=0; i<aNbEF; ++i) {
1365     BOPDS_InterfEF& aEF=aEFs(i);
1366     if(aEF.Contains(theF)) {
1367       if(aEF.HasIndexNew(nV)) {
1368         if (HasShapeSD(nV, nVSD)) {
1369           nV=nVSD;
1370         }
1371         theMI.Add(nV);
1372       }
1373       else {
1374         nE=aEF.OppositeIndex(theF);
1375         const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1376         aItPB.Initialize(aLPB);
1377         for (; aItPB.More(); aItPB.Next()) {
1378           const Handle(BOPDS_PaveBlock)& aPB=aItPB.Value();
1379           if (IsCommonBlock(aPB)) {
1380             const Handle(BOPDS_CommonBlock)& aCB=CommonBlock(aPB);
1381             if (aCB->Contains(theF)) {
1382               const Handle(BOPDS_PaveBlock)& aPB1=aCB->PaveBlock1();
1383               theMPB.Add(aPB1);
1384             }
1385           }
1386         }// for (; aItPB.More(); aItPB.Next()) {
1387       }// else {
1388     }// if(aEF.Contains(theF)) {
1389   }// for (i=0; i<aNbEF; ++i) {
1390 }
1391
1392 //=======================================================================
1393 //function : RefineFaceInfoOn
1394 //purpose  : 
1395 //=======================================================================
1396 void BOPDS_DS::RefineFaceInfoOn()
1397 {
1398   Standard_Integer i, aNb, nF, aNbPB, j;
1399   BOPDS_IndexedMapOfPaveBlock aMPB;
1400   //
1401   aNb=myFaceInfoPool.Extent();
1402   for (i=0; i<aNb; ++i) {
1403     BOPDS_FaceInfo &aFI=myFaceInfoPool(i);
1404     nF=aFI.Index();
1405     UpdateFaceInfoOn(nF);
1406     BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.ChangePaveBlocksOn();
1407     //
1408     aMPB.Clear();
1409     aMPB.Assign(aMPBOn);
1410     aMPBOn.Clear();
1411     //
1412     aNbPB=aMPB.Extent();
1413     for (j=1; j<=aNbPB; ++j) {
1414       const Handle(BOPDS_PaveBlock)& aPB=aMPB(j);
1415       if (aPB->HasEdge()) {
1416         aMPBOn.Add(aPB);
1417       }
1418     }
1419   }
1420 }
1421 //=======================================================================
1422 //function : AloneVertices
1423 //purpose  : 
1424 //=======================================================================
1425 void BOPDS_DS::AloneVertices(const Standard_Integer theI,
1426                              BOPCol_ListOfInteger& theLI)const
1427 {
1428   if (HasFaceInfo(theI)) {
1429     //
1430     Standard_Integer i, j, nV1, nV2, nV, aNbPB;
1431     BOPCol_MapIteratorOfMapOfInteger aItMI;
1432     //
1433     BOPCol_MapOfInteger aMI(100, myAllocator);
1434     //
1435     const BOPDS_FaceInfo& aFI=FaceInfo(theI);
1436     //
1437     for (i = 0; i < 2; ++i) {
1438       const BOPDS_IndexedMapOfPaveBlock& aMPB=
1439         (!i) ? aFI.PaveBlocksIn() : aFI.PaveBlocksSc();
1440       aNbPB = aMPB.Extent();
1441       for (j = 1; j <= aNbPB; ++j) {
1442         const Handle(BOPDS_PaveBlock)& aPB = aMPB(j);
1443         aPB->Indices(nV1, nV2);
1444         aMI.Add(nV1);
1445         aMI.Add(nV2);
1446       }
1447     }
1448     //
1449     for (i=0; i<2; ++i) {
1450       const BOPCol_MapOfInteger& aMIV=
1451         (!i) ? aFI.VerticesIn() : aFI.VerticesSc();
1452       aItMI.Initialize(aMIV);
1453       for (; aItMI.More(); aItMI.Next()) {
1454         nV=aItMI.Value();
1455         if (nV>=0) {
1456           if (aMI.Add(nV)) {
1457             theLI.Append(nV);
1458           }
1459         }
1460       }
1461     }
1462   }
1463 }
1464 //=======================================================================
1465 //function : VerticesOnIn
1466 //purpose  : 
1467 //=======================================================================
1468 void BOPDS_DS::SubShapesOnIn
1469   (const Standard_Integer nF1,
1470    const Standard_Integer nF2,
1471    BOPCol_MapOfInteger& theMVOnIn,
1472    BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
1473    BOPDS_MapOfPaveBlock& theCommonPB)const
1474 {
1475   Standard_Integer i, j, nV, nV1, nV2, aNbPB;
1476   BOPCol_MapIteratorOfMapOfInteger aIt;
1477   BOPDS_IndexedMapOfPaveBlock pMPB[4];
1478   //
1479   const BOPDS_FaceInfo& aFI1=FaceInfo(nF1);
1480   const BOPDS_FaceInfo& aFI2=FaceInfo(nF2);
1481   //
1482   pMPB[0]=aFI1.PaveBlocksOn();
1483   pMPB[1]=aFI1.PaveBlocksIn();
1484   pMPB[2]=aFI2.PaveBlocksOn();
1485   pMPB[3]=aFI2.PaveBlocksIn();
1486   //
1487   for (i=0; i<4; ++i) {
1488     aNbPB = pMPB[i].Extent();
1489     for (j = 1; j <= aNbPB; ++j) {
1490       const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j);
1491       thePBOnIn.Add(aPB);
1492       aPB->Indices(nV1, nV2);
1493       theMVOnIn.Add(nV1);
1494       theMVOnIn.Add(nV2);
1495       if (i < 2) {
1496         if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
1497           theCommonPB.Add(aPB);
1498       }
1499     }
1500   }
1501   //
1502   const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
1503   const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
1504   const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
1505   const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
1506   //
1507   for (i=0; i<2; ++i) {
1508     const BOPCol_MapOfInteger& aMV1=(!i) ? aMVOn1 : aMVIn1;
1509     aIt.Initialize(aMV1);
1510     for (; aIt.More(); aIt.Next()) {
1511       nV=aIt.Value();
1512       if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
1513         theMVOnIn.Add(nV);
1514       }
1515     }
1516   }
1517
1518 //=======================================================================
1519 //function : SharedEdges
1520 //purpose  : 
1521 //=======================================================================
1522 void BOPDS_DS::SharedEdges(const Standard_Integer nF1,
1523       const Standard_Integer nF2,
1524       BOPCol_ListOfInteger& theLI,
1525       const Handle(NCollection_BaseAllocator)& aAllocator)
1526 {
1527   Standard_Integer nE, nSp;
1528   BOPCol_ListIteratorOfListOfInteger aItLI;
1529   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1530   BOPCol_MapOfInteger aMI(100, aAllocator);
1531   //
1532   const BOPDS_ShapeInfo& aSI1=ShapeInfo(nF1);
1533   const BOPCol_ListOfInteger& aLI1=aSI1.SubShapes();
1534   aItLI.Initialize(aLI1);
1535   for (; aItLI.More(); aItLI.Next()) {
1536     nE=aItLI.Value();
1537     const BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
1538     if(aSIE.ShapeType()==TopAbs_EDGE) {
1539       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1540       if (aLPB.IsEmpty()) {
1541         aMI.Add(nE);
1542       }
1543       else {
1544         aItLPB.Initialize(aLPB);
1545         for (; aItLPB.More(); aItLPB.Next()) {
1546           const Handle(BOPDS_PaveBlock) aPB=RealPaveBlock(aItLPB.Value());
1547           nSp=aPB->Edge();
1548           aMI.Add(nSp);
1549         }
1550       }
1551     }
1552   }
1553   // 
1554   const BOPDS_ShapeInfo& aSI2=ShapeInfo(nF2);
1555   const BOPCol_ListOfInteger& aLI2=aSI2.SubShapes();
1556   aItLI.Initialize(aLI2);
1557   for (; aItLI.More(); aItLI.Next()) {
1558     nE=aItLI.Value();
1559     const BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
1560     if(aSIE.ShapeType()==TopAbs_EDGE) {
1561       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1562       if (aLPB.IsEmpty()) {
1563         if (aMI.Contains(nE)) {
1564           theLI.Append(nE);
1565         }
1566       }
1567       else {
1568         aItLPB.Initialize(aLPB);
1569         for (; aItLPB.More(); aItLPB.Next()) {
1570           const Handle(BOPDS_PaveBlock) aPB=RealPaveBlock(aItLPB.Value());
1571           nSp=aPB->Edge();
1572           if (aMI.Contains(nSp)) {
1573             theLI.Append(nSp);
1574           }
1575         }
1576       }
1577     }
1578   }
1579 }
1580
1581 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1582 //
1583 // same domain shapes
1584 //
1585 //=======================================================================
1586 //function : ShapesSD
1587 //purpose  : 
1588 //=======================================================================
1589 BOPCol_DataMapOfIntegerInteger& BOPDS_DS::ShapesSD()
1590 {
1591   return myShapesSD;
1592 }
1593 //=======================================================================
1594 //function : AddShapeSD
1595 //purpose  : 
1596 //=======================================================================
1597 void BOPDS_DS::AddShapeSD(const Standard_Integer theIndex,
1598                           const Standard_Integer theIndexSD)
1599 {
1600   if (theIndex != theIndexSD)
1601     myShapesSD.Bind(theIndex, theIndexSD);
1602 }
1603 //=======================================================================
1604 //function : HasShapeSD
1605 //purpose  : 
1606 //=======================================================================
1607 Standard_Boolean BOPDS_DS::HasShapeSD
1608   (const Standard_Integer theIndex,
1609    Standard_Integer& theIndexSD)const
1610 {
1611   Standard_Boolean bHasSD = Standard_False;
1612   const Standard_Integer *pSD = myShapesSD.Seek(theIndex);
1613   while (pSD) {
1614     theIndexSD = *pSD;
1615     bHasSD = Standard_True;
1616     pSD = myShapesSD.Seek(theIndexSD);
1617   }
1618   return bHasSD;
1619 }
1620 //=======================================================================
1621 //function : Dump
1622 //purpose  : 
1623 //=======================================================================
1624 void BOPDS_DS::Dump()const
1625 {
1626   Standard_Integer i, aNb, aNbSS;
1627   //
1628   printf(" *** DS ***\n");
1629   aNb=NbRanges();
1630   printf(" Ranges:%d\n", aNb);
1631   for (i=0; i<aNb; ++i) {
1632     const BOPDS_IndexRange& aR=Range(i);
1633     aR.Dump();
1634     printf("\n");
1635   }
1636   //
1637   aNbSS=NbSourceShapes();
1638   printf(" Shapes:%d\n", aNbSS);
1639   aNb=NbShapes();
1640   for (i=0; i<aNb; ++i) {
1641     const BOPDS_ShapeInfo& aSI=ShapeInfo(i);
1642     printf(" %d :", i);
1643     aSI.Dump();
1644     printf("\n");
1645     if (i==aNbSS-1) {
1646       printf(" ****** adds\n");
1647     }
1648   }
1649   printf(" ******\n");
1650 }
1651
1652 //=======================================================================
1653 // function: CheckCoincidence
1654 // purpose:
1655 //=======================================================================
1656 Standard_Boolean BOPDS_DS::CheckCoincidence
1657   (const Handle(BOPDS_PaveBlock)& aPB1,
1658    const Handle(BOPDS_PaveBlock)& aPB2,
1659    const Standard_Real theFuzz)
1660 {
1661   Standard_Boolean bRet;
1662   Standard_Integer nE1, nE2, aNbPoints;
1663   Standard_Real aT11, aT12, aT21, aT22, aT1m, aD, aTol, aT2x;
1664   gp_Pnt aP1m;
1665   //
1666   bRet=Standard_False;
1667   //
1668   aPB1->Range(aT11, aT12);
1669   aT1m=IntTools_Tools::IntermediatePoint (aT11, aT12);
1670   nE1=aPB1->OriginalEdge();
1671   const TopoDS_Edge& aE1=(*(TopoDS_Edge*)(&Shape(nE1)));
1672   BOPTools_AlgoTools::PointOnEdge(aE1, aT1m, aP1m);
1673   //
1674   aPB2->Range(aT21, aT22);
1675   nE2=aPB2->OriginalEdge();
1676   const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&Shape(nE2)));
1677   //
1678   Standard_Real f, l;
1679   Handle(Geom_Curve)aC2 = BRep_Tool::Curve (aE2, f, l);
1680   GeomAPI_ProjectPointOnCurve aPPC;
1681   aPPC.Init(aC2, f, l);
1682   aPPC.Perform(aP1m);
1683   aNbPoints=aPPC.NbPoints();
1684   if (aNbPoints) {
1685     aD=aPPC.LowerDistance();
1686     //
1687     aTol = BRep_Tool::MaxTolerance(aE1, TopAbs_VERTEX);
1688     aTol = aTol + BRep_Tool::MaxTolerance(aE2, TopAbs_VERTEX) + Max(theFuzz, Precision::Confusion());
1689     if (aD<aTol) {
1690       aT2x=aPPC.LowerDistanceParameter();
1691       if (aT2x>aT21 && aT2x<aT22) {
1692         return !bRet;
1693       }
1694     }
1695   }
1696   return bRet;
1697 }
1698 //=======================================================================
1699 // function: IsSubShape
1700 // purpose:
1701 //=======================================================================
1702 Standard_Boolean BOPDS_DS::IsSubShape
1703   (const Standard_Integer theI1,
1704    const Standard_Integer theI2)
1705 {
1706   Standard_Boolean bRet;
1707   Standard_Integer nS;
1708   bRet = Standard_False;
1709   //
1710   BOPCol_ListIteratorOfListOfInteger aItLI;
1711   //
1712   const BOPDS_ShapeInfo& aSI = ShapeInfo(theI2);
1713   const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1714   aItLI.Initialize(aLI);
1715   for(;aItLI.More(); aItLI.Next()) {
1716     nS = aItLI.Value();
1717     if (nS == theI1) {
1718       bRet = Standard_True;
1719       break;
1720     }
1721   }
1722
1723   return bRet;
1724 }
1725 //=======================================================================
1726 // function: Paves
1727 // purpose:
1728 //=======================================================================
1729 void BOPDS_DS::Paves(const Standard_Integer theEdge,
1730                      BOPDS_ListOfPave& theLP)
1731 {
1732   Standard_Integer aNb, i;
1733   BOPDS_ListIteratorOfListOfPaveBlock aIt;
1734   BOPDS_MapOfPave aMP;
1735   //
1736   const BOPDS_ListOfPaveBlock& aLPB = PaveBlocks(theEdge);
1737   aNb = aLPB.Extent() + 1;
1738   if (aNb == 1) {
1739     return;
1740   }
1741   //
1742   BOPDS_VectorOfPave pPaves(1, aNb);
1743   //
1744   i = 1;
1745   aIt.Initialize(aLPB);
1746   for (; aIt.More(); aIt.Next()) {
1747     const Handle(BOPDS_PaveBlock)& aPB = aIt.Value();
1748     const BOPDS_Pave& aPave1 = aPB->Pave1();
1749     const BOPDS_Pave& aPave2 = aPB->Pave2();
1750     //
1751     if (aMP.Add(aPave1)){
1752       pPaves(i) = aPave1;
1753       ++i;
1754     }
1755     //
1756     if (aMP.Add(aPave2)){
1757       pPaves(i) = aPave2;
1758       ++i;
1759     }
1760   }
1761   //
1762   Standard_ASSERT_VOID(aNb == aMP.Extent(), "Abnormal number of paves");
1763   //
1764   std::sort(pPaves.begin(), pPaves.end());
1765   //
1766   for (i = 1; i <= aNb; ++i) {
1767     theLP.Append(pPaves(i));
1768   }
1769 }
1770 //=======================================================================
1771 // function: UpdateTolerance
1772 // purpose:
1773 //=======================================================================
1774 void BOPDS_DS::UpdateEdgeTolerance(const Standard_Integer nE,
1775                                    const Standard_Real aTol,
1776                                    const Standard_Real theFuzz)
1777 {
1778   Standard_Integer nV;
1779   Standard_Real aTolV;
1780   BRep_Builder aBB;
1781   BOPCol_ListIteratorOfListOfInteger aIt;
1782   //
1783   Standard_Real aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
1784
1785   const TopoDS_Edge& aE = *(TopoDS_Edge*)&Shape(nE);
1786   aBB.UpdateEdge(aE, aTol);
1787   BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
1788   Bnd_Box& aBoxE=aSIE.ChangeBox();
1789   BRepBndLib::Add(aE, aBoxE);
1790   aBoxE.SetGap(aBoxE.GetGap() + aTolAdd);
1791   //
1792   const BOPCol_ListOfInteger& aLI = aSIE.SubShapes();
1793   aIt.Initialize(aLI);
1794   for (; aIt.More(); aIt.Next()) {
1795     nV = aIt.Value();
1796     const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&Shape(nV);
1797     aTolV = BRep_Tool::Tolerance(aV);
1798     if (aTolV < aTol) {
1799       aBB.UpdateVertex(aV, aTol);
1800       BOPDS_ShapeInfo& aSIV = ChangeShapeInfo(nV);
1801       Bnd_Box& aBoxV = aSIV.ChangeBox();
1802       BRepBndLib::Add(aV, aBoxV);
1803       aBoxV.SetGap(aBoxV.GetGap() + aTolAdd);
1804     }
1805   }
1806 }
1807 //=======================================================================
1808 //function : TotalShapes
1809 //purpose  : 
1810 //=======================================================================
1811 void TotalShapes(const TopoDS_Shape& aS, 
1812                  Standard_Integer& aNbS,
1813                  BOPCol_MapOfShape& aMS)
1814 {
1815   if (aMS.Add(aS)) {
1816     TopoDS_Iterator aIt;
1817     ++aNbS;
1818     aIt.Initialize(aS);
1819     for (; aIt.More(); aIt.Next()) {
1820       const TopoDS_Shape& aSx=aIt.Value();
1821       TotalShapes(aSx, aNbS, aMS);
1822     }
1823   }
1824 }
1825
1826 //=======================================================================
1827 //function : ComputeParameter
1828 //purpose  : 
1829 //=======================================================================
1830 Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
1831                                const TopoDS_Edge& aE)
1832 {
1833   Standard_Real aT1, aT2, aTRet, aTolE2, aD2;
1834   gp_Pnt aPC, aPV;
1835   Handle(Geom_Curve) aC3D;
1836   TopoDS_Edge aEE;
1837   //
1838   aEE=aE;
1839   aEE.Orientation(TopAbs_FORWARD);
1840   //
1841   aTRet=0.;
1842   //
1843   aTolE2=BRep_Tool::Tolerance(aE);
1844   aTolE2=aTolE2*aTolE2;
1845   //
1846   aPV=BRep_Tool::Pnt(aV);
1847   //
1848   aC3D=BRep_Tool::Curve (aEE, aT1, aT2);
1849   //
1850   aC3D->D0(aT1, aPC);
1851   aD2=aPC.SquareDistance(aPV);
1852   if (aD2<aTolE2) {
1853     aTRet=aT1;
1854   }
1855   //
1856   aC3D->D0(aT2, aPC);
1857   aD2=aPC.SquareDistance(aPV);
1858   if (aD2<aTolE2) {
1859     aTRet=aT2;
1860   }
1861   //
1862   return aTRet;
1863 }
1864 //=======================================================================
1865 //function : BuildBndBoxSolid
1866 //purpose  : 
1867 //=======================================================================
1868 void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
1869                                 Bnd_Box& aBoxS)
1870 {
1871   Standard_Boolean bIsOpenBox, bIsInverted;
1872   Standard_Integer nSh, nFc;
1873   Standard_Real aTolS, aTolFc;
1874   BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
1875   //
1876   const BOPDS_ShapeInfo& aSI=ShapeInfo(theIndex);
1877   const TopoDS_Shape& aS=aSI.Shape();
1878   const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
1879   //
1880   bIsOpenBox=Standard_False;
1881   //
1882   aTolS=0.;
1883   const BOPCol_ListOfInteger& aLISh=aSI.SubShapes();
1884   aItLI.Initialize(aLISh);
1885   for (; aItLI.More(); aItLI.Next()) {
1886     nSh=aItLI.Value();
1887     const BOPDS_ShapeInfo& aSISh=ShapeInfo(nSh);
1888     if (aSISh.ShapeType()!=TopAbs_SHELL) {
1889       continue;
1890     }
1891     //
1892     const BOPCol_ListOfInteger& aLIFc=aSISh.SubShapes();
1893     aItLI1.Initialize(aLIFc);
1894     for (; aItLI1.More(); aItLI1.Next()) {
1895       nFc=aItLI1.Value();
1896       const BOPDS_ShapeInfo& aSIFc=ShapeInfo(nFc);
1897       if (aSIFc.ShapeType()!=TopAbs_FACE) {
1898         continue;
1899       }
1900       //
1901       const Bnd_Box& aBFc=aSIFc.Box();
1902       aBoxS.Add(aBFc);
1903       //
1904       if (!bIsOpenBox) {
1905         bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() ||
1906                     aBFc.IsOpenYmin() || aBFc.IsOpenYmax() ||
1907                     aBFc.IsOpenZmin() || aBFc.IsOpenZmax()); 
1908         if (bIsOpenBox) {
1909           break;
1910         }
1911       }
1912       //
1913       const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape());
1914       aTolFc=BRep_Tool::Tolerance(aFc);
1915       if (aTolFc>aTolS) {
1916         aTolS=aTolFc;
1917       }
1918     }//for (; aItLI1.More(); aItLI1.Next()) {
1919     if (bIsOpenBox) {
1920       break;
1921     }
1922     //
1923     const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape());
1924     bIsOpenBox=BOPTools_AlgoTools::IsOpenShell(aSh);
1925     if (bIsOpenBox) {
1926       break;
1927     }
1928   }//for (; aItLI.More(); aItLI.Next()) {
1929   //
1930   if (bIsOpenBox) {
1931     aBoxS.SetWhole();
1932   }
1933   else {
1934     bIsInverted=BOPTools_AlgoTools::IsInvertedSolid(aSolid);
1935     if (bIsInverted) {
1936       aBoxS.SetWhole(); 
1937     }
1938   }
1939 }
1940
1941 //=======================================================================
1942 //function : UpdatePaveBlocksWithSDVertices
1943 //purpose  : 
1944 //=======================================================================
1945 void BOPDS_DS::UpdatePaveBlocksWithSDVertices()
1946 {
1947   Standard_Integer i, aNbPBP;
1948   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
1949   //
1950   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
1951   //
1952   aNbPBP=aPBP.Size();
1953   for (i = 0; i < aNbPBP; ++i) {
1954     BOPDS_ListOfPaveBlock& aLPB = aPBP(i); 
1955     //
1956     aItPB.Initialize(aLPB);
1957     for (; aItPB.More(); aItPB.Next()) {
1958       Handle(BOPDS_PaveBlock)& aPB = aItPB.ChangeValue();
1959       UpdatePaveBlockWithSDVertices(aPB);
1960     }// for (; aItPB.More(); aItPB.Next()) {
1961   }// for (i = 0; i < aNbPBP; ++i) {
1962 }
1963 //=======================================================================
1964 //function : UpdatePaveBlockWithSDVertices
1965 //purpose  : 
1966 //=======================================================================
1967 void BOPDS_DS::UpdatePaveBlockWithSDVertices
1968   (const Handle(BOPDS_PaveBlock)& thePB)
1969 {
1970   Standard_Integer nV1, nV2;
1971   BOPDS_Pave aPave1, aPave2;
1972   //
1973   aPave1 = thePB->Pave1();
1974   aPave2 = thePB->Pave2();
1975   //
1976   nV1 = aPave1.Index();
1977   nV2 = aPave2.Index();
1978   //
1979   if (HasShapeSD(nV1, nV1)) {
1980     aPave1.SetIndex(nV1);
1981     thePB->SetPave1(aPave1);
1982   }
1983   //
1984   if (HasShapeSD(nV2, nV2)) {
1985     aPave2.SetIndex(nV2);
1986     thePB->SetPave2(aPave2);
1987   }
1988 }
1989 //=======================================================================
1990 //function : UpdateCommonBlockWithSDVertices
1991 //purpose  : 
1992 //=======================================================================
1993 void BOPDS_DS::UpdateCommonBlockWithSDVertices
1994   (const Handle(BOPDS_CommonBlock)& theCB)
1995 {
1996   const BOPDS_ListOfPaveBlock& aLPB = theCB->PaveBlocks();
1997   BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
1998   for (; aItPB.More(); aItPB.Next()) {
1999     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2000     UpdatePaveBlockWithSDVertices(aPB);
2001   }
2002 }
2003 //=======================================================================
2004 //function : InitPaveBlocksForVertex
2005 //purpose  : 
2006 //=======================================================================
2007 void BOPDS_DS::InitPaveBlocksForVertex(const Standard_Integer theNV)
2008 {
2009   Standard_Integer nE;
2010   BOPCol_ListIteratorOfListOfInteger aItLE;
2011   //
2012   if (myMapVE.IsBound(theNV)) {
2013     const BOPCol_ListOfInteger& aLE=myMapVE.Find(theNV);
2014     aItLE.Initialize(aLE);
2015     for (; aItLE.More(); aItLE.Next()) {
2016       nE=aItLE.Value();
2017       ChangePaveBlocks(nE);
2018     }
2019   }
2020 }
2021
2022 //=======================================================================
2023 //function : ReleasePaveBlocks
2024 //purpose  :
2025 //=======================================================================
2026 void BOPDS_DS::ReleasePaveBlocks()
2027 {
2028   // It is necessary to remove the reference to PaveBlocks for the untouched
2029   // edges to avoid creation of the same images for them.
2030   // Pave blocks for this reference should be cleared.
2031   // This will allow to differ the small edges, for which it is
2032   // impossible to even build a pave block from the normal edges for which the
2033   // pave block have been created, but stayed untouched.
2034   // The small edge, for which no pave blocks have been created,
2035   // should be avoided in the result, thus the reference to empty list
2036   // of pave blocks will stay to mark the edge as Deleted.
2037
2038   BOPDS_VectorOfListOfPaveBlock& aPBP = ChangePaveBlocksPool();
2039   Standard_Integer aNbPBP = aPBP.Extent();
2040   if (!aNbPBP) {
2041     return;
2042   }
2043   //
2044   for (Standard_Integer i = 0; i < aNbPBP; ++i) {
2045     BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2046     if (aLPB.Extent() == 1) {
2047       const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
2048       if (!IsCommonBlock(aPB)) {
2049         Standard_Integer nV1, nV2;
2050         aPB->Indices(nV1, nV2);
2051         if (!IsNewShape(nV1) && !IsNewShape(nV2)) {
2052           // Both vertices are original, thus the PB is untouched.
2053           // Remove reference for the original edge
2054           Standard_Integer nE = aPB->OriginalEdge();
2055           if (nE >= 0) {
2056             ChangeShapeInfo(nE).SetReference(-1);
2057           }
2058           // Clear contents of the list
2059           aLPB.Clear();
2060         }
2061       }
2062     }
2063   }
2064 }
2065
2066 //=======================================================================
2067 //function : IsValidShrunkData
2068 //purpose  :
2069 //=======================================================================
2070 Standard_Boolean BOPDS_DS::IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB)
2071 {
2072   if (!thePB->HasShrunkData())
2073     return Standard_False;
2074
2075   // Compare the distances from the bounds of the shrunk range to the vertices
2076   // with the tolerance values of vertices
2077
2078   // Shrunk range
2079   Standard_Real aTS[2];
2080   Bnd_Box aBox;
2081   Standard_Boolean bIsSplit;
2082   //
2083   thePB->ShrunkData(aTS[0], aTS[1], aBox, bIsSplit);
2084   //
2085   // Vertices
2086   Standard_Integer nV[2];
2087   thePB->Indices(nV[0], nV[1]);
2088   //
2089   const TopoDS_Edge& aE = TopoDS::Edge(Shape(thePB->OriginalEdge()));
2090   BRepAdaptor_Curve aBAC(aE);
2091   //
2092   Standard_Real anEps = BRep_Tool::Tolerance(aE) * 0.01;
2093   //
2094   for (Standard_Integer i = 0; i < 2; ++i) {
2095     const TopoDS_Vertex& aV = TopoDS::Vertex(Shape(nV[i]));
2096     Standard_Real aTol = BRep_Tool::Tolerance(aV) + Precision::Confusion();
2097     // Bounding point
2098     gp_Pnt aP = BRep_Tool::Pnt(aV);
2099     //
2100     // Point on the end of shrunk range
2101     gp_Pnt aPS = aBAC.Value(aTS[i]);
2102     //
2103     Standard_Real aDist = aP.Distance(aPS);
2104     if (aTol - aDist > anEps) {
2105       return Standard_False;
2106     }
2107   }
2108   return Standard_True;
2109 }