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