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