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