0024952: Possibility to break Boolean operations algorithm by user request
[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.ixx>
19
20 #include <NCollection_IncAllocator.hxx>
21
22 #include <Geom_RectangularTrimmedSurface.hxx>
23 #include <Geom_Plane.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Geom_RectangularTrimmedSurface.hxx>
26
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30
31 #include <BRepBndLib.hxx>
32
33 #include <BRep_Tool.hxx>
34 #include <BRep_Builder.hxx>
35
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38
39 #include <Geom_Curve.hxx>
40 #include <Geom_Surface.hxx>
41 #include <Geom2d_Curve.hxx>
42
43 #include <BOPCol_NCVector.hxx>
44 #include <BOPCol_TBB.hxx>
45 #include <BOPCol_MapOfShape.hxx>
46
47 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
48 #include <BOPDS_ListOfPaveBlock.hxx>
49 #include <BOPDS_PaveBlock.hxx>
50 #include <BOPDS_CommonBlock.hxx>
51 #include <BOPDS_Pave.hxx>
52 #include <BOPDS_ShapeInfo.hxx>
53 #include <BOPDS_MapOfPaveBlock.hxx>
54 #include <BOPDS_VectorOfInterfFF.hxx>
55 #include <BOPDS_Interf.hxx>
56 #include <BOPDS_VectorOfCurve.hxx>
57 #include <BOPDS_VectorOfFaceInfo.hxx>
58 #include <BOPDS_FaceInfo.hxx>
59 #include <BOPDS_MapOfPaveBlock.hxx>
60 #include <BOPDS_Curve.hxx>
61 #include <BOPDS_Iterator.hxx>
62
63 #include <BOPTools_AlgoTools.hxx>
64 #include <BOPTools_AlgoTools2D.hxx>
65
66 static
67   Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
68
69
70 static void UpdateVertices(const TopoDS_Edge& aE, 
71                            const TopoDS_Face& aF);
72
73 //=======================================================================
74 //class    : BOPAlgo_SplitEdge
75 //purpose  : 
76 //=======================================================================
77 class BOPAlgo_SplitEdge : public BOPAlgo_Algo  {
78  
79  public:
80   DEFINE_STANDARD_ALLOC
81
82   BOPAlgo_SplitEdge() :
83     BOPAlgo_Algo() {
84     myT1=0.;
85     myT2=0.;
86   }
87   //
88   virtual ~BOPAlgo_SplitEdge() {
89   }
90   //
91   void SetData(const TopoDS_Edge& aE,
92                const TopoDS_Vertex& aV1,
93                const Standard_Real aT1,
94                const TopoDS_Vertex& aV2,
95                const Standard_Real aT2) {
96     myE=aE;
97     myV1=aV1;
98     myT1=aT1;
99     myV2=aV2;
100     myT2=aT2;
101     myESp=aE;
102   }
103   //
104   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
105     myPB=aPB;
106   }
107   //
108   Handle(BOPDS_PaveBlock)& PaveBlock() {
109     return myPB;
110   }
111   //
112   void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
113     myCB=aCB;
114   }
115   //
116   Handle(BOPDS_CommonBlock)& CommonBlock() {
117     return myCB;
118   }
119   //
120   const TopoDS_Edge& SplitEdge() const {
121     return myESp;
122   }
123   //
124   const Bnd_Box Box() {
125     return myBox;
126   }
127   //
128   virtual void Perform () {
129     BOPAlgo_Algo::UserBreak();
130     BOPTools_AlgoTools::MakeSplitEdge(myE, 
131                                       myV1, myT1, 
132                                       myV2, myT2, 
133                                       myESp);
134     BRepBndLib::Add(myESp, myBox);  
135   }
136   //
137  protected:
138   // ->
139   TopoDS_Edge myE;
140   TopoDS_Vertex myV1;
141   Standard_Real myT1;
142   TopoDS_Vertex myV2;
143   Standard_Real myT2;
144   // <->
145   Handle(BOPDS_PaveBlock) myPB;
146   Handle(BOPDS_CommonBlock) myCB;
147   // <-
148   TopoDS_Edge myESp;
149   Bnd_Box myBox;
150 };
151 //
152 //=======================================================================
153 typedef BOPCol_NCVector
154   <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; 
155 //
156 typedef BOPCol_TBBFunctor 
157   <BOPAlgo_SplitEdge,
158   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
159 //
160 typedef BOPCol_TBBCnt 
161   <BOPAlgo_SplitEdgeFunctor,
162   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
163 //
164 //=======================================================================
165 //class    : BOPAlgo_MPC
166 //purpose  : 
167 //=======================================================================
168 class BOPAlgo_MPC : public BOPAlgo_Algo  {
169  
170  public:
171   DEFINE_STANDARD_ALLOC
172
173   BOPAlgo_MPC() : 
174     BOPAlgo_Algo(),
175     myFlag(Standard_False) {
176   };
177   //
178   virtual ~BOPAlgo_MPC(){
179   };
180   //
181   void SetEdge(const TopoDS_Edge& aE) {
182     myE=aE;
183   }
184   //
185   const TopoDS_Edge& Edge() const {
186     return myE;
187   }
188   //
189   void SetFace(const TopoDS_Face& aF) {
190     myF=aF;
191   }
192   //
193   const TopoDS_Face& Face() const {
194     return myF;
195   }
196   //
197   void SetFlag(const Standard_Boolean bFlag) {
198     myFlag=bFlag;
199   }
200   //
201   Standard_Boolean Flag() const {
202     return myFlag;
203   }
204   //
205   virtual void Perform() {
206     BOPAlgo_Algo::UserBreak();
207     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF);
208     if (myFlag) {
209       UpdateVertices(myE, myF);
210     }
211   }
212   //
213  protected:
214   Standard_Boolean myFlag;
215   TopoDS_Edge myE;
216   TopoDS_Face myF;
217 };
218 //
219 //=======================================================================
220 typedef BOPCol_NCVector
221   <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; 
222 //
223 typedef BOPCol_TBBFunctor 
224   <BOPAlgo_MPC,
225   BOPAlgo_VectorOfMPC> BOPAlgo_MPCFunctor;
226 //
227 typedef BOPCol_TBBCnt 
228   <BOPAlgo_MPCFunctor,
229   BOPAlgo_VectorOfMPC> BOPAlgo_MPCCnt;
230 //
231 //=======================================================================
232 //class    : BOPAlgo_BPC
233 //purpose  : 
234 //=======================================================================
235 class BOPAlgo_BPC {
236  public:
237   BOPAlgo_BPC(){
238   };
239   //
240   ~BOPAlgo_BPC(){
241   };
242   //
243   void SetFace(const TopoDS_Face& aF) {
244     myF=aF;
245   }
246   //
247   void SetEdge(const TopoDS_Edge& aE) {
248     myE=aE;
249   }
250   //
251   void Perform() {
252     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF);
253   };
254   //
255  protected:
256   TopoDS_Edge myE;
257   TopoDS_Face myF;
258 };
259 //=======================================================================
260 typedef BOPCol_NCVector
261   <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; 
262 //
263 typedef BOPCol_TBBFunctor 
264   <BOPAlgo_BPC,
265   BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
266 //
267 typedef BOPCol_TBBCnt 
268   <BOPAlgo_BPCFunctor,
269   BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
270 //
271 //
272 //=======================================================================
273 // function: MakeSplitEdges
274 // purpose: 
275 //=======================================================================
276 void BOPAlgo_PaveFiller::MakeSplitEdges()
277 {
278   Standard_Integer aNbPBP;
279   //
280   myErrorStatus=0;
281   //
282   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
283   aNbPBP=aPBP.Extent();
284   if(!aNbPBP) {
285     return;
286   }
287   //
288   Standard_Boolean bCB, bV1, bV2;
289   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
290   Standard_Real aT1, aT2;
291   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
292   Handle(BOPDS_PaveBlock) aPB;
293   BOPDS_MapOfPaveBlock aMPB(100);
294   TopoDS_Vertex aV1, aV2;
295   TopoDS_Edge aE;
296   BOPAlgo_VectorOfSplitEdge aVBSE;
297   
298   //
299   for (i=0; i<aNbPBP; ++i) {
300     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
301     //
302     aNbPB=aLPB.Extent();
303     if (aNbPB==1) {
304       aPB=aLPB.First();
305       aPB->Indices(nV1, nV2);
306       bV1=myDS->IsNewShape(nV1);
307       bV2=myDS->IsNewShape(nV2);
308       //
309       if (!(bV1 || bV2)) {
310         nE=aPB->OriginalEdge();
311         aPB->SetEdge(nE);
312         continue;
313       }
314     }
315     //
316     aItPB.Initialize(aLPB);
317     for (; aItPB.More(); aItPB.Next()) {
318       aPB=aItPB.Value();
319       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
320       bCB=!aCB.IsNull();
321       if (bCB) {
322         myDS->SortPaveBlocks(aCB);
323         aPB=aCB->PaveBlock1();
324       }
325       //
326       if (aMPB.Add(aPB)) {
327         nE=aPB->OriginalEdge();
328         aPB->Indices(nV1, nV2);
329         aPB->Range(aT1, aT2);
330         //
331         aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
332         aE.Orientation(TopAbs_FORWARD);
333         //
334         aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
335         aV1.Orientation(TopAbs_FORWARD); 
336         //
337         aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
338         aV2.Orientation(TopAbs_REVERSED); 
339         //
340         BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
341         //
342         aBSE.SetData(aE, aV1, aT1, aV2, aT2);
343         aBSE.SetPaveBlock(aPB);
344         if (bCB) {
345           aBSE.SetCommonBlock(aCB);
346         }
347         aBSE.SetProgressIndicator(myProgressIndicator);
348       }
349     } // for (; aItPB.More(); aItPB.Next()) {
350   }  // for (i=0; i<aNbPBP; ++i) {      
351   //
352   aNbVBSE=aVBSE.Extent();
353   //======================================================
354   BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
355   //======================================================
356   //
357   BOPDS_ShapeInfo aSI;
358   //
359   aSI.SetShapeType(TopAbs_EDGE);
360   //
361   for (k=0; k < aNbVBSE; ++k) {
362     BOPAlgo_SplitEdge& aBSE=aVBSE(k);
363     //
364     const TopoDS_Edge& aSp=aBSE.SplitEdge();
365     const Bnd_Box& aBox=aBSE.Box();
366     //
367     Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
368     Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
369     //
370     aSI.SetShape(aSp);
371     aSI.ChangeBox()=aBox;
372     //
373     nSp=myDS->Append(aSI);
374     //
375     if (!aCBk.IsNull()) {
376       aCBk->SetEdge(nSp);
377     }
378     else {
379       aPBk->SetEdge(nSp);
380     }
381   }
382 }
383 //=======================================================================
384 // function: SplitEdge
385 // purpose: 
386 //=======================================================================
387 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
388                                                const Standard_Integer nV1,
389                                                const Standard_Real aT1, 
390                                                const Standard_Integer nV2, 
391                                                const Standard_Real aT2)
392 {
393   Standard_Integer nSp;
394   TopoDS_Vertex aV1, aV2;
395   TopoDS_Edge aE, aSp;
396   BOPDS_ShapeInfo aSI;
397   //
398   aSI.SetShapeType(TopAbs_EDGE);
399   //
400   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
401   aE.Orientation(TopAbs_FORWARD);
402   //
403   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
404   aV1.Orientation(TopAbs_FORWARD); 
405   //
406   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
407   aV2.Orientation(TopAbs_REVERSED); 
408   //
409   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
410   //
411   aSI.SetShape(aSp);
412   //
413   Bnd_Box& aBox=aSI.ChangeBox();
414   BRepBndLib::Add(aSp, aBox);
415   //
416   nSp=myDS->Append(aSI);
417   return nSp;
418 }
419 //=======================================================================
420 // function: MakePCurves
421 // purpose: 
422 //=======================================================================
423 void BOPAlgo_PaveFiller::MakePCurves()
424 {
425   
426   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI;
427   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
428   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
429   TopoDS_Face aF1F, aF2F;
430   BOPAlgo_VectorOfMPC aVMPC;
431   //
432   myErrorStatus=0;
433   //
434   // 1. Process Common Blocks 
435   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
436   //
437   aNbFI=aFIP.Extent();
438   for (i=0; i<aNbFI; ++i) {
439     const BOPDS_FaceInfo& aFI=aFIP(i);
440     nF1=aFI.Index();
441     //
442     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
443     aF1F.Orientation(TopAbs_FORWARD);
444     // In
445     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
446     aItMPB.Initialize(aMPBIn);
447     for(; aItMPB.More(); aItMPB.Next()) {
448       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
449       nE=aPB->Edge();
450       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
451       //
452       BOPAlgo_MPC& aMPC=aVMPC.Append1();
453       aMPC.SetEdge(aE);
454       aMPC.SetFace(aF1F);
455       aMPC.SetProgressIndicator(myProgressIndicator);
456     }
457     //
458     // On
459     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
460     aItMPB.Initialize(aMPBOn);
461     for(; aItMPB.More(); aItMPB.Next()) {
462       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
463       if (myDS->IsCommonBlockOnEdge(aPB)) {
464         nE=aPB->Edge();
465         const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
466         //
467         BOPAlgo_MPC& aMPC=aVMPC.Append1();
468         aMPC.SetEdge(aE);
469         aMPC.SetFace(aF1F);
470         aMPC.SetProgressIndicator(myProgressIndicator);
471       }
472     }
473   }// for (i=0; i<aNbFI; ++i) {
474   //
475   // 2. Process section edges
476   Standard_Boolean bPCurveOnS[2];
477   Standard_Integer m;
478   TopoDS_Face aFf[2];
479   //
480   bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
481   bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
482   //
483   if (bPCurveOnS[0] || bPCurveOnS[1]) {
484     BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
485     aNbFF=aFFs.Extent();
486     for (i=0; i<aNbFF; ++i) {
487       const BOPDS_InterfFF& aFF=aFFs(i);
488       aFF.Indices(nF1, nF2);
489       //
490       aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
491       aFf[0].Orientation(TopAbs_FORWARD);
492       //
493       aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
494       aFf[1].Orientation(TopAbs_FORWARD);
495       //
496       const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
497       aNbC=aVNC.Extent();
498       for (k=0; k<aNbC; ++k) {
499         const BOPDS_Curve& aNC=aVNC(k);
500         const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
501         aItLPB.Initialize(aLPB);
502         for(; aItLPB.More(); aItLPB.Next()) {
503           const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
504           nE=aPB->Edge();
505           const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
506           //
507           for (m=0; m<2; ++m) {
508             if (bPCurveOnS[m]) {
509               BOPAlgo_MPC& aMPC=aVMPC.Append1();
510               aMPC.SetEdge(aE);
511               aMPC.SetFace(aFf[m]);
512               aMPC.SetFlag(bPCurveOnS[m]);
513               aMPC.SetProgressIndicator(myProgressIndicator);
514             }
515           }
516         }
517       }
518     }// for (i=0; i<aNbFF; ++i) {
519   }//if (bPCurveOnS1 || bPCurveOnS2 ) {
520   //
521   //======================================================
522   BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC);
523   //======================================================
524 }
525 //=======================================================================
526 // function: RefineFaceInfoOn
527 // purpose: 
528 //=======================================================================
529 void BOPAlgo_PaveFiller::RefineFaceInfoOn() 
530 {
531   Standard_Integer aNbPBP;
532   //
533   myErrorStatus=0;
534   //
535   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
536   aNbPBP=aPBP.Extent();
537   if(!aNbPBP) {
538     return;
539   }
540   //
541   Standard_Boolean bV1, bV2;
542   Standard_Integer i, nV1, nV2, aNbPB;
543   Handle(BOPDS_PaveBlock) aPB;
544   //
545   for (i=0; i<aNbPBP; ++i) {
546     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
547     //
548     aNbPB=aLPB.Extent();
549     if (aNbPB==1) {
550       aPB=aLPB.First();
551       aPB->Indices(nV1, nV2);
552       bV1=myDS->IsNewShape(nV1);
553       bV2=myDS->IsNewShape(nV2);
554       //
555       if (!(bV1 || bV2)) {
556         if (!myDS->IsCommonBlock(aPB)) {
557           // the PB seems to be untouced
558           aLPB.Clear();
559           continue;
560         }
561       }//if (!(bV1 || bV2)) {
562     }//if (aNbPB==1) {
563   }//for (i=0; i<aNbPBP; ++i) {
564   myDS->RefineFaceInfoOn();
565 }
566 //=======================================================================
567 //function : UpdateVertices
568 //purpose  : update tolerances of vertices comparing extremities of
569 //           3d and 2d curves
570 //=======================================================================
571 void UpdateVertices(const TopoDS_Edge& aE, 
572                     const TopoDS_Face& aF)
573 {
574   Standard_Integer j;
575   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
576   gp_Pnt aP3D, aP3Dx;
577   gp_Pnt2d aP2Dx;
578   Handle(Geom_Surface) aS;
579   Handle(Geom_Curve) aC3D;
580   Handle(Geom2d_Curve) aC2D;
581   TopoDS_Edge aEf;
582   TopoDS_Vertex aV[2];
583   BRep_Builder aBB;
584   //
585   aEf=aE;
586   aEf.Orientation(TopAbs_FORWARD);
587   //
588   TopExp::Vertices(aEf, aV[0], aV[1]);
589   //
590   aS=BRep_Tool::Surface(aF);
591   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
592   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
593   //
594   for (j=0; j<2; ++j) {
595     aTolV2=BRep_Tool::Tolerance(aV[j]);
596     aTolV2=aTolV2*aTolV2;
597     //
598     aC3D->D0(aT[j], aP3D);
599     aC2D->D0(aT[j], aP2Dx);
600     aP2Dx.Coord(aUx, aVx);
601     aS->D0(aUx, aVx, aP3Dx);
602     aD2=aP3D.SquareDistance(aP3Dx);
603     if (aD2>aTolV2) {
604       aD=sqrt(aD2);
605       aBB.UpdateVertex(aV[j], aD);
606     }
607   }
608 }
609 //=======================================================================
610 // function: Prepare
611 // purpose: 
612 //=======================================================================
613 void BOPAlgo_PaveFiller::Prepare()
614 {
615   TopAbs_ShapeEnum aType[] = {
616     TopAbs_VERTEX,
617     TopAbs_EDGE,
618     TopAbs_FACE
619   };
620   Standard_Boolean bJustAdd, bIsBasedOnPlane;
621   Standard_Integer i, aNb, n1, nF;
622   TopExp_Explorer aExp;
623   BOPCol_MapOfShape aMF;
624   BOPCol_MapIteratorOfMapOfShape aItMF;
625   //
626   myErrorStatus=0;
627   //
628   aNb=3;
629   for(i=0; i<aNb; ++i) {
630     myIterator->Initialize(aType[i], aType[2]);
631     for (; myIterator->More(); myIterator->Next()) {
632       myIterator->Value(n1, nF, bJustAdd);
633       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
634       //
635       bIsBasedOnPlane=IsBasedOnPlane(aF);
636       if (bIsBasedOnPlane) {
637         aMF.Add(aF);
638       }
639     }
640   }
641   //
642   if (aMF.IsEmpty()) {
643     return;
644   }
645   //
646   BOPAlgo_VectorOfBPC aVBPC;
647   //
648   aItMF.Initialize(aMF);
649   for (; aItMF.More(); aItMF.Next()) {
650     const TopoDS_Face& aF=*((TopoDS_Face *)&aItMF.Key());
651     aExp.Init(aF, aType[1]);
652     for (; aExp.More(); aExp.Next()) {
653       const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
654       BOPAlgo_BPC& aBPC=aVBPC.Append1();
655       aBPC.SetEdge(aE);
656       aBPC.SetFace(aF);
657     }
658   }
659   //
660   //======================================================
661   BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
662   //======================================================
663 }
664 //=======================================================================
665 //function : IsBasedOnPlane
666 //purpose  : 
667 //=======================================================================
668 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
669 {
670   TopLoc_Location aLoc; 
671   Handle(Geom_RectangularTrimmedSurface) aGRTS;
672   Handle(Geom_Plane) aGP;
673   
674   const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
675   aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
676   if(!aGRTS.IsNull()) {
677     aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
678   }
679   else {
680     aGP = Handle(Geom_Plane)::DownCast(aS);
681   }
682   //
683   return (!aGP.IsNull()); 
684 }