0026560: BRepBndLib build too large bounding box in Z direction for planar spline...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_6.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 #include <Bnd_Box.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPAlgo_Tools.hxx>
22 #include <BOPCol_DataMapOfIntegerReal.hxx>
23 #include <BOPCol_DataMapOfShapeInteger.hxx>
24 #include <BOPCol_ListOfInteger.hxx>
25 #include <BOPCol_ListOfShape.hxx>
26 #include <BOPCol_MapOfInteger.hxx>
27 #include <BOPCol_NCVector.hxx>
28 #include <BOPCol_Parallel.hxx>
29 #include <BOPDS_CommonBlock.hxx>
30 #include <BOPDS_CoupleOfPaveBlocks.hxx>
31 #include <BOPDS_Curve.hxx>
32 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
33 #include <BOPDS_DS.hxx>
34 #include <BOPDS_FaceInfo.hxx>
35 #include <BOPDS_Interf.hxx>
36 #include <BOPDS_Iterator.hxx>
37 #include <BOPDS_ListOfPave.hxx>
38 #include <BOPDS_ListOfPaveBlock.hxx>
39 #include <BOPDS_MapOfPaveBlock.hxx>
40 #include <BOPDS_PaveBlock.hxx>
41 #include <BOPDS_Point.hxx>
42 #include <BOPDS_ShapeInfo.hxx>
43 #include <BOPDS_VectorOfCurve.hxx>
44 #include <BOPDS_VectorOfPoint.hxx>
45 #include <BOPTools_AlgoTools.hxx>
46 #include <BOPTools_AlgoTools3D.hxx>
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRepAdaptor_Curve.hxx>
50 #include <BRepAdaptor_Surface.hxx>
51 #include <BRepBndLib.hxx>
52 #include <BRepBuilderAPI_MakeVertex.hxx>
53 #include <BRepTools.hxx>
54 #include <Geom2d_Curve.hxx>
55 #include <Geom_Curve.hxx>
56 #include <GeomAPI_ProjectPointOnCurve.hxx>
57 #include <GeomAPI_ProjectPointOnSurf.hxx>
58 #include <gp_Pnt.hxx>
59 #include <IntSurf_ListOfPntOn2S.hxx>
60 #include <IntSurf_PntOn2S.hxx>
61 #include <IntTools_Context.hxx>
62 #include <IntTools_Curve.hxx>
63 #include <IntTools_EdgeFace.hxx>
64 #include <IntTools_FaceFace.hxx>
65 #include <IntTools_PntOn2Faces.hxx>
66 #include <IntTools_SequenceOfCurves.hxx>
67 #include <IntTools_SequenceOfPntOn2Faces.hxx>
68 #include <IntTools_ShrunkRange.hxx>
69 #include <IntTools_Tools.hxx>
70 #include <Precision.hxx>
71 #include <TopExp.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Compound.hxx>
74 #include <TopoDS_Edge.hxx>
75 #include <TopoDS_Face.hxx>
76 #include <TopoDS_Vertex.hxx>
77
78 //
79 static void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
80                         const BRepAdaptor_Surface& aBAS2,
81                         Standard_Real& aTolFF);
82
83 /////////////////////////////////////////////////////////////////////////
84 //=======================================================================
85 //class    : BOPAlgo_FaceFace
86 //purpose  : 
87 //=======================================================================
88 class BOPAlgo_FaceFace : 
89   public IntTools_FaceFace,
90   public BOPAlgo_Algo {
91
92  public:
93   DEFINE_STANDARD_ALLOC
94
95   BOPAlgo_FaceFace() : 
96     IntTools_FaceFace(),  
97     BOPAlgo_Algo(),
98     myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
99   }
100   //
101   virtual ~BOPAlgo_FaceFace() {
102   }
103   //
104   void SetIndices(const Standard_Integer nF1,
105                   const Standard_Integer nF2) {
106     myIF1=nF1;
107     myIF2=nF2;
108   }
109   //
110   void Indices(Standard_Integer& nF1,
111                Standard_Integer& nF2) const {
112     nF1=myIF1;
113     nF2=myIF2;
114   }
115   //
116   void SetFaces(const TopoDS_Face& aF1,
117                 const TopoDS_Face& aF2) {
118     myF1=aF1;
119     myF2=aF2;
120   }
121   //
122   const TopoDS_Face& Face1()const {
123     return myF1;
124   }
125   //
126   const TopoDS_Face& Face2()const {
127     return myF2;
128   }
129   //
130   void SetTolFF(const Standard_Real aTolFF) {
131     myTolFF=aTolFF;
132   }
133   //
134   Standard_Real TolFF() const{
135     return myTolFF;
136   }
137   //
138   virtual void Perform() {
139     BOPAlgo_Algo::UserBreak();
140     IntTools_FaceFace::Perform(myF1, myF2);
141   }
142   //
143  protected:
144   Standard_Integer myIF1;
145   Standard_Integer myIF2;
146   Standard_Real myTolFF;
147   TopoDS_Face myF1;
148   TopoDS_Face myF2;
149 };
150 //
151 //=======================================================================
152 typedef BOPCol_NCVector
153   <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; 
154 //
155 typedef BOPCol_Functor 
156   <BOPAlgo_FaceFace,
157   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
158 //
159 typedef BOPCol_Cnt 
160   <BOPAlgo_FaceFaceFunctor,
161   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
162 /////////////////////////////////////////////////////////////////////////
163 //=======================================================================
164 //function : PerformFF
165 //purpose  : 
166 //=======================================================================
167 void BOPAlgo_PaveFiller::PerformFF()
168 {
169   Standard_Integer iSize;
170   Standard_Boolean bValid;
171   //
172   myErrorStatus=0;
173   //
174   myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
175   iSize=myIterator->ExpectedLength();
176   if (!iSize) {
177     return; 
178   }
179   //
180   Standard_Boolean bJustAdd, bApp, bCompC2D1, bCompC2D2, bIsDone;
181   Standard_Boolean bToSplit, bTangentFaces;
182   Standard_Integer nF1, nF2, aNbCurves, aNbPoints, i, aNbLP;
183   Standard_Integer aNbFaceFace, k;
184   Standard_Real aApproxTol, aTolR3D, aTolR2D, aTolFF;
185   BRepAdaptor_Surface aBAS1, aBAS2;
186   BOPCol_MapOfInteger aMI;
187   BOPAlgo_VectorOfFaceFace aVFaceFace;
188   //
189   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
190   aFFs.SetIncrement(iSize);
191   //
192   bApp=mySectionAttribute.Approximation();
193   bCompC2D1=mySectionAttribute.PCurveOnS1();
194   bCompC2D2=mySectionAttribute.PCurveOnS2();
195   aApproxTol=1.e-7;
196   bToSplit = Standard_False;
197   //
198   for (; myIterator->More(); myIterator->Next()) {
199     myIterator->Value(nF1, nF2, bJustAdd);
200     if(bJustAdd) {
201       continue;
202     }
203     //
204     const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
205     const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
206     //
207     aBAS1.Initialize(aF1, Standard_False);
208     aBAS2.Initialize(aF2, Standard_False);
209     //
210     if (aBAS1.GetType() == GeomAbs_Plane && 
211         aBAS2.GetType() == GeomAbs_Plane) {
212       Standard_Boolean bToIntersect;
213       //
214       if (aMI.Add(nF1)) {
215         myDS->UpdateFaceInfoOn(nF1);
216         myDS->UpdateFaceInfoIn(nF1);
217       }
218       if (aMI.Add(nF2)) {
219         myDS->UpdateFaceInfoOn(nF2);
220         myDS->UpdateFaceInfoIn(nF2);
221       }
222       //
223       bToIntersect = CheckPlanes(nF1, nF2);
224       if (!bToIntersect) {
225         myDS->AddInterf(nF1, nF2);
226         BOPDS_InterfFF& aFF=aFFs.Append1();
227         aFF.SetIndices(nF1, nF2);
228         aFF.Init(0, 0);
229         continue;
230       }
231     }
232     //
233     ToleranceFF(aBAS1, aBAS2, aTolFF); 
234     //
235     BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
236     //
237     aFaceFace.SetIndices(nF1, nF2);
238     aFaceFace.SetFaces(aF1, aF2);
239     aFaceFace.SetTolFF(aTolFF);
240     //
241     IntSurf_ListOfPntOn2S aListOfPnts;
242     GetEFPnts(nF1, nF2, aListOfPnts);
243     aNbLP = aListOfPnts.Extent();
244     if (aNbLP) {
245       aFaceFace.SetList(aListOfPnts);
246     }
247     //
248     aFaceFace.SetParameters(bApp, bCompC2D1, bCompC2D2, aApproxTol);
249     aFaceFace.SetProgressIndicator(myProgressIndicator);
250   }//for (; myIterator->More(); myIterator->Next()) {
251   //
252   aNbFaceFace=aVFaceFace.Extent();
253   //======================================================
254   BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
255   //======================================================
256   //
257   for (k=0; k < aNbFaceFace; ++k) {
258     BOPAlgo_FaceFace& aFaceFace=aVFaceFace(k);
259     //
260     aFaceFace.Indices(nF1, nF2);
261     aTolFF=aFaceFace.TolFF();
262     //
263     bIsDone=aFaceFace.IsDone();
264     if (bIsDone) {
265       aTolR3D=aFaceFace.TolReached3d();
266       aTolR2D=aFaceFace.TolReached2d();
267       bTangentFaces=aFaceFace.TangentFaces();
268       //
269       if (aTolR3D < aTolFF){
270         aTolR3D=aTolFF;
271       }
272       if (aTolR2D < 1.e-7){
273         aTolR2D=1.e-7;
274       }
275       //
276       aFaceFace.PrepareLines3D(bToSplit);
277       //
278       const IntTools_SequenceOfCurves& aCvsX=aFaceFace.Lines();
279       const IntTools_SequenceOfPntOn2Faces& aPntsX=aFaceFace.Points();
280       //
281       aNbCurves=aCvsX.Length();
282       aNbPoints=aPntsX.Length();
283       //
284       if (aNbCurves || aNbPoints) {
285         myDS->AddInterf(nF1, nF2);
286       } 
287       //
288       BOPDS_InterfFF& aFF=aFFs.Append1();
289       aFF.SetIndices(nF1, nF2);
290       //
291       aFF.SetTolR3D(aTolR3D);
292       aFF.SetTolR2D(aTolR2D);
293       aFF.SetTangentFaces(bTangentFaces);
294       //
295       // Curves, Points 
296       aFF.Init(aNbCurves, aNbPoints);
297       //
298       // Curves
299
300       // Fix bounding box expanding coefficient.
301       Standard_Real aBoxExpandValue = aTolR3D;
302       if (aNbCurves > 0)
303       {
304         // Modify geometric expanding coefficient by topology value,
305         // since this bounging box used in sharing (vertex or edge).
306         Standard_Real aMaxVertexTol = Max (BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
307                                            BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
308         aBoxExpandValue += aMaxVertexTol;
309       }
310
311       BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
312       for (i=1; i<=aNbCurves; ++i) {
313         Bnd_Box aBox;
314         //
315         const IntTools_Curve& aIC=aCvsX(i);
316         const Handle(Geom_Curve)& aC3D= aIC.Curve();
317         bValid=IntTools_Tools::CheckCurve(aC3D, aBoxExpandValue, aBox);
318         if (bValid) {
319           BOPDS_Curve& aNC=aVNC.Append1();
320           aNC.SetCurve(aIC);
321           aNC.SetBox(aBox);
322         }
323       }
324       //
325       // Points
326       BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
327       for (i=1; i<=aNbPoints; ++i) {
328         const IntTools_PntOn2Faces& aPi=aPntsX(i);
329         const gp_Pnt& aP=aPi.P1().Pnt();
330         //
331         BOPDS_Point& aNP=aVNP.Append1();
332         aNP.SetPnt(aP);
333       }
334     //}// if (aNbCs || aNbPs)
335     }// if (bIsDone) {
336     else {// 904/L1
337       BOPDS_InterfFF& aFF=aFFs.Append1();
338       aFF.SetIndices(nF1, nF2);
339       aNbCurves=0;
340       aNbPoints=0;
341       aFF.Init(aNbCurves, aNbPoints);
342     }
343   }// for (k=0; k < aNbFaceFace; ++k) {
344 }
345 //=======================================================================
346 //function : MakeBlocks
347 //purpose  : 
348 //=======================================================================
349 void BOPAlgo_PaveFiller::MakeBlocks()
350 {
351   Standard_Integer aNbFF;
352   //
353   myErrorStatus=0;
354   //
355   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
356   aNbFF=aFFs.Extent();
357   if (!aNbFF) {
358     return;
359   }
360   //
361   Standard_Boolean bExist, bValid2D;
362   Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
363   Standard_Integer nV1, nV2;
364   Standard_Real aTolR3D, aT1, aT2, aTol;
365   Handle(NCollection_BaseAllocator) aAllocator;
366   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
367   TopoDS_Edge aES;
368   Handle(BOPDS_PaveBlock) aPBOut;
369   //
370   //-----------------------------------------------------scope f
371   aAllocator=
372     NCollection_BaseAllocator::CommonBaseAllocator();
373   //
374   BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
375   BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
376                       aMVStick(100,aAllocator), aMVEF(100, aAllocator),
377                       aMI(100, aAllocator);
378   BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
379   BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator);
380   BOPDS_ListOfPaveBlock aLPB(aAllocator);
381   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); 
382   BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
383   BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
384   BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
385   BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
386   BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
387   BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
388   //
389   for (i=0; i<aNbFF; ++i) {
390     //
391     UserBreak();
392     //
393     BOPDS_InterfFF& aFF=aFFs(i);
394     aFF.Indices(nF1, nF2);
395     //
396     BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
397     aNbP=aVP.Extent();
398     BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
399     aNbC=aVC.Extent();
400     if (!aNbP && !aNbC) {
401       continue;
402     }
403     //
404     const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
405     const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
406     //
407     aTolR3D=aFF.TolR3D();
408     //
409     // Update face info
410     if (aMF.Add(nF1)) {
411       myDS->UpdateFaceInfoOn(nF1);
412       myDS->UpdateFaceInfoIn(nF1);
413     }
414     if (aMF.Add(nF2)) {
415       myDS->UpdateFaceInfoOn(nF2);
416       myDS->UpdateFaceInfoIn(nF2);
417     }
418     //
419     BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
420     BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
421     //
422     aMVOnIn.Clear();
423     aMPBOnIn.Clear();
424     aDMBV.Clear();
425     aMVTol.Clear();
426     //
427     myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn);
428     myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
429     
430     // 1. Treat Points
431     for (j=0; j<aNbP; ++j) {
432       TopoDS_Vertex aV;
433       BOPDS_CoupleOfPaveBlocks aCPB;
434       //
435       BOPDS_Point& aNP=aVP.ChangeValue(j);
436       const gp_Pnt& aP=aNP.Pnt();
437       //
438       bExist=IsExistingVertex(aP, aTolR3D, aMVOnIn);
439       if (!bExist) {
440         BOPTools_AlgoTools::MakeNewVertex(aP, aTolR3D, aV);
441         //
442         aCPB.SetIndexInterf(i);
443         aCPB.SetIndex(j);
444         aMSCPB.Add(aV, aCPB);
445       }
446     }
447     //
448     // 2. Treat Curves
449     aMVStick.Clear();
450     aMVEF.Clear();
451     GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
452     //
453     for (j=0; j<aNbC; ++j) {
454       BOPDS_Curve& aNC=aVC.ChangeValue(j);
455       const IntTools_Curve& aIC=aNC.Curve();
456       // DEBt
457       aNC.InitPaveBlock1();
458       //
459       PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol);
460       //
461       PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol);
462       //904/F7
463       if (aNbC == 1) {
464         PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol);
465       }
466       //
467       if (aIC.HasBounds()) {
468         aLBV.Clear();
469         //
470         PutBoundPaveOnCurve(aF1, aF2, aTolR3D, aNC, aLBV);
471         //
472         if (!aLBV.IsEmpty()) {
473           aDMBV.Bind(j, aLBV);
474         }
475       }
476     }//for (j=0; j<aNbC; ++j) {
477     //
478     // Put closing pave if needed
479     for (j=0; j<aNbC; ++j) {
480       BOPDS_Curve& aNC=aVC.ChangeValue(j);
481       PutClosingPaveOnCurve (aNC);
482     }
483     //
484     // 3. Make section edges
485     for (j=0; j<aNbC; ++j) {
486       BOPDS_Curve& aNC=aVC.ChangeValue(j);
487       const IntTools_Curve& aIC=aNC.Curve();
488       //
489       BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
490       Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
491       //
492       aLPB.Clear();
493       aPB1->Update(aLPB, Standard_False);
494       //
495       aItLPB.Initialize(aLPB);
496       for (; aItLPB.More(); aItLPB.Next()) {
497         Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
498         aPB->Indices(nV1, nV2);
499         aPB->Range  (aT1, aT2);
500         //
501         if (fabs(aT1 - aT2) < Precision::PConfusion()) {
502           continue;
503         }
504         //
505         bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC, 
506                                                  aF1, aF2, aTolR3D);
507         if (!bValid2D) {
508           continue;
509         }
510         //
511         bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aLSE);
512         if (bExist) {
513           continue;
514         }
515         //
516         bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut);
517         if (bExist) {
518           if (aMPBAdd.Add(aPBOut)) {
519             Standard_Boolean bInBothFaces = Standard_True;
520             if (!myDS->IsCommonBlock(aPBOut)) {
521               Standard_Integer nE;
522               Standard_Real aTolE;
523               //
524               nE = aPBOut->Edge();
525               const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
526               aTolE = BRep_Tool::Tolerance(aE);
527               if (aTolR3D > aTolE) {
528                 myDS->UpdateEdgeTolerance(nE, aTolR3D);
529               }
530               bInBothFaces = Standard_False;
531             } else {
532               bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
533                               aFI1.PaveBlocksIn().Contains(aPBOut))&&
534                              (aFI2.PaveBlocksOn().Contains(aPBOut) ||
535                               aFI2.PaveBlocksIn().Contains(aPBOut));
536             }
537             if (!bInBothFaces) {
538               PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
539             }
540           }
541           continue;
542         }
543         //
544         // Make Edge
545         const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
546         const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
547         //
548         BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, 
549                                       aV2, aT2, aTolR3D, aES);
550         BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC, 
551                                        mySectionAttribute.PCurveOnS1(),
552                                        mySectionAttribute.PCurveOnS2());
553         //
554         if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext)) {
555           continue;
556         }
557         //
558         // Append the Pave Block to the Curve j
559         aLPBC.Append(aPB);
560         //
561         // Keep info for post treatment 
562         BOPDS_CoupleOfPaveBlocks aCPB;
563         aCPB.SetIndexInterf(i);
564         aCPB.SetIndex(j);
565         aCPB.SetPaveBlock1(aPB);
566         //
567         aMSCPB.Add(aES, aCPB);
568         aMVI.Bind(aV1, nV1);
569         aMVI.Bind(aV2, nV2);
570         //
571         aMVTol.UnBind(nV1);
572         aMVTol.UnBind(nV2);
573       }
574       //
575       aLPBC.RemoveFirst();
576     }//for (j=0; j<aNbC; ++j) {
577     //back to previous tolerance values for unused vertices
578     aItMV.Initialize(aMVTol);
579     for (; aItMV.More(); aItMV.Next()) {
580       nV1 = aItMV.Key();
581       aTol = aItMV.Value();
582       //
583       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
584       const Handle(BRep_TVertex)& TV = 
585         *((Handle(BRep_TVertex)*)&aV.TShape());
586       TV->Tolerance(aTol);
587     }
588     //
589     ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
590   }//for (i=0; i<aNbFF; ++i) {
591   // 
592   // post treatment
593   myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aAllocator);
594   if (myErrorStatus) {
595     return;
596   }
597   //
598   // update face info
599   UpdateFaceInfo(aDMExEdges, aDMI);
600   //Update all pave blocks
601   UpdatePaveBlocks(aDMI);
602   //-----------------------------------------------------scope t
603   aMF.Clear();
604   aMVStick.Clear();
605   aMPBOnIn.Clear();
606   aMVOnIn.Clear();
607   aDMExEdges.Clear();
608   aMI.Clear();
609   aDMI.Clear();
610 }
611
612 //=======================================================================
613 //function : PostTreatFF
614 //purpose  : 
615 //=======================================================================
616 Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
617     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
618      BOPCol_DataMapOfShapeInteger& aMVI,
619      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
620      BOPCol_DataMapOfIntegerInteger& aDMI,
621      const Handle(NCollection_BaseAllocator)& theAllocator)
622 {
623   Standard_Integer iRet, aNbS;
624   //
625   iRet=0;
626   aNbS=theMSCPB.Extent();
627   if (!aNbS) {
628     return iRet;
629   }
630   //
631   Standard_Boolean bHasPaveBlocks, bOld;
632   Standard_Integer iErr, nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
633   Standard_Integer jx, aNbLPBx;
634   Standard_Real aT;
635   TopAbs_ShapeEnum aType;
636   TopoDS_Shape aV, aE;
637   BOPCol_ListIteratorOfListOfShape aItLS;
638   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
639   BOPDS_PDS aPDS;
640   Handle(BOPDS_PaveBlock) aPB1;
641   BOPDS_Pave aPave[2], aPave1[2];
642   BOPDS_ShapeInfo aSI;
643   //
644   BOPCol_ListOfShape aLS(theAllocator);
645   BOPAlgo_PaveFiller aPF(theAllocator);
646   //
647   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
648   //
649   // 0
650   if (aNbS==1) {
651     const TopoDS_Shape& aS=theMSCPB.FindKey(1);
652     const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
653     
654     //
655     aType=aS.ShapeType();
656     if (aType==TopAbs_VERTEX) {
657       aSI.SetShapeType(aType);
658       aSI.SetShape(aS);
659       iV=myDS->Append(aSI);
660       //
661       iX=aCPB.IndexInterf();
662       iP=aCPB.Index();
663       BOPDS_InterfFF& aFF=aFFs(iX); 
664       BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
665       BOPDS_Point& aNP=aVNP(iP);
666       aNP.SetIndex(iV);
667     }
668     else if (aType==TopAbs_EDGE) {
669       aPB1=aCPB.PaveBlock1();
670       //
671       if (aPB1->HasEdge()) {
672         BOPDS_ListOfPaveBlock aLPBx;
673         aLPBx.Append(aPB1);
674         aDMExEdges.Bind(aPB1, aLPBx);
675       } else {
676         aSI.SetShapeType(aType);
677         aSI.SetShape(aS);
678         iE=myDS->Append(aSI);
679         //
680         aPB1->SetEdge(iE);
681       }
682     }
683     return iRet;
684   }
685   //
686   // 1 prepare arguments
687   for (k=1; k<=aNbS; ++k) {
688     const TopoDS_Shape& aS=theMSCPB.FindKey(k);
689     aLS.Append(aS);
690   }
691   //
692   // 2 Fuse shapes
693   aPF.SetProgressIndicator(myProgressIndicator);
694   aPF.SetRunParallel(myRunParallel);
695   aPF.SetArguments(aLS);
696   aPF.Perform();
697   iErr=aPF.ErrorStatus();
698   if (iErr) {
699     return iRet;
700   }
701   aPDS=aPF.PDS();
702   //
703   aItLS.Initialize(aLS);
704   for (; aItLS.More(); aItLS.Next()) {
705     const TopoDS_Shape& aSx=aItLS.Value();
706     nSx=aPDS->Index(aSx);
707     const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
708     //
709     aType=aSIx.ShapeType();
710     //
711     if (aType==TopAbs_VERTEX) {
712       if (aPDS->HasShapeSD(nSx, nVSD)) {
713         aV=aPDS->Shape(nVSD);
714       }
715       else {
716         aV=aSx;
717       }
718       // index of new vertex in theDS -> iV
719       if (!aMVI.IsBound(aV)) {
720         aSI.SetShapeType(aType);
721         aSI.SetShape(aV);
722         iV=myDS->Append(aSI);
723         //
724         aMVI.Bind(aV, iV);
725       }
726       else {
727         iV=aMVI.Find(aV);
728       }
729       // update FF interference
730       const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
731       iX=aCPB.IndexInterf();
732       iP=aCPB.Index();
733       BOPDS_InterfFF& aFF=aFFs(iX);
734       BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
735       BOPDS_Point& aNP=aVNP(iP);
736       aNP.SetIndex(iV);
737     }//if (aType==TopAbs_VERTEX) {
738     //
739     else if (aType==TopAbs_EDGE) {
740       bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
741       const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
742       iX=aCPB.IndexInterf();
743       iC=aCPB.Index();
744       aPB1=aCPB.PaveBlock1();
745       //
746       bOld = aPB1->HasEdge();
747       if (bOld) {
748         BOPDS_ListOfPaveBlock aLPBx;
749         aDMExEdges.Bind(aPB1, aLPBx);
750       }
751       //
752       if (!bHasPaveBlocks) {
753         if (bOld) {
754           aDMExEdges.ChangeFind(aPB1).Append(aPB1);
755         }
756         else {
757           aSI.SetShapeType(aType);
758           aSI.SetShape(aSx);
759           iE=myDS->Append(aSI);
760           //
761           aPB1->SetEdge(iE);
762         }
763       }
764       else {
765         BOPDS_InterfFF& aFF=aFFs(iX);
766         BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
767         BOPDS_Curve& aNC=aVNC(iC);
768         BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
769         //
770         const BOPDS_ListOfPaveBlock& aLPBx=aPDS->PaveBlocks(nSx);
771         aNbLPBx=aLPBx.Extent();
772         //
773         if (bOld && !aNbLPBx) {
774           aDMExEdges.ChangeFind(aPB1).Append(aPB1);
775           continue;
776         }
777         //
778         if (!bOld) {
779           aItLPB.Initialize(aLPBC);
780           for (; aItLPB.More(); aItLPB.Next()) {
781             const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
782             if (aPBC==aPB1) {
783               aLPBC.Remove(aItLPB);
784               break;
785             }
786           } 
787         }
788         //
789         if (!aNbLPBx) {
790           aE=aSx;
791           //
792           if (!aMVI.IsBound(aE)) {
793             aSI.SetShapeType(aType);
794             aSI.SetShape(aE);
795             iE=myDS->Append(aSI);
796             aMVI.Bind(aE, iE);
797           }
798           else {
799             iE=aMVI.Find(aE);
800           }
801           // append new PaveBlock to aLPBC
802           aPB1->SetEdge(iE);
803           aLPBC.Append(aPB1);
804         } // if (!aNbLPBx) {
805         //
806         else {
807           aItLPB.Initialize(aLPBx);
808           if (bOld) {
809             aPave1[0] = aPB1->Pave1();
810             aPave1[1] = aPB1->Pave2();
811           }
812           for (; aItLPB.More(); aItLPB.Next()) {
813             const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
814             const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
815             //
816             // update vertices of paves
817             aPave[0]=aPBx->Pave1();
818             aPave[1]=aPBx->Pave2();
819             for (j=0; j<2; ++j) {
820               jx = 0;
821               if (bOld) {
822                 aT = aPave[j].Parameter();
823                 if (aT == aPave1[0].Parameter()) {
824                   jx = 1;
825                 } else if (aT == aPave1[1].Parameter()) {
826                   jx = 2;
827                 }
828                 //
829                 if (jx) {
830                   iV = aPave1[jx-1].Index();
831                 }
832               } 
833               if (!jx) {
834                 nV=aPave[j].Index();
835                 aV=aPDS->Shape(nV);
836                 //
837                 if (!aMVI.IsBound(aV)) {
838                   // index of new vertex in theDS -> iV
839                   aSI.SetShapeType(TopAbs_VERTEX);
840                   aSI.SetShape(aV);
841                   iV=myDS->Append(aSI);
842                   aMVI.Bind(aV, iV);
843                 }
844                 else {
845                   iV=aMVI.Find(aV);
846                 }
847               }
848               const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
849               if (aP1.Parameter() == aPave[j].Parameter() && 
850                   aP1.Index() != iV) {
851                 aDMI.Bind(aP1.Index(), iV);
852                 myDS->AddShapeSD(aP1.Index(), iV);
853               }
854               //
855               aPave[j].SetIndex(iV);
856             }
857             //
858             // add edge
859             aE=aPDS->Shape(aPBRx->Edge());
860             //
861             if (!aMVI.IsBound(aE)) {
862               aSI.SetShapeType(aType);
863               aSI.SetShape(aE);
864               iE=myDS->Append(aSI);
865               aMVI.Bind(aE, iE);
866             }
867             else {
868               iE=aMVI.Find(aE);
869             }
870             // append new PaveBlock to aLPBC
871             Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
872             //
873             aPBC->SetPave1(aPave[0]);
874             aPBC->SetPave2(aPave[1]);
875             aPBC->SetEdge(iE);
876             if (bOld) {
877               aPBC->SetOriginalEdge(aPB1->OriginalEdge());
878               aDMExEdges.ChangeFind(aPB1).Append(aPBC);
879             }
880             else {
881               aLPBC.Append(aPBC);
882             }
883           }
884         }
885       }
886     }//else if (aType==TopAbs_EDGE)
887   }//for (; aItLS.More(); aItLS.Next()) {
888   return iRet;
889 }
890
891 //=======================================================================
892 //function : UpdateFaceInfo
893 //purpose  : 
894 //=======================================================================
895 void BOPAlgo_PaveFiller::UpdateFaceInfo
896   (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
897    const BOPCol_DataMapOfIntegerInteger& theDMV)
898 {
899   Standard_Integer i, j, nV1, nF1, nF2, 
900                    aNbFF, aNbC, aNbP;
901   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
902   BOPCol_MapOfInteger aMF;
903   //
904   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
905   aNbFF=aFFs.Extent();
906   //
907   //1. Sections (curves, points);
908   for (i=0; i<aNbFF; ++i) {
909     BOPDS_InterfFF& aFF=aFFs(i);
910     aFF.Indices(nF1, nF2);
911     //
912     BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
913     BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
914     //
915     // 1.1. Section edges
916     BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
917     aNbC=aVNC.Extent();
918     for (j=0; j<aNbC; ++j) {
919       BOPDS_Curve& aNC=aVNC(j);
920       BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
921       //
922       // Add section edges to face info
923       aItLPB.Initialize(aLPBC);
924       for (; aItLPB.More(); ) {
925         const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
926         //
927         // Treat existing pave blocks
928         if (theDME.IsBound(aPB)) {
929           BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
930           UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
931           aLPBC.Remove(aItLPB);
932           continue;
933         }
934         //
935         aFI1.ChangePaveBlocksSc().Add(aPB);
936         aFI2.ChangePaveBlocksSc().Add(aPB);
937         aItLPB.Next();
938       }
939     }
940     //
941     // 1.2. Section vertices
942     const BOPDS_VectorOfPoint& aVNP=aFF.Points();
943     aNbP=aVNP.Extent();
944     for (j=0; j<aNbP; ++j) {
945       const BOPDS_Point& aNP=aVNP(j);
946       nV1=aNP.Index();
947       if (nV1<0) {
948         continue;
949       }
950       aFI1.ChangeVerticesSc().Add(nV1);
951       aFI2.ChangeVerticesSc().Add(nV1);
952     }
953     //
954     aMF.Add(nF1);
955     aMF.Add(nF2);
956   }
957   //
958   Standard_Boolean bVerts, bEdges;
959   //
960   bVerts = theDMV.Extent() > 0;
961   bEdges = theDME.Extent() > 0;
962   //
963   if (!bVerts && !bEdges) {
964     return;
965   }
966   //
967   // 2. Update Face Info information with new vertices and new
968   //    pave blocks created in PostTreatFF from existing ones
969   Standard_Integer nV2, aNbPB;
970   BOPCol_MapIteratorOfMapOfInteger aItMF;
971   BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
972   //
973   aItMF.Initialize(aMF);
974   for (; aItMF.More(); aItMF.Next()) {
975     nF1 = aItMF.Value();
976     //
977     BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
978     //
979     // 2.1. Update information about vertices
980     if (bVerts) {
981       BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
982       BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
983       //
984       aItMV.Initialize(theDMV);
985       for (; aItMV.More(); aItMV.Next()) {
986         nV1 = aItMV.Key();
987         nV2 = aItMV.Value();
988         //
989         if (aMVOn.Remove(nV1)) {
990           aMVOn.Add(nV2);
991         }
992         //
993         if (aMVIn.Remove(nV1)) {
994           aMVIn.Add(nV2);
995         }
996       } // for (; aItMV.More(); aItMV.Next()) {
997     } // if (bVerts) {
998     //
999     // 2.2. Update information about pave blocks
1000     if (bEdges) {
1001       BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1002       BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1003       //
1004       BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1005       for (i = 0; i < 2; ++i) {
1006         BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1007         aMPBCopy = aMPBOnIn;
1008         aMPBOnIn.Clear();
1009         //
1010         aNbPB = aMPBCopy.Extent();
1011         for (j = 1; j <= aNbPB; ++j) {
1012           const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1013           if (theDME.IsBound(aPB)) {
1014             const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1015             if (aLPB.IsEmpty()) {
1016               aMPBOnIn.Add(aPB);
1017               continue;
1018             }
1019             //
1020             aItLPB.Initialize(aLPB);
1021             for (; aItLPB.More(); aItLPB.Next()) {
1022               const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1023               aMPBOnIn.Add(aPB1);
1024             }
1025           }
1026           else {
1027             aMPBOnIn.Add(aPB);
1028           }
1029         } // for (j = 1; j <= aNbPB; ++j) {
1030       } // for (i = 0; i < 2; ++i) {
1031     } // if (bEdges) {
1032   }
1033 }
1034 //=======================================================================
1035 //function : IsExistingVertex
1036 //purpose  : 
1037 //=======================================================================
1038   Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1039     (const gp_Pnt& aP,
1040      const Standard_Real theTolR3D,
1041      const BOPCol_MapOfInteger& aMVOnIn)const
1042 {
1043   Standard_Boolean bRet;
1044   Standard_Integer nV, iFlag;
1045   Standard_Real aTolV;
1046   gp_Pnt aPV;
1047   Bnd_Box aBoxP;
1048   BOPCol_MapIteratorOfMapOfInteger aIt;
1049   //
1050   bRet=Standard_True;
1051   //
1052   aBoxP.Add(aP);
1053   aBoxP.Enlarge(theTolR3D);
1054   //
1055   aIt.Initialize(aMVOnIn);
1056   for (; aIt.More(); aIt.Next()) {
1057     Bnd_Box aBoxV;
1058     //
1059     nV=aIt.Value();
1060     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1061     aPV=BRep_Tool::Pnt(aV);
1062     aTolV=BRep_Tool::Tolerance(aV);
1063     aBoxV.Add(aP);
1064     aBoxV.Enlarge(aTolV);
1065     //
1066     if (!aBoxP.IsOut(aBoxV)) {
1067       iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, theTolR3D);
1068       if (!iFlag) {
1069         return bRet;
1070       }
1071     }
1072   }
1073   return !bRet;
1074 }
1075 //=======================================================================
1076 //function : IsExistingPaveBlock
1077 //purpose  : 
1078 //=======================================================================
1079   Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1080     (const Handle(BOPDS_PaveBlock)& thePB,
1081      const BOPDS_Curve& theNC,
1082      const Standard_Real theTolR3D,
1083      const BOPCol_ListOfInteger& theLSE)
1084 {
1085   Standard_Boolean bRet=Standard_True;
1086   //
1087   if (theLSE.IsEmpty()) {
1088     return !bRet;
1089   } 
1090   //
1091   Standard_Real aT1, aT2, aTm, aTx, aTol;
1092   Standard_Integer nE, iFlag;
1093   gp_Pnt aPm;
1094   Bnd_Box aBoxPm;
1095   BOPCol_ListIteratorOfListOfInteger aItLI;
1096   //
1097   thePB->Range(aT1, aT2);
1098   aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1099   theNC.Curve().D0(aTm, aPm);
1100   aBoxPm.Add(aPm);
1101   aBoxPm.Enlarge(theTolR3D);
1102   //
1103   aItLI.Initialize(theLSE);
1104   for (; aItLI.More(); aItLI.Next()) {
1105     nE=aItLI.Value();
1106     const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1107     const Bnd_Box& aBoxE=aSIE.Box();
1108     if (!aBoxE.IsOut(aBoxPm)) {
1109       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1110       aTol = BRep_Tool::Tolerance(aE);
1111       aTol = aTol > theTolR3D ? aTol : theTolR3D;
1112       iFlag=myContext->ComputePE(aPm, aTol, aE, aTx);
1113       if (!iFlag) {
1114         return bRet;
1115       }
1116     }
1117   }
1118   return !bRet;
1119 }
1120
1121 //=======================================================================
1122 //function : IsExistingPaveBlock
1123 //purpose  : 
1124 //=======================================================================
1125   Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1126     (const Handle(BOPDS_PaveBlock)& thePB,
1127      const BOPDS_Curve& theNC,
1128      const Standard_Real theTolR3D,
1129      const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1130      Handle(BOPDS_PaveBlock)& aPBOut)
1131 {
1132   Standard_Boolean bRet;
1133   Standard_Real aT1, aT2, aTm, aTx;
1134   Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1135   gp_Pnt aP1, aPm, aP2;
1136   Bnd_Box aBoxP1, aBoxPm, aBoxP2;
1137   //
1138   bRet=Standard_False;
1139   const IntTools_Curve& aIC=theNC.Curve();
1140   //
1141   thePB->Range(aT1, aT2);
1142   thePB->Indices(nV11, nV12);
1143   //first point
1144   aIC.D0(aT1, aP1);
1145   aBoxP1.Add(aP1);
1146   aBoxP1.Enlarge(theTolR3D);
1147   //intermediate point
1148   aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1149   aIC.D0(aTm, aPm);
1150   aBoxPm.Add(aPm);
1151   aBoxPm.Enlarge(theTolR3D);
1152   //last point
1153   aIC.D0(aT2, aP2);
1154   aBoxP2.Add(aP2);
1155   aBoxP2.Enlarge(theTolR3D);
1156   //
1157   aNbPB = theMPBOnIn.Extent();
1158   for (i = 1; i <= aNbPB; ++i) {
1159     const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1160     aPB->Indices(nV21, nV22);
1161     nSp=aPB->Edge();
1162     const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1163     const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1164     const Bnd_Box& aBoxSp=aSISp.Box();
1165     //
1166     iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 : 
1167       (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1168     iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : 
1169       (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1170     if (iFlag1 && iFlag2) {
1171       if (aBoxSp.IsOut(aBoxPm) || myContext->ComputePE(aPm, 
1172                                                        theTolR3D, 
1173                                                        aSp, 
1174                                                        aTx)) {
1175         continue;
1176       }
1177       //
1178       if (iFlag1 == 1) {
1179         iFlag1 = !myContext->ComputePE(aP1, theTolR3D, aSp, aTx);
1180       }
1181       //
1182       if (iFlag2 == 1) {
1183         iFlag2 = !myContext->ComputePE(aP2, theTolR3D, aSp, aTx);
1184       }
1185       //
1186       if (iFlag1 && iFlag2) {
1187         aPBOut = aPB;
1188         bRet=Standard_True;
1189         break;
1190       }
1191     }
1192   }
1193   return bRet;
1194 }
1195 //=======================================================================
1196 //function : PutBoundPaveOnCurve
1197 //purpose  : 
1198 //=======================================================================
1199   void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1200                                                const TopoDS_Face& aF2,
1201                                                const Standard_Real aTolR3D,
1202                                                BOPDS_Curve& aNC,
1203                                                BOPCol_ListOfInteger& aLVB)
1204 {
1205   Standard_Boolean bVF;
1206   Standard_Integer nV, iFlag, nVn, j, aNbEP;
1207   Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1208   gp_Pnt aP[2];
1209   TopoDS_Vertex aVn;
1210   BOPDS_ListIteratorOfListOfPave aItLP;
1211   BOPDS_Pave aPn, aPMM[2];
1212   //
1213   aTolVnew = Precision::Confusion();
1214   //
1215   const IntTools_Curve& aIC=aNC.Curve();
1216   aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1217   //
1218   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1219   const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1220   //
1221   aNbEP=aLP.Extent();
1222   if (aNbEP) {
1223     aTmin=1.e10;
1224     aTmax=-aTmin;
1225     //
1226     aItLP.Initialize(aLP);
1227     for (; aItLP.More(); aItLP.Next()) {
1228       const BOPDS_Pave& aPv=aItLP.Value();
1229       aPv.Contents(nV, aTV);
1230       if (aTV<aTmin) {
1231         aPMM[0]=aPv;
1232         aTmin=aTV;
1233       }
1234       if (aTV>aTmax) {
1235         aPMM[1]=aPv;
1236         aTmax=aTV;
1237       }
1238     }
1239   }
1240   //
1241   for (j=0; j<2; ++j) {
1242     //if curve is closed, process only one bound
1243     if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1244       continue;
1245     }
1246     //
1247     iFlag=1;
1248     //
1249     if (aNbEP) {
1250       Bnd_Box aBoxP;
1251       //
1252       aBoxP.Set(aP[j]);
1253       aTol = aTolR3D+Precision::Confusion();
1254       aBoxP.Enlarge(aTol);
1255       const BOPDS_Pave& aPV=aPMM[j];
1256       nV=aPV.Index();
1257       const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1258       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1259       const Bnd_Box& aBoxV=aSIV.Box();
1260       if (!aBoxP.IsOut(aBoxV)){
1261         iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1262       }
1263     }
1264     if (iFlag) {
1265       // 900/L5
1266       bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1267       if (!bVF) {
1268         continue;
1269       }
1270       //
1271       BOPDS_ShapeInfo aSIVn;
1272       //
1273       BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1274       aSIVn.SetShapeType(TopAbs_VERTEX);
1275       aSIVn.SetShape(aVn);
1276       //
1277       nVn=myDS->Append(aSIVn);
1278       //
1279       aPn.SetIndex(nVn);
1280       aPn.SetParameter(aT[j]);
1281       aPB->AppendExtPave(aPn);
1282       //
1283       aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1284       BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1285       //
1286       aTolVnew = BRep_Tool::Tolerance(aVn);
1287       //
1288       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1289       Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1290       BRepBndLib::Add(aVn, aBoxDS);
1291       //
1292       aLVB.Append(nVn);
1293     }
1294   }
1295 }
1296
1297 //=======================================================================
1298 //function : PutPavesOnCurve
1299 //purpose  : 
1300 //=======================================================================
1301   void BOPAlgo_PaveFiller::PutPavesOnCurve
1302   (const BOPCol_MapOfInteger& aMVOnIn,
1303    const Standard_Real aTolR3D,
1304    BOPDS_Curve& aNC,
1305    const Standard_Integer nF1,
1306    const Standard_Integer nF2,
1307    const BOPCol_MapOfInteger& aMI,
1308    const BOPCol_MapOfInteger& aMVEF,
1309    BOPCol_DataMapOfIntegerReal& aMVTol)
1310 {
1311   Standard_Boolean bInBothFaces;
1312   Standard_Integer nV;
1313   BOPCol_MapIteratorOfMapOfInteger aIt;
1314   //
1315   const Bnd_Box& aBoxC=aNC.Box();
1316   //
1317   //Put EF vertices first
1318   aIt.Initialize(aMVEF);
1319   for (; aIt.More(); aIt.Next()) {
1320     nV=aIt.Value();
1321     PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 2);
1322   }
1323   //Put all other vertices
1324   aIt.Initialize(aMVOnIn);
1325   for (; aIt.More(); aIt.Next()) {
1326     nV=aIt.Value();
1327     if (aMVEF.Contains(nV)) {
1328       continue;
1329     }
1330     //
1331     const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1332     const Bnd_Box& aBoxV=aSIV.Box();
1333     //
1334     if (aBoxC.IsOut(aBoxV)){
1335       continue;
1336     }
1337     if (!myDS->IsNewShape(nV)) {
1338       const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1339       const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
1340       //
1341       bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1342                       aFI1.VerticesIn().Contains(nV))&&
1343                      (aFI2.VerticesOn().Contains(nV) ||
1344                       aFI2.VerticesIn().Contains(nV));
1345       if (!bInBothFaces) {
1346         continue;
1347       }
1348     }
1349     //
1350     PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 1);
1351   }
1352 }
1353
1354 //=======================================================================
1355 //function : ExtendedTolerance
1356 //purpose  : 
1357 //=======================================================================
1358 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1359   (const Standard_Integer nV,
1360    const BOPCol_MapOfInteger& aMI,
1361    Standard_Real& aTolVExt,
1362    const Standard_Integer aType)
1363 {
1364   Standard_Boolean bFound = Standard_False;
1365   if (!(myDS->IsNewShape(nV))) {
1366     return bFound;
1367   }
1368   //
1369   Standard_Integer i, k, aNbLines, aNbInt;
1370   Standard_Real aT11, aT12, aD1, aD2, aD;
1371   TopoDS_Vertex aV;
1372   gp_Pnt aPV, aP11, aP12;
1373   //
1374   k = 0;
1375   aNbInt = 2;
1376   if (aType == 1) {
1377     aNbInt = 1;
1378   } else if (aType == 2) {
1379     k = 1;
1380   }
1381   //
1382   aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1383   aPV=BRep_Tool::Pnt(aV);
1384   //
1385   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1386   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1387   //
1388   for (; k<aNbInt; ++k) {
1389     aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1390     for (i = 0; i < aNbLines; ++i) {
1391       BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1392         (BOPDS_Interf*) (&aEFs(i));
1393       if (aInt->IndexNew() == nV) {
1394         if (aMI.Contains(aInt->Index1()) && 
1395             aMI.Contains(aInt->Index2())) {
1396           const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1397             aEFs(i).CommonPart();
1398           //
1399           const TopoDS_Edge& aE1=aComPrt.Edge1();
1400           aComPrt.Range1(aT11, aT12);
1401           BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1402           BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1403           aD1=aPV.Distance(aP11);
1404           aD2=aPV.Distance(aP12);
1405           aD=(aD1>aD2)? aD1 : aD2;
1406           if (aD>aTolVExt) {
1407             aTolVExt=aD;
1408           }
1409           return !bFound;
1410         }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1411       }//if (aInt->IndexNew() == nV) {
1412     }//for (i = 0; i < aNbLines; ++i) {
1413   }//for (k=0; k<2; ++k) {
1414   return bFound;
1415 }
1416
1417 //=======================================================================
1418 //function : GetEFPnts
1419 //purpose  : 
1420 //=======================================================================
1421   void BOPAlgo_PaveFiller::GetEFPnts(const Standard_Integer nF1,
1422                                      const Standard_Integer nF2,
1423                                      IntSurf_ListOfPntOn2S& aListOfPnts)
1424 {
1425   Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1426   Standard_Real U1, U2, V1, V2, f, l;
1427   BOPCol_MapOfInteger aMI;
1428   //
1429   //collect indexes of all shapes from nF1 and nF2.
1430   GetFullShapeMap(nF1, aMI);
1431   GetFullShapeMap(nF2, aMI);
1432   //
1433   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1434   aNbEFs = aEFs.Extent();
1435   //
1436   for(i = 0; i < aNbEFs; ++i) {
1437     const BOPDS_InterfEF& aEF = aEFs(i);
1438     if (aEF.HasIndexNew()) {
1439       aEF.Indices(nE, nFOpposite);
1440       if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1441         const IntTools_CommonPrt& aCP = aEF.CommonPart();
1442         Standard_Real aPar = aCP.VertexParameter1();
1443         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1444         const TopoDS_Face& aFOpposite = 
1445           (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1446         //
1447         const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1448         //
1449         nF = (nFOpposite == nF1) ? nF2 : nF1;
1450         const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1451         Handle(Geom2d_Curve) aPCurve = 
1452           BRep_Tool::CurveOnSurface(aE, aF, f, l);
1453         //
1454         GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1455         //
1456         gp_Pnt aPoint;
1457         aCurve->D0(aPar, aPoint);
1458         IntSurf_PntOn2S aPnt;
1459         if(!aPCurve.IsNull()) {
1460           gp_Pnt2d aP2d = aPCurve->Value(aPar);
1461           aProj.Perform(aPoint);
1462           if(aProj.IsDone()) {
1463             aProj.LowerDistanceParameters(U1,V1);
1464             if (nF == nF1) {
1465               aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1466             } else {
1467               aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1468             }
1469             aListOfPnts.Append(aPnt);
1470           }
1471         }
1472         else {
1473           GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1474           aProj1.Perform(aPoint);
1475           aProj.Perform(aPoint);
1476           if(aProj1.IsDone() && aProj.IsDone()){
1477             aProj1.LowerDistanceParameters(U1,V1);
1478             aProj.LowerDistanceParameters(U2,V2);
1479             if (nF == nF1) {
1480               aPnt.SetValue(U1,V1,U2,V2);
1481             } else {
1482               aPnt.SetValue(U2,V2,U1,V1);
1483             }
1484             aListOfPnts.Append(aPnt);
1485           }
1486         }
1487       }
1488     }
1489   }
1490 }
1491
1492 //=======================================================================
1493 //function : ProcessUnUsedVertices
1494 //purpose  : 
1495 //=======================================================================
1496   void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1497   (BOPDS_Curve& aNC,
1498    const BOPCol_MapOfInteger& aMI,
1499    const BOPCol_MapOfInteger& aMVEF,
1500    BOPCol_DataMapOfIntegerReal& aMVTol)
1501 {
1502   if (!aMVEF.Extent()) {
1503     return;
1504   }
1505   //
1506   const IntTools_Curve& aIC=aNC.Curve();
1507   GeomAbs_CurveType aTypeC;
1508   aTypeC=aIC.Type();
1509   if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1510     return;
1511   }
1512   //
1513   Standard_Integer nV;
1514   BOPCol_MapOfInteger aMV;
1515   //
1516   aMV.Assign(aMVEF);
1517   RemoveUsedVertices(aNC, aMV);
1518   if (!aMV.Extent()) {
1519     return;
1520   }
1521   //
1522   Standard_Real aDist;
1523   BOPDS_Pave aPave;
1524   //
1525   const Handle(Geom_Curve)& aC3D=aIC.Curve();
1526   GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1527   //
1528   BOPCol_MapIteratorOfMapOfInteger aItMI;
1529   aItMI.Initialize(aMV);
1530   for (; aItMI.More(); aItMI.Next()) {
1531     nV = aItMI.Value();
1532     const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1533     gp_Pnt aPV = BRep_Tool::Pnt(aV);
1534     aProjPT.Perform(aPV);
1535     Standard_Integer aNbPoints = aProjPT.NbPoints();
1536     if (aNbPoints) {
1537       aDist = aProjPT.LowerDistance();
1538       PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol);
1539     }
1540   }
1541 }
1542
1543 //=======================================================================
1544 //function : ProcessUnUsedVertices
1545 //purpose  : 
1546 //=======================================================================
1547   void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1548   (const TopoDS_Face& aF1,
1549    const TopoDS_Face& aF2,
1550    const BOPCol_MapOfInteger& aMI,
1551    BOPDS_Curve& aNC,
1552    const BOPCol_MapOfInteger& aMVStick,
1553    BOPCol_DataMapOfIntegerReal& aMVTol)
1554 {
1555   BOPCol_MapOfInteger aMV;
1556   aMV.Assign(aMVStick);
1557   RemoveUsedVertices(aNC, aMV);
1558   //
1559   if (!aMV.Extent()) {
1560     return;
1561   }
1562   //
1563   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1564   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1565   //
1566   const IntTools_Curve& aIC=aNC.Curve();
1567   //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1568   Handle(Geom2d_Curve) aC2D[2];
1569   //
1570   aC2D[0]=aIC.FirstCurve2d();
1571   aC2D[1]=aIC.SecondCurve2d();
1572   if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1573     Standard_Integer nV, m, n;
1574     Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1575     gp_Pnt aPC[2], aPV;
1576     gp_Dir aDN[2];
1577     gp_Pnt2d aP2D;
1578     BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1579     //
1580     aDT2=2e-7;     // the rich criteria
1581     aDScPr=5.e-9;  // the creasing criteria
1582     aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1583     //
1584     aItMI.Initialize(aMV);
1585     for (; aItMI.More(); aItMI.Next()) {
1586       nV = aItMI.Value();
1587       const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1588       aPV=BRep_Tool::Pnt(aV);
1589       //
1590       for (m=0; m<2; ++m) {
1591         aD2=aPC[m].SquareDistance(aPV);
1592         if (aD2>aDT2) {// no rich
1593           continue; 
1594         }
1595         //
1596         for (n=0; n<2; ++n) {
1597           Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1598           aC2D[n]->D0(aTC[m], aP2D);
1599           aP2D.Coord(u, v);
1600           BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1601         }
1602         // 
1603         aScPr=aDN[0]*aDN[1];
1604         if (aScPr<0.) {
1605           aScPr=-aScPr;
1606         }
1607         aScPr=1.-aScPr;
1608         //
1609         if (aScPr>aDScPr) {
1610           continue;
1611         }
1612         //
1613         // The intersection curve aIC is vanishing curve (the crease)
1614         aD=sqrt(aD2);
1615         //
1616         PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol);
1617       }
1618     }//for (jVU=1; jVU=aNbVU; ++jVU) {
1619   }
1620   //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1621   //}//if(aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
1622 }
1623
1624 //=======================================================================
1625 //function : GetStickVertices
1626 //purpose  : 
1627 //=======================================================================
1628   void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1629                                             const Standard_Integer nF2,
1630                                             BOPCol_MapOfInteger& aMVStick,
1631                                             BOPCol_MapOfInteger& aMVEF,
1632                                             BOPCol_MapOfInteger& aMI)
1633 {
1634   Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
1635   //
1636   BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1637   BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
1638   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1639   BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
1640   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1641   //
1642   Standard_Integer aNbLines[5] = {
1643     aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
1644     aVFs.Extent(), aEFs.Extent()
1645     };
1646   //collect indices of all shapes from nF1 and nF2.
1647   aMI.Clear();
1648   GetFullShapeMap(nF1, aMI);
1649   GetFullShapeMap(nF2, aMI);
1650   //
1651   //collect VV, VE, EE, VF interferences
1652   for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
1653     for (i = 0; i < aNbLines[aTypeInt]; ++i) {
1654       BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : 
1655         ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
1656          ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : 
1657           (BOPDS_Interf*)(&aVFs(i))));
1658       if (aInt->HasIndexNew()) {
1659         aInt->Indices(nS1, nS2);
1660         if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1661           nVNew = aInt->IndexNew();
1662           aMVStick.Add(nVNew);
1663         }
1664       }
1665     }
1666   }
1667   //collect EF interferences
1668   for (i = 0; i < aNbLines[4]; ++i) {
1669     const BOPDS_InterfEF& aInt = aEFs(i);
1670     if (aInt.HasIndexNew()) {
1671       aInt.Indices(nS1, nS2);
1672       if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1673         nVNew = aInt.IndexNew();
1674         aMVStick.Add(nVNew);
1675         aMVEF.Add(nVNew);
1676       }
1677     }
1678   }
1679 }
1680
1681 //=======================================================================
1682 // function: GetFullShapeMap
1683 // purpose: 
1684 //=======================================================================
1685 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
1686                                          BOPCol_MapOfInteger& aMI)
1687 {
1688   BOPCol_ListIteratorOfListOfInteger aIt;
1689   Standard_Integer nS;
1690   //
1691   const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
1692   const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1693   //
1694   aMI.Add(nF);
1695   aIt.Initialize(aLI);
1696   for (; aIt.More(); aIt.Next()) {
1697     nS = aIt.Value();
1698     aMI.Add(nS);
1699   }
1700 }
1701
1702 //=======================================================================
1703 // function: RemoveUsedVertices
1704 // purpose: 
1705 //=======================================================================
1706 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
1707                                             BOPCol_MapOfInteger& aMV)
1708 {
1709   if (!aMV.Extent()) {
1710     return;
1711   }
1712   Standard_Integer nV;
1713   BOPDS_Pave aPave;
1714   BOPDS_ListIteratorOfListOfPave aItLP;
1715   //
1716   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1717   const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1718   aItLP.Initialize(aLP);
1719   for (;aItLP.More();aItLP.Next()) {
1720     aPave = aItLP.Value();
1721     nV = aPave.Index();
1722     aMV.Remove(nV);
1723   }
1724 }
1725
1726 //=======================================================================
1727 //function : PutPaveOnCurve
1728 //purpose  : 
1729 //=======================================================================
1730   void BOPAlgo_PaveFiller::PutPaveOnCurve
1731   (const Standard_Integer nV,
1732    const Standard_Real aTolR3D,
1733    BOPDS_Curve& aNC,
1734    const BOPCol_MapOfInteger& aMI,
1735    BOPCol_DataMapOfIntegerReal& aMVTol,
1736    const Standard_Integer iCheckExtend)
1737 {
1738   Standard_Boolean bIsVertexOnLine;
1739   Standard_Real aT, aTolV;
1740   //
1741   const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1742   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1743   const IntTools_Curve& aIC = aNC.Curve();
1744   //
1745   bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
1746   if (!bIsVertexOnLine && iCheckExtend) {
1747     aTolV = BRep_Tool::Tolerance(aV);
1748     //
1749     ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
1750     bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D, aT);
1751   }
1752   //
1753   if (bIsVertexOnLine) {
1754     // check if aPB contains the parameter aT
1755     Standard_Boolean bExist;
1756     Standard_Integer nVToUpdate;
1757     Standard_Real aPTol, aDist, aTolVNew, aTolV2, aDTol;
1758     TopoDS_Vertex aVToUpdate;
1759     gp_Pnt aP1, aP2;
1760     //
1761     aTolV2 = 0.;
1762     aDTol = 1.e-12;
1763     //
1764     GeomAdaptor_Curve aGAC(aIC.Curve());
1765     aPTol = aGAC.Resolution(aTolR3D);
1766     //
1767     bExist = aPB->ContainsParameter(aT, aPTol, nVToUpdate);
1768     if (bExist) {
1769       // use existing pave
1770       aP1 = BRep_Tool::Pnt(aV);
1771       aTolV2 = BRep_Tool::Tolerance(aV);
1772       aVToUpdate = (*(TopoDS_Vertex *)(&myDS->Shape(nVToUpdate)));
1773     }
1774     else {
1775       // add new pave
1776       BOPDS_Pave aPave;
1777       aPave.SetIndex(nV);
1778       aPave.SetParameter(aT);
1779       aPB->AppendExtPave(aPave);
1780       //
1781       aP1 = aGAC.Value(aT);
1782       nVToUpdate = nV;
1783       aVToUpdate = aV;
1784     }
1785     //
1786     aTolV = BRep_Tool::Tolerance(aVToUpdate);
1787     aP2 = BRep_Tool::Pnt(aVToUpdate);
1788     aDist = aP1.Distance(aP2);
1789     aTolVNew = aDist - aTolV2;
1790     //
1791     if (aTolVNew > aTolV) {
1792       BRep_Builder aBB;
1793       aBB.UpdateVertex(aVToUpdate, aTolVNew+aDTol);
1794       //
1795       if (!aMVTol.IsBound(nVToUpdate)) {
1796         aMVTol.Bind(nVToUpdate, aTolV);
1797       }
1798       // 
1799       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVToUpdate);
1800       Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1801       BRepBndLib::Add(aVToUpdate, aBoxDS);
1802     }
1803   }
1804 }
1805
1806 //=======================================================================
1807 //function : ProcessOldPaveBlocks
1808 //purpose  : 
1809 //=======================================================================
1810   void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
1811     (const Standard_Integer theInt,
1812      const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
1813      const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
1814      BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
1815      BOPCol_DataMapOfShapeInteger& aMVI,
1816      BOPDS_MapOfPaveBlock& aMPB)
1817 {
1818   if (aDMBV.IsEmpty()) {
1819     return;
1820   }
1821   //
1822   Standard_Real aT;
1823   Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
1824   BOPCol_ListIteratorOfListOfInteger aItLI;
1825   BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
1826   //
1827   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
1828   BOPDS_InterfFF& aFF = aFFs(theInt);
1829   BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
1830   //
1831   aNbPB = aMPBOnIn.Extent();
1832   //
1833   aItBV.Initialize(aDMBV);
1834   for (; aItBV.More(); aItBV.Next()) {
1835     iC = aItBV.Key();
1836     const BOPCol_ListOfInteger& aLBV = aItBV.Value();
1837     //
1838     BOPDS_Curve& aNC = aVC.ChangeValue(iC);
1839     BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
1840     //
1841     aItLI.Initialize(aLBV);
1842     for (; aItLI.More(); aItLI.Next()) {
1843       nV = aItLI.Value();
1844       const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1845       const Bnd_Box& aBoxV=aSIV.Box();
1846       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
1847       if (!aMVI.IsBound(aV)) {
1848         continue;
1849       }
1850       //
1851       for (i = 1; i <= aNbPB; ++i) {
1852         const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
1853         if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
1854           continue;
1855         }
1856         //
1857         if (aMPB.Contains(aPB)) {
1858           continue;
1859         }
1860         //
1861         nE = aPB->Edge();
1862         const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
1863         const Bnd_Box& aBoxE = aSIE.Box();
1864         //
1865         if (aBoxV.IsOut(aBoxE)) {
1866           continue;
1867         }
1868         //
1869         const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
1870         //
1871         iFlag = myContext->ComputeVE(aV, aE, aT);
1872         if (!iFlag) {
1873           aMPB.Add(aPB);
1874           PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
1875         }
1876       }
1877     }
1878   }
1879 }
1880 //=======================================================================
1881 //function : UpdateExistingPaveBlocks
1882 //purpose  : 
1883 //=======================================================================
1884   void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
1885     (const Handle(BOPDS_PaveBlock)& aPBf,
1886      BOPDS_ListOfPaveBlock& aLPB,
1887      const Standard_Integer nF1,
1888      const Standard_Integer nF2) 
1889 {
1890   Standard_Integer nE;
1891   Standard_Boolean bCB;
1892   Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
1893   Handle(BOPDS_CommonBlock) aCB;
1894   BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
1895   //
1896   // 1. Remove micro edges from aLPB
1897   aIt.Initialize(aLPB);
1898   for (; aIt.More();) {
1899     aPB = aIt.Value();
1900     const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
1901     if (BOPTools_AlgoTools::IsMicroEdge(aE, myContext)) {
1902       aLPB.Remove(aIt);
1903       continue;
1904     }
1905     aIt.Next();
1906   }
1907   //
1908   if (!aLPB.Extent()) {
1909     return;
1910   }
1911   //
1912   BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
1913   BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
1914   //
1915   BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
1916   BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
1917   BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
1918   BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
1919   //
1920   // 2. Remove old pave blocks
1921   const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
1922   bCB = !aCB1.IsNull();
1923   BOPDS_ListOfPaveBlock aLPB1;
1924   //
1925   if (bCB) {
1926     aLPB1.Assign(aCB1->PaveBlocks());
1927   } else {
1928     aLPB1.Append(aPBf);
1929   }
1930   aIt1.Initialize(aLPB1);
1931   for (; aIt1.More(); aIt1.Next()) {
1932     aPB1 = aIt1.Value();
1933     nE = aPB1->OriginalEdge();
1934     //
1935     BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
1936     aIt2.Initialize(aLPB2);
1937     for (; aIt2.More(); aIt2.Next()) {
1938       aPB2 = aIt2.Value();
1939       if (aPB1 == aPB2) {
1940         aLPB2.Remove(aIt2);
1941         break;
1942       }
1943     }
1944   }
1945   //
1946   // 3. Update pave blocks
1947   if (bCB) {
1948     //create new common blocks
1949     BOPDS_ListOfPaveBlock aLPBNew;
1950     const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
1951     aIt.Initialize(aLPB);
1952     for (; aIt.More(); aIt.Next()) {
1953       const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
1954       //
1955       aCB = new BOPDS_CommonBlock;
1956       aIt1.Initialize(aLPB1);
1957       for (; aIt1.More(); aIt1.Next()) {
1958         aPB2 = aIt1.Value();
1959         nE = aPB2->OriginalEdge();
1960         //
1961         aPB2n = new BOPDS_PaveBlock;
1962         aPB2n->SetPave1(aPBValue->Pave1());
1963         aPB2n->SetPave2(aPBValue->Pave2());
1964         aPB2n->SetEdge(aPBValue->Edge());
1965         aPB2n->SetOriginalEdge(nE);
1966         aCB->AddPaveBlock(aPB2n);
1967         myDS->SetCommonBlock(aPB2n, aCB);
1968         myDS->ChangePaveBlocks(nE).Append(aPB2n);
1969       }
1970       aCB->AddFaces(aFaces);
1971       myDS->SortPaveBlocks(aCB);
1972       //
1973       const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
1974       aLPBNew.Append(aPBNew);
1975     }
1976     //
1977     aLPB = aLPBNew;
1978   } 
1979   else {
1980     nE = aPBf->OriginalEdge();
1981     BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
1982     aIt.Initialize(aLPB);
1983     for (; aIt.More(); aIt.Next()) {
1984       aPB = aIt.Value();
1985       aLPBE.Append(aPB);
1986     }
1987   }
1988   //
1989   Standard_Boolean bIn1, bIn2;
1990   //
1991   bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
1992   bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
1993   //
1994   if (bIn1 && bIn2) {
1995     return;
1996   }
1997   //
1998   // 4. Check new pave blocks for coincidence 
1999   //    with the opposite face.
2000   //    In case of coincidence create common blocks
2001   Standard_Integer nF;
2002   Standard_Real aTolE, aTolF;
2003   //
2004   nF = bIn1 ? nF2 : nF1;
2005   const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2006   BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2007   aTolF = BRep_Tool::Tolerance(aF);
2008   //
2009   aIt.Initialize(aLPB);
2010   for (; aIt.More(); aIt.Next()) {
2011     Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2012     const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2013     aTolE = BRep_Tool::Tolerance(aE);
2014     //
2015     IntTools_EdgeFace anEF;
2016     anEF.SetEdge(aE);
2017     anEF.SetFace(aF);
2018     anEF.SetTolE(aTolE);
2019     anEF.SetTolF(aTolF);
2020     anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2021     anEF.SetContext(myContext);
2022     anEF.Perform();
2023     //
2024     const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2025     if (aCPrts.Length() == 1) {
2026       Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2027       if (bCoinc) {
2028         if (bCB) {
2029           aCB = myDS->CommonBlock(aPBChangeValue);
2030         } else {
2031           aCB = new BOPDS_CommonBlock;
2032           aCB->AddPaveBlock(aPBChangeValue);
2033           myDS->SetCommonBlock(aPBChangeValue, aCB);
2034         }
2035         aCB->AddFace(nF);
2036         //
2037         aMPBIn.Add(aPBChangeValue);
2038       }
2039     }
2040   }
2041 }
2042 //=======================================================================
2043 // function: PutClosingPaveOnCurve
2044 // purpose:
2045 //=======================================================================
2046   void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2047 {
2048   Standard_Boolean bIsClosed, bHasBounds, bAdded;
2049   Standard_Integer nVC, j;
2050   Standard_Real aT[2], aTC, dT, aTx;
2051   gp_Pnt aP[2] ; 
2052   BOPDS_Pave aPVx;
2053   BOPDS_ListIteratorOfListOfPave aItLP;
2054   //
2055   const IntTools_Curve& aIC=aNC.Curve();
2056   const Handle(Geom_Curve)& aC3D=aIC.Curve();
2057   if(aC3D.IsNull()) {
2058     return;
2059   }
2060   //
2061   bIsClosed=IntTools_Tools::IsClosed(aC3D);
2062   if (!bIsClosed) {
2063     return;
2064   }
2065   //
2066   bHasBounds=aIC.HasBounds ();
2067   if (!bHasBounds){
2068     return;
2069   }
2070   // 
2071   bAdded=Standard_False;
2072   dT=Precision::PConfusion();
2073   aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2074   //
2075   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2076   BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2077   //
2078   aItLP.Initialize(aLP);
2079   for (; aItLP.More() && !bAdded; aItLP.Next()) {
2080     const BOPDS_Pave& aPC=aItLP.Value();
2081     nVC=aPC.Index();
2082     aTC=aPC.Parameter();
2083     //
2084     for (j=0; j<2; ++j) {
2085       if (fabs(aTC-aT[j]) < dT) {
2086         aTx=(!j) ? aT[1] : aT[0];
2087         aPVx.SetIndex(nVC);
2088         aPVx.SetParameter(aTx);
2089         aLP.Append(aPVx);
2090         //
2091         bAdded=Standard_True;
2092         break;
2093       }
2094     }
2095   }
2096 }
2097 //=======================================================================
2098 //function : PreparePostTreatFF
2099 //purpose  : 
2100 //=======================================================================
2101   void BOPAlgo_PaveFiller::PreparePostTreatFF
2102     (const Standard_Integer aInt,
2103      const Standard_Integer aCur,
2104      const Handle(BOPDS_PaveBlock)& aPB,
2105      BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2106      BOPCol_DataMapOfShapeInteger& aMVI,
2107      BOPDS_ListOfPaveBlock& aLPBC)
2108 {
2109   Standard_Integer nV1, nV2;
2110   //
2111   aLPBC.Append(aPB);
2112   //
2113   aPB->Indices(nV1, nV2);
2114   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2115   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2116   const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2117   // Keep info for post treatment 
2118   BOPDS_CoupleOfPaveBlocks aCPB;
2119   aCPB.SetIndexInterf(aInt);
2120   aCPB.SetIndex(aCur);
2121   aCPB.SetPaveBlock1(aPB);
2122   //
2123   aMSCPB.Add(aE, aCPB);
2124   aMVI.Bind(aV1, nV1);
2125   aMVI.Bind(aV2, nV2);
2126 }
2127
2128 //=======================================================================
2129 //function : CheckPlanes
2130 //purpose  : 
2131 //=======================================================================
2132 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2133   (const Standard_Integer nF1,
2134    const Standard_Integer nF2)const
2135 {
2136   Standard_Boolean bToIntersect;
2137   Standard_Integer i, nV2, iCnt;
2138   BOPCol_MapIteratorOfMapOfInteger aIt;
2139   //
2140   bToIntersect=Standard_False;
2141   //
2142   const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2143   const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2144   //
2145   const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2146   const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2147   //
2148   iCnt=0;
2149   for (i=0; (i<2 && !bToIntersect); ++i) {
2150     const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn() 
2151       : aFI2.VerticesOn();
2152     //
2153     aIt.Initialize(aMV2);
2154     for (; aIt.More(); aIt.Next()) {
2155       nV2=aIt.Value();
2156       if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2157         ++iCnt;
2158         if (iCnt>1) {
2159           bToIntersect=!bToIntersect;
2160           break;
2161         }
2162       }
2163     }
2164   }
2165   //
2166   return bToIntersect;
2167 }
2168 //=======================================================================
2169 //function : UpdatePaveBlocks
2170 //purpose  : 
2171 //=======================================================================
2172 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2173   (const BOPCol_DataMapOfIntegerInteger& aDMI)
2174 {
2175   if (aDMI.IsEmpty()) {
2176     return;
2177   }
2178   //
2179   Standard_Integer nSp, aNbPBP, nV[2], i, j;
2180   Standard_Real aT[2];
2181   Standard_Boolean bCB, bRebuild;
2182   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2183   BOPDS_MapOfPaveBlock aMPB;
2184   //
2185   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
2186   aNbPBP = aPBP.Extent();
2187   for (i=0; i<aNbPBP; ++i) {
2188     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
2189     //
2190     aItPB.Initialize(aLPB);
2191     for (; aItPB.More(); aItPB.Next()) {
2192       Handle(BOPDS_PaveBlock) aPB=aItPB.Value();
2193       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
2194       bCB = !aCB.IsNull();
2195       if (bCB) {
2196         aPB=aCB->PaveBlock1();
2197       }
2198       //
2199       if (aMPB.Add(aPB)) {
2200         bRebuild = Standard_False;
2201         aPB->Indices(nV[0], nV[1]);
2202         aPB->Range(aT[0], aT[1]);
2203         //
2204         for (j = 0; j < 2; ++j) {
2205           if (aDMI.IsBound(nV[j])) {
2206             BOPDS_Pave aPave;
2207             //
2208             nV[j] = aDMI.Find(nV[j]);
2209             aPave.SetIndex(nV[j]);
2210             aPave.SetParameter(aT[j]);
2211             //
2212             bRebuild = Standard_True;
2213             if (!j) {
2214               aPB->SetPave1(aPave);
2215             } else {
2216               aPB->SetPave2(aPave);
2217             }
2218           }
2219         }
2220         //
2221         if (bRebuild) {
2222           nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]);
2223           if (bCB) {
2224             aCB->SetEdge(nSp);
2225           }
2226           else {
2227             aPB->SetEdge(nSp);
2228           }
2229         }// if (bRebuild) {
2230       }// if (aMPB.Add(aPB)) {
2231     }// for (; aItPB.More(); aItPB.Next()) {
2232   }// for (i=0; i<aNbPBP; ++i) {
2233   aMPB.Clear();
2234 }
2235 //=======================================================================
2236 //function : ToleranceFF
2237 //purpose  : Computes the TolFF according to the tolerance value and 
2238 //           types of the faces.
2239 //=======================================================================
2240   void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2241                    const BRepAdaptor_Surface& aBAS2,
2242                    Standard_Real& aTolFF)
2243 {
2244   Standard_Real aTol1, aTol2;
2245   Standard_Boolean isAna1, isAna2;
2246   //
2247   aTol1 = aBAS1.Tolerance();
2248   aTol2 = aBAS2.Tolerance();
2249   aTolFF = Max(aTol1, aTol2);
2250   //
2251   isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2252             aBAS1.GetType() == GeomAbs_Cylinder ||
2253             aBAS1.GetType() == GeomAbs_Cone ||
2254             aBAS1.GetType() == GeomAbs_Sphere ||
2255             aBAS1.GetType() == GeomAbs_Torus);
2256   //
2257   isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2258             aBAS2.GetType() == GeomAbs_Cylinder ||
2259             aBAS2.GetType() == GeomAbs_Cone ||
2260             aBAS2.GetType() == GeomAbs_Sphere ||
2261             aBAS2.GetType() == GeomAbs_Torus);
2262   //
2263   if (!isAna1 || !isAna2) {
2264     aTolFF =  Max(aTolFF, 5.e-6);
2265   }
2266 }