0025880: fuzzy booleans with multiple tools
[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_Parallel.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_Functor 
157   <BOPAlgo_SplitEdge,
158   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
159 //
160 typedef BOPCol_Cnt 
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   void SetData(const TopoDS_Edge& aEz,
206                const TopoDS_Vertex& aV1,
207                const Standard_Real aT1,
208                const TopoDS_Vertex& aV2,
209                const Standard_Real aT2) {
210     myEz=aEz;
211     myV1=aV1;
212     myT1=aT1;
213     myV2=aV2;
214     myT2=aT2;
215   }
216   //
217   void SetContext(const Handle(IntTools_Context)& aContext) {
218     myContext=aContext;
219   }
220   //
221   const Handle(IntTools_Context)& Context()const {
222     return myContext;
223   }
224   //
225   virtual void Perform() {
226     Standard_Integer iErr;
227     //
228     iErr=1;
229     if (!myEz.IsNull()) {
230       TopoDS_Edge aSpz;
231       //
232       BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, 
233                                         myV2, myT2, aSpz);
234       //
235       iErr=
236         BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, 
237                                                    myE, 
238                                                    myF, 
239                                                    myContext);
240     }
241     //
242     if (iErr) { 
243       BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF);
244     }
245     // 
246     if (myFlag) {
247       UpdateVertices(myE, myF);
248     }
249   }
250   //
251  protected:
252   Standard_Boolean myFlag;
253   TopoDS_Edge myE;
254   TopoDS_Face myF;
255   TopoDS_Edge myEz;
256   TopoDS_Vertex myV1;
257   Standard_Real myT1;
258   TopoDS_Vertex myV2;
259   Standard_Real myT2;
260   //
261   Handle(IntTools_Context) myContext;
262 };
263 //
264 //=======================================================================
265 typedef BOPCol_NCVector
266   <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; 
267 //
268 typedef BOPCol_ContextFunctor 
269   <BOPAlgo_MPC,
270   BOPAlgo_VectorOfMPC,
271   Handle(IntTools_Context), 
272   IntTools_Context> BOPAlgo_MPCFunctor;
273 //
274 typedef BOPCol_ContextCnt 
275   <BOPAlgo_MPCFunctor,
276   BOPAlgo_VectorOfMPC,
277   Handle(IntTools_Context)> BOPAlgo_MPCCnt;
278 //
279 //=======================================================================
280 //class    : BOPAlgo_BPC
281 //purpose  : 
282 //=======================================================================
283 class BOPAlgo_BPC {
284  public:
285   BOPAlgo_BPC(){
286   };
287   //
288   ~BOPAlgo_BPC(){
289   };
290   //
291   void SetFace(const TopoDS_Face& aF) {
292     myF=aF;
293   }
294   //
295   void SetEdge(const TopoDS_Edge& aE) {
296     myE=aE;
297   }
298   //
299   void Perform() {
300     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF);
301   };
302   //
303  protected:
304   TopoDS_Edge myE;
305   TopoDS_Face myF;
306 };
307 //=======================================================================
308 typedef BOPCol_NCVector
309   <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; 
310 //
311 typedef BOPCol_Functor 
312   <BOPAlgo_BPC,
313   BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
314 //
315 typedef BOPCol_Cnt 
316   <BOPAlgo_BPCFunctor,
317   BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
318 //
319 //
320 //=======================================================================
321 // function: MakeSplitEdges
322 // purpose: 
323 //=======================================================================
324 void BOPAlgo_PaveFiller::MakeSplitEdges()
325 {
326   Standard_Integer aNbPBP;
327   //
328   myErrorStatus=0;
329   //
330   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
331   aNbPBP=aPBP.Extent();
332   if(!aNbPBP) {
333     return;
334   }
335   //
336   Standard_Boolean bCB, bV1, bV2;
337   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
338   Standard_Real aT1, aT2;
339   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
340   Handle(BOPDS_PaveBlock) aPB;
341   BOPDS_MapOfPaveBlock aMPB(100);
342   TopoDS_Vertex aV1, aV2;
343   TopoDS_Edge aE;
344   BOPAlgo_VectorOfSplitEdge aVBSE;
345   
346   //
347   for (i=0; i<aNbPBP; ++i) {
348     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
349     //
350     aNbPB=aLPB.Extent();
351     if (aNbPB==1) {
352       aPB=aLPB.First();
353       aPB->Indices(nV1, nV2);
354       bV1=myDS->IsNewShape(nV1);
355       bV2=myDS->IsNewShape(nV2);
356       //
357       if (!(bV1 || bV2)) {
358         nE=aPB->OriginalEdge();
359         aPB->SetEdge(nE);
360         continue;
361       }
362     }
363     //
364     aItPB.Initialize(aLPB);
365     for (; aItPB.More(); aItPB.Next()) {
366       aPB=aItPB.Value();
367       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
368       bCB=!aCB.IsNull();
369       if (bCB) {
370         myDS->SortPaveBlocks(aCB);
371         aPB=aCB->PaveBlock1();
372       }
373       //
374       if (aMPB.Add(aPB)) {
375         nE=aPB->OriginalEdge();
376         aPB->Indices(nV1, nV2);
377         aPB->Range(aT1, aT2);
378         //
379         aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
380         aE.Orientation(TopAbs_FORWARD);
381         //
382         aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
383         aV1.Orientation(TopAbs_FORWARD); 
384         //
385         aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
386         aV2.Orientation(TopAbs_REVERSED); 
387         //
388         BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
389         //
390         aBSE.SetData(aE, aV1, aT1, aV2, aT2);
391         aBSE.SetPaveBlock(aPB);
392         if (bCB) {
393           aBSE.SetCommonBlock(aCB);
394         }
395         aBSE.SetProgressIndicator(myProgressIndicator);
396       }
397     } // for (; aItPB.More(); aItPB.Next()) {
398   }  // for (i=0; i<aNbPBP; ++i) {      
399   //
400   aNbVBSE=aVBSE.Extent();
401   //======================================================
402   BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
403   //======================================================
404   //
405   BOPDS_ShapeInfo aSI;
406   //
407   aSI.SetShapeType(TopAbs_EDGE);
408   //
409   for (k=0; k < aNbVBSE; ++k) {
410     BOPAlgo_SplitEdge& aBSE=aVBSE(k);
411     //
412     const TopoDS_Edge& aSp=aBSE.SplitEdge();
413     const Bnd_Box& aBox=aBSE.Box();
414     //
415     Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
416     Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
417     //
418     aSI.SetShape(aSp);
419     aSI.ChangeBox()=aBox;
420     //
421     nSp=myDS->Append(aSI);
422     //
423     if (!aCBk.IsNull()) {
424       aCBk->SetEdge(nSp);
425     }
426     else {
427       aPBk->SetEdge(nSp);
428     }
429   }
430 }
431 //=======================================================================
432 // function: SplitEdge
433 // purpose: 
434 //=======================================================================
435 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
436                                                const Standard_Integer nV1,
437                                                const Standard_Real aT1, 
438                                                const Standard_Integer nV2, 
439                                                const Standard_Real aT2)
440 {
441   Standard_Integer nSp;
442   TopoDS_Vertex aV1, aV2;
443   TopoDS_Edge aE, aSp;
444   BOPDS_ShapeInfo aSI;
445   //
446   aSI.SetShapeType(TopAbs_EDGE);
447   //
448   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
449   aE.Orientation(TopAbs_FORWARD);
450   //
451   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
452   aV1.Orientation(TopAbs_FORWARD); 
453   //
454   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
455   aV2.Orientation(TopAbs_REVERSED); 
456   //
457   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
458   //
459   aSI.SetShape(aSp);
460   //
461   Bnd_Box& aBox=aSI.ChangeBox();
462   BRepBndLib::Add(aSp, aBox);
463   //
464   nSp=myDS->Append(aSI);
465   return nSp;
466 }
467 //=======================================================================
468 // function: MakePCurves
469 // purpose: 
470 //=======================================================================
471 void BOPAlgo_PaveFiller::MakePCurves()
472 {
473   Standard_Boolean bHasPC;
474   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx;
475   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
476   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
477   TopoDS_Face aF1F, aF2F;
478   BOPAlgo_VectorOfMPC aVMPC;
479   //
480   myErrorStatus=0;
481   //
482   // 1. Process Common Blocks 
483   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
484   //
485   aNbFI=aFIP.Extent();
486   for (i=0; i<aNbFI; ++i) {
487     const BOPDS_FaceInfo& aFI=aFIP(i);
488     nF1=aFI.Index();
489     //
490     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
491     aF1F.Orientation(TopAbs_FORWARD);
492     // In
493     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
494     aItMPB.Initialize(aMPBIn);
495     for(; aItMPB.More(); aItMPB.Next()) {
496       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
497       nE=aPB->Edge();
498       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
499       //
500       BOPAlgo_MPC& aMPC=aVMPC.Append1();
501       aMPC.SetEdge(aE);
502       aMPC.SetFace(aF1F);
503       aMPC.SetProgressIndicator(myProgressIndicator);
504     }
505     //
506     // On
507     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
508     aItMPB.Initialize(aMPBOn);
509     for(; aItMPB.More(); aItMPB.Next()) {
510       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
511       nE=aPB->Edge();
512       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
513       bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
514       if (bHasPC) {
515         continue;
516       }
517       //
518       Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
519       if (!aCB) {
520         continue;
521       }
522       //
523       const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
524       if (aLPB.Extent()<2) {
525         continue;
526       }
527       //
528       BOPAlgo_MPC& aMPC=aVMPC.Append1();
529       //
530       aItLPB.Initialize(aLPB);
531       for(; aItLPB.More(); aItLPB.Next()) {
532         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
533         if (aPBx==aPB) {
534           continue;
535         }
536         //
537         nEx=aPBx->OriginalEdge();
538         const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx))); 
539         bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
540         if (!bHasPC) {
541           continue;
542         }
543         //
544         Standard_Integer nV1x, nV2x;
545         Standard_Real aT1x, aT2x;
546         TopoDS_Vertex aV1x, aV2x;
547         TopoDS_Edge aEz;
548         //
549         aEz=aEx;
550         aEz.Orientation(TopAbs_FORWARD);
551         //
552         aPBx->Indices(nV1x, nV2x);
553         aPBx->Range(aT1x, aT2x);
554         //
555         aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
556         aV1x.Orientation(TopAbs_FORWARD); 
557         //
558         aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
559         aV2x.Orientation(TopAbs_REVERSED); 
560         //
561         aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
562         //
563         break;
564       }
565       //
566       aMPC.SetEdge(aE);
567       aMPC.SetFace(aF1F);
568       aMPC.SetProgressIndicator(myProgressIndicator);
569     }
570   }// for (i=0; i<aNbFI; ++i) {
571   //
572   // 2. Process section edges
573   Standard_Boolean bPCurveOnS[2];
574   Standard_Integer m;
575   TopoDS_Face aFf[2];
576   //
577   bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
578   bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
579   //
580   if (bPCurveOnS[0] || bPCurveOnS[1]) {
581     BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
582     aNbFF=aFFs.Extent();
583     for (i=0; i<aNbFF; ++i) {
584       const BOPDS_InterfFF& aFF=aFFs(i);
585       aFF.Indices(nF1, nF2);
586       //
587       aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
588       aFf[0].Orientation(TopAbs_FORWARD);
589       //
590       aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
591       aFf[1].Orientation(TopAbs_FORWARD);
592       //
593       const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
594       aNbC=aVNC.Extent();
595       for (k=0; k<aNbC; ++k) {
596         const BOPDS_Curve& aNC=aVNC(k);
597         const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
598         aItLPB.Initialize(aLPB);
599         for(; aItLPB.More(); aItLPB.Next()) {
600           const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
601           nE=aPB->Edge();
602           const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
603           //
604           for (m=0; m<2; ++m) {
605             if (bPCurveOnS[m]) {
606               BOPAlgo_MPC& aMPC=aVMPC.Append1();
607               aMPC.SetEdge(aE);
608               aMPC.SetFace(aFf[m]);
609               aMPC.SetFlag(bPCurveOnS[m]);
610               aMPC.SetProgressIndicator(myProgressIndicator);
611             }
612           }
613         }
614       }
615     }// for (i=0; i<aNbFF; ++i) {
616   }//if (bPCurveOnS1 || bPCurveOnS2 ) {
617   //
618   //======================================================
619   BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
620   //======================================================
621 }
622 //=======================================================================
623 // function: RefineFaceInfoOn
624 // purpose: 
625 //=======================================================================
626 void BOPAlgo_PaveFiller::RefineFaceInfoOn() 
627 {
628   Standard_Integer aNbPBP;
629   //
630   myErrorStatus=0;
631   //
632   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
633   aNbPBP=aPBP.Extent();
634   if(!aNbPBP) {
635     return;
636   }
637   //
638   Standard_Boolean bV1, bV2;
639   Standard_Integer i, nV1, nV2, aNbPB;
640   Handle(BOPDS_PaveBlock) aPB;
641   //
642   for (i=0; i<aNbPBP; ++i) {
643     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
644     //
645     aNbPB=aLPB.Extent();
646     if (aNbPB==1) {
647       aPB=aLPB.First();
648       aPB->Indices(nV1, nV2);
649       bV1=myDS->IsNewShape(nV1);
650       bV2=myDS->IsNewShape(nV2);
651       //
652       if (!(bV1 || bV2)) {
653         if (!myDS->IsCommonBlock(aPB)) {
654           // the PB seems to be untouced
655           aLPB.Clear();
656           continue;
657         }
658       }//if (!(bV1 || bV2)) {
659     }//if (aNbPB==1) {
660   }//for (i=0; i<aNbPBP; ++i) {
661   myDS->RefineFaceInfoOn();
662 }
663 //=======================================================================
664 //function : UpdateVertices
665 //purpose  : update tolerances of vertices comparing extremities of
666 //           3d and 2d curves
667 //=======================================================================
668 void UpdateVertices(const TopoDS_Edge& aE, 
669                     const TopoDS_Face& aF)
670 {
671   Standard_Integer j;
672   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
673   gp_Pnt aP3D, aP3Dx;
674   gp_Pnt2d aP2Dx;
675   Handle(Geom_Surface) aS;
676   Handle(Geom_Curve) aC3D;
677   Handle(Geom2d_Curve) aC2D;
678   TopoDS_Edge aEf;
679   TopoDS_Vertex aV[2];
680   BRep_Builder aBB;
681   //
682   aEf=aE;
683   aEf.Orientation(TopAbs_FORWARD);
684   //
685   TopExp::Vertices(aEf, aV[0], aV[1]);
686   //
687   aS=BRep_Tool::Surface(aF);
688   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
689   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
690   //
691   for (j=0; j<2; ++j) {
692     aTolV2=BRep_Tool::Tolerance(aV[j]);
693     aTolV2=aTolV2*aTolV2;
694     //
695     aC3D->D0(aT[j], aP3D);
696     aC2D->D0(aT[j], aP2Dx);
697     aP2Dx.Coord(aUx, aVx);
698     aS->D0(aUx, aVx, aP3Dx);
699     aD2=aP3D.SquareDistance(aP3Dx);
700     if (aD2>aTolV2) {
701       aD=sqrt(aD2);
702       aBB.UpdateVertex(aV[j], aD);
703     }
704   }
705 }
706 //=======================================================================
707 // function: Prepare
708 // purpose: 
709 //=======================================================================
710 void BOPAlgo_PaveFiller::Prepare()
711 {
712   TopAbs_ShapeEnum aType[] = {
713     TopAbs_VERTEX,
714     TopAbs_EDGE,
715     TopAbs_FACE
716   };
717   Standard_Boolean bJustAdd, bIsBasedOnPlane;
718   Standard_Integer i, aNb, n1, nF;
719   TopExp_Explorer aExp;
720   BOPCol_MapOfShape aMF;
721   BOPCol_MapIteratorOfMapOfShape aItMF;
722   //
723   myErrorStatus=0;
724   //
725   aNb=3;
726   for(i=0; i<aNb; ++i) {
727     myIterator->Initialize(aType[i], aType[2]);
728     for (; myIterator->More(); myIterator->Next()) {
729       myIterator->Value(n1, nF, bJustAdd);
730       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
731       //
732       bIsBasedOnPlane=IsBasedOnPlane(aF);
733       if (bIsBasedOnPlane) {
734         aMF.Add(aF);
735       }
736     }
737   }
738   //
739   if (aMF.IsEmpty()) {
740     return;
741   }
742   //
743   BOPAlgo_VectorOfBPC aVBPC;
744   //
745   aItMF.Initialize(aMF);
746   for (; aItMF.More(); aItMF.Next()) {
747     const TopoDS_Face& aF=*((TopoDS_Face *)&aItMF.Key());
748     aExp.Init(aF, aType[1]);
749     for (; aExp.More(); aExp.Next()) {
750       const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
751       BOPAlgo_BPC& aBPC=aVBPC.Append1();
752       aBPC.SetEdge(aE);
753       aBPC.SetFace(aF);
754     }
755   }
756   //
757   //======================================================
758   BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
759   //======================================================
760 }
761 //=======================================================================
762 //function : IsBasedOnPlane
763 //purpose  : 
764 //=======================================================================
765 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
766 {
767   TopLoc_Location aLoc; 
768   Handle(Geom_RectangularTrimmedSurface) aGRTS;
769   Handle(Geom_Plane) aGP;
770   
771   const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
772   aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
773   if(!aGRTS.IsNull()) {
774     aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
775   }
776   else {
777     aGP = Handle(Geom_Plane)::DownCast(aS);
778   }
779   //
780   return (!aGP.IsNull()); 
781 }