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