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