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