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