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