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