0028259: Method MakeBlocksCnx is duplicated in two different places in BOPAlgo
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_7.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.hxx>
19 #include <BOPAlgo_SectionAttribute.hxx>
20 #include <BOPAlgo_Tools.hxx>
21 #include <BOPCol_IndexedMapOfShape.hxx>
22 #include <BOPCol_NCVector.hxx>
23 #include <BOPCol_Parallel.hxx>
24 #include <BOPDS_CommonBlock.hxx>
25 #include <BOPDS_Curve.hxx>
26 #include <BOPDS_DS.hxx>
27 #include <BOPDS_FaceInfo.hxx>
28 #include <BOPDS_Interf.hxx>
29 #include <BOPDS_Iterator.hxx>
30 #include <BOPDS_ListOfPaveBlock.hxx>
31 #include <BOPDS_MapOfPaveBlock.hxx>
32 #include <BOPDS_Pave.hxx>
33 #include <BOPDS_PaveBlock.hxx>
34 #include <BOPDS_ShapeInfo.hxx>
35 #include <BOPDS_VectorOfCurve.hxx>
36 #include <BOPDS_VectorOfFaceInfo.hxx>
37 #include <BOPDS_VectorOfInterfFF.hxx>
38 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
39 #include <BOPTools_AlgoTools.hxx>
40 #include <BOPTools_AlgoTools2D.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRepBndLib.hxx>
44 #include <Geom2d_Curve.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom_Plane.hxx>
47 #include <Geom_RectangularTrimmedSurface.hxx>
48 #include <Geom_Surface.hxx>
49 #include <GeomAPI_ProjectPointOnCurve.hxx>
50 #include <GeomAPI_ProjectPointOnSurf.hxx>
51 #include <gp_Pnt.hxx>
52 #include <IntTools_Context.hxx>
53 #include <IntTools_Tools.hxx>
54 #include <TopExp.hxx>
55 #include <TopExp_Explorer.hxx>
56 #include <TopoDS.hxx>
57 #include <TopoDS_Edge.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Vertex.hxx>
60
61
62 static
63   Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
64
65
66 static void UpdateVertices(const TopoDS_Edge& aE, 
67                            const TopoDS_Face& aF);
68
69 //=======================================================================
70 //class    : BOPAlgo_SplitEdge
71 //purpose  : 
72 //=======================================================================
73 class BOPAlgo_SplitEdge : public BOPAlgo_Algo  {
74  
75  public:
76   DEFINE_STANDARD_ALLOC
77
78   BOPAlgo_SplitEdge() :
79     BOPAlgo_Algo() {
80     myT1=0.;
81     myT2=0.;
82     myTol = 0.;
83   }
84   //
85   virtual ~BOPAlgo_SplitEdge() {
86   }
87   //
88   void SetData(const TopoDS_Edge& aE,
89                const TopoDS_Vertex& aV1,
90                const Standard_Real aT1,
91                const TopoDS_Vertex& aV2,
92                const Standard_Real aT2) {
93     myE=aE;
94     myV1=aV1;
95     myT1=aT1;
96     myV2=aV2;
97     myT2=aT2;
98     myESp=aE;
99   }
100   //
101   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
102     myPB=aPB;
103   }
104   //
105   Handle(BOPDS_PaveBlock)& PaveBlock() {
106     return myPB;
107   }
108   //
109   void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
110     myCB=aCB;
111   }
112   //
113   Handle(BOPDS_CommonBlock)& CommonBlock() {
114     return myCB;
115   }
116   //
117   const TopoDS_Edge& SplitEdge() const {
118     return myESp;
119   }
120   //
121   const Bnd_Box Box() {
122     return myBox;
123   }
124   //
125   Standard_Real Tolerance() const {
126     return myTol;
127   }
128   //
129   void SetDS(const BOPDS_PDS theDS) {
130     myDS = theDS;
131   }
132   //
133   void SetContext(const Handle(IntTools_Context)& aContext) {
134     myContext = aContext;
135   }
136   //
137   virtual void Perform () {
138     BOPAlgo_Algo::UserBreak();
139     myTol = BOPAlgo_Tools::ComputeToleranceOfCB(myCB, myDS, myContext);
140     BOPTools_AlgoTools::MakeSplitEdge(myE, 
141                                       myV1, myT1, 
142                                       myV2, myT2, 
143                                       myESp);
144     BRepBndLib::Add(myESp, myBox);
145     myBox.SetGap(myBox.GetGap() + Precision::Confusion());
146   }
147   //
148  protected:
149   // ->
150   TopoDS_Edge myE;
151   TopoDS_Vertex myV1;
152   Standard_Real myT1;
153   TopoDS_Vertex myV2;
154   Standard_Real myT2;
155   // <->
156   Handle(BOPDS_PaveBlock) myPB;
157   Handle(BOPDS_CommonBlock) myCB;
158   // <-
159   TopoDS_Edge myESp;
160   Bnd_Box myBox;
161   Standard_Real myTol;
162   //
163   BOPDS_PDS   myDS;
164   Handle(IntTools_Context) myContext;
165 };
166 //
167 //=======================================================================
168 typedef BOPCol_NCVector
169   <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; 
170 //
171 typedef BOPCol_ContextFunctor
172   <BOPAlgo_SplitEdge,
173   BOPAlgo_VectorOfSplitEdge,
174   Handle(IntTools_Context),
175   IntTools_Context> BOPAlgo_SplitEdgeFunctor;
176 //
177 typedef BOPCol_ContextCnt
178   <BOPAlgo_SplitEdgeFunctor,
179   BOPAlgo_VectorOfSplitEdge,
180   Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt;
181 //
182 //=======================================================================
183 //class    : BOPAlgo_MPC
184 //purpose  : 
185 //=======================================================================
186 class BOPAlgo_MPC : public BOPAlgo_Algo  {
187  
188  public:
189   DEFINE_STANDARD_ALLOC
190
191   BOPAlgo_MPC() : 
192     BOPAlgo_Algo(),
193     myFlag(Standard_False) {
194   };
195   //
196   virtual ~BOPAlgo_MPC(){
197   };
198   //
199   void SetEdge(const TopoDS_Edge& aE) {
200     myE=aE;
201   }
202   //
203   const TopoDS_Edge& Edge() const {
204     return myE;
205   }
206   //
207   void SetFace(const TopoDS_Face& aF) {
208     myF=aF;
209   }
210   //
211   const TopoDS_Face& Face() const {
212     return myF;
213   }
214   //
215   void SetFlag(const Standard_Boolean bFlag) {
216     myFlag=bFlag;
217   }
218   //
219   Standard_Boolean Flag() const {
220     return myFlag;
221   }
222   //
223   void SetData(const TopoDS_Edge& aEz,
224                const TopoDS_Vertex& aV1,
225                const Standard_Real aT1,
226                const TopoDS_Vertex& aV2,
227                const Standard_Real aT2) {
228     myEz=aEz;
229     myV1=aV1;
230     myT1=aT1;
231     myV2=aV2;
232     myT2=aT2;
233   }
234   //
235   void SetContext(const Handle(IntTools_Context)& aContext) {
236     myContext=aContext;
237   }
238   //
239   const Handle(IntTools_Context)& Context()const {
240     return myContext;
241   }
242   //
243   virtual void Perform() {
244     Standard_Integer iErr;
245     //
246     iErr=1;
247     if (!myEz.IsNull()) {
248       TopoDS_Edge aSpz;
249       //
250       BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, 
251                                         myV2, myT2, aSpz);
252       //
253       iErr=
254         BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, 
255                                                    myE, 
256                                                    myF, 
257                                                    myContext);
258     }
259     //
260     if (iErr) { 
261       BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF, myContext);
262     }
263     // 
264     if (myFlag) {
265       UpdateVertices(myE, myF);
266     }
267   }
268   //
269  protected:
270   Standard_Boolean myFlag;
271   TopoDS_Edge myE;
272   TopoDS_Face myF;
273   TopoDS_Edge myEz;
274   TopoDS_Vertex myV1;
275   Standard_Real myT1;
276   TopoDS_Vertex myV2;
277   Standard_Real myT2;
278   //
279   Handle(IntTools_Context) myContext;
280 };
281 //
282 //=======================================================================
283 typedef BOPCol_NCVector
284   <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; 
285 //
286 typedef BOPCol_ContextFunctor 
287   <BOPAlgo_MPC,
288   BOPAlgo_VectorOfMPC,
289   Handle(IntTools_Context), 
290   IntTools_Context> BOPAlgo_MPCFunctor;
291 //
292 typedef BOPCol_ContextCnt 
293   <BOPAlgo_MPCFunctor,
294   BOPAlgo_VectorOfMPC,
295   Handle(IntTools_Context)> BOPAlgo_MPCCnt;
296 //
297 //=======================================================================
298 //class    : BOPAlgo_BPC
299 //purpose  : 
300 //=======================================================================
301 class BOPAlgo_BPC {
302  public:
303   BOPAlgo_BPC(){
304   };
305   //
306   ~BOPAlgo_BPC(){
307   };
308   //
309   void SetFace(const TopoDS_Face& aF) {
310     myF=aF;
311   }
312   //
313   void SetEdge(const TopoDS_Edge& aE) {
314     myE=aE;
315   }
316   //
317   const TopoDS_Edge& GetEdge() const {
318     return myE;
319   }
320   const TopoDS_Face& GetFace() const {
321     return myF;
322   }
323   const Handle(Geom2d_Curve)& GetCurve2d() const {
324     return myCurve;
325   }
326   Standard_Boolean IsToUpdate() const {
327     return myToUpdate;
328   }
329   //
330   void Perform() {
331     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF, myCurve, myToUpdate);
332   };
333   //
334  protected:
335   TopoDS_Edge myE;
336   TopoDS_Face myF;
337   Handle(Geom2d_Curve) myCurve;
338   Standard_Boolean myToUpdate;
339 };
340 //=======================================================================
341 typedef BOPCol_NCVector
342   <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; 
343 //
344 typedef BOPCol_Functor 
345   <BOPAlgo_BPC,
346   BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
347 //
348 typedef BOPCol_Cnt 
349   <BOPAlgo_BPCFunctor,
350   BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
351 //
352 //
353 //=======================================================================
354 // function: MakeSplitEdges
355 // purpose: 
356 //=======================================================================
357 void BOPAlgo_PaveFiller::MakeSplitEdges()
358 {
359   Standard_Integer aNbPBP;
360   //
361   myErrorStatus=0;
362   //
363   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
364   aNbPBP=aPBP.Extent();
365   if(!aNbPBP) {
366     return;
367   }
368   //
369   Standard_Boolean bCB, bV1, bV2;
370   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
371   Standard_Real aT1, aT2;
372   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
373   Handle(BOPDS_PaveBlock) aPB;
374   BOPDS_MapOfPaveBlock aMPB(100);
375   TopoDS_Vertex aV1, aV2;
376   TopoDS_Edge aE;
377   BOPAlgo_VectorOfSplitEdge aVBSE;
378   
379   //
380   UpdateCommonBlocksWithSDVertices();
381   //
382   aNbPBP=aPBP.Extent();
383   //
384   for (i=0; i<aNbPBP; ++i) {
385     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
386     //
387     aNbPB=aLPB.Extent();
388     if (aNbPB==1) {
389       aPB=aLPB.First();
390       aPB->Indices(nV1, nV2);
391       bV1=myDS->IsNewShape(nV1);
392       bV2=myDS->IsNewShape(nV2);
393       bCB=myDS->IsCommonBlock(aPB);
394       //
395       if (!(bV1 || bV2)) { // no new vertices here
396         if (!myNonDestructive || !bCB) {
397           if (bCB) {
398             if (!aPB->HasEdge()) {
399               const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
400               nE = aCB->PaveBlock1()->OriginalEdge();
401               aCB->SetEdge(nE);
402               // Compute tolerance of the common block and update the edge
403               Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
404               myDS->UpdateEdgeTolerance(nE, aTol);
405             }
406           }
407           else {
408             nE = aPB->OriginalEdge();
409             aPB->SetEdge(nE);
410           }
411           continue;
412         }
413       }
414     }
415     //
416     aItPB.Initialize(aLPB);
417     for (; aItPB.More(); aItPB.Next()) {
418       aPB=aItPB.Value();
419       nE=aPB->OriginalEdge();
420       const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
421       if (aSIE.HasFlag()){
422         continue;
423       }
424       //
425       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
426       bCB=!aCB.IsNull();
427       if (bCB) {
428         aPB=aCB->PaveBlock1();
429       }
430       //
431       if (aMPB.Add(aPB)) {
432         nE=aPB->OriginalEdge();
433         aPB->Indices(nV1, nV2);
434         aPB->Range(aT1, aT2);
435         //
436         aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
437         aE.Orientation(TopAbs_FORWARD);
438         //
439         aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
440         aV1.Orientation(TopAbs_FORWARD); 
441         //
442         aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
443         aV2.Orientation(TopAbs_REVERSED); 
444         //
445         BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
446         //
447         aBSE.SetData(aE, aV1, aT1, aV2, aT2);
448         aBSE.SetPaveBlock(aPB);
449         if (bCB) {
450           aBSE.SetCommonBlock(aCB);
451         }
452         aBSE.SetDS(myDS);
453         aBSE.SetProgressIndicator(myProgressIndicator);
454       }
455     } // for (; aItPB.More(); aItPB.Next()) {
456   }  // for (i=0; i<aNbPBP; ++i) {      
457   //
458   aNbVBSE=aVBSE.Extent();
459   //======================================================
460   BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
461   //======================================================
462   //
463   BOPDS_ShapeInfo aSI;
464   //
465   aSI.SetShapeType(TopAbs_EDGE);
466   //
467   for (k=0; k < aNbVBSE; ++k) {
468     BOPAlgo_SplitEdge& aBSE=aVBSE(k);
469     //
470     const TopoDS_Edge& aSp=aBSE.SplitEdge();
471     const Bnd_Box& aBox=aBSE.Box();
472     //
473     Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
474     Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
475     //
476     aSI.SetShape(aSp);
477     aSI.ChangeBox()=aBox;
478     //
479     nSp=myDS->Append(aSI);
480     //
481     if (!aCBk.IsNull()) {
482       myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance());
483       aCBk->SetEdge(nSp);
484     }
485     else {
486       aPBk->SetEdge(nSp);
487     }
488   }
489 }
490
491 //=======================================================================
492 // function: SplitEdge
493 // purpose: 
494 //=======================================================================
495 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
496                                                const Standard_Integer nV1,
497                                                const Standard_Real aT1, 
498                                                const Standard_Integer nV2, 
499                                                const Standard_Real aT2)
500 {
501   Standard_Integer nSp;
502   TopoDS_Vertex aV1, aV2;
503   TopoDS_Edge aE, aSp;
504   BOPDS_ShapeInfo aSI;
505   //
506   aSI.SetShapeType(TopAbs_EDGE);
507   //
508   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
509   aE.Orientation(TopAbs_FORWARD);
510   //
511   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
512   aV1.Orientation(TopAbs_FORWARD); 
513   //
514   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
515   aV2.Orientation(TopAbs_REVERSED); 
516   //
517   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
518   //
519   aSI.SetShape(aSp);
520   //
521   Bnd_Box& aBox=aSI.ChangeBox();
522   BRepBndLib::Add(aSp, aBox);
523   aBox.SetGap(aBox.GetGap() + Precision::Confusion());
524   //
525   nSp=myDS->Append(aSI);
526   return nSp;
527 }
528 //=======================================================================
529 // function: MakePCurves
530 // purpose: 
531 //=======================================================================
532 void BOPAlgo_PaveFiller::MakePCurves()
533 {
534   if (myAvoidBuildPCurve ||
535       (!mySectionAttribute.PCurveOnS1() && !mySectionAttribute.PCurveOnS2()))
536     return;
537   Standard_Boolean bHasPC;
538   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx;
539   Standard_Integer j, aNbPBIn, aNbPBOn;
540   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
541   TopoDS_Face aF1F, aF2F;
542   BOPAlgo_VectorOfMPC aVMPC;
543   //
544   myErrorStatus=0;
545   //
546   // 1. Process Common Blocks 
547   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
548   //
549   aNbFI=aFIP.Extent();
550   for (i=0; i<aNbFI; ++i) {
551     const BOPDS_FaceInfo& aFI=aFIP(i);
552     nF1=aFI.Index();
553     //
554     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
555     aF1F.Orientation(TopAbs_FORWARD);
556     // In
557     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
558     aNbPBIn = aMPBIn.Extent();
559     for (j = 1; j <= aNbPBIn; ++j) {
560       const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j);
561       nE=aPB->Edge();
562       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
563       //
564       BOPAlgo_MPC& aMPC=aVMPC.Append1();
565       aMPC.SetEdge(aE);
566       aMPC.SetFace(aF1F);
567       aMPC.SetProgressIndicator(myProgressIndicator);
568     }
569     //
570     // On
571     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
572     aNbPBOn = aMPBOn.Extent();
573     for (j = 1; j <= aNbPBOn; ++j) {
574       const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j);
575       nE=aPB->Edge();
576       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
577       bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
578       if (bHasPC) {
579         continue;
580       }
581       //
582       Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
583       if (aCB.IsNull()) {
584         continue;
585       }
586       //
587       const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
588       if (aLPB.Extent()<2) {
589         continue;
590       }
591       //
592       BOPAlgo_MPC& aMPC=aVMPC.Append1();
593       //
594       aItLPB.Initialize(aLPB);
595       for(; aItLPB.More(); aItLPB.Next()) {
596         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
597         if (aPBx==aPB) {
598           continue;
599         }
600         //
601         nEx=aPBx->OriginalEdge();
602         const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx))); 
603         bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
604         if (!bHasPC) {
605           continue;
606         }
607         //
608         Standard_Integer nV1x, nV2x;
609         Standard_Real aT1x, aT2x;
610         TopoDS_Vertex aV1x, aV2x;
611         TopoDS_Edge aEz;
612         //
613         aEz=aEx;
614         aEz.Orientation(TopAbs_FORWARD);
615         //
616         aPBx->Indices(nV1x, nV2x);
617         aPBx->Range(aT1x, aT2x);
618         //
619         aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
620         aV1x.Orientation(TopAbs_FORWARD); 
621         //
622         aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
623         aV2x.Orientation(TopAbs_REVERSED); 
624         //
625         aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
626         //
627         break;
628       }
629       //
630       aMPC.SetEdge(aE);
631       aMPC.SetFace(aF1F);
632       aMPC.SetProgressIndicator(myProgressIndicator);
633     }
634   }// for (i=0; i<aNbFI; ++i) {
635   //
636   // 2. Process section edges
637   Standard_Boolean bPCurveOnS[2];
638   Standard_Integer m;
639   TopoDS_Face aFf[2];
640   //
641   bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
642   bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
643   //
644   if (bPCurveOnS[0] || bPCurveOnS[1]) {
645     BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
646     aNbFF=aFFs.Extent();
647     for (i=0; i<aNbFF; ++i) {
648       const BOPDS_InterfFF& aFF=aFFs(i);
649       aFF.Indices(nF1, nF2);
650       //
651       aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
652       aFf[0].Orientation(TopAbs_FORWARD);
653       //
654       aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
655       aFf[1].Orientation(TopAbs_FORWARD);
656       //
657       const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
658       aNbC=aVNC.Extent();
659       for (k=0; k<aNbC; ++k) {
660         const BOPDS_Curve& aNC=aVNC(k);
661         const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
662         aItLPB.Initialize(aLPB);
663         for(; aItLPB.More(); aItLPB.Next()) {
664           const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
665           nE=aPB->Edge();
666           const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
667           //
668           for (m=0; m<2; ++m) {
669             if (bPCurveOnS[m]) {
670               BOPAlgo_MPC& aMPC=aVMPC.Append1();
671               aMPC.SetEdge(aE);
672               aMPC.SetFace(aFf[m]);
673               aMPC.SetFlag(bPCurveOnS[m]);
674               aMPC.SetProgressIndicator(myProgressIndicator);
675             }
676           }
677         }
678       }
679     }// for (i=0; i<aNbFF; ++i) {
680   }//if (bPCurveOnS1 || bPCurveOnS2 ) {
681   //
682   //======================================================
683   BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
684   //======================================================
685 }
686 //=======================================================================
687 //function : UpdateVertices
688 //purpose  : update tolerances of vertices comparing extremities of
689 //           3d and 2d curves
690 //=======================================================================
691 void UpdateVertices(const TopoDS_Edge& aE, 
692                     const TopoDS_Face& aF)
693 {
694   Standard_Integer j;
695   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
696   gp_Pnt aP3D, aP3Dx;
697   gp_Pnt2d aP2Dx;
698   Handle(Geom_Surface) aS;
699   Handle(Geom_Curve) aC3D;
700   Handle(Geom2d_Curve) aC2D;
701   TopoDS_Edge aEf;
702   TopoDS_Vertex aV[2];
703   BRep_Builder aBB;
704   //
705   aEf=aE;
706   aEf.Orientation(TopAbs_FORWARD);
707   //
708   TopExp::Vertices(aEf, aV[0], aV[1]);
709   //
710   aS=BRep_Tool::Surface(aF);
711   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
712   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
713   //
714   for (j=0; j<2; ++j) {
715     aTolV2=BRep_Tool::Tolerance(aV[j]);
716     aTolV2=aTolV2*aTolV2;
717     //
718     aC3D->D0(aT[j], aP3D);
719     aC2D->D0(aT[j], aP2Dx);
720     aP2Dx.Coord(aUx, aVx);
721     aS->D0(aUx, aVx, aP3Dx);
722     aD2=aP3D.SquareDistance(aP3Dx);
723     if (aD2>aTolV2) {
724       aD=sqrt(aD2);
725       aBB.UpdateVertex(aV[j], aD);
726     }
727   }
728 }
729 //=======================================================================
730 // function: Prepare
731 // purpose: 
732 //=======================================================================
733 void BOPAlgo_PaveFiller::Prepare()
734 {
735   if (myNonDestructive) {
736     // do not allow storing pcurves in original edges if non-destructive mode is on
737     return;
738   }
739   TopAbs_ShapeEnum aType[] = {
740     TopAbs_VERTEX,
741     TopAbs_EDGE,
742     TopAbs_FACE
743   };
744   Standard_Boolean bIsBasedOnPlane;
745   Standard_Integer i, aNb, n1, nF, aNbF;
746   TopExp_Explorer aExp;
747   BOPCol_IndexedMapOfShape aMF;
748   //
749   myErrorStatus=0;
750   //
751   aNb=3;
752   for(i=0; i<aNb; ++i) {
753     myIterator->Initialize(aType[i], aType[2]);
754     for (; myIterator->More(); myIterator->Next()) {
755       myIterator->Value(n1, nF);
756       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
757       //
758       bIsBasedOnPlane=IsBasedOnPlane(aF);
759       if (bIsBasedOnPlane) {
760         aMF.Add(aF);
761       }
762     }
763   }
764   //
765   aNbF = aMF.Extent();
766   if (!aNbF) {
767     return;
768   }
769   //
770   // Build pcurves of edges on planes; first collect pairs edge-face.
771   BOPAlgo_VectorOfBPC aVBPC;
772   //
773   for (i = 1; i <= aNbF; ++i) {
774     const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i);
775     aExp.Init(aF, aType[1]);
776     for (; aExp.More(); aExp.Next()) {
777       const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
778       BOPAlgo_BPC& aBPC=aVBPC.Append1();
779       aBPC.SetEdge(aE);
780       aBPC.SetFace(aF);
781     }
782   }
783   //
784   //======================================================
785   BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
786   //======================================================
787
788   // pcurves are built, and now update edges
789   BRep_Builder aBB;
790   TopoDS_Edge E;
791   for (i = 0; i < aVBPC.Extent(); i++) {
792     const BOPAlgo_BPC& aBPC=aVBPC(i);
793     if (aBPC.IsToUpdate()) {
794       Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge());
795       aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE);
796     }
797   }
798 }
799 //=======================================================================
800 //function : IsBasedOnPlane
801 //purpose  : 
802 //=======================================================================
803 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
804 {
805   TopLoc_Location aLoc; 
806   Handle(Geom_RectangularTrimmedSurface) aGRTS;
807   Handle(Geom_Plane) aGP;
808   
809   const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
810   aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
811   if(!aGRTS.IsNull()) {
812     aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
813   }
814   else {
815     aGP = Handle(Geom_Plane)::DownCast(aS);
816   }
817   //
818   return (!aGP.IsNull()); 
819 }