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 | |
4e57c75e |
18 | |
42cf5bc1 |
19 | #include <BOPAlgo_PaveFiller.hxx> |
ad8b073e |
20 | #include <BOPAlgo_Alerts.hxx> |
8ae442a8 |
21 | #include <BOPAlgo_Tools.hxx> |
42cf5bc1 |
22 | #include <BOPDS_DS.hxx> |
4e57c75e |
23 | #include <BOPDS_Interf.hxx> |
42cf5bc1 |
24 | #include <BOPDS_Iterator.hxx> |
25dfc507 |
25 | #include <BOPDS_Pair.hxx> |
42cf5bc1 |
26 | #include <BOPDS_PaveBlock.hxx> |
27 | #include <BOPDS_VectorOfInterfVE.hxx> |
3510db62 |
28 | #include <BOPTools_AlgoTools.hxx> |
1155d05a |
29 | #include <BOPTools_Parallel.hxx> |
ad8b073e |
30 | #include <BRep_Builder.hxx> |
42cf5bc1 |
31 | #include <BRep_Tool.hxx> |
42cf5bc1 |
32 | #include <gp_Pnt.hxx> |
33 | #include <IntTools_Context.hxx> |
1155d05a |
34 | #include <NCollection_Vector.hxx> |
8ae442a8 |
35 | #include <TopoDS.hxx> |
42cf5bc1 |
36 | #include <TopoDS_Edge.hxx> |
42cf5bc1 |
37 | #include <TopoDS_Vertex.hxx> |
4e57c75e |
38 | |
505abfb8 |
39 | //======================================================================= |
8ae442a8 |
40 | //class : BOPAlgo_VertexEdge |
505abfb8 |
41 | //purpose : |
42 | //======================================================================= |
d03c0898 |
43 | class BOPAlgo_VertexEdge : public BOPAlgo_ParallelAlgo { |
36f4947b |
44 | |
505abfb8 |
45 | public: |
36f4947b |
46 | DEFINE_STANDARD_ALLOC |
47 | |
48 | BOPAlgo_VertexEdge() : |
d03c0898 |
49 | BOPAlgo_ParallelAlgo(), |
0d0481c7 |
50 | myIV(-1), myIE(-1), myFlag(-1), myT(-1.), myTolVNew(-1.) { |
505abfb8 |
51 | }; |
52 | // |
36f4947b |
53 | virtual ~BOPAlgo_VertexEdge(){ |
505abfb8 |
54 | }; |
55 | // |
56 | void SetIndices(const Standard_Integer nV, |
0d0481c7 |
57 | const Standard_Integer nE) { |
505abfb8 |
58 | myIV=nV; |
59 | myIE=nE; |
505abfb8 |
60 | } |
61 | // |
62 | void Indices(Standard_Integer& nV, |
0d0481c7 |
63 | Standard_Integer& nE) const { |
505abfb8 |
64 | nV=myIV; |
65 | nE=myIE; |
505abfb8 |
66 | } |
67 | // |
68 | void SetVertex(const TopoDS_Vertex& aV) { |
69 | myV=aV; |
70 | } |
71 | // |
505abfb8 |
72 | void SetEdge(const TopoDS_Edge& aE) { |
73 | myE=aE; |
74 | } |
75 | // |
3510db62 |
76 | const TopoDS_Vertex& Vertex() const { |
77 | return myV; |
78 | } |
79 | // |
80 | const TopoDS_Edge& Edge() const { |
505abfb8 |
81 | return myE; |
82 | } |
83 | // |
84 | Standard_Integer Flag()const { |
85 | return myFlag; |
86 | } |
87 | // |
88 | Standard_Real Parameter()const { |
89 | return myT; |
90 | } |
91 | // |
3510db62 |
92 | Standard_Real VertexNewTolerance()const { |
93 | return myTolVNew; |
94 | } |
95 | // |
1e143abb |
96 | void SetContext(const Handle(IntTools_Context)& aContext) { |
505abfb8 |
97 | myContext=aContext; |
98 | } |
99 | // |
1e143abb |
100 | const Handle(IntTools_Context)& Context()const { |
505abfb8 |
101 | return myContext; |
102 | } |
103 | // |
8ae442a8 |
104 | void SetPaveBlock(const Handle(BOPDS_PaveBlock)& thePB) { |
105 | myPB = thePB; |
106 | } |
107 | // |
108 | const Handle(BOPDS_PaveBlock)& PaveBlock() const { |
109 | return myPB; |
110 | } |
111 | // |
36f4947b |
112 | virtual void Perform() { |
d03c0898 |
113 | Message_ProgressScope aPS(myProgressRange, NULL, 1); |
114 | if (UserBreak(aPS)) |
115 | { |
116 | return; |
117 | } |
ad8b073e |
118 | try |
119 | { |
120 | OCC_CATCH_SIGNALS |
121 | |
122 | myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue); |
123 | } |
a738b534 |
124 | catch (Standard_Failure const&) |
ad8b073e |
125 | { |
126 | AddError(new BOPAlgo_AlertIntersectionFailed); |
127 | } |
505abfb8 |
128 | }; |
129 | // |
130 | protected: |
131 | Standard_Integer myIV; |
132 | Standard_Integer myIE; |
505abfb8 |
133 | Standard_Integer myFlag; |
134 | Standard_Real myT; |
3510db62 |
135 | Standard_Real myTolVNew; |
505abfb8 |
136 | TopoDS_Vertex myV; |
137 | TopoDS_Edge myE; |
1e143abb |
138 | Handle(IntTools_Context) myContext; |
8ae442a8 |
139 | Handle(BOPDS_PaveBlock) myPB; |
505abfb8 |
140 | }; |
141 | //======================================================================= |
fc867b96 |
142 | typedef NCollection_Vector<BOPAlgo_VertexEdge> BOPAlgo_VectorOfVertexEdge; |
143 | |
4e57c75e |
144 | //======================================================================= |
145 | // function: PerformVE |
146 | // purpose: |
147 | //======================================================================= |
d03c0898 |
148 | void BOPAlgo_PaveFiller::PerformVE(const Message_ProgressRange& theRange) |
4e57c75e |
149 | { |
3510db62 |
150 | FillShrunkData(TopAbs_VERTEX, TopAbs_EDGE); |
151 | // |
4e57c75e |
152 | myIterator->Initialize(TopAbs_VERTEX, TopAbs_EDGE); |
d03c0898 |
153 | Message_ProgressScope aPS(theRange, NULL, 1); |
154 | |
8ae442a8 |
155 | Standard_Integer iSize = myIterator->ExpectedLength(); |
4e57c75e |
156 | if (!iSize) { |
157 | return; |
158 | } |
159 | // |
8ae442a8 |
160 | // Prepare pairs for intersection |
161 | BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMVEPairs; |
4e57c75e |
162 | for (; myIterator->More(); myIterator->Next()) { |
d03c0898 |
163 | if (UserBreak(aPS)) |
164 | { |
165 | return; |
166 | } |
8ae442a8 |
167 | Standard_Integer nV, nE; |
25dfc507 |
168 | myIterator->Value(nV, nE); |
4e57c75e |
169 | // |
170 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
171 | if (aSIE.HasSubShape(nV)) { |
172 | continue; |
173 | } |
174 | // |
175 | if (aSIE.HasFlag()){ |
176 | continue; |
177 | } |
178 | // |
d3578357 |
179 | if (myDS->HasInterf(nV, nE)) { |
180 | continue; |
181 | } |
182 | // |
4e57c75e |
183 | if (myDS->HasInterfShapeSubShapes(nV, nE)) { |
4e57c75e |
184 | continue; |
185 | } |
186 | // |
3510db62 |
187 | const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE); |
01b5b3df |
188 | if (aLPB.IsEmpty()) { |
189 | continue; |
190 | } |
191 | // |
192 | const Handle(BOPDS_PaveBlock)& aPB = aLPB.First(); |
193 | if (!aPB->IsSplittable()) { |
3510db62 |
194 | // this is a micro edge, ignore it |
195 | continue; |
196 | } |
197 | // |
1155d05a |
198 | TColStd_ListOfInteger* pLV = aMVEPairs.ChangeSeek(aPB); |
8ae442a8 |
199 | if (!pLV) |
1155d05a |
200 | pLV = &aMVEPairs(aMVEPairs.Add(aPB, TColStd_ListOfInteger())); |
8ae442a8 |
201 | pLV->Append(nV); |
202 | } |
203 | // |
d03c0898 |
204 | IntersectVE(aMVEPairs, aPS.Next()); |
8ae442a8 |
205 | } |
206 | |
207 | //======================================================================= |
208 | // function: IntersectVE |
209 | // purpose: |
210 | //======================================================================= |
211 | void BOPAlgo_PaveFiller::IntersectVE |
212 | (const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& theVEPairs, |
d03c0898 |
213 | const Message_ProgressRange& theRange, |
8ae442a8 |
214 | const Standard_Boolean theAddInterfs) |
215 | { |
216 | Standard_Integer i, aNbVE = theVEPairs.Extent(); |
217 | if (!aNbVE) { |
218 | return; |
219 | } |
220 | // |
221 | BOPDS_VectorOfInterfVE& aVEs = myDS->InterfVE(); |
222 | if (theAddInterfs) { |
223 | aVEs.SetIncrement(aNbVE); |
224 | } |
225 | // |
226 | // Prepare for intersection. |
227 | BOPAlgo_VectorOfVertexEdge aVVE; |
228 | // Map to collect all SD connections to add interferences |
229 | // for all vertices having the same SD vertex. |
230 | // It will also be used as a Fence map to avoid repeated |
231 | // intersection of the same SD vertex with edge |
1155d05a |
232 | NCollection_DataMap<BOPDS_Pair, TColStd_ListOfInteger, BOPDS_PairMapHasher> aDMVSD; |
8ae442a8 |
233 | // |
d03c0898 |
234 | Message_ProgressScope aPSOuter(theRange, NULL, 10); |
8ae442a8 |
235 | for (i = 1; i <= aNbVE; ++i) { |
d03c0898 |
236 | if (UserBreak(aPSOuter)) |
237 | { |
238 | return; |
239 | } |
8ae442a8 |
240 | const Handle(BOPDS_PaveBlock)& aPB = theVEPairs.FindKey(i); |
241 | Standard_Integer nE = aPB->OriginalEdge(); |
505abfb8 |
242 | // |
3f7e5e99 |
243 | TColStd_MapOfInteger aMVPB; |
244 | const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE); |
245 | for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next()) |
246 | { |
247 | aMVPB.Add (itPB.Value()->Pave1().Index()); |
248 | aMVPB.Add (itPB.Value()->Pave2().Index()); |
249 | } |
250 | |
1155d05a |
251 | const TColStd_ListOfInteger& aLV = theVEPairs(i); |
252 | TColStd_ListIteratorOfListOfInteger aItLV(aLV); |
8ae442a8 |
253 | for (; aItLV.More(); aItLV.Next()) { |
254 | Standard_Integer nV = aItLV.Value(); |
255 | // |
256 | Standard_Integer nVSD = nV; |
257 | myDS->HasShapeSD(nV, nVSD); |
258 | // |
3f7e5e99 |
259 | if (aMVPB.Contains (nVSD)) |
260 | continue; |
261 | |
8ae442a8 |
262 | BOPDS_Pair aPair(nVSD, nE); |
1155d05a |
263 | TColStd_ListOfInteger* pLI = aDMVSD.ChangeSeek(aPair); |
8ae442a8 |
264 | if (pLI) { |
265 | // Already added |
266 | pLI->Append(nV); |
267 | continue; |
268 | } |
269 | // New pair |
1155d05a |
270 | pLI = aDMVSD.Bound(aPair, TColStd_ListOfInteger()); |
8ae442a8 |
271 | pLI->Append(nV); |
272 | // |
273 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nVSD)); |
274 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); |
275 | // |
1155d05a |
276 | BOPAlgo_VertexEdge& aVESolver = aVVE.Appended(); |
8ae442a8 |
277 | aVESolver.SetIndices(nVSD, nE); |
278 | aVESolver.SetVertex(aV); |
279 | aVESolver.SetEdge(aE); |
280 | aVESolver.SetPaveBlock(aPB); |
281 | aVESolver.SetFuzzyValue(myFuzzyValue); |
8ae442a8 |
282 | } |
283 | } |
505abfb8 |
284 | // |
d03c0898 |
285 | aNbVE = aVVE.Length(); |
286 | |
287 | Message_ProgressScope aPS(aPSOuter.Next(9), "Performing Vertex-Edge intersection", aNbVE); |
288 | for (i = 0; i < aNbVE; i++) |
289 | { |
290 | BOPAlgo_VertexEdge& aVESolver = aVVE.ChangeValue(i); |
291 | aVESolver.SetProgressRange(aPS.Next()); |
292 | } |
8ae442a8 |
293 | // Perform intersection |
505abfb8 |
294 | //============================================================= |
fc867b96 |
295 | BOPTools_Parallel::Perform (myRunParallel, aVVE, myContext); |
505abfb8 |
296 | //============================================================= |
d03c0898 |
297 | if (UserBreak(aPSOuter)) |
298 | { |
299 | return; |
300 | } |
505abfb8 |
301 | // |
8ae442a8 |
302 | // Keep the modified edges for further update |
1155d05a |
303 | TColStd_MapOfInteger aMEdges; |
8ae442a8 |
304 | // |
305 | // Analyze intersections |
8ae442a8 |
306 | for (i = 0; i < aNbVE; ++i) { |
d03c0898 |
307 | if (UserBreak(aPSOuter)) |
308 | { |
309 | return; |
310 | } |
8ae442a8 |
311 | const BOPAlgo_VertexEdge& aVESolver = aVVE(i); |
312 | if (aVESolver.Flag() != 0) { |
ad8b073e |
313 | if (aVESolver.HasErrors()) |
314 | { |
315 | // Warn about failed intersection of sub-shapes |
316 | AddIntersectionFailedWarning(aVESolver.Vertex(), aVESolver.Edge()); |
317 | } |
8ae442a8 |
318 | continue; |
319 | } |
320 | // |
321 | Standard_Integer nV, nE; |
322 | aVESolver.Indices(nV, nE); |
323 | // Parameter of vertex on edge |
324 | Standard_Real aT = aVESolver.Parameter(); |
325 | // 1. Update vertex V/E if necessary |
326 | Standard_Real aTolVNew = aVESolver.VertexNewTolerance(); |
327 | Standard_Integer nVx = UpdateVertex(nV, aTolVNew); |
328 | // 2. Create new pave and add it as extra pave to pave block |
329 | // for further splitting of the edge |
3f7e5e99 |
330 | const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE); |
331 | // Find the appropriate one |
332 | Handle(BOPDS_PaveBlock) aPB; |
333 | BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); |
334 | for (; itPB.More(); itPB.Next()) |
335 | { |
336 | aPB = itPB.Value(); |
337 | Standard_Real aT1, aT2; |
338 | aPB->Range (aT1, aT2); |
339 | if (aT > aT1 && aT < aT2) |
340 | break; |
341 | } |
342 | if (!itPB.More()) |
343 | continue; |
344 | |
8ae442a8 |
345 | BOPDS_Pave aPave; |
346 | aPave.SetIndex(nVx); |
347 | aPave.SetParameter(aT); |
348 | aPB->AppendExtPave(aPave); |
349 | aMEdges.Add(nE); |
350 | // |
351 | if (theAddInterfs) { |
352 | // Add interferences into DS |
353 | BOPDS_Pair aPair(nV, nE); |
1155d05a |
354 | const TColStd_ListOfInteger& aLI = aDMVSD.Find(aPair); |
355 | TColStd_ListIteratorOfListOfInteger aItLI(aLI); |
8ae442a8 |
356 | for (; aItLI.More(); aItLI.Next()) { |
357 | const Standard_Integer nVOld = aItLI.Value(); |
358 | // 3. Create interference V/E |
1155d05a |
359 | BOPDS_InterfVE& aVE = aVEs.Appended(); |
8ae442a8 |
360 | aVE.SetIndices(nVOld, nE); |
361 | aVE.SetParameter(aT); |
362 | // 2. Add a pair in the whole table of interferences |
363 | myDS->AddInterf(nVOld, nE); |
364 | // 4. Set index of new vertex in the interference |
365 | if (myDS->IsNewShape(nVx)) { |
366 | aVE.SetIndexNew(nVx); |
3510db62 |
367 | } |
368 | } |
8ae442a8 |
369 | } |
370 | } |
371 | // |
372 | // Split pave blocks of the intersected edges with the extra paves. |
373 | // At the same time compute shrunk data for the new pave blocks |
374 | // and in case there is no valid range for the pave block, |
375 | // the vertices of this pave block should be unified. |
376 | SplitPaveBlocks(aMEdges, theAddInterfs); |
377 | } |
378 | |
379 | //======================================================================= |
380 | // function: MakeNewCommonBlock |
381 | // purpose: Make new Common Block from the given list of Pave Blocks |
382 | //======================================================================= |
383 | static |
384 | void MakeNewCommonBlock(const BOPDS_ListOfPaveBlock& theLPB, |
1155d05a |
385 | const TColStd_ListOfInteger& theLFaces, |
8ae442a8 |
386 | BOPDS_PDS& theDS) |
387 | { |
388 | // Make Common Block from the pave blocks in the list |
389 | Handle(BOPDS_CommonBlock) aCBNew = new BOPDS_CommonBlock; |
390 | aCBNew->SetPaveBlocks(theLPB); |
391 | aCBNew->SetFaces(theLFaces); |
392 | // |
393 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(theLPB); |
394 | for (; aItLPB.More(); aItLPB.Next()) { |
395 | theDS->SetCommonBlock(aItLPB.ChangeValue(), aCBNew); |
396 | } |
397 | } |
398 | |
399 | //======================================================================= |
400 | // function: SplitPaveBlocks |
401 | // purpose: |
402 | //======================================================================= |
1155d05a |
403 | void BOPAlgo_PaveFiller::SplitPaveBlocks(const TColStd_MapOfInteger& theMEdges, |
8ae442a8 |
404 | const Standard_Boolean theAddInterfs) |
405 | { |
406 | // Fence map to avoid unification of the same vertices twice |
407 | BOPDS_MapOfPair aMPairs; |
408 | // Map to treat the Common Blocks |
409 | NCollection_IndexedDataMap<Handle(BOPDS_CommonBlock), |
410 | BOPDS_ListOfPaveBlock, |
411 | TColStd_MapTransientHasher> aMCBNewPB; |
412 | // |
241a6133 |
413 | // Map of vertices to init the pave blocks for them |
414 | TColStd_MapOfInteger aMVerticesToInitPB; |
415 | |
1155d05a |
416 | TColStd_MapIteratorOfMapOfInteger aItM(theMEdges); |
8ae442a8 |
417 | for (; aItM.More(); aItM.Next()) { |
418 | Standard_Integer nE = aItM.Value(); |
419 | BOPDS_ListOfPaveBlock& aLPB = myDS->ChangePaveBlocks(nE); |
420 | // |
421 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
422 | for (; aItLPB.More();) { |
423 | Handle(BOPDS_PaveBlock)& aPB = aItLPB.ChangeValue(); |
424 | // |
425 | if (!aPB->IsToUpdate()) { |
426 | aItLPB.Next(); |
3510db62 |
427 | continue; |
8ae442a8 |
428 | } |
429 | // |
430 | const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB); |
431 | // |
432 | // Compute new pave blocks |
433 | BOPDS_ListOfPaveBlock aLPBN; |
434 | aPB->Update(aLPBN); |
435 | // |
436 | // Make sure that each new pave block has a valid range, |
437 | // otherwise unify the vertices of the pave block |
438 | BOPDS_ListIteratorOfListOfPaveBlock aItLPBN(aLPBN); |
439 | for (; aItLPBN.More(); aItLPBN.Next()) { |
440 | Handle(BOPDS_PaveBlock)& aPBN = aItLPBN.ChangeValue(); |
441 | myDS->UpdatePaveBlockWithSDVertices(aPBN); |
442 | FillShrunkData(aPBN); |
443 | // |
e25185ff |
444 | Standard_Boolean bHasValidRange = aPBN->HasShrunkData(); |
445 | // Take into account that the edge could have really small valid range, |
446 | // so that the Pave Block cannot be further split. In this case, check if |
447 | // the vertices of the Pave Block do not interfere. And if they are, unify them. |
448 | Standard_Boolean bCheckDist = (bHasValidRange && !aPBN->IsSplittable()); |
449 | if (!bHasValidRange || bCheckDist) |
450 | { |
8ae442a8 |
451 | Standard_Integer nV1, nV2; |
452 | aPBN->Indices(nV1, nV2); |
e25185ff |
453 | if (nV1 == nV2) |
454 | // Same vertices -> no valid range, no need to unify vertices |
455 | continue; |
456 | |
457 | // Decide whether to unify vertices or not |
458 | if (bCheckDist) |
459 | { |
460 | const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1)); |
461 | const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2)); |
462 | if (BOPTools_AlgoTools::ComputeVV(aV1, aV2, myFuzzyValue) == 0) |
463 | // vertices are interfering -> no valid range, unify vertices |
464 | bHasValidRange = Standard_False; |
465 | } |
466 | |
467 | if (!bHasValidRange) |
468 | { |
8ae442a8 |
469 | BOPDS_Pair aPair; |
470 | aPair.SetIndices(nV1, nV2); |
e25185ff |
471 | if (aMPairs.Add(aPair)) |
472 | { |
1155d05a |
473 | TColStd_ListOfInteger aLV; |
8ae442a8 |
474 | aLV.Append(nV1); |
475 | aLV.Append(nV2); |
476 | MakeSDVertices(aLV, theAddInterfs); |
241a6133 |
477 | |
478 | // Save vertices to init pave blocks |
479 | aMVerticesToInitPB.Add(nV1); |
480 | aMVerticesToInitPB.Add(nV2); |
8ae442a8 |
481 | } |
e25185ff |
482 | continue; |
8ae442a8 |
483 | } |
8ae442a8 |
484 | } |
485 | // |
486 | // Update the list with new pave block |
487 | aLPB.Append(aPBN); |
488 | // Treat the common block |
489 | if (!aCB.IsNull()) { |
490 | // Store the new pave block to make new common block |
491 | BOPDS_ListOfPaveBlock* pLPBCB = aMCBNewPB.ChangeSeek(aCB); |
492 | if (!pLPBCB) { |
493 | pLPBCB = &aMCBNewPB(aMCBNewPB.Add(aCB, BOPDS_ListOfPaveBlock())); |
494 | } |
495 | pLPBCB->Append(aPBN); |
496 | } |
497 | } |
498 | // Remove old pave block |
499 | aLPB.Remove(aItLPB); |
500 | } |
501 | } |
502 | // |
503 | // Make Common Blocks |
504 | Standard_Integer i, aNbCB = aMCBNewPB.Extent(); |
505 | for (i = 1; i <= aNbCB; ++i) { |
506 | const Handle(BOPDS_CommonBlock)& aCB = aMCBNewPB.FindKey(i); |
507 | const BOPDS_ListOfPaveBlock& aLPBN = aMCBNewPB(i); |
508 | // |
509 | // For each group of pave blocks with the same vertices make new common block |
510 | NCollection_IndexedDataMap<BOPDS_Pair, BOPDS_ListOfPaveBlock, BOPDS_PairMapHasher> aMInds; |
511 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBN); |
512 | for (; aItLPB.More(); aItLPB.Next()) { |
513 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
3510db62 |
514 | // |
8ae442a8 |
515 | BOPDS_Pair aPair; |
516 | aPair.SetIndices(aPB->Pave1().Index(), aPB->Pave2().Index()); |
3510db62 |
517 | // |
8ae442a8 |
518 | BOPDS_ListOfPaveBlock* pLPBx = aMInds.ChangeSeek(aPair); |
519 | if (!pLPBx) { |
520 | pLPBx = &aMInds(aMInds.Add(aPair, BOPDS_ListOfPaveBlock())); |
3510db62 |
521 | } |
8ae442a8 |
522 | pLPBx->Append(aPB); |
4e57c75e |
523 | } |
8ae442a8 |
524 | // |
525 | Standard_Integer nV1, nV2; |
526 | aCB->PaveBlock1()->Indices(nV1, nV2); |
527 | Standard_Boolean bIsClosed = (nV1 == nV2); |
528 | // |
529 | Standard_Integer j, aNbPairs = aMInds.Extent(); |
530 | for (j = 1; j <= aNbPairs; ++j) { |
531 | BOPDS_ListOfPaveBlock& aLPB = aMInds(j); |
532 | // |
533 | if (!bIsClosed) { |
534 | // Make Common Block from the pave blocks in the list |
535 | MakeNewCommonBlock(aLPB, aCB->Faces(), myDS); |
536 | continue; |
537 | } |
538 | // |
539 | // Find coinciding pave blocks |
540 | while (aLPB.Extent()) { |
541 | // Pave blocks forming the common block |
542 | BOPDS_ListOfPaveBlock aLPBCB; |
543 | // Point in the middle of the first pave block in the common block |
544 | gp_Pnt aPMFirst(0., 0., 0.); |
545 | // Tolerance of the first edge in the common block |
546 | Standard_Real aTolEFirst = 0.; |
547 | // |
548 | aItLPB.Initialize(aLPB); |
549 | for (; aItLPB.More();) { |
550 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
551 | if (aLPBCB.IsEmpty()) { |
552 | aLPBCB.Append(aPB); |
553 | const TopoDS_Edge& aEFirst = TopoDS::Edge(myDS->Shape(aPB->OriginalEdge())); |
554 | aTolEFirst = BRep_Tool::MaxTolerance(aEFirst, TopAbs_VERTEX); |
555 | // |
556 | Standard_Real aTmFirst = (aPB->Pave1().Parameter() + aPB->Pave2().Parameter()) / 2.; |
557 | BOPTools_AlgoTools::PointOnEdge(aEFirst, aTmFirst, aPMFirst); |
558 | // |
559 | aLPB.Remove(aItLPB); |
560 | continue; |
561 | } |
562 | // |
563 | // Check pave blocks for coincidence |
564 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->OriginalEdge())); |
565 | Standard_Real aTolE = BRep_Tool::MaxTolerance(aE, TopAbs_VERTEX); |
566 | // |
567 | Standard_Real aTOut, aDist; |
568 | Standard_Integer iErr = |
569 | myContext->ComputePE(aPMFirst, aTolEFirst + aTolE + myFuzzyValue, aE, aTOut, aDist); |
570 | if (!iErr && ((aTOut > aPB->Pave1().Parameter()) && (aTOut < aPB->Pave2().Parameter()))) { |
571 | aLPBCB.Append(aPB); |
572 | aLPB.Remove(aItLPB); |
573 | continue; |
574 | } |
575 | aItLPB.Next(); |
576 | } |
577 | // |
578 | // Make Common Block from the pave blocks in the list |
579 | MakeNewCommonBlock(aLPBCB, aCB->Faces(), myDS); |
580 | } |
581 | } |
582 | } |
241a6133 |
583 | |
584 | // Init pave blocks for vertices which have acquired SD vertex |
585 | aItM.Initialize(aMVerticesToInitPB); |
586 | for (; aItM.More(); aItM.Next()) |
587 | myDS->InitPaveBlocksForVertex(aItM.Value()); |
8ae442a8 |
588 | } |
ad8b073e |
589 | |
590 | //======================================================================= |
591 | // function: AddIntersectionFailedWarning |
592 | // purpose: |
593 | //======================================================================= |
594 | void BOPAlgo_PaveFiller::AddIntersectionFailedWarning(const TopoDS_Shape& theS1, |
595 | const TopoDS_Shape& theS2) |
596 | { |
597 | // Create the warn shape |
598 | TopoDS_Compound aWC; |
599 | BRep_Builder().MakeCompound(aWC); |
600 | BRep_Builder().Add(aWC, theS1); |
601 | BRep_Builder().Add(aWC, theS2); |
602 | // Add the warning |
603 | AddWarning(new BOPAlgo_AlertIntersectionOfPairOfShapesFailed(aWC)); |
241a6133 |
604 | } |