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