0026619: Tolerances of operands are modified using bop
[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);
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 || (myNonDestructive && !bCB)) {
397           nE = aPB->OriginalEdge();
398           aPB->SetEdge(nE);
399           if (!myNonDestructive && bCB) {
400             const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
401             Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
402             myDS->UpdateEdgeTolerance(nE, aTol);
403           }
404           continue;
405         }
406       }
407     }
408     //
409     aItPB.Initialize(aLPB);
410     for (; aItPB.More(); aItPB.Next()) {
411       aPB=aItPB.Value();
412       nE=aPB->OriginalEdge();
413       const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
414       if (aSIE.HasFlag()){
415         continue;
416       }
417       //
418       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
419       bCB=!aCB.IsNull();
420       if (bCB) {
421         myDS->SortPaveBlocks(aCB);
422         aPB=aCB->PaveBlock1();
423       }
424       //
425       if (aMPB.Add(aPB)) {
426         nE=aPB->OriginalEdge();
427         aPB->Indices(nV1, nV2);
428         aPB->Range(aT1, aT2);
429         //
430         aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
431         aE.Orientation(TopAbs_FORWARD);
432         //
433         aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
434         aV1.Orientation(TopAbs_FORWARD); 
435         //
436         aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
437         aV2.Orientation(TopAbs_REVERSED); 
438         //
439         BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
440         //
441         aBSE.SetData(aE, aV1, aT1, aV2, aT2);
442         aBSE.SetPaveBlock(aPB);
443         if (bCB) {
444           aBSE.SetCommonBlock(aCB);
445         }
446         aBSE.SetDS(myDS);
447         aBSE.SetProgressIndicator(myProgressIndicator);
448       }
449     } // for (; aItPB.More(); aItPB.Next()) {
450   }  // for (i=0; i<aNbPBP; ++i) {      
451   //
452   aNbVBSE=aVBSE.Extent();
453   //======================================================
454   BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
455   //======================================================
456   //
457   BOPDS_ShapeInfo aSI;
458   //
459   aSI.SetShapeType(TopAbs_EDGE);
460   //
461   for (k=0; k < aNbVBSE; ++k) {
462     BOPAlgo_SplitEdge& aBSE=aVBSE(k);
463     //
464     const TopoDS_Edge& aSp=aBSE.SplitEdge();
465     const Bnd_Box& aBox=aBSE.Box();
466     //
467     Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
468     Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
469     //
470     aSI.SetShape(aSp);
471     aSI.ChangeBox()=aBox;
472     //
473     nSp=myDS->Append(aSI);
474     //
475     if (!aCBk.IsNull()) {
476       myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance());
477       aCBk->SetEdge(nSp);
478     }
479     else {
480       aPBk->SetEdge(nSp);
481     }
482   }
483 }
484
485 //=======================================================================
486 // function: SplitEdge
487 // purpose: 
488 //=======================================================================
489 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
490                                                const Standard_Integer nV1,
491                                                const Standard_Real aT1, 
492                                                const Standard_Integer nV2, 
493                                                const Standard_Real aT2)
494 {
495   Standard_Integer nSp;
496   TopoDS_Vertex aV1, aV2;
497   TopoDS_Edge aE, aSp;
498   BOPDS_ShapeInfo aSI;
499   //
500   aSI.SetShapeType(TopAbs_EDGE);
501   //
502   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
503   aE.Orientation(TopAbs_FORWARD);
504   //
505   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
506   aV1.Orientation(TopAbs_FORWARD); 
507   //
508   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
509   aV2.Orientation(TopAbs_REVERSED); 
510   //
511   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
512   //
513   aSI.SetShape(aSp);
514   //
515   Bnd_Box& aBox=aSI.ChangeBox();
516   BRepBndLib::Add(aSp, aBox);
517   aBox.SetGap(aBox.GetGap() + Precision::Confusion());
518   //
519   nSp=myDS->Append(aSI);
520   return nSp;
521 }
522 //=======================================================================
523 // function: MakePCurves
524 // purpose: 
525 //=======================================================================
526 void BOPAlgo_PaveFiller::MakePCurves()
527 {
528   Standard_Boolean bHasPC;
529   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx;
530   Standard_Integer j, aNbPBIn, aNbPBOn;
531   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
532   TopoDS_Face aF1F, aF2F;
533   BOPAlgo_VectorOfMPC aVMPC;
534   //
535   myErrorStatus=0;
536   //
537   // 1. Process Common Blocks 
538   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
539   //
540   aNbFI=aFIP.Extent();
541   for (i=0; i<aNbFI; ++i) {
542     const BOPDS_FaceInfo& aFI=aFIP(i);
543     nF1=aFI.Index();
544     //
545     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
546     aF1F.Orientation(TopAbs_FORWARD);
547     // In
548     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
549     aNbPBIn = aMPBIn.Extent();
550     for (j = 1; j <= aNbPBIn; ++j) {
551       const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j);
552       nE=aPB->Edge();
553       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
554       //
555       BOPAlgo_MPC& aMPC=aVMPC.Append1();
556       aMPC.SetEdge(aE);
557       aMPC.SetFace(aF1F);
558       aMPC.SetProgressIndicator(myProgressIndicator);
559     }
560     //
561     // On
562     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
563     aNbPBOn = aMPBOn.Extent();
564     for (j = 1; j <= aNbPBOn; ++j) {
565       const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j);
566       nE=aPB->Edge();
567       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
568       bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
569       if (bHasPC) {
570         continue;
571       }
572       //
573       Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
574       if (aCB.IsNull()) {
575         continue;
576       }
577       //
578       const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
579       if (aLPB.Extent()<2) {
580         continue;
581       }
582       //
583       BOPAlgo_MPC& aMPC=aVMPC.Append1();
584       //
585       aItLPB.Initialize(aLPB);
586       for(; aItLPB.More(); aItLPB.Next()) {
587         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
588         if (aPBx==aPB) {
589           continue;
590         }
591         //
592         nEx=aPBx->OriginalEdge();
593         const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx))); 
594         bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
595         if (!bHasPC) {
596           continue;
597         }
598         //
599         Standard_Integer nV1x, nV2x;
600         Standard_Real aT1x, aT2x;
601         TopoDS_Vertex aV1x, aV2x;
602         TopoDS_Edge aEz;
603         //
604         aEz=aEx;
605         aEz.Orientation(TopAbs_FORWARD);
606         //
607         aPBx->Indices(nV1x, nV2x);
608         aPBx->Range(aT1x, aT2x);
609         //
610         aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
611         aV1x.Orientation(TopAbs_FORWARD); 
612         //
613         aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
614         aV2x.Orientation(TopAbs_REVERSED); 
615         //
616         aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
617         //
618         break;
619       }
620       //
621       aMPC.SetEdge(aE);
622       aMPC.SetFace(aF1F);
623       aMPC.SetProgressIndicator(myProgressIndicator);
624     }
625   }// for (i=0; i<aNbFI; ++i) {
626   //
627   // 2. Process section edges
628   Standard_Boolean bPCurveOnS[2];
629   Standard_Integer m;
630   TopoDS_Face aFf[2];
631   //
632   bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
633   bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
634   //
635   if (bPCurveOnS[0] || bPCurveOnS[1]) {
636     BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
637     aNbFF=aFFs.Extent();
638     for (i=0; i<aNbFF; ++i) {
639       const BOPDS_InterfFF& aFF=aFFs(i);
640       aFF.Indices(nF1, nF2);
641       //
642       aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
643       aFf[0].Orientation(TopAbs_FORWARD);
644       //
645       aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
646       aFf[1].Orientation(TopAbs_FORWARD);
647       //
648       const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
649       aNbC=aVNC.Extent();
650       for (k=0; k<aNbC; ++k) {
651         const BOPDS_Curve& aNC=aVNC(k);
652         const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
653         aItLPB.Initialize(aLPB);
654         for(; aItLPB.More(); aItLPB.Next()) {
655           const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
656           nE=aPB->Edge();
657           const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
658           //
659           for (m=0; m<2; ++m) {
660             if (bPCurveOnS[m]) {
661               BOPAlgo_MPC& aMPC=aVMPC.Append1();
662               aMPC.SetEdge(aE);
663               aMPC.SetFace(aFf[m]);
664               aMPC.SetFlag(bPCurveOnS[m]);
665               aMPC.SetProgressIndicator(myProgressIndicator);
666             }
667           }
668         }
669       }
670     }// for (i=0; i<aNbFF; ++i) {
671   }//if (bPCurveOnS1 || bPCurveOnS2 ) {
672   //
673   //======================================================
674   BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
675   //======================================================
676 }
677 //=======================================================================
678 // function: RefineFaceInfoOn
679 // purpose: 
680 //=======================================================================
681 void BOPAlgo_PaveFiller::RefineFaceInfoOn() 
682 {
683   Standard_Integer aNbPBP;
684   //
685   myErrorStatus=0;
686   //
687   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
688   aNbPBP=aPBP.Extent();
689   if(!aNbPBP) {
690     return;
691   }
692   //
693   Standard_Boolean bV1, bV2;
694   Standard_Integer i, nV1, nV2, aNbPB;
695   Handle(BOPDS_PaveBlock) aPB;
696   //
697   for (i=0; i<aNbPBP; ++i) {
698     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
699     //
700     aNbPB=aLPB.Extent();
701     if (aNbPB==1) {
702       aPB=aLPB.First();
703       aPB->Indices(nV1, nV2);
704       bV1=myDS->IsNewShape(nV1);
705       bV2=myDS->IsNewShape(nV2);
706       //
707       if (!(bV1 || bV2)) {
708         if (!myDS->IsCommonBlock(aPB)) {
709           // the PB seems to be untouced
710           aLPB.Clear();
711           Standard_Integer nE = aPB->OriginalEdge();
712           if (nE >= 0) {
713             myDS->ChangeShapeInfo(nE).SetReference(-1);
714           }
715           continue;
716         }
717       }//if (!(bV1 || bV2)) {
718     }//if (aNbPB==1) {
719   }//for (i=0; i<aNbPBP; ++i) {
720   myDS->RefineFaceInfoOn();
721 }
722 //=======================================================================
723 //function : UpdateVertices
724 //purpose  : update tolerances of vertices comparing extremities of
725 //           3d and 2d curves
726 //=======================================================================
727 void UpdateVertices(const TopoDS_Edge& aE, 
728                     const TopoDS_Face& aF)
729 {
730   Standard_Integer j;
731   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
732   gp_Pnt aP3D, aP3Dx;
733   gp_Pnt2d aP2Dx;
734   Handle(Geom_Surface) aS;
735   Handle(Geom_Curve) aC3D;
736   Handle(Geom2d_Curve) aC2D;
737   TopoDS_Edge aEf;
738   TopoDS_Vertex aV[2];
739   BRep_Builder aBB;
740   //
741   aEf=aE;
742   aEf.Orientation(TopAbs_FORWARD);
743   //
744   TopExp::Vertices(aEf, aV[0], aV[1]);
745   //
746   aS=BRep_Tool::Surface(aF);
747   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
748   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
749   //
750   for (j=0; j<2; ++j) {
751     aTolV2=BRep_Tool::Tolerance(aV[j]);
752     aTolV2=aTolV2*aTolV2;
753     //
754     aC3D->D0(aT[j], aP3D);
755     aC2D->D0(aT[j], aP2Dx);
756     aP2Dx.Coord(aUx, aVx);
757     aS->D0(aUx, aVx, aP3Dx);
758     aD2=aP3D.SquareDistance(aP3Dx);
759     if (aD2>aTolV2) {
760       aD=sqrt(aD2);
761       aBB.UpdateVertex(aV[j], aD);
762     }
763   }
764 }
765 //=======================================================================
766 // function: Prepare
767 // purpose: 
768 //=======================================================================
769 void BOPAlgo_PaveFiller::Prepare()
770 {
771   if (myNonDestructive) {
772     // do not allow storing pcurves in original edges if non-destructive mode is on
773     return;
774   }
775   TopAbs_ShapeEnum aType[] = {
776     TopAbs_VERTEX,
777     TopAbs_EDGE,
778     TopAbs_FACE
779   };
780   Standard_Boolean bJustAdd, bIsBasedOnPlane;
781   Standard_Integer i, aNb, n1, nF, aNbF;
782   TopExp_Explorer aExp;
783   BOPCol_IndexedMapOfShape aMF;
784   //
785   myErrorStatus=0;
786   //
787   aNb=3;
788   for(i=0; i<aNb; ++i) {
789     myIterator->Initialize(aType[i], aType[2]);
790     for (; myIterator->More(); myIterator->Next()) {
791       myIterator->Value(n1, nF, bJustAdd);
792       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
793       //
794       bIsBasedOnPlane=IsBasedOnPlane(aF);
795       if (bIsBasedOnPlane) {
796         aMF.Add(aF);
797       }
798     }
799   }
800   //
801   aNbF = aMF.Extent();
802   if (!aNbF) {
803     return;
804   }
805   //
806   // Build pcurves of edges on planes; first collect pairs edge-face.
807   BOPAlgo_VectorOfBPC aVBPC;
808   //
809   for (i = 1; i <= aNbF; ++i) {
810     const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i);
811     aExp.Init(aF, aType[1]);
812     for (; aExp.More(); aExp.Next()) {
813       const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
814       BOPAlgo_BPC& aBPC=aVBPC.Append1();
815       aBPC.SetEdge(aE);
816       aBPC.SetFace(aF);
817     }
818   }
819   //
820   //======================================================
821   BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
822   //======================================================
823
824   // pcurves are built, and now update edges
825   BRep_Builder aBB;
826   TopoDS_Edge E;
827   for (i = 0; i < aVBPC.Extent(); i++) {
828     const BOPAlgo_BPC& aBPC=aVBPC(i);
829     if (aBPC.IsToUpdate()) {
830       Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge());
831       aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE);
832     }
833   }
834 }
835 //=======================================================================
836 //function : IsBasedOnPlane
837 //purpose  : 
838 //=======================================================================
839 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
840 {
841   TopLoc_Location aLoc; 
842   Handle(Geom_RectangularTrimmedSurface) aGRTS;
843   Handle(Geom_Plane) aGP;
844   
845   const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
846   aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
847   if(!aGRTS.IsNull()) {
848     aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
849   }
850   else {
851     aGP = Handle(Geom_Plane)::DownCast(aS);
852   }
853   //
854   return (!aGP.IsNull()); 
855 }