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