0025748: Parallel version of progress indicator
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_4.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
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_Alerts.hxx>
21 #include <BOPAlgo_SectionAttribute.hxx>
22 #include <BOPDS_Curve.hxx>
23 #include <BOPDS_DS.hxx>
24 #include <BOPDS_FaceInfo.hxx>
25 #include <BOPDS_Interf.hxx>
26 #include <BOPDS_Iterator.hxx>
27 #include <BOPDS_MapOfPaveBlock.hxx>
28 #include <BOPDS_PaveBlock.hxx>
29 #include <BOPDS_SubIterator.hxx>
30 #include <BOPDS_VectorOfInterfVF.hxx>
31 #include <BOPTools_Parallel.hxx>
32 #include <BRep_Builder.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRepBndLib.hxx>
35 #include <gp_Pnt.hxx>
36 #include <IntTools_Context.hxx>
37 #include <NCollection_Vector.hxx>
38 #include <TColStd_MapOfInteger.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Vertex.hxx>
41
42 //=======================================================================
43 //class    : BOPAlgo_VertexFace
44 //purpose  : 
45 //=======================================================================
46 class BOPAlgo_VertexFace : public BOPAlgo_Algo {
47  public:
48   DEFINE_STANDARD_ALLOC
49
50   BOPAlgo_VertexFace() : 
51     BOPAlgo_Algo(),
52     myIV(-1), myIF(-1),
53     myFlag(-1), myT1(-1.),  myT2(-1.), myTolVNew(-1.) {
54   }
55   //
56   virtual ~BOPAlgo_VertexFace(){
57   }
58   //
59   void SetIndices(const Standard_Integer nV,
60                   const Standard_Integer nF) {
61     myIV=nV;
62     myIF=nF;
63   }
64   //
65   void Indices(Standard_Integer& nV,
66                Standard_Integer& nF) const {
67     nV=myIV;
68     nF=myIF;
69   }
70   //
71   void SetVertex(const TopoDS_Vertex& aV) {
72     myV=aV;
73   }
74   //
75   const TopoDS_Vertex& Vertex()const {
76     return myV;
77   }
78   //
79   void SetFace(const TopoDS_Face& aF) {
80     myF=aF;
81   }
82   //
83   const TopoDS_Face& Face()const {
84     return myF;
85   }
86   //
87   Standard_Integer Flag()const {
88     return myFlag;
89   }
90   //
91   void Parameters(Standard_Real& aT1,
92                   Standard_Real& aT2)const {
93     aT1=myT1;
94     aT2=myT2;
95   }
96   //
97   Standard_Real VertexNewTolerance()const {
98     return myTolVNew;
99   }
100   //
101   void SetContext(const Handle(IntTools_Context)& aContext) {
102     myContext=aContext;
103   }
104   //
105   const Handle(IntTools_Context)& Context()const {
106     return myContext;
107   }
108   //
109   virtual void Perform() {
110     BOPAlgo_Algo::UserBreak();
111     try
112     {
113       OCC_CATCH_SIGNALS
114
115       myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue);
116     }
117     catch (Standard_Failure const&)
118     {
119       AddError(new BOPAlgo_AlertIntersectionFailed);
120     }
121   }
122   //
123  protected:
124   Standard_Integer myIV;
125   Standard_Integer myIF;
126   Standard_Integer myFlag;
127   Standard_Real myT1;
128   Standard_Real myT2;
129   Standard_Real myTolVNew;
130   TopoDS_Vertex myV;
131   TopoDS_Face myF;
132   Handle(IntTools_Context) myContext;
133 };
134 //=======================================================================
135 typedef NCollection_Vector<BOPAlgo_VertexFace> BOPAlgo_VectorOfVertexFace;
136
137 //=======================================================================
138 // function: PerformVF
139 // purpose: 
140 //=======================================================================
141 void BOPAlgo_PaveFiller::PerformVF()
142 {
143   myIterator->Initialize(TopAbs_VERTEX, TopAbs_FACE);
144   Standard_Integer iSize = myIterator->ExpectedLength();
145   //
146   Standard_Integer nV, nF;
147   //
148   if (myGlue == BOPAlgo_GlueFull) {
149     // there is no need to intersect vertices with faces in this mode
150     // just initialize FaceInfo for all faces
151     for (; myIterator->More(); myIterator->Next()) {
152       myIterator->Value(nV, nF);
153       if (!myDS->IsSubShape(nV, nF)) {
154         myDS->ChangeFaceInfo(nF);
155       }
156     }
157     return;
158   }
159   //
160   BOPDS_VectorOfInterfVF& aVFs = myDS->InterfVF();
161   if (!iSize) {
162     iSize = 10;
163     aVFs.SetIncrement(iSize);
164     //
165     TreatVerticesEE();
166     return;
167   }
168   //
169   Standard_Integer nVSD, iFlag, nVx, aNbVF, k;
170   Standard_Real aT1, aT2;
171   BOPAlgo_VectorOfVertexFace aVVF; 
172   //
173   aVFs.SetIncrement(iSize);
174   //
175   // Avoid repeated intersection of the same vertex with face in case
176   // the group of vertices formed a single SD vertex
177   NCollection_DataMap<BOPDS_Pair, TColStd_MapOfInteger, BOPDS_PairMapHasher> aMVFPairs;
178
179   for (; myIterator->More(); myIterator->Next()) {
180     myIterator->Value(nV, nF);
181     //
182     if (myDS->IsSubShape(nV, nF)) {
183       continue;
184     }
185     //
186     if (myDS->HasInterf(nV, nF)) {
187       continue;
188     }
189     //
190     myDS->ChangeFaceInfo(nF);
191     if (myDS->HasInterfShapeSubShapes(nV, nF)) {
192       continue;
193     }
194     //
195     nVx=nV;
196     if (myDS->HasShapeSD(nV, nVSD)) {
197       nVx=nVSD;
198     }
199     //
200     BOPDS_Pair aVFPair(nVx, nF);
201     TColStd_MapOfInteger* pMV = aMVFPairs.ChangeSeek(aVFPair);
202     if (pMV)
203     {
204       pMV->Add(nV);
205       continue;
206     }
207
208     pMV = aMVFPairs.Bound(aVFPair, TColStd_MapOfInteger());
209     pMV->Add(nV);
210
211     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nVx))); 
212     const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
213     //
214     BOPAlgo_VertexFace& aVertexFace=aVVF.Appended();
215     //
216     aVertexFace.SetIndices(nVx, nF);
217     aVertexFace.SetVertex(aV);
218     aVertexFace.SetFace(aF);
219     aVertexFace.SetFuzzyValue(myFuzzyValue);
220     aVertexFace.SetProgressIndicator(*myProgressScope);
221   }//for (; myIterator->More(); myIterator->Next()) {
222   //
223   aNbVF=aVVF.Length();
224   //================================================================
225   BOPTools_Parallel::Perform (myRunParallel, aVVF, myContext);
226   //================================================================
227   //
228   for (k=0; k < aNbVF; ++k) {
229     const BOPAlgo_VertexFace& aVertexFace=aVVF(k);
230     // 
231     iFlag=aVertexFace.Flag();
232     if (iFlag != 0) {
233       if (aVertexFace.HasErrors())
234       {
235         // Warn about failed intersection of sub-shapes
236         AddIntersectionFailedWarning(aVertexFace.Vertex(), aVertexFace.Face());
237       }
238       continue;
239     }
240     //
241     aVertexFace.Indices(nVx, nF);
242     aVertexFace.Parameters(aT1, aT2);
243     Standard_Real aTolVNew = aVertexFace.VertexNewTolerance();
244
245     BOPDS_Pair aVFPair(nVx, nF);
246     const TColStd_MapOfInteger& aMV = aMVFPairs.Find(aVFPair);
247     TColStd_MapIteratorOfMapOfInteger itMV(aMV);
248     for (; itMV.More(); itMV.Next())
249     {
250       nV = itMV.Value();
251       // 1
252       BOPDS_InterfVF& aVF = aVFs.Appended();
253       aVF.SetIndices(nV, nF);
254       aVF.SetUV(aT1, aT2);
255       // 2
256       myDS->AddInterf(nV, nF);
257       //
258       // 3 update vertex V/F if necessary
259       nVx = UpdateVertex(nV, aTolVNew);
260       //
261       // 4
262       if (myDS->IsNewShape(nVx)) {
263         aVF.SetIndexNew(nVx);
264       }
265     }
266     // 5 update FaceInfo
267     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
268     TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
269     aMVIn.Add(nVx);
270   }//for (k=0; k < aNbVF; ++k) {
271   //
272   TreatVerticesEE();
273 }
274 //=======================================================================
275 //function : TreatVerticesEE
276 //purpose  : 
277 //=======================================================================
278 void BOPAlgo_PaveFiller::TreatVerticesEE()
279 {
280   Standard_Integer i, aNbS,aNbEEs, nF, nV, iFlag;
281   Standard_Real aT1, aT2, dummy;
282   TColStd_ListIteratorOfListOfInteger aItLI;
283   Handle(NCollection_BaseAllocator) aAllocator;
284   //
285   aAllocator=
286     NCollection_BaseAllocator::CommonBaseAllocator();
287   TColStd_ListOfInteger aLIV(aAllocator), aLIF(aAllocator);
288   TColStd_MapOfInteger aMI(100, aAllocator);
289   BOPDS_MapOfPaveBlock aMPBF(100, aAllocator);
290   //
291   aNbS=myDS->NbSourceShapes();
292   //
293   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
294   aNbEEs=aEEs.Length();
295   for (i=0; i<aNbEEs; ++i) {
296     BOPDS_InterfEE& aEE=aEEs(i);
297     if (aEE.HasIndexNew()) {
298       nV=aEE.IndexNew();
299       if (aMI.Add(nV)) {
300         aLIV.Append(nV);
301       }   
302     }   
303   }
304   if (!aLIV.Extent()) {
305     aAllocator.Nullify();
306     return;
307   }
308   //
309   aNbS=myDS->NbSourceShapes();
310   for (nF=0; nF<aNbS; ++nF) {
311     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(nF);
312     if (aSI.ShapeType()==TopAbs_FACE) {
313       aLIF.Append(nF);
314     }
315   }
316   if (!aLIF.Extent()) {
317     aAllocator.Nullify();
318     return;
319   }
320   //-------------------------------------------------------------
321   BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
322   //
323   BOPDS_SubIterator aIt(aAllocator);
324   //
325   aIt.SetDS(myDS);
326   aIt.SetSubSet1(aLIF);
327   aIt.SetSubSet2(aLIV);
328   aIt.Prepare();
329   aIt.Initialize();
330   for (; aIt.More(); aIt.Next()) {
331     aIt.Value(nV, nF);
332     //
333     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
334     const TColStd_MapOfInteger& aMVOn=aFI.VerticesOn();
335     //
336     if (!aMVOn.Contains(nV)) {
337       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV))); 
338       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
339       iFlag = myContext->ComputeVF(aV, aF, aT1, aT2, dummy, myFuzzyValue);
340       if (!iFlag) {
341         // 1
342         BOPDS_InterfVF& aVF=aVFs.Appended();
343         i=aVFs.Length()-1;
344         aVF.SetIndices(nV, nF);
345         aVF.SetUV(aT1, aT2);
346         // 2
347         myDS->AddInterf(nV, nF);
348         //
349         TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
350         aMVIn.Add(nV);
351       }
352     }
353   }
354 }