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