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