0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[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 <BOPAlgo_Alerts.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.hxx>
46 #include <BOPTools_AlgoTools.hxx>
47 #include <BOPTools_AlgoTools3D.hxx>
48 #include <BRep_Builder.hxx>
49 #include <BRep_Tool.hxx>
50 #include <BRep_TEdge.hxx>
51 #include <BRepAdaptor_Curve.hxx>
52 #include <BRepAdaptor_Surface.hxx>
53 #include <BRepBndLib.hxx>
54 #include <BRepBuilderAPI_MakeVertex.hxx>
55 #include <BRepTools.hxx>
56 #include <Geom2d_Curve.hxx>
57 #include <Geom_Curve.hxx>
58 #include <GeomAPI_ProjectPointOnCurve.hxx>
59 #include <GeomAPI_ProjectPointOnSurf.hxx>
60 #include <gp_Pnt.hxx>
61 #include <IntSurf_ListOfPntOn2S.hxx>
62 #include <IntSurf_PntOn2S.hxx>
63 #include <IntTools.hxx>
64 #include <IntTools_Context.hxx>
65 #include <IntTools_Curve.hxx>
66 #include <IntTools_EdgeFace.hxx>
67 #include <IntTools_FaceFace.hxx>
68 #include <IntTools_PntOn2Faces.hxx>
69 #include <IntTools_SequenceOfCurves.hxx>
70 #include <IntTools_SequenceOfPntOn2Faces.hxx>
71 #include <IntTools_ShrunkRange.hxx>
72 #include <IntTools_Tools.hxx>
73 #include <Precision.hxx>
74 #include <TopExp.hxx>
75 #include <TopExp_Explorer.hxx>
76 #include <TopoDS.hxx>
77 #include <TopoDS_Compound.hxx>
78 #include <TopoDS_Edge.hxx>
79 #include <TopoDS_Face.hxx>
80 #include <TopoDS_Vertex.hxx>
81
82 //
83 static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
84                                  const BRepAdaptor_Surface& aBAS2);
85
86 /////////////////////////////////////////////////////////////////////////
87 //=======================================================================
88 //class    : BOPAlgo_FaceFace
89 //purpose  : 
90 //=======================================================================
91 class BOPAlgo_FaceFace : 
92   public IntTools_FaceFace,
93   public BOPAlgo_Algo {
94
95  public:
96   DEFINE_STANDARD_ALLOC
97
98   BOPAlgo_FaceFace() : 
99     IntTools_FaceFace(),  
100     BOPAlgo_Algo(),
101     myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
102   }
103   //
104   virtual ~BOPAlgo_FaceFace() {
105   }
106   //
107   void SetIndices(const Standard_Integer nF1,
108                   const Standard_Integer nF2) {
109     myIF1=nF1;
110     myIF2=nF2;
111   }
112   //
113   void Indices(Standard_Integer& nF1,
114                Standard_Integer& nF2) const {
115     nF1=myIF1;
116     nF2=myIF2;
117   }
118   //
119   void SetFaces(const TopoDS_Face& aF1,
120                 const TopoDS_Face& aF2) {
121     myF1=aF1;
122     myF2=aF2;
123   }
124   //
125   const TopoDS_Face& Face1()const {
126     return myF1;
127   }
128   //
129   const TopoDS_Face& Face2()const {
130     return myF2;
131   }
132   //
133   void SetTolFF(const Standard_Real aTolFF) {
134     myTolFF=aTolFF;
135   }
136   //
137   Standard_Real TolFF() const{
138     return myTolFF;
139   }
140   //
141   void SetFuzzyValue(const Standard_Real theFuzz) {
142     IntTools_FaceFace::SetFuzzyValue(theFuzz);
143   }
144   //
145   virtual void Perform() {
146     BOPAlgo_Algo::UserBreak();
147     IntTools_FaceFace::Perform(myF1, myF2);
148   }
149   //
150  protected:
151   Standard_Integer myIF1;
152   Standard_Integer myIF2;
153   Standard_Real myTolFF;
154   TopoDS_Face myF1;
155   TopoDS_Face myF2;
156 };
157 //
158 //=======================================================================
159 typedef BOPCol_NCVector
160   <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; 
161 //
162 typedef BOPCol_Functor 
163   <BOPAlgo_FaceFace,
164   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
165 //
166 typedef BOPCol_Cnt 
167   <BOPAlgo_FaceFaceFunctor,
168   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
169 /////////////////////////////////////////////////////////////////////////
170 //=======================================================================
171 //function : PerformFF
172 //purpose  : 
173 //=======================================================================
174 void BOPAlgo_PaveFiller::PerformFF()
175 {
176   myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
177   Standard_Integer iSize = myIterator->ExpectedLength();
178   if (!iSize) {
179     return; 
180   }
181   //
182   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
183   aFFs.SetIncrement(iSize);
184   //
185   // Options for the intersection algorithm
186   Standard_Boolean bApprox   = mySectionAttribute.Approximation(),
187                    bCompC2D1 = mySectionAttribute.PCurveOnS1(),
188                    bCompC2D2 = mySectionAttribute.PCurveOnS2();
189   Standard_Real    anApproxTol = 1.e-7;
190   // Post-processing options
191   Standard_Boolean bSplitCurve = Standard_False;
192   //
193   // Fence map to store faces with updated FaceInfo structure
194   BOPCol_MapOfInteger aMIFence;
195   // Prepare the pairs of faces for intersection
196   BOPAlgo_VectorOfFaceFace aVFaceFace;
197   Standard_Integer nF1, nF2;
198   //
199   for (; myIterator->More(); myIterator->Next()) {
200     myIterator->Value(nF1, nF2);
201     //
202     const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
203     const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
204     //
205     if (aMIFence.Add(nF1)) {
206       myDS->UpdateFaceInfoOn(nF1);
207       myDS->UpdateFaceInfoIn(nF1);
208     }
209     if (aMIFence.Add(nF2)) {
210       myDS->UpdateFaceInfoOn(nF2);
211       myDS->UpdateFaceInfoIn(nF2);
212     }
213     //
214     const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
215     const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
216     if (aBAS1.GetType() == GeomAbs_Plane && 
217         aBAS2.GetType() == GeomAbs_Plane) {
218       // Check if the planes are really interfering
219       Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
220       if (!bToIntersect) {
221         BOPDS_InterfFF& aFF=aFFs.Append1();
222         aFF.SetIndices(nF1, nF2);
223         aFF.Init(0, 0);
224         continue;
225       }
226     }
227     //
228     if (myGlue == BOPAlgo_GlueOff) {
229       BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
230       //
231       aFaceFace.SetIndices(nF1, nF2);
232       aFaceFace.SetFaces(aF1, aF2);
233       // compute minimal tolerance for the curves
234       Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
235       aFaceFace.SetTolFF(aTolFF);
236       //
237       IntSurf_ListOfPntOn2S aListOfPnts;
238       GetEFPnts(nF1, nF2, aListOfPnts);
239       Standard_Integer aNbLP = aListOfPnts.Extent();
240       if (aNbLP) {
241         aFaceFace.SetList(aListOfPnts);
242       }
243       //
244       aFaceFace.SetParameters(bApprox, bCompC2D1, bCompC2D2, anApproxTol);
245       aFaceFace.SetFuzzyValue(myFuzzyValue);
246       aFaceFace.SetProgressIndicator(myProgressIndicator);
247     }
248     else {
249       // for the Glue mode just add all interferences of that type
250       BOPDS_InterfFF& aFF = aFFs.Append1();
251       aFF.SetIndices(nF1, nF2);
252       aFF.SetTangentFaces(Standard_False);
253       aFF.Init(0, 0);
254     }
255   }//for (; myIterator->More(); myIterator->Next()) {
256   //
257   //======================================================
258   // Perform intersection
259   BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
260   //======================================================
261   // Treatment of the results
262   Standard_Integer k, aNbFaceFace = aVFaceFace.Extent();
263   for (k = 0; k < aNbFaceFace; ++k) {
264     BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k);
265     aFaceFace.Indices(nF1, nF2);
266     if (!aFaceFace.IsDone()) {
267       BOPDS_InterfFF& aFF = aFFs.Append1();
268       aFF.SetIndices(nF1, nF2);
269       aFF.Init(0, 0);
270       continue;
271     }
272     //
273     Standard_Boolean bTangentFaces = aFaceFace.TangentFaces();
274     Standard_Real aTolFF = aFaceFace.TolFF();
275     //
276     aFaceFace.PrepareLines3D(bSplitCurve);
277     //
278     const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
279     const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
280     //
281     Standard_Integer aNbCurves = aCvsX.Length();
282     Standard_Integer aNbPoints = aPntsX.Length();
283     //
284     if (aNbCurves || aNbPoints) {
285       myDS->AddInterf(nF1, nF2);
286     }
287     //
288     BOPDS_InterfFF& aFF = aFFs.Append1();
289     aFF.SetIndices(nF1, nF2);
290     aFF.SetTangentFaces(bTangentFaces);
291     aFF.Init(aNbCurves, aNbPoints);
292     //
293     // Curves
294     // Fix bounding box expanding coefficient.
295     Standard_Real aBoxExpandValue = aTolFF;
296     if (aNbCurves > 0)
297     {
298       // Modify geometric expanding coefficient by topology value,
299       // since this bounding box used in sharing (vertex or edge).
300       Standard_Real aMaxVertexTol = Max(BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
301         BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
302       aBoxExpandValue += aMaxVertexTol;
303     }
304     //
305     BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
306     for (Standard_Integer i = 1; i <= aNbCurves; ++i) {
307       Bnd_Box aBox;
308       const IntTools_Curve& aIC = aCvsX(i);
309       Standard_Boolean bIsValid = IntTools_Tools::CheckCurve(aIC, aBox);
310       if (bIsValid) {
311         BOPDS_Curve& aNC = aVNC.Append1();
312         aNC.SetCurve(aIC);
313         // make sure that the bounding box has the maximal gap
314         aBox.Enlarge(aBoxExpandValue);
315         aNC.SetBox(aBox);
316         aNC.SetTolerance(Max(aIC.Tolerance(), aTolFF));
317       }
318     }
319     //
320     // Points
321     BOPDS_VectorOfPoint& aVNP = aFF.ChangePoints();
322     for (Standard_Integer i = 1; i <= aNbPoints; ++i) {
323       const IntTools_PntOn2Faces& aPi = aPntsX(i);
324       const gp_Pnt& aP = aPi.P1().Pnt();
325       //
326       BOPDS_Point& aNP = aVNP.Append1();
327       aNP.SetPnt(aP);
328     }
329   }
330 }
331 //=======================================================================
332 //function : MakeBlocks
333 //purpose  : 
334 //=======================================================================
335 void BOPAlgo_PaveFiller::MakeBlocks()
336 {
337   if (myGlue != BOPAlgo_GlueOff) {
338     return;
339   }
340   //
341   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
342   Standard_Integer aNbFF = aFFs.Extent();
343   if (!aNbFF) {
344     return;
345   }
346   //
347   Standard_Boolean bExist, bValid2D;
348   Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
349   Standard_Integer nV1, nV2;
350   Standard_Real aT1, aT2;
351   Handle(NCollection_BaseAllocator) aAllocator;
352   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
353   TopoDS_Edge aES;
354   Handle(BOPDS_PaveBlock) aPBOut;
355   //
356   //-----------------------------------------------------scope f
357   aAllocator=
358     NCollection_BaseAllocator::CommonBaseAllocator();
359   //
360   BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
361   BOPCol_MapOfInteger aMVOnIn(100, aAllocator),
362                       aMVStick(100,aAllocator), aMVEF(100, aAllocator),
363                       aMI(100, aAllocator), aMVBounds(100, aAllocator);
364   BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
365   BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
366   BOPDS_ListOfPaveBlock aLPB(aAllocator);
367   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); 
368   BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
369   BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
370   BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
371   BOPCol_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
372   BOPCol_DataMapOfIntegerListOfInteger aDMVLV;
373   BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
374   BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
375   BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
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     Standard_Real aTolFF = Max(BRep_Tool::Tolerance(aF1), BRep_Tool::Tolerance(aF2));
396     //
397     BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
398     BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
399     //
400     aMVOnIn.Clear();
401     aMPBOnIn.Clear();
402     aMPBCommon.Clear();
403     aDMBV.Clear();
404     aMVTol.Clear();
405     aLSE.Clear();
406     //
407     myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
408     myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
409     //
410     Standard_Boolean bHasRealSectionEdge = Standard_False;
411     // 1. Treat Points
412     for (j=0; j<aNbP; ++j) {
413       TopoDS_Vertex aV;
414       BOPDS_CoupleOfPaveBlocks aCPB;
415       //
416       BOPDS_Point& aNP=aVP.ChangeValue(j);
417       const gp_Pnt& aP=aNP.Pnt();
418       //
419       bExist=IsExistingVertex(aP, aTolFF, aMVOnIn);
420       if (!bExist) {
421         BOPTools_AlgoTools::MakeNewVertex(aP, aTolFF, aV);
422         //
423         aCPB.SetIndexInterf(i);
424         aCPB.SetIndex(j);
425         aMSCPB.Add(aV, aCPB);
426       }
427     }
428     //
429     // 2. Treat Curves
430     aMVStick.Clear();
431     aMVEF.Clear();
432     GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
433     //
434     for (j = 0; j < aNbC; ++j) {
435       BOPDS_Curve& aNC = aVC.ChangeValue(j);
436       // DEBt
437       aNC.InitPaveBlock1();
438       //
439       PutPavesOnCurve(aMVOnIn, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
440     }
441
442     // if some E-F vertex was put on a curve due to large E-F intersection range,
443     // and it also was put on another curve correctly then remove this vertex from
444     // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
445     FilterPavesOnCurves(aVC);
446
447     for (j = 0; j<aNbC; ++j) {
448       BOPDS_Curve& aNC=aVC.ChangeValue(j);
449       const IntTools_Curve& aIC=aNC.Curve();
450       //
451       PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
452       //904/F7
453       if (aNbC == 1) {
454         PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
455       }
456       //
457       if (aIC.HasBounds()) {
458         aLBV.Clear();
459         //
460         PutBoundPaveOnCurve(aF1, aF2, aNC, aLBV);
461         //
462         if (!aLBV.IsEmpty()) {
463           aDMBV.Bind(j, aLBV);
464           BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
465           for (; aItI.More(); aItI.Next()) {
466             aMVBounds.Add(aItI.Value());
467           }
468         }
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       Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
483       //
484       BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
485       Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
486       //
487       aLPB.Clear();
488       aPB1->Update(aLPB, Standard_False);
489       //
490       aItLPB.Initialize(aLPB);
491       for (; aItLPB.More(); aItLPB.Next()) {
492         Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
493         aPB->Indices(nV1, nV2);
494         aPB->Range  (aT1, aT2);
495         //
496         if (fabs(aT1 - aT2) < Precision::PConfusion()) {
497           continue;
498         }
499         //
500         bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC, 
501                                                  aF1, aF2, aTolR3D);
502         if (!bValid2D) {
503           continue;
504         }
505         //
506         bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
507         if (bExist) {
508           continue;
509         }
510         //
511         const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
512         const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
513         //
514         // Make Edge
515         BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
516         //
517         // check for micro edge
518         if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
519           // If the section edge is a micro edge, i.e. the whole edge is
520           // covered by the tolerance spheres of its vertices, it will be
521           // passed into post treatment process to fuse its vertices.
522           // The edge itself will not be kept.
523           if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
524             aMicroEdges.Add(aES);
525             // keep vertices for post treatment
526             aMVI.Bind(aV1, nV1);
527             aMVI.Bind(aV2, nV2);
528           }
529           continue;
530         }
531         //
532         Standard_Real aTolNew;
533         bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
534         if (bExist) {
535           if (!aMPBAdd.Contains(aPBOut)) {
536             Standard_Boolean bInBothFaces = Standard_True;
537             if (!myDS->IsCommonBlock(aPBOut)) {
538               Standard_Integer nE;
539               Standard_Real aTolE;
540               //
541               nE = aPBOut->Edge();
542               const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
543               aTolE = BRep_Tool::Tolerance(aE);
544               if (aTolNew < aNC.Tolerance())
545                 aTolNew = aNC.Tolerance();  // use real tolerance of intersection
546               if (aTolNew > aTolE) {
547                 UpdateEdgeTolerance(nE, aTolNew);
548               }
549               bInBothFaces = Standard_False;
550             } 
551             else {
552               bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
553                               aFI1.PaveBlocksIn().Contains(aPBOut))&&
554                              (aFI2.PaveBlocksOn().Contains(aPBOut) ||
555                               aFI2.PaveBlocksIn().Contains(aPBOut));
556             }
557             if (!bInBothFaces) {
558               aMPBAdd.Add(aPBOut);
559               PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
560             }
561           }
562           continue;
563         }
564         //
565         // Make p-curves
566         BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC, 
567                                        mySectionAttribute.PCurveOnS1(),
568                                        mySectionAttribute.PCurveOnS2(),
569                                        myContext);
570         //
571         // Append the Pave Block to the Curve j
572         aLPBC.Append(aPB);
573         //
574         // Keep info for post treatment 
575         BOPDS_CoupleOfPaveBlocks aCPB;
576         aCPB.SetIndexInterf(i);
577         aCPB.SetIndex(j);
578         aCPB.SetPaveBlock1(aPB);
579         //
580         aMSCPB.Add(aES, aCPB);
581         aMVI.Bind(aV1, nV1);
582         aMVI.Bind(aV2, nV2);
583         //
584         aMVTol.UnBind(nV1);
585         aMVTol.UnBind(nV2);
586         //
587         bHasRealSectionEdge = Standard_True;
588       }
589       //
590       aLPBC.RemoveFirst();
591     }//for (j=0; j<aNbC; ++j) {
592     //
593     //back to previous tolerance values for unused vertices
594     //and forget about SD groups of such vertices
595     aItMV.Initialize(aMVTol);
596     for (; aItMV.More(); aItMV.Next()) {
597       nV1 = aItMV.Key();
598       Standard_Real aTol = aItMV.Value();
599       //
600       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
601       const Handle(BRep_TVertex)& TV = 
602         *((Handle(BRep_TVertex)*)&aV.TShape());
603       TV->Tolerance(aTol);
604       // reset bnd box
605       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
606       Bnd_Box& aBoxDS=aSIDS.ChangeBox();
607       aBoxDS = Bnd_Box();
608       BRepBndLib::Add(aV, aBoxDS);
609       aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
610       //
611       if (aDMVLV.IsBound(nV1))
612         aDMVLV.UnBind(nV1);
613     }
614     //
615     ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
616     //
617     // If the pair of faces has produced any real section edges
618     // it is necessary to check if these edges do not intersect
619     // any common IN edges of the faces. For that, all such edges
620     // are added for Post Treatment along with sections edges.
621     if (bHasRealSectionEdge) {
622       const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
623       const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
624       //
625       // For simplicity add all IN edges into the first set of section curves.
626       // These existing edges will be removed from the set on the post treatment
627       // stage in the UpdateFaceInfo function.
628       BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks();
629       //
630       Standard_Integer aNbIn1 = aMPBIn1.Extent();
631       for (j = 1; j <= aNbIn1; ++j) {
632         const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j);
633         if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) {
634           PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC);
635         }
636       }
637     }
638   }//for (i=0; i<aNbFF; ++i) {
639   // 
640   // post treatment
641   MakeSDVerticesFF(aDMVLV, aDMNewSD);
642   PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
643   if (HasErrors()) {
644     return;
645   }
646   // reduce tolerances of section edges where it is appropriate
647   CorrectToleranceOfSE();
648   //
649   // update face info
650   UpdateFaceInfo(aDMExEdges, aDMNewSD);
651   //Update all pave blocks
652   UpdatePaveBlocks(aDMNewSD);
653   //
654   // Treat possible common zones by trying to put each section edge
655   // into all faces, not participated in creation of that edge, as IN edge
656   PutSEInOtherFaces();
657   //
658   //-----------------------------------------------------scope t
659   aMVStick.Clear();
660   aMPBOnIn.Clear();
661   aMVOnIn.Clear();
662   aDMExEdges.Clear();
663   aMI.Clear();
664   aDMNewSD.Clear();
665 }
666
667 //=======================================================================
668 //function : MakeSDVerticesFF
669 //purpose  : 
670 //=======================================================================
671 void BOPAlgo_PaveFiller::MakeSDVerticesFF
672   (const BOPCol_DataMapOfIntegerListOfInteger& theDMVLV,
673    BOPCol_DataMapOfIntegerInteger& theDMNewSD)
674 {
675   // Create a new SD vertex for each group of coinciding vertices
676   // and put new substitutions to theDMNewSD.
677   BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
678   for (; aItG.More(); aItG.Next()) {
679     const BOPCol_ListOfInteger& aList = aItG.Value();
680     // make SD vertices w/o creation of interfs
681     Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
682     // update theDMNewSD
683     BOPCol_ListIteratorOfListOfInteger aItL(aList);
684     for (; aItL.More(); aItL.Next()) {
685       Standard_Integer nV = aItL.Value();
686       theDMNewSD.Bind(nV, nSD);
687     }
688   }
689 }
690
691 //=======================================================================
692 //function : PostTreatFF
693 //purpose  : 
694 //=======================================================================
695 void BOPAlgo_PaveFiller::PostTreatFF
696     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
697      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
698      BOPCol_DataMapOfIntegerInteger& aDMNewSD,
699      const BOPCol_IndexedMapOfShape& theMicroEdges,
700      const Handle(NCollection_BaseAllocator)& theAllocator)
701 {
702   Standard_Integer aNbS = theMSCPB.Extent();
703   if (!aNbS) {
704     return;
705   }
706   //
707   Standard_Boolean bHasPaveBlocks, bOld;
708   Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
709   Standard_Integer aNbLPBx;
710   TopAbs_ShapeEnum aType;
711   TopoDS_Shape aV, aE;
712   BOPCol_ListIteratorOfListOfShape aItLS;
713   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
714   BOPDS_PDS aPDS;
715   Handle(BOPDS_PaveBlock) aPB1;
716   BOPDS_Pave aPave[2];
717   BOPDS_ShapeInfo aSI;
718   //
719   BOPCol_ListOfShape aLS(theAllocator);
720   BOPAlgo_PaveFiller aPF(theAllocator);
721   aPF.SetIsPrimary(Standard_False);
722   aPF.SetNonDestructive(myNonDestructive);
723   //
724   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
725   //
726   Standard_Integer aNbME = theMicroEdges.Extent();
727   // 0
728   if (aNbS==1 && (aNbME == 0)) {
729     const TopoDS_Shape& aS=theMSCPB.FindKey(1);
730     const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
731     //
732     aType=aS.ShapeType();
733     if (aType==TopAbs_VERTEX) {
734       aSI.SetShapeType(aType);
735       aSI.SetShape(aS);
736       iV=myDS->Append(aSI);
737       //
738       iX=aCPB.IndexInterf();
739       iP=aCPB.Index();
740       BOPDS_InterfFF& aFF=aFFs(iX); 
741       BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
742       BOPDS_Point& aNP=aVNP(iP);
743       aNP.SetIndex(iV);
744     }
745     else if (aType==TopAbs_EDGE) {
746       aPB1=aCPB.PaveBlock1();
747       //
748       if (aPB1->HasEdge()) {
749         BOPDS_ListOfPaveBlock aLPBx;
750         aLPBx.Append(aPB1);
751         aDMExEdges.Bind(aPB1, aLPBx);
752       } else {
753         aSI.SetShapeType(aType);
754         aSI.SetShape(aS);
755         iE=myDS->Append(aSI);
756         //
757         aPB1->SetEdge(iE);
758       }
759     }
760     return;
761   }
762   //
763   // 1 prepare arguments
764   BOPCol_MapOfShape anAddedSD;
765   for (k=1; k<=aNbS; ++k) {
766     const TopoDS_Shape& aS=theMSCPB.FindKey(k);
767     aLS.Append(aS);
768     // add vertices-candidates for SD from the map aDMNewSD,
769     // so that they took part in fuse operation.
770     TopoDS_Iterator itV(aS);
771     for (; itV.More(); itV.Next())
772     {
773       const TopoDS_Shape& aVer = itV.Value();
774       Standard_Integer iVer = myDS->Index(aVer);
775       const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
776       if (pSD)
777       {
778         const TopoDS_Shape& aVSD = myDS->Shape(*pSD);
779         if (anAddedSD.Add(aVSD))
780           aLS.Append(aVSD);
781       }
782     }
783   }
784   //
785   // The section edges considered as a micro should be
786   // specially treated - their vertices should be united and
787   // the edge itself should be removed. Thus, we add only
788   // its vertices into operation.
789   //
790   BRep_Builder aBB;
791   for (k = 1; k <= aNbME; ++k) {
792     const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
793     //
794     TopoDS_Vertex aVerts[2];
795     TopExp::Vertices(aEM, aVerts[0], aVerts[1]);
796     for (Standard_Integer i = 0; i < 2; ++i) {
797       nV = myDS->Index(aVerts[i]);
798       const Standard_Integer* pSD = aDMNewSD.Seek(nV);
799       if (pSD) {
800         aVerts[i] = TopoDS::Vertex(myDS->Shape(*pSD));
801       }
802       //
803       if (anAddedSD.Add(aVerts[i])) {
804         aLS.Append(aVerts[i]);
805       }
806     }
807     //
808     if (aVerts[0].IsSame(aVerts[1])) {
809       continue;
810     }
811     //
812     // make sure these vertices will be united
813     const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]);
814     const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]);
815     //
816     Standard_Real aDist = aP1.Distance(aP2);
817     Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]);
818     Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]);
819     //
820     aDist -= (aTolV1 + aTolV2);
821     if (aDist > 0.) {
822       aDist /= 2.;
823       aBB.UpdateVertex(aVerts[0], aTolV1 + aDist);
824       aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
825     }
826   }
827   //
828   // 2 Fuse shapes
829   aPF.SetProgressIndicator(myProgressIndicator);
830   aPF.SetRunParallel(myRunParallel);
831   aPF.SetArguments(aLS);
832   aPF.Perform();
833   if (aPF.HasErrors()) {
834     AddError (new BOPAlgo_AlertPostTreatFF);
835     return;
836   }
837   aPDS=aPF.PDS();
838   //
839   // Map to store the real tolerance of the common block
840   // and avoid repeated computation of it
841   NCollection_DataMap<Handle(BOPDS_CommonBlock),
842                       Standard_Real,
843                       TColStd_MapTransientHasher> aMCBTol;
844   // Map to avoid creation of different pave blocks for
845   // the same intersection edge
846   NCollection_DataMap<Standard_Integer, Handle(BOPDS_PaveBlock)> aMEPB;
847   //
848   aItLS.Initialize(aLS);
849   for (; aItLS.More(); aItLS.Next()) {
850     const TopoDS_Shape& aSx=aItLS.Value();
851     nSx=aPDS->Index(aSx);
852     const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
853     //
854     aType=aSIx.ShapeType();
855     //
856     if (aType==TopAbs_VERTEX) {
857       Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
858       //
859       if (aPDS->HasShapeSD(nSx, nVSD)) {
860         aV=aPDS->Shape(nVSD);
861       }
862       else {
863         aV=aSx;
864       }
865       // index of new vertex in theDS -> iV
866       iV = myDS->Index(aV);
867       if (iV < 0) {
868         aSI.SetShapeType(aType);
869         aSI.SetShape(aV);
870         iV=myDS->Append(aSI);
871       }
872       //
873       if (!bIntersectionPoint) {
874         // save SD connection
875         nSx = myDS->Index(aSx);
876         aDMNewSD.Bind(nSx, iV);
877         myDS->AddShapeSD(nSx, iV);
878       }
879       else {
880         // update FF interference
881         const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
882         iX=aCPB.IndexInterf();
883         iP=aCPB.Index();
884         BOPDS_InterfFF& aFF=aFFs(iX);
885         BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
886         BOPDS_Point& aNP=aVNP(iP);
887         aNP.SetIndex(iV);
888       }
889     }//if (aType==TopAbs_VERTEX) {
890     //
891     else if (aType==TopAbs_EDGE) {
892       bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
893       const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
894       iX=aCPB.IndexInterf();
895       iC=aCPB.Index();
896       aPB1=aCPB.PaveBlock1();
897       //
898       bOld = aPB1->HasEdge();
899       if (bOld) {
900         BOPDS_ListOfPaveBlock aLPBx;
901         aDMExEdges.Bind(aPB1, aLPBx);
902       }
903       //
904       if (!bHasPaveBlocks) {
905         if (bOld) {
906           aDMExEdges.ChangeFind(aPB1).Append(aPB1);
907         }
908         else {
909           aSI.SetShapeType(aType);
910           aSI.SetShape(aSx);
911           iE = myDS->Append(aSI);
912           //
913           aPB1->SetEdge(iE);
914         }
915       }
916       else {
917         BOPDS_InterfFF& aFF=aFFs(iX);
918         BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
919         BOPDS_Curve& aNC=aVNC(iC);
920         BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
921         //
922         // check if edge occured to be micro edge;
923         // note we check not the edge aSx itself, but its image in aPDS
924         const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
925         aNbLPBx = aLPBx.Extent();
926         if (aPDS->HasPaveBlocks(nSx) &&
927             (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
928           BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
929           for (; it.More(); it.Next()) {
930             if (it.Value() == aPB1) {
931               aLPBC.Remove(it);
932               break;
933             }
934           }
935           continue;
936         }
937         //
938         if (bOld && !aNbLPBx) {
939           aDMExEdges.ChangeFind(aPB1).Append(aPB1);
940           continue;
941         }
942         //
943         if (!bOld) {
944           aItLPB.Initialize(aLPBC);
945           for (; aItLPB.More(); aItLPB.Next()) {
946             const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
947             if (aPBC==aPB1) {
948               aLPBC.Remove(aItLPB);
949               break;
950             }
951           }
952         }
953         //
954         if (aNbLPBx) {
955           aItLPB.Initialize(aLPBx);
956           for (; aItLPB.More(); aItLPB.Next()) {
957             const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
958             const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
959             //
960             // update vertices of paves
961             aPave[0] = aPBx->Pave1();
962             aPave[1] = aPBx->Pave2();
963             for (j=0; j<2; ++j) {
964               nV = aPave[j].Index();
965               aV = aPDS->Shape(nV);
966               // index of new vertex in myDS -> iV
967               iV = myDS->Index(aV);
968               if (iV < 0) {
969                 aSI.SetShapeType(TopAbs_VERTEX);
970                 aSI.SetShape(aV);
971                 iV = myDS->Append(aSI);
972               }
973               const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
974               if (aP1.Index() != iV) {
975                 if (aP1.Parameter() == aPave[j].Parameter()) {
976                   aDMNewSD.Bind(aP1.Index(), iV);
977                   myDS->AddShapeSD(aP1.Index(), iV);
978                 }
979                 else {
980                   // check aPDS to have the SD connection between these vertices
981                   const TopoDS_Shape& aVPave = myDS->Shape(aP1.Index());
982                   Standard_Integer nVnewSD, nVnew = aPDS->Index(aVPave);
983                   if (aPDS->HasShapeSD(nVnew, nVnewSD)) {
984                     if (nVnewSD == nV) {
985                       aDMNewSD.Bind(aP1.Index(), iV);
986                       myDS->AddShapeSD(aP1.Index(), iV);
987                     }
988                   }
989                 }
990               }
991               //
992               aPave[j].SetIndex(iV);
993             }
994             //
995             // add edge
996             aE=aPDS->Shape(aPBRx->Edge());
997             iE = myDS->Index(aE);
998             if (iE < 0) {
999               aSI.SetShapeType(aType);
1000               aSI.SetShape(aE);
1001               iE=myDS->Append(aSI);
1002             }
1003             //
1004             // update real edge tolerance according to distances in common block if any
1005             if (aPDS->IsCommonBlock(aPBRx)) {
1006               const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
1007               Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
1008               if (!pTol) {
1009                 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
1010                 pTol = aMCBTol.Bound(aCB, aTol);
1011               }
1012               //
1013               if (aNC.Tolerance() < *pTol) {
1014                 aNC.SetTolerance(*pTol);
1015               }
1016             }
1017             // append new PaveBlock to aLPBC
1018             Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
1019             if (!pPBC) {
1020               pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
1021               BOPDS_Pave aPaveR1, aPaveR2;
1022               aPaveR1 = aPBRx->Pave1();
1023               aPaveR2 = aPBRx->Pave2();
1024               aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index())));
1025               aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index())));
1026               //
1027               (*pPBC)->SetPave1(aPaveR1);
1028               (*pPBC)->SetPave2(aPaveR2);
1029               (*pPBC)->SetEdge(iE);
1030             }
1031             //
1032             if (bOld) {
1033               (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
1034               aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
1035             }
1036             else {
1037               aLPBC.Append(*pPBC);
1038             }
1039           }
1040         }
1041       }
1042     }//else if (aType==TopAbs_EDGE)
1043   }//for (; aItLS.More(); aItLS.Next()) {
1044
1045   // Update SD for vertices that did not participate in operation
1046   BOPCol_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD);
1047   for (; itDM.More(); itDM.Next())
1048   {
1049     const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value());
1050     if (pSD)
1051     {
1052       itDM.ChangeValue() = *pSD;
1053       myDS->AddShapeSD(itDM.Key(), *pSD);
1054     }
1055   }
1056   return;
1057 }
1058
1059 //=======================================================================
1060 //function : UpdateFaceInfo
1061 //purpose  : 
1062 //=======================================================================
1063 void BOPAlgo_PaveFiller::UpdateFaceInfo
1064   (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1065    const BOPCol_DataMapOfIntegerInteger& theDMV)
1066 {
1067   Standard_Integer i, j, nV1, nF1, nF2, 
1068                    aNbFF, aNbC, aNbP;
1069   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1070   BOPCol_MapOfInteger aMF;
1071   //
1072   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1073   aNbFF=aFFs.Extent();
1074   //
1075   //1. Sections (curves, points);
1076   for (i=0; i<aNbFF; ++i) {
1077     BOPDS_InterfFF& aFF=aFFs(i);
1078     aFF.Indices(nF1, nF2);
1079     //
1080     BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1081     BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1082     //
1083     // 1.1. Section edges
1084     BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1085     aNbC=aVNC.Extent();
1086     for (j=0; j<aNbC; ++j) {
1087       BOPDS_Curve& aNC=aVNC(j);
1088       BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1089       //
1090       // Add section edges to face info
1091       aItLPB.Initialize(aLPBC);
1092       for (; aItLPB.More(); ) {
1093         const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1094         //
1095         // Treat existing pave blocks
1096         if (theDME.IsBound(aPB)) {
1097           BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1098           UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1099           aLPBC.Remove(aItLPB);
1100           continue;
1101         }
1102         //
1103         aFI1.ChangePaveBlocksSc().Add(aPB);
1104         aFI2.ChangePaveBlocksSc().Add(aPB);
1105         aItLPB.Next();
1106       }
1107     }
1108     //
1109     // 1.2. Section vertices
1110     const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1111     aNbP=aVNP.Extent();
1112     for (j=0; j<aNbP; ++j) {
1113       const BOPDS_Point& aNP=aVNP(j);
1114       nV1=aNP.Index();
1115       if (nV1<0) {
1116         continue;
1117       }
1118       aFI1.ChangeVerticesSc().Add(nV1);
1119       aFI2.ChangeVerticesSc().Add(nV1);
1120     }
1121     //
1122     aMF.Add(nF1);
1123     aMF.Add(nF2);
1124   }
1125   //
1126   Standard_Boolean bVerts, bEdges;
1127   //
1128   bVerts = theDMV.Extent() > 0;
1129   bEdges = theDME.Extent() > 0;
1130   //
1131   if (!bVerts && !bEdges) {
1132     return;
1133   }
1134   //
1135   // 2. Update Face Info information with new vertices and new
1136   //    pave blocks created in PostTreatFF from existing ones
1137   Standard_Integer nV2, aNbPB;
1138   BOPCol_MapIteratorOfMapOfInteger aItMF;
1139   BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1140   //
1141   aItMF.Initialize(aMF);
1142   for (; aItMF.More(); aItMF.Next()) {
1143     nF1 = aItMF.Value();
1144     //
1145     BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1146     //
1147     // 2.1. Update information about vertices
1148     if (bVerts) {
1149       BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1150       BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1151       //
1152       aItMV.Initialize(theDMV);
1153       for (; aItMV.More(); aItMV.Next()) {
1154         nV1 = aItMV.Key();
1155         nV2 = aItMV.Value();
1156         //
1157         if (aMVOn.Remove(nV1)) {
1158           aMVOn.Add(nV2);
1159         }
1160         //
1161         if (aMVIn.Remove(nV1)) {
1162           aMVIn.Add(nV2);
1163         }
1164       } // for (; aItMV.More(); aItMV.Next()) {
1165     } // if (bVerts) {
1166     //
1167     // 2.2. Update information about pave blocks
1168     if (bEdges) {
1169       BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1170       BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1171       //
1172       BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1173       for (i = 0; i < 2; ++i) {
1174         BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1175         aMPBCopy = aMPBOnIn;
1176         aMPBOnIn.Clear();
1177         //
1178         aNbPB = aMPBCopy.Extent();
1179         for (j = 1; j <= aNbPB; ++j) {
1180           const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1181           if (theDME.IsBound(aPB)) {
1182             const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1183             if (aLPB.IsEmpty()) {
1184               aMPBOnIn.Add(aPB);
1185               continue;
1186             }
1187             //
1188             aItLPB.Initialize(aLPB);
1189             for (; aItLPB.More(); aItLPB.Next()) {
1190               const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1191               aMPBOnIn.Add(aPB1);
1192             }
1193           }
1194           else {
1195             aMPBOnIn.Add(aPB);
1196           }
1197         } // for (j = 1; j <= aNbPB; ++j) {
1198       } // for (i = 0; i < 2; ++i) {
1199     } // if (bEdges) {
1200   }
1201 }
1202 //=======================================================================
1203 //function : IsExistingVertex
1204 //purpose  : 
1205 //=======================================================================
1206 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1207   (const gp_Pnt& aP,
1208    const Standard_Real theTolR3D,
1209    const BOPCol_MapOfInteger& aMVOnIn)const
1210 {
1211   Standard_Boolean bRet;
1212   Standard_Integer nV, iFlag;
1213   Standard_Real aTolCheck;
1214   gp_Pnt aPV;
1215   Bnd_Box aBoxP;
1216   BOPCol_MapIteratorOfMapOfInteger aIt;
1217   //
1218   aTolCheck = theTolR3D + myFuzzyValue;
1219   bRet=Standard_True;
1220   //
1221   aBoxP.Add(aP);
1222   aBoxP.Enlarge(theTolR3D);
1223   //
1224   aIt.Initialize(aMVOnIn);
1225   for (; aIt.More(); aIt.Next()) {
1226     nV=aIt.Value();
1227     const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1228     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1229     const Bnd_Box& aBoxV=aSIV.Box();
1230     //
1231     if (!aBoxP.IsOut(aBoxV)) {
1232       iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
1233       if (!iFlag) {
1234         return bRet;
1235       }
1236     }
1237   }
1238   return !bRet;
1239 }
1240 //=======================================================================
1241 //function : IsExistingPaveBlock
1242 //purpose  : 
1243 //=======================================================================
1244 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1245   (const Handle(BOPDS_PaveBlock)& thePB,
1246    const BOPDS_Curve& theNC,
1247    const BOPCol_ListOfInteger& theLSE)
1248 {
1249   Standard_Boolean bRet=Standard_True;
1250   //
1251   if (theLSE.IsEmpty()) {
1252     return !bRet;
1253   } 
1254   //
1255   Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
1256   Standard_Integer nE, iFlag, nV1, nV2;
1257   gp_Pnt aPm;
1258   Bnd_Box aBoxPm;
1259   BOPCol_ListIteratorOfListOfInteger aItLI;
1260   //
1261   thePB->Range(aT1, aT2);
1262   thePB->Indices(nV1, nV2);
1263   const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1264                       &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1265   const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1266                       aTolV2 = BRep_Tool::Tolerance(aV2);
1267
1268   aTol = Max(aTolV1, aTolV2);
1269
1270   aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1271   theNC.Curve().D0(aTm, aPm);
1272   aBoxPm.Add(aPm);
1273   aBoxPm.Enlarge(aTol);
1274   //
1275   aItLI.Initialize(theLSE);
1276   for (; aItLI.More(); aItLI.Next()) {
1277     nE=aItLI.Value();
1278     if (nE < 0)
1279       continue;
1280     const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1281     const Bnd_Box& aBoxE=aSIE.Box();
1282     if (!aBoxE.IsOut(aBoxPm)) {
1283       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1284       aTolE = BRep_Tool::Tolerance(aE);
1285       aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1286       iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
1287       if (!iFlag) {
1288         return bRet;
1289       }
1290     }
1291   }
1292   return !bRet;
1293 }
1294
1295 //=======================================================================
1296 //function : IsExistingPaveBlock
1297 //purpose  : 
1298 //=======================================================================
1299 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1300     (const Handle(BOPDS_PaveBlock)& thePB,
1301      const BOPDS_Curve& theNC,
1302      const Standard_Real theTolR3D,
1303      const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1304      const BOPDS_MapOfPaveBlock& theMPBCommon,
1305      Handle(BOPDS_PaveBlock)& aPBOut,
1306      Standard_Real& theTolNew)
1307 {
1308   Standard_Boolean bRet;
1309   Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
1310   Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1311   gp_Pnt aP1, aPm, aP2;
1312   Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
1313   //
1314   bRet=Standard_False;
1315   aTolCheck = theTolR3D + myFuzzyValue;
1316   const IntTools_Curve& aIC=theNC.Curve();
1317   //
1318   thePB->Range(aT1, aT2);
1319   thePB->Indices(nV11, nV12);
1320   const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1321   const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
1322   const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
1323
1324   //first point
1325   aIC.D0(aT1, aP1);
1326   aBoxP1.Add(aP1);
1327   aBoxP1.Enlarge(aTolV11);
1328   //intermediate point
1329   aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1330   aIC.D0(aTm, aPm);
1331   aBoxPm.Add(aPm);
1332   //last point
1333   aIC.D0(aT2, aP2);
1334   aBoxP2.Add(aP2);
1335   aBoxP2.Enlarge(aTolV12);
1336   //
1337   theTolNew = 0.;
1338   aNbPB = theMPBOnIn.Extent();
1339   for (i = 1; i <= aNbPB; ++i) {
1340     const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1341     aPB->Indices(nV21, nV22);
1342     const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1343     const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
1344     const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
1345     nSp=aPB->Edge();
1346     if (nSp < 0)
1347       continue;
1348     const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1349     const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1350     const Bnd_Box& aBoxSp=aSISp.Box();
1351     //
1352     iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 : 
1353       (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1354     iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : 
1355       (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1356     if (iFlag1 && iFlag2) {
1357       Standard_Real aDist = 0.;
1358
1359       Standard_Real aRealTol = aTolCheck;
1360       if (myDS->IsCommonBlock(aPB))
1361       {
1362         aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1363         if (theMPBCommon.Contains(aPB))
1364           // for an edge, which is a common block with a face,
1365           // increase the chance to coincide with section curve
1366           aRealTol *= 2.;
1367       }
1368       
1369       aBoxTmp = aBoxPm;
1370       aBoxTmp.Enlarge(aRealTol);
1371
1372       if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm, 
1373                                                         aRealTol,
1374                                                         aSp, 
1375                                                         aTx, theTolNew)) {
1376         continue;
1377       }
1378       //
1379       if (iFlag1 == 1) {
1380         iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1381         if (iFlag1 && theTolNew < aDist)
1382           theTolNew = aDist;
1383       }
1384       //
1385       if (iFlag2 == 1) {
1386         iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1387         if (iFlag2 && theTolNew < aDist)
1388           theTolNew = aDist;
1389       }
1390       //
1391       if (iFlag1 && iFlag2) {
1392         aPBOut = aPB;
1393         bRet=Standard_True;
1394         break;
1395       }
1396     }
1397   }
1398   return bRet;
1399 }
1400 //=======================================================================
1401 //function : PutBoundPaveOnCurve
1402 //purpose  : 
1403 //=======================================================================
1404 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1405                                              const TopoDS_Face& aF2,
1406                                              BOPDS_Curve& aNC,
1407                                              BOPCol_ListOfInteger& aLVB)
1408 {
1409   Standard_Boolean bVF;
1410   Standard_Integer nV, iFlag, nVn, j, aNbEP;
1411   Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1412   gp_Pnt aP[2];
1413   TopoDS_Vertex aVn;
1414   BOPDS_ListIteratorOfListOfPave aItLP;
1415   BOPDS_Pave aPn, aPMM[2];
1416   //
1417   aTolVnew = Precision::Confusion();
1418   //
1419   const IntTools_Curve& aIC=aNC.Curve();
1420   aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1421   Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1422   //
1423   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1424   const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1425   //
1426   aNbEP=aLP.Extent();
1427   if (aNbEP) {
1428     aTmin=1.e10;
1429     aTmax=-aTmin;
1430     //
1431     aItLP.Initialize(aLP);
1432     for (; aItLP.More(); aItLP.Next()) {
1433       const BOPDS_Pave& aPv=aItLP.Value();
1434       aPv.Contents(nV, aTV);
1435       if (aTV<aTmin) {
1436         aPMM[0]=aPv;
1437         aTmin=aTV;
1438       }
1439       if (aTV>aTmax) {
1440         aPMM[1]=aPv;
1441         aTmax=aTV;
1442       }
1443     }
1444   }
1445   //
1446   for (j=0; j<2; ++j) {
1447     //if curve is closed, process only one bound
1448     if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1449       continue;
1450     }
1451     //
1452     iFlag=1;
1453     //
1454     if (aNbEP) {
1455       Bnd_Box aBoxP;
1456       //
1457       aBoxP.Set(aP[j]);
1458       aTol = aTolR3D+Precision::Confusion();
1459       aBoxP.Enlarge(aTol);
1460       const BOPDS_Pave& aPV=aPMM[j];
1461       nV=aPV.Index();
1462       const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1463       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1464       const Bnd_Box& aBoxV=aSIV.Box();
1465       if (!aBoxP.IsOut(aBoxV)){
1466         iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1467       }
1468     }
1469     if (iFlag) {
1470       // 900/L5
1471       bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1472       if (!bVF) {
1473         continue;
1474       }
1475       //
1476       BOPDS_ShapeInfo aSIVn;
1477       //
1478       BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1479       aSIVn.SetShapeType(TopAbs_VERTEX);
1480       aSIVn.SetShape(aVn);
1481       //
1482       nVn=myDS->Append(aSIVn);
1483       //
1484       aPn.SetIndex(nVn);
1485       aPn.SetParameter(aT[j]);
1486       aPB->AppendExtPave(aPn);
1487       //
1488       aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1489       BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1490       //
1491       aTolVnew = BRep_Tool::Tolerance(aVn);
1492       //
1493       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1494       Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1495       BRepBndLib::Add(aVn, aBoxDS);
1496       aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
1497       //
1498       aLVB.Append(nVn);
1499     }
1500   }
1501 }
1502
1503 //=======================================================================
1504 //function : PutPavesOnCurve
1505 //purpose  : 
1506 //=======================================================================
1507 void BOPAlgo_PaveFiller::PutPavesOnCurve
1508   (const BOPCol_MapOfInteger& aMVOnIn,
1509    BOPDS_Curve& aNC,
1510    const Standard_Integer nF1,
1511    const Standard_Integer nF2,
1512    const BOPCol_MapOfInteger& aMI,
1513    const BOPCol_MapOfInteger& aMVEF,
1514    BOPCol_DataMapOfIntegerReal& aMVTol,
1515    BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1516 {
1517   Standard_Boolean bInBothFaces;
1518   Standard_Integer nV;
1519   BOPCol_MapIteratorOfMapOfInteger aIt;
1520   //
1521   const Bnd_Box& aBoxC=aNC.Box();
1522   Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1523   //
1524   //Put EF vertices first
1525   aIt.Initialize(aMVEF);
1526   for (; aIt.More(); aIt.Next()) {
1527     nV=aIt.Value();
1528     PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
1529   }
1530   //Put all other vertices
1531   aIt.Initialize(aMVOnIn);
1532   for (; aIt.More(); aIt.Next()) {
1533     nV=aIt.Value();
1534     if (aMVEF.Contains(nV)) {
1535       continue;
1536     }
1537     //
1538     const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1539     const Bnd_Box& aBoxV=aSIV.Box();
1540     //
1541     if (aBoxC.IsOut(aBoxV)){
1542       continue;
1543     }
1544     if (!myDS->IsNewShape(nV)) {
1545       const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1546       const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
1547       //
1548       bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1549                       aFI1.VerticesIn().Contains(nV))&&
1550                      (aFI2.VerticesOn().Contains(nV) ||
1551                       aFI2.VerticesIn().Contains(nV));
1552       if (!bInBothFaces) {
1553         continue;
1554       }
1555     }
1556     //
1557     PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
1558   }
1559 }
1560
1561 //=======================================================================
1562 //function : FilterPavesOnCurves
1563 //purpose  : 
1564 //=======================================================================
1565 namespace {
1566   struct PaveBlockDist {
1567     Handle(BOPDS_PaveBlock) PB;
1568     Standard_Real Dist; // square distance from vertex to the paveblock
1569     Standard_Real SinAngle; // sinus of angle between projection vector 
1570     // and tangent at projection point
1571     Standard_Real Tolerance; // tolerance of the section curve
1572   };
1573 }
1574 void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC)
1575 {
1576   // For each vertex found in ExtPaves of pave blocks of section curves
1577   // collect list of pave blocks with distance to the curve
1578   NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
1579   Standard_Integer i;
1580   const Standard_Real anEps = gp::Resolution();
1581   for (i = 0; i < theVNC.Extent(); ++i)
1582   {
1583     const BOPDS_Curve& aNC = theVNC(i);
1584     const IntTools_Curve& aIC = aNC.Curve();
1585     const Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1586     GeomAdaptor_Curve aGAC(aIC.Curve());
1587     const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
1588     const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
1589     BOPDS_ListOfPave::Iterator itPaves(aPaves);
1590     for (; itPaves.More(); itPaves.Next())
1591     {
1592       const BOPDS_Pave& aPave = itPaves.Value();
1593       Standard_Integer nV = aPave.Index();
1594       const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
1595       // compute distance from vertex to the point on curve with vertex parameter
1596       gp_Pnt aPV = BRep_Tool::Pnt(aV);
1597       Standard_Real aPar = aPave.Parameter();
1598       gp_Pnt aPonC;
1599       gp_Vec aD1;
1600       aGAC.D1(aPar, aPonC, aD1);
1601       gp_Vec aProjVec(aPV, aPonC);
1602       Standard_Real aSqDist = aProjVec.SquareMagnitude();
1603       Standard_Real aSqD1Mod = aD1.SquareMagnitude();
1604       Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
1605       if (aSqDist > anEps && aSqD1Mod > anEps)
1606         aSin = sqrt(aSin / aSqDist / aSqD1Mod);
1607       NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
1608       if (!pList)
1609         pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
1610       PaveBlockDist aPBD = { aPB, aSqDist, aSin, aTolR3D };
1611       pList->Append(aPBD);
1612     }
1613   }
1614
1615   // Process each vertex
1616   const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
1617   for (i = 1; i <= aIDMVertPBs.Extent(); i++)
1618   {
1619     Standard_Integer nV = aIDMVertPBs.FindKey(i);
1620     const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
1621     // Find a pave with minimal distance
1622     Standard_Real aMinDist = RealLast();
1623     Handle(BOPDS_PaveBlock) aPBMinDist;
1624     NCollection_List<PaveBlockDist>::Iterator itL(aList);
1625     for (; itL.More(); itL.Next())
1626     {
1627       const PaveBlockDist& aPBD = itL.Value();
1628       if (aPBD.Dist < aMinDist)
1629       {
1630         aMinDist = aPBD.Dist;
1631         aPBMinDist = aPBD.PB;
1632       }
1633     }
1634     // Remove a vertex from a pave block if the distance is greater than the tolerance 
1635     // and there are other pave blocks for which the distance is less than the current.
1636     // Do not remove a vertex if it is projected on the curve with quite large angle
1637     // (see test bugs modalg_6 bug27761).
1638     for (itL.Init(aList); itL.More(); itL.Next())
1639     {
1640       const PaveBlockDist& aPBD = itL.Value();
1641       Standard_Real aCheckDist = 100. * Max(aPBD.Tolerance*aPBD.Tolerance, aMinDist);
1642       if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
1643       {
1644         aPBD.PB->RemoveExtPave(nV);
1645       }
1646     }
1647   }
1648 }
1649
1650 //=======================================================================
1651 //function : ExtendedTolerance
1652 //purpose  : 
1653 //=======================================================================
1654 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1655   (const Standard_Integer nV,
1656    const BOPCol_MapOfInteger& aMI,
1657    Standard_Real& aTolVExt,
1658    const Standard_Integer aType)
1659 {
1660   Standard_Boolean bFound = Standard_False;
1661   if (!(myDS->IsNewShape(nV))) {
1662     return bFound;
1663   }
1664   //
1665   Standard_Integer i, k, aNbLines, aNbInt;
1666   Standard_Real aT11, aT12, aD1, aD2, aD;
1667   TopoDS_Vertex aV;
1668   gp_Pnt aPV, aP11, aP12;
1669   //
1670   k = 0;
1671   aNbInt = 2;
1672   if (aType == 1) {
1673     aNbInt = 1;
1674   } else if (aType == 2) {
1675     k = 1;
1676   }
1677   //
1678   aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1679   aPV=BRep_Tool::Pnt(aV);
1680   //
1681   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1682   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1683   //
1684   for (; k<aNbInt; ++k) {
1685     aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1686     for (i = 0; i < aNbLines; ++i) {
1687       BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1688         (BOPDS_Interf*) (&aEFs(i));
1689       if (aInt->IndexNew() == nV) {
1690         if (aMI.Contains(aInt->Index1()) && 
1691             aMI.Contains(aInt->Index2())) {
1692           const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1693             aEFs(i).CommonPart();
1694           //
1695           const TopoDS_Edge& aE1=aComPrt.Edge1();
1696           aComPrt.Range1(aT11, aT12);
1697           BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1698           BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1699           aD1=aPV.Distance(aP11);
1700           aD2=aPV.Distance(aP12);
1701           aD=(aD1>aD2)? aD1 : aD2;
1702           if (aD>aTolVExt) {
1703             aTolVExt=aD;
1704           }
1705           return !bFound;
1706         }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1707       }//if (aInt->IndexNew() == nV) {
1708     }//for (i = 0; i < aNbLines; ++i) {
1709   }//for (k=0; k<2; ++k) {
1710   return bFound;
1711 }
1712
1713 //=======================================================================
1714 //function : GetEFPnts
1715 //purpose  : 
1716 //=======================================================================
1717 void BOPAlgo_PaveFiller::GetEFPnts
1718   (const Standard_Integer nF1,
1719    const Standard_Integer nF2,
1720    IntSurf_ListOfPntOn2S& aListOfPnts)
1721 {
1722   Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1723   Standard_Real U1, U2, V1, V2, f, l;
1724   BOPCol_MapOfInteger aMI;
1725   //
1726   //collect indexes of all shapes from nF1 and nF2.
1727   GetFullShapeMap(nF1, aMI);
1728   GetFullShapeMap(nF2, aMI);
1729   //
1730   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1731   aNbEFs = aEFs.Extent();
1732   //
1733   for(i = 0; i < aNbEFs; ++i) {
1734     const BOPDS_InterfEF& aEF = aEFs(i);
1735     if (aEF.HasIndexNew()) {
1736       aEF.Indices(nE, nFOpposite);
1737       if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1738         const IntTools_CommonPrt& aCP = aEF.CommonPart();
1739         Standard_Real aPar = aCP.VertexParameter1();
1740         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1741         const TopoDS_Face& aFOpposite = 
1742           (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1743         //
1744         const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1745         //
1746         nF = (nFOpposite == nF1) ? nF2 : nF1;
1747         const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1748         Handle(Geom2d_Curve) aPCurve = 
1749           BRep_Tool::CurveOnSurface(aE, aF, f, l);
1750         //
1751         GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1752         //
1753         gp_Pnt aPoint;
1754         aCurve->D0(aPar, aPoint);
1755         IntSurf_PntOn2S aPnt;
1756         if(!aPCurve.IsNull()) {
1757           gp_Pnt2d aP2d = aPCurve->Value(aPar);
1758           aProj.Perform(aPoint);
1759           if(aProj.IsDone()) {
1760             aProj.LowerDistanceParameters(U1,V1);
1761             if (nF == nF1) {
1762               aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1763             } else {
1764               aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1765             }
1766             aListOfPnts.Append(aPnt);
1767           }
1768         }
1769         else {
1770           GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1771           aProj1.Perform(aPoint);
1772           aProj.Perform(aPoint);
1773           if(aProj1.IsDone() && aProj.IsDone()){
1774             aProj1.LowerDistanceParameters(U1,V1);
1775             aProj.LowerDistanceParameters(U2,V2);
1776             if (nF == nF1) {
1777               aPnt.SetValue(U1,V1,U2,V2);
1778             } else {
1779               aPnt.SetValue(U2,V2,U1,V1);
1780             }
1781             aListOfPnts.Append(aPnt);
1782           }
1783         }
1784       }
1785     }
1786   }
1787 }
1788
1789 //=======================================================================
1790 //function : PutEFPavesOnCurve
1791 //purpose  : 
1792 //=======================================================================
1793   void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1794   (BOPDS_Curve& aNC,
1795    const BOPCol_MapOfInteger& aMI,
1796    const BOPCol_MapOfInteger& aMVEF,
1797    BOPCol_DataMapOfIntegerReal& aMVTol,
1798    BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1799 {
1800   if (!aMVEF.Extent()) {
1801     return;
1802   }
1803   //
1804   const IntTools_Curve& aIC=aNC.Curve();
1805   GeomAbs_CurveType aTypeC;
1806   aTypeC=aIC.Type();
1807   if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1808     return;
1809   }
1810   //
1811   Standard_Integer nV;
1812   BOPCol_MapOfInteger aMV;
1813   //
1814   aMV.Assign(aMVEF);
1815   RemoveUsedVertices(aNC, aMV);
1816   if (!aMV.Extent()) {
1817     return;
1818   }
1819   //
1820   Standard_Real aDist;
1821   BOPDS_Pave aPave;
1822   //
1823   const Handle(Geom_Curve)& aC3D=aIC.Curve();
1824   GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1825   //
1826   BOPCol_MapIteratorOfMapOfInteger aItMI;
1827   aItMI.Initialize(aMV);
1828   for (; aItMI.More(); aItMI.Next()) {
1829     nV = aItMI.Value();
1830     const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1831     gp_Pnt aPV = BRep_Tool::Pnt(aV);
1832     aProjPT.Perform(aPV);
1833     Standard_Integer aNbPoints = aProjPT.NbPoints();
1834     if (aNbPoints) {
1835       aDist = aProjPT.LowerDistance();
1836       PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
1837     }
1838   }
1839 }
1840
1841 //=======================================================================
1842 //function : ProcessUnUsedVertices
1843 //purpose  : 
1844 //=======================================================================
1845   void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1846   (const TopoDS_Face& aF1,
1847    const TopoDS_Face& aF2,
1848    const BOPCol_MapOfInteger& aMI,
1849    BOPDS_Curve& aNC,
1850    const BOPCol_MapOfInteger& aMVStick,
1851    BOPCol_DataMapOfIntegerReal& aMVTol,
1852    BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1853 {
1854   BOPCol_MapOfInteger aMV;
1855   aMV.Assign(aMVStick);
1856   RemoveUsedVertices(aNC, aMV);
1857   //
1858   if (!aMV.Extent()) {
1859     return;
1860   }
1861   //
1862   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1863   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1864   //
1865   const IntTools_Curve& aIC=aNC.Curve();
1866   //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1867   Handle(Geom2d_Curve) aC2D[2];
1868   //
1869   aC2D[0]=aIC.FirstCurve2d();
1870   aC2D[1]=aIC.SecondCurve2d();
1871   if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1872     Standard_Integer nV, m, n;
1873     Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1874     gp_Pnt aPC[2], aPV;
1875     gp_Dir aDN[2];
1876     gp_Pnt2d aP2D;
1877     BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1878     //
1879     aDT2=2e-7;     // the rich criteria
1880     aDScPr=5.e-9;  // the creasing criteria
1881     aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1882     //
1883     aItMI.Initialize(aMV);
1884     for (; aItMI.More(); aItMI.Next()) {
1885       nV = aItMI.Value();
1886       const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1887       aPV=BRep_Tool::Pnt(aV);
1888       //
1889       for (m=0; m<2; ++m) {
1890         aD2=aPC[m].SquareDistance(aPV);
1891         if (aD2>aDT2) {// no rich
1892           continue; 
1893         }
1894         //
1895         for (n=0; n<2; ++n) {
1896           Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1897           aC2D[n]->D0(aTC[m], aP2D);
1898           aP2D.Coord(u, v);
1899           BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1900         }
1901         // 
1902         aScPr=aDN[0]*aDN[1];
1903         if (aScPr<0.) {
1904           aScPr=-aScPr;
1905         }
1906         aScPr=1.-aScPr;
1907         //
1908         if (aScPr>aDScPr) {
1909           continue;
1910         }
1911         //
1912         // The intersection curve aIC is vanishing curve (the crease)
1913         aD=sqrt(aD2);
1914         //
1915         PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
1916       }
1917     }//for (jVU=1; jVU=aNbVU; ++jVU) {
1918   }
1919   //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1920   //}//if(aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
1921 }
1922
1923 //=======================================================================
1924 //function : GetStickVertices
1925 //purpose  : 
1926 //=======================================================================
1927 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1928                                           const Standard_Integer nF2,
1929                                           BOPCol_MapOfInteger& aMVStick,
1930                                           BOPCol_MapOfInteger& aMVEF,
1931                                           BOPCol_MapOfInteger& aMI)
1932 {
1933   Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
1934   //
1935   BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1936   BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
1937   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1938   BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
1939   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1940   //
1941   Standard_Integer aNbLines[5] = {
1942     aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
1943     aVFs.Extent(), aEFs.Extent()
1944     };
1945   //collect indices of all shapes from nF1 and nF2.
1946   aMI.Clear();
1947   GetFullShapeMap(nF1, aMI);
1948   GetFullShapeMap(nF2, aMI);
1949   //
1950   //collect VV, VE, EE, VF interferences
1951   for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
1952     for (i = 0; i < aNbLines[aTypeInt]; ++i) {
1953       BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : 
1954         ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
1955          ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : 
1956           (BOPDS_Interf*)(&aVFs(i))));
1957       if (aInt->HasIndexNew()) {
1958         aInt->Indices(nS1, nS2);
1959         if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1960           nVNew = aInt->IndexNew();
1961           aMVStick.Add(nVNew);
1962         }
1963       }
1964     }
1965   }
1966   //collect EF interferences
1967   for (i = 0; i < aNbLines[4]; ++i) {
1968     const BOPDS_InterfEF& aInt = aEFs(i);
1969     if (aInt.HasIndexNew()) {
1970       aInt.Indices(nS1, nS2);
1971       if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1972         nVNew = aInt.IndexNew();
1973         aMVStick.Add(nVNew);
1974         aMVEF.Add(nVNew);
1975       }
1976     }
1977   }
1978 }
1979
1980 //=======================================================================
1981 // function: GetFullShapeMap
1982 // purpose: 
1983 //=======================================================================
1984 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
1985                                          BOPCol_MapOfInteger& aMI)
1986 {
1987   BOPCol_ListIteratorOfListOfInteger aIt;
1988   Standard_Integer nS;
1989   //
1990   const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
1991   const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1992   //
1993   aMI.Add(nF);
1994   aIt.Initialize(aLI);
1995   for (; aIt.More(); aIt.Next()) {
1996     nS = aIt.Value();
1997     aMI.Add(nS);
1998   }
1999 }
2000
2001 //=======================================================================
2002 // function: RemoveUsedVertices
2003 // purpose: 
2004 //=======================================================================
2005 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
2006                                             BOPCol_MapOfInteger& aMV)
2007 {
2008   if (!aMV.Extent()) {
2009     return;
2010   }
2011   Standard_Integer nV;
2012   BOPDS_Pave aPave;
2013   BOPDS_ListIteratorOfListOfPave aItLP;
2014   //
2015   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2016   const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
2017   aItLP.Initialize(aLP);
2018   for (;aItLP.More();aItLP.Next()) {
2019     aPave = aItLP.Value();
2020     nV = aPave.Index();
2021     aMV.Remove(nV);
2022   }
2023 }
2024
2025 //=======================================================================
2026 //function : PutPaveOnCurve
2027 //purpose  : 
2028 //=======================================================================
2029 void BOPAlgo_PaveFiller::PutPaveOnCurve
2030   (const Standard_Integer nV,
2031    const Standard_Real aTolR3D,
2032    const BOPDS_Curve& aNC,
2033    const BOPCol_MapOfInteger& aMI,
2034    BOPCol_DataMapOfIntegerReal& aMVTol,
2035    BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
2036    const Standard_Integer iCheckExtend)
2037 {
2038   Standard_Boolean bIsVertexOnLine;
2039   Standard_Real aT;
2040   //
2041   const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2042   const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2043   const IntTools_Curve& aIC = aNC.Curve();
2044   //
2045   Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2046
2047   bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2048   if (!bIsVertexOnLine && iCheckExtend) {
2049     ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
2050     bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2051   }
2052   //
2053   if (bIsVertexOnLine) {
2054     // check if aPB contains the parameter aT
2055     Standard_Boolean bExist;
2056     Standard_Integer nVUsed;
2057     Standard_Real aPTol, aDTol;
2058     //
2059     aDTol = 1.e-12;
2060     //
2061     GeomAdaptor_Curve aGAC(aIC.Curve());
2062     aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
2063     //
2064     bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
2065     if (bExist) {
2066       // use existing pave
2067       BOPCol_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2068       if (!pList) {
2069         pList = aDMVLV.Bound(nVUsed, BOPCol_ListOfInteger());
2070         pList->Append(nVUsed);
2071         if (!aMVTol.IsBound(nVUsed)) {
2072           const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2073           aTolV = BRep_Tool::Tolerance(aVUsed);
2074           aMVTol.Bind(nVUsed, aTolV);
2075         }
2076       }
2077       // avoid repeated elements in the list
2078       BOPCol_ListIteratorOfListOfInteger aItLI(*pList);
2079       for (; aItLI.More(); aItLI.Next()) {
2080         if (aItLI.Value() == nV) {
2081           break;
2082         }
2083       }
2084       if (!aItLI.More()) {
2085         pList->Append(nV);
2086       }
2087       // save initial tolerance for the vertex
2088       if (!aMVTol.IsBound(nV)) {
2089         aTolV = BRep_Tool::Tolerance(aV);
2090         aMVTol.Bind(nV, aTolV);
2091       }
2092     }
2093     else {
2094       // add new pave
2095       BOPDS_Pave aPave;
2096       aPave.SetIndex(nV);
2097       aPave.SetParameter(aT);
2098       aPB->AppendExtPave(aPave);
2099       //
2100       gp_Pnt aP1 = aGAC.Value(aT);
2101       aTolV = BRep_Tool::Tolerance(aV);
2102       gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2103       Standard_Real aDist = aP1.Distance(aP2);
2104       if (aDist > aTolV) {
2105         BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2106         //
2107         if (!aMVTol.IsBound(nV)) {
2108           aMVTol.Bind(nV, aTolV);
2109         }
2110         //
2111         BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2112         Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2113         BRepBndLib::Add(aV, aBoxDS);
2114         aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
2115       }
2116     }
2117   }
2118 }
2119
2120 //=======================================================================
2121 //function : ProcessExistingPaveBlocks
2122 //purpose  : 
2123 //=======================================================================
2124 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
2125     (const Standard_Integer theInt,
2126      const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
2127      const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
2128      BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2129      BOPCol_DataMapOfShapeInteger& aMVI,
2130      BOPDS_MapOfPaveBlock& aMPB)
2131 {
2132   if (aDMBV.IsEmpty()) {
2133     return;
2134   }
2135   //
2136   Standard_Real aT, dummy;
2137   Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
2138   BOPCol_ListIteratorOfListOfInteger aItLI;
2139   BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
2140   //
2141   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2142   BOPDS_InterfFF& aFF = aFFs(theInt);
2143   BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2144   //
2145   aNbPB = aMPBOnIn.Extent();
2146   //
2147   aItBV.Initialize(aDMBV);
2148   for (; aItBV.More(); aItBV.Next()) {
2149     iC = aItBV.Key();
2150     const BOPCol_ListOfInteger& aLBV = aItBV.Value();
2151     //
2152     BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2153     BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2154     //
2155     aItLI.Initialize(aLBV);
2156     for (; aItLI.More(); aItLI.Next()) {
2157       nV = aItLI.Value();
2158       const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2159       const Bnd_Box& aBoxV=aSIV.Box();
2160       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2161       if (!aMVI.IsBound(aV)) {
2162         continue;
2163       }
2164       //
2165       for (i = 1; i <= aNbPB; ++i) {
2166         const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
2167         if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2168           continue;
2169         }
2170         //
2171         if (aMPB.Contains(aPB)) {
2172           continue;
2173         }
2174         if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
2175           continue;
2176         }
2177         //
2178         nE = aPB->Edge();
2179         const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2180         const Bnd_Box& aBoxE = aSIE.Box();
2181         //
2182         if (aBoxV.IsOut(aBoxE)) {
2183           continue;
2184         }
2185         //
2186         const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2187         //
2188         iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
2189         if (!iFlag) {
2190           aMPB.Add(aPB);
2191           PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
2192         }
2193       }
2194     }
2195   }
2196 }
2197 //=======================================================================
2198 //function : UpdateExistingPaveBlocks
2199 //purpose  : 
2200 //=======================================================================
2201 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2202   (const Handle(BOPDS_PaveBlock)& aPBf,
2203    BOPDS_ListOfPaveBlock& aLPB,
2204    const Standard_Integer nF1,
2205    const Standard_Integer nF2) 
2206 {
2207   if (!aLPB.Extent()) {
2208     return;
2209   }
2210   //
2211   Standard_Integer nE;
2212   Standard_Boolean bCB;
2213   Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2214   Handle(BOPDS_CommonBlock) aCB;
2215   BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2216   //
2217   BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2218   BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2219   //
2220   BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2221   BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2222   BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2223   BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2224   //
2225   // 1. Remove old pave blocks
2226   const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2227   bCB = !aCB1.IsNull();
2228   BOPDS_ListOfPaveBlock aLPB1;
2229   //
2230   if (bCB) {
2231     aLPB1.Assign(aCB1->PaveBlocks());
2232   } else {
2233     aLPB1.Append(aPBf);
2234   }
2235   aIt1.Initialize(aLPB1);
2236   for (; aIt1.More(); aIt1.Next()) {
2237     aPB1 = aIt1.Value();
2238     nE = aPB1->OriginalEdge();
2239     //
2240     BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2241     aIt2.Initialize(aLPB2);
2242     for (; aIt2.More(); aIt2.Next()) {
2243       aPB2 = aIt2.Value();
2244       if (aPB1 == aPB2) {
2245         aLPB2.Remove(aIt2);
2246         break;
2247       }
2248     }
2249   }
2250   //
2251   // 2. Update pave blocks
2252   if (bCB) {
2253     // Create new common blocks
2254     BOPDS_ListOfPaveBlock aLPBNew;
2255     const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
2256     aIt.Initialize(aLPB);
2257     for (; aIt.More(); aIt.Next()) {
2258       const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2259       BOPDS_Pave aPBValuePaves[2] = {aPBValue->Pave1(), aPBValue->Pave2()};
2260       //
2261       aCB = new BOPDS_CommonBlock;
2262       aIt1.Initialize(aLPB1);
2263       for (; aIt1.More(); aIt1.Next()) {
2264         aPB2 = aIt1.Value();
2265         nE = aPB2->OriginalEdge();
2266         //
2267         // Create new pave block
2268         aPB2n = new BOPDS_PaveBlock;
2269         if (aPBValue->OriginalEdge() == nE) {
2270           aPB2n->SetPave1(aPBValuePaves[0]);
2271           aPB2n->SetPave2(aPBValuePaves[1]);
2272         }
2273         else {
2274           // For the different original edge compute the parameters of paves
2275           BOPDS_Pave aPave[2];
2276           for (Standard_Integer i = 0; i < 2; ++i) {
2277             Standard_Integer nV = aPBValuePaves[i].Index();
2278             aPave[i].SetIndex(nV);
2279             if (nV == aPB2->Pave1().Index()) {
2280               aPave[i].SetParameter(aPB2->Pave1().Parameter());
2281             }
2282             else if (nV == aPB2->Pave2().Index()) {
2283               aPave[i].SetParameter(aPB2->Pave2().Parameter());
2284             }
2285             else {
2286               // Compute the parameter by projecting the point
2287               const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2288               const TopoDS_Edge& aEOr = TopoDS::Edge(myDS->Shape(nE));
2289               Standard_Real aTOut, aDist;
2290               Standard_Integer iErr = myContext->ComputeVE(aV, aEOr, aTOut, aDist, myFuzzyValue);
2291               if (!iErr) {
2292                 aPave[i].SetParameter(aTOut);
2293               }
2294               else {
2295                 // Unable to project - set the parameter of the closest boundary
2296                 const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(aPB2->Pave1().Index()));
2297                 const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(aPB2->Pave2().Index()));
2298                 //
2299                 gp_Pnt aP = BRep_Tool::Pnt(aV);
2300                 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
2301                 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
2302                 //
2303                 Standard_Real aDist1 = aP.SquareDistance(aP1);
2304                 Standard_Real aDist2 = aP.SquareDistance(aP2);
2305                 //
2306                 aPave[i].SetParameter(aDist1 < aDist2 ? aPB2->Pave1().Parameter() : aPB2->Pave2().Parameter());
2307               }
2308             }
2309           }
2310           //
2311           if (aPave[1].Parameter() < aPave[0].Parameter()) {
2312             BOPDS_Pave aPaveTmp = aPave[0];
2313             aPave[0] = aPave[1];
2314             aPave[1] = aPaveTmp;
2315           }
2316           //
2317           aPB2n->SetPave1(aPave[0]);
2318           aPB2n->SetPave2(aPave[1]);
2319         }
2320         //
2321         aPB2n->SetEdge(aPBValue->Edge());
2322         aPB2n->SetOriginalEdge(nE);
2323         aCB->AddPaveBlock(aPB2n);
2324         myDS->SetCommonBlock(aPB2n, aCB);
2325         myDS->ChangePaveBlocks(nE).Append(aPB2n);
2326       }
2327       aCB->SetFaces(aFaces);
2328       //
2329       const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2330       aLPBNew.Append(aPBNew);
2331     }
2332     //
2333     aLPB = aLPBNew;
2334   } 
2335   else {
2336     nE = aPBf->OriginalEdge();
2337     BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2338     aIt.Initialize(aLPB);
2339     for (; aIt.More(); aIt.Next()) {
2340       aPB = aIt.Value();
2341       aLPBE.Append(aPB);
2342     }
2343   }
2344   //
2345   Standard_Boolean bIn1, bIn2;
2346   //
2347   bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2348   bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2349   //
2350   if (bIn1 && bIn2) {
2351     return;
2352   }
2353   //
2354   // 3. Check new pave blocks for coincidence 
2355   //    with the opposite face.
2356   //    In case of coincidence create common blocks
2357   Standard_Integer nF;
2358   //
2359   nF = bIn1 ? nF2 : nF1;
2360   const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2361   BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2362   //
2363   aIt.Initialize(aLPB);
2364   for (; aIt.More(); aIt.Next()) {
2365     Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2366     const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2367     //
2368     IntTools_EdgeFace anEF;
2369     anEF.SetEdge(aE);
2370     anEF.SetFace(aF);
2371     anEF.SetFuzzyValue(myFuzzyValue);
2372     anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2373     anEF.SetContext(myContext);
2374     anEF.Perform();
2375     //
2376     const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2377     if (aCPrts.Length() == 1) {
2378       Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2379       if (bCoinc) {
2380         if (bCB) {
2381           aCB = myDS->CommonBlock(aPBChangeValue);
2382         } else {
2383           aCB = new BOPDS_CommonBlock;
2384           aCB->AddPaveBlock(aPBChangeValue);
2385           myDS->SetCommonBlock(aPBChangeValue, aCB);
2386         }
2387         aCB->AddFace(nF);
2388         //
2389         aMPBIn.Add(aPBChangeValue);
2390       }
2391     }
2392   }
2393 }
2394 //=======================================================================
2395 // function: PutClosingPaveOnCurve
2396 // purpose:
2397 //=======================================================================
2398 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2399 {
2400   Standard_Boolean bIsClosed, bHasBounds, bAdded;
2401   Standard_Integer nVC, j;
2402   Standard_Real aT[2], aTC, dT, aTx;
2403   gp_Pnt aP[2] ; 
2404   BOPDS_Pave aPVx;
2405   BOPDS_ListIteratorOfListOfPave aItLP;
2406   //
2407   const IntTools_Curve& aIC=aNC.Curve();
2408   const Handle(Geom_Curve)& aC3D=aIC.Curve();
2409   if(aC3D.IsNull()) {
2410     return;
2411   }
2412   //
2413   bIsClosed=IntTools_Tools::IsClosed(aC3D);
2414   if (!bIsClosed) {
2415     return;
2416   }
2417   //
2418   bHasBounds=aIC.HasBounds ();
2419   if (!bHasBounds){
2420     return;
2421   }
2422   // 
2423   bAdded=Standard_False;
2424   dT=Precision::PConfusion();
2425   aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2426   //
2427   Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2428   BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2429   //
2430   aItLP.Initialize(aLP);
2431   for (; aItLP.More() && !bAdded; aItLP.Next()) {
2432     const BOPDS_Pave& aPC=aItLP.Value();
2433     nVC=aPC.Index();
2434     aTC=aPC.Parameter();
2435     //
2436     for (j=0; j<2; ++j) {
2437       if (fabs(aTC-aT[j]) < dT) {
2438         aTx=(!j) ? aT[1] : aT[0];
2439         aPVx.SetIndex(nVC);
2440         aPVx.SetParameter(aTx);
2441         aLP.Append(aPVx);
2442         //
2443         bAdded=Standard_True;
2444         break;
2445       }
2446     }
2447   }
2448 }
2449 //=======================================================================
2450 //function : PreparePostTreatFF
2451 //purpose  : 
2452 //=======================================================================
2453 void BOPAlgo_PaveFiller::PreparePostTreatFF
2454     (const Standard_Integer aInt,
2455      const Standard_Integer aCur,
2456      const Handle(BOPDS_PaveBlock)& aPB,
2457      BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2458      BOPCol_DataMapOfShapeInteger& aMVI,
2459      BOPDS_ListOfPaveBlock& aLPBC)
2460 {
2461   Standard_Integer nV1, nV2;
2462   //
2463   aLPBC.Append(aPB);
2464   //
2465   aPB->Indices(nV1, nV2);
2466   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2467   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2468   const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2469   // Keep info for post treatment 
2470   BOPDS_CoupleOfPaveBlocks aCPB;
2471   aCPB.SetIndexInterf(aInt);
2472   aCPB.SetIndex(aCur);
2473   aCPB.SetPaveBlock1(aPB);
2474   //
2475   aMSCPB.Add(aE, aCPB);
2476   aMVI.Bind(aV1, nV1);
2477   aMVI.Bind(aV2, nV2);
2478 }
2479
2480 //=======================================================================
2481 //function : CheckPlanes
2482 //purpose  : 
2483 //=======================================================================
2484 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2485   (const Standard_Integer nF1,
2486    const Standard_Integer nF2)const
2487 {
2488   Standard_Boolean bToIntersect;
2489   Standard_Integer i, nV2, iCnt;
2490   BOPCol_MapIteratorOfMapOfInteger aIt;
2491   //
2492   bToIntersect=Standard_False;
2493   //
2494   const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2495   const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2496   //
2497   const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2498   const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2499   //
2500   iCnt=0;
2501   for (i=0; (i<2 && !bToIntersect); ++i) {
2502     const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn() 
2503       : aFI2.VerticesOn();
2504     //
2505     aIt.Initialize(aMV2);
2506     for (; aIt.More(); aIt.Next()) {
2507       nV2=aIt.Value();
2508       if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2509         ++iCnt;
2510         if (iCnt>1) {
2511           bToIntersect=!bToIntersect;
2512           break;
2513         }
2514       }
2515     }
2516   }
2517   //
2518   return bToIntersect;
2519 }
2520 //=======================================================================
2521 //function : UpdatePaveBlocks
2522 //purpose  : 
2523 //=======================================================================
2524 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2525 (const BOPCol_DataMapOfIntegerInteger& aDMNewSD)
2526 {
2527   if (aDMNewSD.IsEmpty()) {
2528     return;
2529   }
2530   //
2531   Standard_Integer nSp, aNbPBP, nV[2], i, j;
2532   Standard_Real aT[2];
2533   Standard_Boolean bCB, bRebuild;
2534   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2535   BOPDS_MapOfPaveBlock aMPB;
2536   BOPCol_MapOfInteger aMicroEdges;
2537   //
2538   BOPDS_ListOfPaveBlock anAllPBs;
2539
2540   // Get pave blocks of section edges
2541   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2542   Standard_Integer aNbFF = aFFs.Extent();
2543   for (i = 0; i < aNbFF; ++i)
2544   {
2545     const BOPDS_InterfFF& aFF = aFFs(i);
2546     const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
2547     Standard_Integer aNbC = aVNC.Extent();
2548     for (j = 0; j < aNbC; ++j)
2549     {
2550       const BOPDS_Curve& aNC = aVNC(j);
2551       const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
2552       aItPB.Initialize(aLPBC);
2553       for (; aItPB.More(); aItPB.Next())
2554         anAllPBs.Append(aItPB.Value());
2555     }
2556   }
2557
2558   // Get pave blocks from the pool
2559   BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2560   aNbPBP = aPBP.Extent();
2561   for (i = 0; i < aNbPBP; ++i) {
2562     BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2563     aItPB.Initialize(aLPB);
2564     for (; aItPB.More(); aItPB.Next())
2565       anAllPBs.Append(aItPB.Value());
2566   }
2567
2568   // Process all pave blocks
2569   aItPB.Initialize(anAllPBs);
2570   for (; aItPB.More(); aItPB.Next())
2571   {
2572     Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2573     const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
2574     bCB = !aCB.IsNull();
2575     if (bCB) {
2576       aPB = aCB->PaveBlock1();
2577     }
2578     //
2579     if (aMPB.Add(aPB)) {
2580       bRebuild = Standard_False;
2581       aPB->Indices(nV[0], nV[1]);
2582       aPB->Range(aT[0], aT[1]);
2583       // remember the fact if the edge had different vertices before substitution
2584       Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
2585       //
2586       for (j = 0; j < 2; ++j) {
2587         if (aDMNewSD.IsBound(nV[j])) {
2588           BOPDS_Pave aPave;
2589           //
2590           nV[j] = aDMNewSD.Find(nV[j]);
2591           aPave.SetIndex(nV[j]);
2592           aPave.SetParameter(aT[j]);
2593           //
2594           bRebuild = Standard_True;
2595           if (!j) {
2596             aPB->SetPave1(aPave);
2597           }
2598           else {
2599             aPB->SetPave2(aPave);
2600           }
2601         }
2602       }
2603       //
2604       if (bRebuild) {
2605         Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
2606         if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2607           // now edge has the same vertex on both ends;
2608           // check if it is not a regular closed curve.
2609           const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
2610           const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
2611           Standard_Real aLength = IntTools::Length(aE);
2612           Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2613           if (aLength <= aTolV * 2.) {
2614             // micro edge, so mark it for removal
2615             aMicroEdges.Add(aPB->Edge());
2616             continue;
2617           }
2618         }
2619         nSp = SplitEdge(aPB->Edge(), nV[0], aT[0], nV[1], aT[1]);
2620         if (bCB)
2621           aCB->SetEdge(nSp);
2622         else
2623           aPB->SetEdge(nSp);
2624       }// if (bRebuild) {
2625     }// if (aMPB.Add(aPB)) {
2626   }// for (; aItPB.More(); aItPB.Next()) {
2627   aMPB.Clear();
2628
2629   if (aMicroEdges.Extent())
2630     RemovePaveBlocks(aMicroEdges);
2631 }
2632 //=======================================================================
2633 //function : RemovePaveBlocks
2634 //purpose  : 
2635 //=======================================================================
2636 void BOPAlgo_PaveFiller::RemovePaveBlocks(const BOPCol_MapOfInteger theEdges)
2637 {
2638   // Remove all pave blocks referring to input edges:
2639   //
2640   // 1. from the Pave Blocks Pool
2641   BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2642   Standard_Integer aNbPBP = aPBP.Extent(), i;
2643   for (i = 0; i < aNbPBP; ++i) {
2644     BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2645     //
2646     BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2647     while (aItPB.More()) {
2648       const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2649       if (theEdges.Contains(aPB->Edge()))
2650         aLPB.Remove(aItPB);
2651       else
2652         aItPB.Next();
2653     }
2654   }
2655
2656   // 2. from Face Info and section curves
2657   BOPCol_MapOfInteger aMPassed;
2658   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2659   Standard_Integer aNbFF = aFFs.Extent(), j;
2660   for (i = 0; i < aNbFF; ++i) {
2661     BOPDS_InterfFF& aFF = aFFs(i);
2662     Standard_Integer nF1, nF2;
2663     aFF.Indices(nF1, nF2);
2664     //
2665     // rebuild pave block maps of face info
2666     for (j = 0; j < 2; j++) {
2667       Standard_Integer nF = (j == 0 ? nF1 : nF2);
2668       if (!aMPassed.Add(nF))
2669         continue;
2670       BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2671       BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2672         &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2673       for (Standard_Integer k = 0; k < 3; k++) {
2674         Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2675         for (m = 1; m <= aNbPB; ++m) {
2676           const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2677           if (theEdges.Contains(aPB->Edge()))
2678             break;
2679         }
2680         if (m <= aNbPB) {
2681           BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2682           aIMPB[k]->Clear();
2683           for (m = 1; m <= aNbPB; ++m) {
2684             const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2685             if (!theEdges.Contains(aPB->Edge()))
2686               aIMPB[k]->Add(aPB);
2687           }
2688         }
2689       }
2690     }
2691     // remove from Section pave blocks
2692     BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2693     Standard_Integer aNbC = aVNC.Extent();
2694     for (j = 0; j < aNbC; ++j) {
2695       BOPDS_Curve& aNC = aVNC(j);
2696       BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2697       BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2698       while (aItPB.More()) {
2699         const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2700         if (theEdges.Contains(aPB->Edge()))
2701           aLPB.Remove(aItPB);
2702         else
2703           aItPB.Next();
2704       }
2705     }
2706   }
2707 }
2708 //=======================================================================
2709 //function : ToleranceFF
2710 //purpose  : Computes the TolFF according to the tolerance value and 
2711 //           types of the faces.
2712 //=======================================================================
2713 Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2714                           const BRepAdaptor_Surface& aBAS2)
2715 {
2716   Standard_Real aTol1 = aBAS1.Tolerance();
2717   Standard_Real aTol2 = aBAS2.Tolerance();
2718   Standard_Real aTolFF = Max(aTol1, aTol2);
2719   //
2720   Standard_Boolean isAna1, isAna2;
2721   isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2722             aBAS1.GetType() == GeomAbs_Cylinder ||
2723             aBAS1.GetType() == GeomAbs_Cone ||
2724             aBAS1.GetType() == GeomAbs_Sphere ||
2725             aBAS1.GetType() == GeomAbs_Torus);
2726   //
2727   isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2728             aBAS2.GetType() == GeomAbs_Cylinder ||
2729             aBAS2.GetType() == GeomAbs_Cone ||
2730             aBAS2.GetType() == GeomAbs_Sphere ||
2731             aBAS2.GetType() == GeomAbs_Torus);
2732   //
2733   if (!isAna1 || !isAna2) {
2734     aTolFF =  Max(aTolFF, 5.e-6);
2735   }
2736   return aTolFF;
2737 }
2738 //=======================================================================
2739 //function : UpdateBlocksWithSharedVertices
2740 //purpose  : 
2741 //=======================================================================
2742 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2743 {
2744   if (!myNonDestructive) {
2745     return;
2746   }
2747   //
2748   Standard_Integer aNbFF;
2749   //
2750   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2751   aNbFF=aFFs.Extent();
2752   if (!aNbFF) {
2753     return;
2754   }
2755   //
2756   Standard_Boolean bOnCurve, bHasShapeSD;
2757   Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2758   Standard_Real aTolV;
2759   BOPCol_MapOfInteger aMF;
2760   //
2761   for (i=0; i<aNbFF; ++i) {
2762     BOPDS_InterfFF& aFF=aFFs(i);
2763     //
2764     BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2765     aNbC=aVC.Extent();
2766     if (!aNbC) {
2767       continue;
2768     }
2769     //
2770     aFF.Indices(nF1, nF2);
2771     //
2772     if (aMF.Add(nF1)) {
2773       myDS->UpdateFaceInfoOn(nF1);
2774     }
2775     if (aMF.Add(nF2)) {
2776       myDS->UpdateFaceInfoOn(nF2);
2777     }
2778     //
2779     // Collect old vertices that are shared for nF1, nF2 ->aMI;
2780     BOPCol_MapOfInteger aMI;
2781     BOPCol_MapIteratorOfMapOfInteger aItMI;
2782     //
2783     BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2784     BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2785     //
2786     const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2787     const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2788     const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2789     const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2790     //
2791     for (j=0; j<2; ++j) {
2792       const BOPCol_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2793       aItMI.Initialize(aMV1);
2794       for (; aItMI.More(); aItMI.Next()) {
2795         nV=aItMI.Value();
2796         if (myDS->IsNewShape(nV)) {
2797           continue;
2798         }
2799         if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2800           aMI.Add(nV);
2801         }
2802       }
2803     }
2804     //
2805     // Try to put vertices aMI on curves
2806     for (j=0; j<aNbC; ++j) {
2807       BOPDS_Curve& aNC=aVC.ChangeValue(j);
2808       Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
2809       //
2810       aItMI.Initialize(aMI);
2811       for (; aItMI.More(); aItMI.Next()) {
2812         nV=aItMI.Value();
2813         //
2814         bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2815         if (bHasShapeSD) {
2816           continue;
2817         }
2818         //
2819         bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2820         if (!bOnCurve) {
2821           continue;
2822         }
2823         //
2824         const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2825         aTolV=BRep_Tool::Tolerance(aV);
2826         //
2827         UpdateVertex(nV, aTolV);
2828       }
2829     }//for (j=0; j<aNbC; ++j) {
2830   }//for (i=0; i<aNbFF; ++i) {
2831   //
2832   UpdateCommonBlocksWithSDVertices();
2833 }
2834 //=======================================================================
2835 //function : EstimatePaveOnCurve
2836 //purpose  : 
2837 //=======================================================================
2838 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2839   (const Standard_Integer nV,
2840    const BOPDS_Curve& aNC,
2841    const Standard_Real aTolR3D)
2842 {
2843   Standard_Boolean bIsVertexOnLine;
2844   Standard_Real aT;
2845   //
2846   const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2847   const IntTools_Curve& aIC=aNC.Curve();
2848   //
2849   bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2850   return bIsVertexOnLine;
2851 }
2852
2853 //=======================================================================
2854 //function : CorrectToleranceOfSE
2855 //purpose  : 
2856 //=======================================================================
2857 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2858 {
2859   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2860   NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
2861   BOPCol_MapOfInteger aMVIToReduce;
2862   // Fence map to avoid repeated checking of the same edge
2863   BOPDS_MapOfPaveBlock aMPB;
2864   //
2865   // 1. iterate on all sections F-F
2866   Standard_Integer aNb = aFFs.Extent(), i;
2867   for (i = 0; i < aNb; ++i) {
2868     BOPDS_InterfFF& aFF = aFFs(i);
2869     //
2870     BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2871     Standard_Integer aNbC = aVNC.Extent(), k;
2872     for (k = 0; k < aNbC; ++k) {
2873       BOPDS_Curve& aNC = aVNC(k);
2874       BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2875       BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2876       for (; aItLPB.More(); ) {
2877         const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2878         Standard_Integer nE;
2879         if (!aPB->HasEdge(nE)) {
2880           aLPB.Remove(aItLPB);
2881           continue;
2882         }
2883         //
2884         if (!aMPB.Add(aPB)) {
2885           aItLPB.Next();
2886           continue;
2887         }
2888         //
2889         Standard_Boolean bIsReduced = Standard_False;
2890         if (aPB->OriginalEdge() < 0) {
2891           // It is possible that due to small angle between faces the
2892           // common zone between faces can be large and the tangential
2893           // tolerance of the curve will be large as well.
2894           // Here we're trying to reduce the tolerance of the section
2895           // edge using the valid tolerance of the edge.
2896           // Note, that if the pave block has created common block with
2897           // other edges its valid tolerance could have been changed to
2898           // cover all edges in common block (see PostTreatFF() method).
2899           Standard_Real aTolC = aNC.Tolerance();
2900           Standard_Real aTolTang = aNC.TangentialTolerance();
2901           if (aTolC < aTolTang) {
2902             const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2903             Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2904             if (aTolC < aTolE) {
2905               // reduce edge tolerance
2906               reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolC);
2907               bIsReduced = Standard_True;
2908             }
2909           }
2910         }
2911         //
2912         // fill in the map vertex index - pave blocks
2913         for (Standard_Integer j=0; j < 2; j++) {
2914           Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
2915           myDS->HasShapeSD(nV, nV);
2916           BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
2917           if (!pPBList) {
2918             pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
2919           }
2920           pPBList->Append(aPB);
2921           if (bIsReduced) {
2922             aMVIToReduce.Add(nV);
2923           }
2924         }
2925         aItLPB.Next();
2926       }
2927     }
2928   }
2929   //
2930   if (aMVIToReduce.IsEmpty()) {
2931     return;
2932   }
2933   //
2934   // 2. try to reduce tolerances of connected vertices
2935   // 2.1 find all other edges containing these connected vertices to avoid
2936   //     reducing the tolerance to the value less than the tolerances of edges,
2937   //     i.e. minimal tolerance for the vertex is the max tolerance of the
2938   //     edges containing this vertex
2939   BOPCol_DataMapOfIntegerReal aMVITol;
2940   BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2941   aNb = aPBP.Extent();
2942   for (i = 0; i < aNb; ++i) {
2943     const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2944     BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2945     for (; aItLPB.More(); aItLPB.Next()) {
2946       const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2947       Standard_Integer nE;
2948       if (!aPB->HasEdge(nE)) {
2949         continue;
2950       }
2951       const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2952       Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2953       //
2954       Standard_Integer nV[2];
2955       aPB->Indices(nV[0], nV[1]);
2956       //
2957       for (Standard_Integer j = 0; j < 2; j++) {
2958         if (aMVIToReduce.Contains(nV[j])) {
2959           Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
2960           if (!aMaxTol) {
2961             aMVITol.Bind(nV[j], aTolE);
2962           }
2963           else if (aTolE > *aMaxTol) {
2964             *aMaxTol = aTolE;
2965           }
2966         }
2967       }
2968     }
2969   }
2970   //
2971   // 2.2 reduce tolerances if possible
2972   aNb = aMVIPBs.Extent();
2973   for (i = 1; i <= aNb; ++i) {
2974     Standard_Integer nV = aMVIPBs.FindKey(i);
2975     if (!aMVIToReduce.Contains(nV)) {
2976       continue;
2977     }
2978     //
2979     const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2980     Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2981     Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
2982     // it makes no sense to compute the real tolerance if it is
2983     // impossible to reduce the tolerance at least 0.1% of the current value
2984     if (aTolV - aMaxTol < 0.001 * aTolV) {
2985       continue;
2986     }
2987     //
2988     // compute the maximal distance from the vertex to the adjacent edges
2989     gp_Pnt aP = BRep_Tool::Pnt(aV);
2990     //
2991     // Avoid repeated checks
2992     BOPDS_MapOfPaveBlock aMPBFence;
2993     //
2994     const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
2995     BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2996     for (; aItLPB.More(); aItLPB.Next()) {
2997       const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2998       if (!aMPBFence.Add(aPB)) {
2999         continue;
3000       }
3001       Standard_Integer nE = aPB->Edge();
3002       const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3003       BRepAdaptor_Curve aC(aE);
3004       for (Standard_Integer iPave = 0; iPave < 2; ++iPave) {
3005         const BOPDS_Pave& aPave = !iPave ? aPB->Pave1() : aPB->Pave2();
3006         Standard_Integer nVSD = aPave.Index();
3007         myDS->HasShapeSD(nVSD, nVSD);
3008         if (nVSD != nV) {
3009           continue;
3010         }
3011         //
3012         gp_Pnt aPonE = aC.Value(aPave.Parameter());
3013         Standard_Real aDist = aP.Distance(aPonE);
3014         aDist += BRep_Tool::Tolerance(aE);
3015         if (aDist > aMaxTol) {
3016           aMaxTol = aDist;
3017         }
3018       }
3019     }
3020     //
3021     if (aMaxTol < aTolV) {
3022       reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);
3023     }
3024   }
3025 }
3026
3027 //=======================================================================
3028 //function : PutSEInOtherFaces
3029 //purpose  : 
3030 //=======================================================================
3031 void BOPAlgo_PaveFiller::PutSEInOtherFaces()
3032 {
3033   // Try to intersect each section edge with the faces
3034   // not participated in its creation
3035   //
3036   // 1. Get all section edges
3037   BOPDS_IndexedMapOfPaveBlock aMPBScAll;
3038   //
3039   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3040   Standard_Integer i, j, aNbFF = aFFs.Extent();
3041   //
3042   for (i = 0; i < aNbFF; ++i) {
3043     const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
3044     Standard_Integer aNbC = aVNC.Extent();
3045     for (j = 0; j < aNbC; ++j) {
3046       const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
3047       BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
3048       for (; aItPB.More(); aItPB.Next()) {
3049         aMPBScAll.Add(aItPB.Value());
3050       }
3051     }
3052   }
3053   //
3054   Standard_Integer aNbPBSc = aMPBScAll.Extent();
3055   //
3056   // 2. Loop for all faces and check each section curve
3057   Standard_Integer aNbS = myDS->NbSourceShapes();
3058   for (i = 0; i < aNbS; ++i) {
3059     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
3060     if (aSI.ShapeType() != TopAbs_FACE) {
3061       continue;
3062     }
3063     //
3064     const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
3065     BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
3066     //
3067     // IN edges to add new ones
3068     BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn();
3069     // Section edges to check the participation of the face
3070     const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc();
3071     //
3072     // Get vertices of the face to check that vertices of the
3073     // processed section edge belong to the face
3074     BOPCol_MapOfInteger aMFVerts;
3075     // Get vertices from ON, IN and Sc pave blocks of the face
3076     for (j = 0; j < 3; ++j) {
3077       const BOPDS_IndexedMapOfPaveBlock& aMPB =
3078         !j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc);
3079       Standard_Integer aNbPB = aMPB.Extent();
3080       for (Standard_Integer k = 1; k <= aNbPB; ++k) {
3081         const Handle(BOPDS_PaveBlock)& aPB = aMPB(k);
3082         aMFVerts.Add(aPB->Pave1().Index());
3083         aMFVerts.Add(aPB->Pave2().Index());
3084       }
3085     }
3086     // Add ON, IN and Sc vertices of the face
3087     for (j = 0; j < 3; ++j) {
3088       const BOPCol_MapOfInteger& aMFV = !j ? aFI.VerticesOn() :
3089         (j == 1 ? aFI.VerticesIn() : aFI.VerticesSc());
3090       BOPCol_MapIteratorOfMapOfInteger aItMI(aMFV);
3091       for (; aItMI.More(); aItMI.Next()) {
3092         aMFVerts.Add(aItMI.Value());
3093       }
3094     }
3095     //
3096     // Check each section edge for possible belonging to the face
3097     for (j = 1; j <= aNbPBSc; ++j) {
3098       const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j);
3099       if (aMFPBSc.Contains(aPB)) {
3100         continue;
3101       }
3102       //
3103       // Both vertices of the section edge should belong to the face
3104       if (!aMFVerts.Contains(aPB->Pave1().Index()) ||
3105         !aMFVerts.Contains(aPB->Pave2().Index())) {
3106         continue;
3107       }
3108       //
3109       // Perform intersection
3110       const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
3111       //
3112       IntTools_EdgeFace anEFInt;
3113       anEFInt.SetEdge(aE);
3114       anEFInt.SetFace(aF);
3115       anEFInt.SetFuzzyValue(myFuzzyValue);
3116       anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
3117       anEFInt.SetContext(myContext);
3118       anEFInt.UseQuickCoincidenceCheck(Standard_True);
3119       anEFInt.Perform();
3120       //
3121       const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts();
3122       if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) {
3123         Handle(BOPDS_CommonBlock) aCB;
3124         if (myDS->IsCommonBlock(aPB)) {
3125           aCB = myDS->CommonBlock(aPB);
3126         }
3127         else {
3128           aCB = new BOPDS_CommonBlock;
3129           aCB->AddPaveBlock(aPB);
3130         }
3131         //
3132         aCB->AddFace(i);
3133         //
3134         aMFPBIn.Add(aPB);
3135       }
3136     }
3137   }
3138 }