0024639: Parallelization FillDS part of BO
[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 <TopoDS_Vertex.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
25
26 #include <BRepBndLib.hxx>
27
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30
31 #include <TopExp.hxx>
32
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom2d_Curve.hxx>
36
37 #include <BOPCol_NCVector.hxx>
38 #include <BOPCol_TBB.hxx>
39
40 #include <BOPTools_AlgoTools.hxx>
41 #include <BOPTools_AlgoTools2D.hxx>
42
43 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
44 #include <BOPDS_ListOfPaveBlock.hxx>
45 #include <BOPDS_PaveBlock.hxx>
46 #include <BOPDS_CommonBlock.hxx>
47 #include <BOPDS_Pave.hxx>
48 #include <BOPDS_ShapeInfo.hxx>
49 #include <BOPDS_MapOfPaveBlock.hxx>
50 #include <BOPDS_VectorOfInterfFF.hxx>
51 #include <BOPDS_Interf.hxx>
52 #include <BOPDS_VectorOfCurve.hxx>
53 #include <BOPDS_VectorOfFaceInfo.hxx>
54 #include <BOPDS_FaceInfo.hxx>
55 #include <BOPDS_MapOfPaveBlock.hxx>
56 #include <BOPDS_Curve.hxx>
57
58
59 static void UpdateVertices(const TopoDS_Edge& aE, 
60                            const TopoDS_Face& aF);
61
62 //=======================================================================
63 //class    : BOPAlgo_SplitEdge
64 //purpose  : 
65 //=======================================================================
66 class BOPAlgo_SplitEdge {
67  public:
68   BOPAlgo_SplitEdge() {
69     myT1=0.;
70     myT2=0.;
71   }
72   //
73   ~BOPAlgo_SplitEdge() {
74   }
75   //
76   void SetData(const TopoDS_Edge& aE,
77                const TopoDS_Vertex& aV1,
78                const Standard_Real aT1,
79                const TopoDS_Vertex& aV2,
80                const Standard_Real aT2) {
81     myE=aE;
82     myV1=aV1;
83     myT1=aT1;
84     myV2=aV2;
85     myT2=aT2;
86     myESp=aE;
87   }
88   //
89   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
90     myPB=aPB;
91   }
92   //
93   Handle(BOPDS_PaveBlock)& PaveBlock() {
94     return myPB;
95   }
96   //
97   void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
98     myCB=aCB;
99   }
100   //
101   Handle(BOPDS_CommonBlock)& CommonBlock() {
102     return myCB;
103   }
104   //
105   const TopoDS_Edge& SplitEdge() const {
106     return myESp;
107   }
108   //
109   const Bnd_Box Box() {
110     return myBox;
111   }
112   //
113   void Perform () {
114     BOPTools_AlgoTools::MakeSplitEdge(myE, 
115                                       myV1, myT1, 
116                                       myV2, myT2, 
117                                       myESp);
118     BRepBndLib::Add(myESp, myBox);  
119   }
120   //
121  protected:
122   // ->
123   TopoDS_Edge myE;
124   TopoDS_Vertex myV1;
125   Standard_Real myT1;
126   TopoDS_Vertex myV2;
127   Standard_Real myT2;
128   // <->
129   Handle(BOPDS_PaveBlock) myPB;
130   Handle(BOPDS_CommonBlock) myCB;
131   // <-
132   TopoDS_Edge myESp;
133   Bnd_Box myBox;
134 };
135 //
136 //=======================================================================
137 typedef BOPCol_NCVector
138   <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; 
139 //
140 typedef BOPCol_TBBFunctor 
141   <BOPAlgo_SplitEdge,
142   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
143 //
144 typedef BOPCol_TBBCnt 
145   <BOPAlgo_SplitEdgeFunctor,
146   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
147 //
148 //=======================================================================
149 // function: MakeSplitEdges
150 // purpose: 
151 //=======================================================================
152 void BOPAlgo_PaveFiller::MakeSplitEdges()
153 {
154   Standard_Integer aNbPBP;
155   //
156   myErrorStatus=0;
157   //
158   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
159   aNbPBP=aPBP.Extent();
160   if(!aNbPBP) {
161     return;
162   }
163   //
164   Standard_Boolean bCB, bV1, bV2;
165   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
166   Standard_Real aT1, aT2;
167   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
168   Handle(BOPDS_PaveBlock) aPB;
169   BOPDS_MapOfPaveBlock aMPB(100);
170   TopoDS_Vertex aV1, aV2;
171   TopoDS_Edge aE;
172   BOPAlgo_VectorOfSplitEdge aVBSE;
173   
174   //
175   for (i=0; i<aNbPBP; ++i) {
176     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
177     //
178     aNbPB=aLPB.Extent();
179     if (aNbPB==1) {
180       aPB=aLPB.First();
181       aPB->Indices(nV1, nV2);
182       bV1=myDS->IsNewShape(nV1);
183       bV2=myDS->IsNewShape(nV2);
184       //
185       if (!(bV1 || bV2)) {
186         nE=aPB->OriginalEdge();
187         aPB->SetEdge(nE);
188         continue;
189       }
190     }
191     //
192     aItPB.Initialize(aLPB);
193     for (; aItPB.More(); aItPB.Next()) {
194       aPB=aItPB.Value();
195       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
196       bCB=!aCB.IsNull();
197       if (bCB) {
198         myDS->SortPaveBlocks(aCB);
199         aPB=aCB->PaveBlock1();
200       }
201       //
202       if (aMPB.Add(aPB)) {
203         nE=aPB->OriginalEdge();
204         aPB->Indices(nV1, nV2);
205         aPB->Range(aT1, aT2);
206         //
207         aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
208         aE.Orientation(TopAbs_FORWARD);
209         //
210         aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
211         aV1.Orientation(TopAbs_FORWARD); 
212         //
213         aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
214         aV2.Orientation(TopAbs_REVERSED); 
215         //
216         BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
217         //
218         aBSE.SetData(aE, aV1, aT1, aV2, aT2);
219         aBSE.SetPaveBlock(aPB);
220         if (bCB) {
221           aBSE.SetCommonBlock(aCB);
222         }
223       }
224     } // for (; aItPB.More(); aItPB.Next()) {
225   }  // for (i=0; i<aNbPBP; ++i) {      
226   //
227   aNbVBSE=aVBSE.Extent();
228   //======================================================
229   BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
230   //======================================================
231   //
232   BOPDS_ShapeInfo aSI;
233   //
234   aSI.SetShapeType(TopAbs_EDGE);
235   //
236   for (k=0; k < aNbVBSE; ++k) {
237     BOPAlgo_SplitEdge& aBSE=aVBSE(k);
238     //
239     const TopoDS_Edge& aSp=aBSE.SplitEdge();
240     const Bnd_Box& aBox=aBSE.Box();
241     //
242     Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
243     Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
244     //
245     aSI.SetShape(aSp);
246     aSI.ChangeBox()=aBox;
247     //
248     nSp=myDS->Append(aSI);
249     //
250     if (!aCBk.IsNull()) {
251       aCBk->SetEdge(nSp);
252     }
253     else {
254       aPBk->SetEdge(nSp);
255     }
256   }
257 }
258 //=======================================================================
259 // function: SplitEdge
260 // purpose: 
261 //=======================================================================
262 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
263                                                const Standard_Integer nV1,
264                                                const Standard_Real aT1, 
265                                                const Standard_Integer nV2, 
266                                                const Standard_Real aT2)
267 {
268   Standard_Integer nSp;
269   TopoDS_Vertex aV1, aV2;
270   TopoDS_Edge aE, aSp;
271   BOPDS_ShapeInfo aSI;
272   //
273   aSI.SetShapeType(TopAbs_EDGE);
274   //
275   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
276   aE.Orientation(TopAbs_FORWARD);
277   //
278   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
279   aV1.Orientation(TopAbs_FORWARD); 
280   //
281   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
282   aV2.Orientation(TopAbs_REVERSED); 
283   //
284   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
285   //
286   aSI.SetShape(aSp);
287   //
288   Bnd_Box& aBox=aSI.ChangeBox();
289   BRepBndLib::Add(aSp, aBox);
290   //
291   nSp=myDS->Append(aSI);
292   return nSp;
293 }
294 //=======================================================================
295 // function: MakePCurves
296 // purpose: 
297 //=======================================================================
298 void BOPAlgo_PaveFiller::MakePCurves()
299 {
300   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI;
301   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
302   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
303   TopoDS_Face aF1F, aF2F;
304   //
305   myErrorStatus=0;
306   //
307   // 1. Process Common Blocks 
308   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
309   //
310   aNbFI=aFIP.Extent();
311   for (i=0; i<aNbFI; ++i) {
312     const BOPDS_FaceInfo& aFI=aFIP(i);
313     nF1=aFI.Index();
314     //
315     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
316     aF1F.Orientation(TopAbs_FORWARD);
317     // In
318     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
319     aItMPB.Initialize(aMPBIn);
320     for(; aItMPB.More(); aItMPB.Next()) {
321       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
322       nE=aPB->Edge();
323       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
324       //
325       BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
326     }
327     // On
328     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
329     aItMPB.Initialize(aMPBOn);
330     for(; aItMPB.More(); aItMPB.Next()) {
331       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
332       if (myDS->IsCommonBlockOnEdge(aPB)) {
333         nE=aPB->Edge();
334         const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
335         //
336         BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
337       }
338     }
339   }
340   //
341   if (!mySectionAttribute.PCurveOnS1() && 
342       !mySectionAttribute.PCurveOnS2()) {
343     return;
344   }
345   //
346   // 2. Process section edges
347   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
348   aNbFF=aFFs.Extent();
349   for (i=0; i<aNbFF; ++i) {
350     const BOPDS_InterfFF& aFF=aFFs(i);
351     aFF.Indices(nF1, nF2);
352     //
353     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
354     aF1F.Orientation(TopAbs_FORWARD);
355     aF2F=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
356     aF2F.Orientation(TopAbs_FORWARD);
357     //
358     const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
359     aNbC=aVNC.Extent();
360     for (k=0; k<aNbC; ++k) {
361       const BOPDS_Curve& aNC=aVNC(k);
362       const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
363       aItLPB.Initialize(aLPB);
364       for(; aItLPB.More(); aItLPB.Next()) {
365         const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
366         nE=aPB->Edge();
367         const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
368         //
369         if (mySectionAttribute.PCurveOnS1()) {
370           BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
371           UpdateVertices(aE, aF1F);
372         }
373         //
374         if (mySectionAttribute.PCurveOnS2()) {
375           BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF2F);
376           UpdateVertices(aE, aF2F);
377         }
378       }
379     }
380   }
381 }
382 //=======================================================================
383 // function: RefineFaceInfoOn
384 // purpose: 
385 //=======================================================================
386 void BOPAlgo_PaveFiller::RefineFaceInfoOn() 
387 {
388   Standard_Integer aNbPBP;
389   //
390   myErrorStatus=0;
391   //
392   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
393   aNbPBP=aPBP.Extent();
394   if(!aNbPBP) {
395     return;
396   }
397   //
398   Standard_Boolean bV1, bV2;
399   Standard_Integer i, nV1, nV2, aNbPB;
400   Handle(BOPDS_PaveBlock) aPB;
401   //
402   for (i=0; i<aNbPBP; ++i) {
403     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
404     //
405     aNbPB=aLPB.Extent();
406     if (aNbPB==1) {
407       aPB=aLPB.First();
408       aPB->Indices(nV1, nV2);
409       bV1=myDS->IsNewShape(nV1);
410       bV2=myDS->IsNewShape(nV2);
411       //
412       if (!(bV1 || bV2)) {
413         if (!myDS->IsCommonBlock(aPB)) {
414           // the PB seems to be untouced
415           aLPB.Clear();
416           continue;
417         }
418       }//if (!(bV1 || bV2)) {
419     }//if (aNbPB==1) {
420   }//for (i=0; i<aNbPBP; ++i) {
421   myDS->RefineFaceInfoOn();
422 }
423 //=======================================================================
424 //function : UpdateVertices
425 //purpose  : update tolerances of vertices comparing extremities of
426 //           3d and 2d curves
427 //=======================================================================
428 void UpdateVertices(const TopoDS_Edge& aE, 
429                     const TopoDS_Face& aF)
430 {
431   Standard_Integer j;
432   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
433   gp_Pnt aP3D, aP3Dx;
434   gp_Pnt2d aP2Dx;
435   Handle(Geom_Surface) aS;
436   Handle(Geom_Curve) aC3D;
437   Handle(Geom2d_Curve) aC2D;
438   TopoDS_Edge aEf;
439   TopoDS_Vertex aV[2];
440   BRep_Builder aBB;
441   //
442   aEf=aE;
443   aEf.Orientation(TopAbs_FORWARD);
444   //
445   TopExp::Vertices(aEf, aV[0], aV[1]);
446   //
447   aS=BRep_Tool::Surface(aF);
448   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
449   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
450   //
451   for (j=0; j<2; ++j) {
452     aTolV2=BRep_Tool::Tolerance(aV[j]);
453     aTolV2=aTolV2*aTolV2;
454     //
455     aC3D->D0(aT[j], aP3D);
456     aC2D->D0(aT[j], aP2Dx);
457     aP2Dx.Coord(aUx, aVx);
458     aS->D0(aUx, aVx, aP3Dx);
459     aD2=aP3D.SquareDistance(aP3Dx);
460     if (aD2>aTolV2) {
461       aD=sqrt(aD2);
462       aBB.UpdateVertex(aV[j], aD);
463     }
464   }
465 }
466