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