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