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