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