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