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 | |
19 | #include <Bnd_Box.hxx> |
42cf5bc1 |
20 | #include <BOPAlgo_PaveFiller.hxx> |
42cf5bc1 |
21 | #include <BOPAlgo_Tools.hxx> |
33ba8565 |
22 | #include <BOPAlgo_Alerts.hxx> |
4e57c75e |
23 | #include <BOPDS_CommonBlock.hxx> |
24 | #include <BOPDS_CoupleOfPaveBlocks.hxx> |
42cf5bc1 |
25 | #include <BOPDS_DS.hxx> |
4e57c75e |
26 | #include <BOPDS_Interf.hxx> |
42cf5bc1 |
27 | #include <BOPDS_Iterator.hxx> |
28 | #include <BOPDS_MapOfPaveBlock.hxx> |
4e57c75e |
29 | #include <BOPDS_Pave.hxx> |
42cf5bc1 |
30 | #include <BOPDS_PaveBlock.hxx> |
31 | #include <BOPDS_VectorOfInterfEE.hxx> |
32 | #include <BOPTools_AlgoTools.hxx> |
d3578357 |
33 | #include <BOPTools_AlgoTools2D.hxx> |
1155d05a |
34 | #include <BOPTools_Parallel.hxx> |
01b5b3df |
35 | #include <BndLib_Add3dCurve.hxx> |
42cf5bc1 |
36 | #include <BRep_Tool.hxx> |
33ba8565 |
37 | #include <BRep_Builder.hxx> |
3510db62 |
38 | #include <BRepAdaptor_Curve.hxx> |
d3578357 |
39 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
42cf5bc1 |
40 | #include <gp_Pnt.hxx> |
41 | #include <IntTools_CommonPrt.hxx> |
42 | #include <IntTools_Context.hxx> |
43 | #include <IntTools_EdgeEdge.hxx> |
44 | #include <IntTools_Range.hxx> |
45 | #include <IntTools_SequenceOfCommonPrts.hxx> |
46 | #include <IntTools_SequenceOfRanges.hxx> |
47 | #include <IntTools_ShrunkRange.hxx> |
48 | #include <IntTools_Tools.hxx> |
b7cd7c2b |
49 | #include <NCollection_IncAllocator.hxx> |
1155d05a |
50 | #include <NCollection_Vector.hxx> |
42cf5bc1 |
51 | #include <Precision.hxx> |
8ae442a8 |
52 | #include <TopoDS.hxx> |
42cf5bc1 |
53 | #include <TopoDS_Edge.hxx> |
42cf5bc1 |
54 | #include <TopoDS_Vertex.hxx> |
db8e4b9a |
55 | |
a2098360 |
56 | ///////////////////////////////////////////////////////////////////////// |
a942f2da |
57 | //======================================================================= |
58 | //class : BOPAlgo_EdgeEdge |
59 | //purpose : |
60 | //======================================================================= |
36f4947b |
61 | class BOPAlgo_EdgeEdge : |
62 | public IntTools_EdgeEdge, |
63 | public BOPAlgo_Algo { |
64 | |
a942f2da |
65 | public: |
36f4947b |
66 | |
67 | DEFINE_STANDARD_ALLOC |
68 | // |
69 | BOPAlgo_EdgeEdge(): |
70 | IntTools_EdgeEdge(), |
71 | BOPAlgo_Algo() { |
a942f2da |
72 | }; |
73 | // |
36f4947b |
74 | virtual ~BOPAlgo_EdgeEdge(){ |
a942f2da |
75 | }; |
76 | // |
77 | void SetPaveBlock1(const Handle(BOPDS_PaveBlock)& aPB) { |
78 | myPB1=aPB; |
79 | } |
80 | // |
81 | Handle(BOPDS_PaveBlock)& PaveBlock1() { |
82 | return myPB1; |
83 | } |
84 | // |
85 | void SetPaveBlock2(const Handle(BOPDS_PaveBlock)& aPB) { |
86 | myPB2=aPB; |
87 | } |
88 | // |
89 | Handle(BOPDS_PaveBlock)& PaveBlock2() { |
90 | return myPB2; |
91 | } |
36f4947b |
92 | // |
0d0481c7 |
93 | void SetFuzzyValue(const Standard_Real theFuzz) { |
94 | IntTools_EdgeEdge::SetFuzzyValue(theFuzz); |
95 | } |
96 | // |
36f4947b |
97 | virtual void Perform() { |
98 | BOPAlgo_Algo::UserBreak(); |
ad8b073e |
99 | try |
100 | { |
101 | OCC_CATCH_SIGNALS |
102 | |
103 | IntTools_EdgeEdge::Perform(); |
104 | } |
105 | catch (Standard_Failure) |
106 | { |
107 | AddError(new BOPAlgo_AlertIntersectionFailed); |
108 | } |
36f4947b |
109 | } |
a942f2da |
110 | // |
111 | protected: |
112 | Handle(BOPDS_PaveBlock) myPB1; |
113 | Handle(BOPDS_PaveBlock) myPB2; |
114 | }; |
115 | // |
505abfb8 |
116 | //======================================================================= |
1155d05a |
117 | typedef NCollection_Vector |
505abfb8 |
118 | <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; |
a942f2da |
119 | // |
1155d05a |
120 | typedef BOPTools_Functor |
505abfb8 |
121 | <BOPAlgo_EdgeEdge, |
122 | BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor; |
123 | // |
1155d05a |
124 | typedef BOPTools_Cnt |
505abfb8 |
125 | <BOPAlgo_EdgeEdgeFunctor, |
126 | BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt; |
a942f2da |
127 | // |
a2098360 |
128 | ///////////////////////////////////////////////////////////////////////// |
129 | //======================================================================= |
4e57c75e |
130 | // function: PerformEE |
131 | // purpose: |
132 | //======================================================================= |
db8e4b9a |
133 | void BOPAlgo_PaveFiller::PerformEE() |
4e57c75e |
134 | { |
505abfb8 |
135 | FillShrunkData(TopAbs_EDGE, TopAbs_EDGE); |
136 | // |
4e57c75e |
137 | myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE); |
33ba8565 |
138 | Standard_Integer iSize = myIterator->ExpectedLength(); |
4e57c75e |
139 | if (!iSize) { |
140 | return; |
141 | } |
142 | // |
25dfc507 |
143 | Standard_Boolean bExpressCompute, bIsPBSplittable1, bIsPBSplittable2; |
01b5b3df |
144 | Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge; |
6dc83e21 |
145 | Standard_Integer nV11, nV12, nV21, nV22; |
a942f2da |
146 | Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22; |
147 | TopAbs_ShapeEnum aType; |
148 | BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2; |
488e5b9d |
149 | Handle(NCollection_BaseAllocator) aAllocator; |
a942f2da |
150 | BOPAlgo_VectorOfEdgeEdge aVEdgeEdge; |
151 | BOPDS_MapIteratorOfMapOfPaveBlock aItPB; |
8ae442a8 |
152 | // keep modified edges for further update |
1155d05a |
153 | TColStd_MapOfInteger aMEdges; |
a942f2da |
154 | // |
488e5b9d |
155 | aAllocator=NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
156 | //-----------------------------------------------------scope f |
4e57c75e |
157 | BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator); |
158 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator); |
01b5b3df |
159 | BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator); |
4e57c75e |
160 | // |
4e57c75e |
161 | BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); |
4e57c75e |
162 | aEEs.SetIncrement(iSize); |
4e57c75e |
163 | // |
164 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
165 | myIterator->Value(nE1, nE2); |
4e57c75e |
166 | // |
167 | const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1); |
168 | if (aSIE1.HasFlag()){ |
169 | continue; |
170 | } |
171 | const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2); |
172 | if (aSIE2.HasFlag()){ |
173 | continue; |
174 | } |
175 | // |
752f9d72 |
176 | BOPDS_ListOfPaveBlock& aLPB1 = myDS->ChangePaveBlocks(nE1); |
177 | if (aLPB1.IsEmpty()) { |
178 | continue; |
179 | } |
180 | // |
181 | BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE2); |
182 | if (aLPB2.IsEmpty()) { |
183 | continue; |
184 | } |
185 | // |
4e57c75e |
186 | const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape())); |
01b5b3df |
187 | const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape())); |
4e57c75e |
188 | // |
4e57c75e |
189 | aIt1.Initialize(aLPB1); |
190 | for (; aIt1.More(); aIt1.Next()) { |
191 | Bnd_Box aBB1; |
192 | // |
193 | Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue(); |
01b5b3df |
194 | // |
195 | if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) { |
505abfb8 |
196 | continue; |
4e57c75e |
197 | } |
4e57c75e |
198 | // |
6dc83e21 |
199 | aPB1->Indices(nV11, nV12); |
200 | // |
4e57c75e |
201 | aIt2.Initialize(aLPB2); |
202 | for (; aIt2.More(); aIt2.Next()) { |
203 | Bnd_Box aBB2; |
204 | // |
205 | Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue(); |
01b5b3df |
206 | // |
207 | if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) { |
505abfb8 |
208 | continue; |
4e57c75e |
209 | } |
4e57c75e |
210 | // |
211 | if (aBB1.IsOut(aBB2)) { |
212 | continue; |
213 | } |
214 | // |
6dc83e21 |
215 | aPB2->Indices(nV21, nV22); |
216 | // |
217 | bExpressCompute=((nV11==nV21 && nV12==nV22) || |
218 | (nV12==nV21 && nV11==nV22)); |
219 | // |
1155d05a |
220 | BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Appended(); |
6dc83e21 |
221 | // |
222 | anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute); |
223 | // |
a942f2da |
224 | anEdgeEdge.SetPaveBlock1(aPB1); |
225 | anEdgeEdge.SetPaveBlock2(aPB2); |
226 | // |
ec0cdc0e |
227 | anEdgeEdge.SetEdge1(aE1, aT11, aT12); |
228 | anEdgeEdge.SetEdge2(aE2, aT21, aT22); |
0d0481c7 |
229 | anEdgeEdge.SetFuzzyValue(myFuzzyValue); |
36f4947b |
230 | anEdgeEdge.SetProgressIndicator(myProgressIndicator); |
a942f2da |
231 | }//for (; aIt2.More(); aIt2.Next()) { |
232 | }//for (; aIt1.More(); aIt1.Next()) { |
233 | }//for (; myIterator->More(); myIterator->Next()) { |
234 | // |
1155d05a |
235 | aNbEdgeEdge=aVEdgeEdge.Length(); |
a942f2da |
236 | //====================================================== |
237 | BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge); |
238 | //====================================================== |
239 | // |
01b5b3df |
240 | for (k = 0; k < aNbEdgeEdge; ++k) { |
a942f2da |
241 | Bnd_Box aBB1, aBB2; |
242 | // |
243 | BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k); |
ad8b073e |
244 | if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors()) { |
245 | // Warn about failed intersection of sub-shapes |
246 | const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge()); |
247 | const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge()); |
248 | AddIntersectionFailedWarning(aE1, aE2); |
a942f2da |
249 | continue; |
250 | } |
251 | // |
51db0179 |
252 | const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts(); |
253 | aNbCPrts = aCPrts.Length(); |
254 | if (!aNbCPrts) { |
255 | continue; |
256 | } |
a942f2da |
257 | //-------------------------------------------- |
258 | Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1(); |
259 | nE1=aPB1->OriginalEdge(); |
260 | aPB1->Range(aT11, aT12); |
01b5b3df |
261 | if (!aPB1->HasShrunkData()) { |
262 | aTS11 = aT11; |
263 | aTS12 = aT12; |
264 | bIsPBSplittable1 = Standard_False; |
265 | } |
266 | else { |
267 | aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1); |
268 | } |
a942f2da |
269 | // |
270 | Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2(); |
271 | nE2=aPB2->OriginalEdge(); |
272 | aPB2->Range(aT21, aT22); |
01b5b3df |
273 | if (!aPB2->HasShrunkData()) { |
274 | aTS21 = aT21; |
275 | aTS22 = aT22; |
276 | bIsPBSplittable2 = Standard_False; |
277 | } |
278 | else { |
279 | aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2); |
280 | } |
a942f2da |
281 | // |
282 | //-------------------------------------------- |
283 | IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12), |
284 | aR21(aT21, aTS21), aR22(aTS22, aT22); |
285 | // |
3065019c |
286 | Standard_Boolean bAnalytical = Standard_False; |
51db0179 |
287 | { |
3510db62 |
288 | const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1); |
289 | const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2); |
290 | // |
291 | BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2); |
292 | // |
3065019c |
293 | GeomAbs_CurveType aType1 = aBAC1.GetType(); |
294 | GeomAbs_CurveType aType2 = aBAC2.GetType(); |
295 | // |
296 | bAnalytical = (((aType1 == GeomAbs_Line) && |
297 | (aType2 == GeomAbs_Line || |
298 | aType2 == GeomAbs_Circle)) || |
299 | ((aType2 == GeomAbs_Line) && |
300 | (aType1 == GeomAbs_Line || |
301 | aType1 == GeomAbs_Circle))); |
3510db62 |
302 | } |
303 | // |
a942f2da |
304 | for (i=1; i<=aNbCPrts; ++i) { |
305 | const IntTools_CommonPrt& aCPart=aCPrts(i); |
306 | // |
307 | const TopoDS_Edge& aE1=aCPart.Edge1(); |
308 | const TopoDS_Edge& aE2=aCPart.Edge2(); |
309 | // |
310 | aType=aCPart.Type(); |
311 | switch (aType) { |
312 | case TopAbs_VERTEX: { |
01b5b3df |
313 | if (!bIsPBSplittable1 || !bIsPBSplittable2) { |
314 | continue; |
315 | } |
316 | // |
d3578357 |
317 | Standard_Boolean bIsOnPave[4]; |
a942f2da |
318 | Standard_Integer nV[4], j; |
319 | Standard_Real aT1, aT2, aTol; |
320 | TopoDS_Vertex aVnew; |
321 | IntTools_Range aCR1, aCR2; |
322 | // |
1e143abb |
323 | IntTools_Tools::VertexParameters(aCPart, aT1, aT2); |
a942f2da |
324 | aTol = Precision::Confusion(); |
325 | aCR1 = aCPart.Range1(); |
326 | aCR2 = aCPart.Ranges2()(1); |
327 | // |
328 | //decide to keep the pave or not |
1e143abb |
329 | bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) || |
330 | IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol); |
331 | bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || |
332 | IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol); |
333 | bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) || |
334 | IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol); |
335 | bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) || |
336 | IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol); |
a942f2da |
337 | // |
338 | aPB1->Indices(nV[0], nV[1]); |
339 | aPB2->Indices(nV[2], nV[3]); |
340 | // |
341 | if((bIsOnPave[0] && bIsOnPave[2]) || |
342 | (bIsOnPave[0] && bIsOnPave[3]) || |
343 | (bIsOnPave[1] && bIsOnPave[2]) || |
344 | (bIsOnPave[1] && bIsOnPave[3])) { |
345 | continue; |
346 | } |
347 | // |
d3578357 |
348 | Standard_Boolean isVExists = Standard_False; |
349 | for (j = 0; j < 4; ++j) |
350 | { |
351 | if (bIsOnPave[j]) |
352 | { |
a942f2da |
353 | Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1; |
d3578357 |
354 | bIsOnPave[j] = ForceInterfVE(nV[j], aPB, aMEdges); |
355 | if (bIsOnPave[j]) isVExists = Standard_True; |
a942f2da |
356 | } |
357 | } |
d3578357 |
358 | |
a942f2da |
359 | BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew); |
d3578357 |
360 | const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew); |
361 | |
362 | if (isVExists) |
363 | { |
364 | // The found intersection point is located closely to one of the |
365 | // pave blocks bounds. So, do not create the new vertex in this point. |
366 | // Check if this point is a real intersection point or just a touching point. |
367 | // If it is a touching point, do nothing. |
368 | // If it is an intersection point, update the existing vertex to cover the |
369 | // intersection point. |
370 | const gp_Pnt aPOnE1 = BRepAdaptor_Curve(aE1).Value(aT1); |
371 | const gp_Pnt aPOnE2 = BRepAdaptor_Curve(aE2).Value(aT2); |
372 | if (aPOnE1.Distance(aPOnE2) > Precision::Intersection()) |
373 | // No intersection point |
374 | continue; |
375 | |
376 | // Real intersection is present. |
377 | // Update the existing vertex to cover the intersection point. |
378 | for (j = 0; j < 4; ++j) |
379 | { |
380 | if (bIsOnPave[j]) |
381 | { |
382 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j])); |
383 | const gp_Pnt aP = BRep_Tool::Pnt(aV); |
384 | Standard_Real aDistPP = aP.Distance(aPnew); |
385 | // Just update the vertex |
386 | UpdateVertex(nV[j], aDistPP); |
387 | myVertsToAvoidExtension.Add(nV[j]); |
388 | } |
389 | } |
390 | } |
391 | |
3510db62 |
392 | Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew); |
3065019c |
393 | if (bAnalytical) { |
3510db62 |
394 | // increase tolerance for Line/Line intersection, but do not update |
395 | // the vertex till its intersection with some other shape |
3065019c |
396 | Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ? |
397 | (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.; |
8bb8064e |
398 | if (aTolMin > aTolVnew) { |
399 | aTolVnew = aTolMin; |
3510db62 |
400 | } |
401 | } |
a942f2da |
402 | // <-LXBR |
403 | { |
51740958 |
404 | Standard_Integer nVS[2], iFound; |
3510db62 |
405 | Standard_Real aTolVx, aD2, aDT2; |
1155d05a |
406 | TColStd_MapOfInteger aMV; |
d3578357 |
407 | gp_Pnt aPx; |
4e57c75e |
408 | // |
a942f2da |
409 | iFound=0; |
410 | j=-1; |
411 | aMV.Add(nV[0]); |
412 | aMV.Add(nV[1]); |
413 | // |
414 | if (aMV.Contains(nV[2])) { |
415 | ++j; |
416 | nVS[j]=nV[2]; |
417 | } |
418 | if (aMV.Contains(nV[3])) { |
419 | ++j; |
420 | nVS[j]=nV[3]; |
421 | } |
422 | // |
51740958 |
423 | for (Standard_Integer k1=0; k1<=j; ++k1) { |
424 | const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1])); |
a942f2da |
425 | aTolVx=BRep_Tool::Tolerance(aVx); |
426 | aPx=BRep_Tool::Pnt(aVx); |
427 | aD2=aPnew.SquareDistance(aPx); |
428 | // |
429 | aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx); |
7eed5d29 |
430 | // |
a942f2da |
431 | if (aD2<aDT2) { |
432 | iFound=1; |
4e57c75e |
433 | break; |
434 | } |
a942f2da |
435 | } |
436 | // |
437 | if (iFound) { |
438 | continue; |
439 | } |
440 | } |
402bfe81 |
441 | // |
a942f2da |
442 | // 1 |
1155d05a |
443 | BOPDS_InterfEE& aEE=aEEs.Appended(); |
444 | iX=aEEs.Length()-1; |
a942f2da |
445 | aEE.SetIndices(nE1, nE2); |
446 | aEE.SetCommonPart(aCPart); |
447 | // 2 |
448 | myDS->AddInterf(nE1, nE2); |
449 | // |
450 | BOPDS_CoupleOfPaveBlocks aCPB; |
451 | // |
452 | aCPB.SetPaveBlocks(aPB1, aPB2); |
453 | aCPB.SetIndexInterf(iX); |
3510db62 |
454 | aCPB.SetTolerance(aTolVnew); |
a942f2da |
455 | aMVCPB.Add(aVnew, aCPB); |
456 | }//case TopAbs_VERTEX: |
457 | break; |
458 | // |
459 | case TopAbs_EDGE: { |
460 | if (aNbCPrts > 1) { |
4e57c75e |
461 | break; |
a942f2da |
462 | } |
463 | // |
464 | Standard_Boolean bHasSameBounds; |
465 | bHasSameBounds=aPB1->HasSameBounds(aPB2); |
466 | if (!bHasSameBounds) { |
467 | break; |
468 | } |
469 | // 1 |
1155d05a |
470 | BOPDS_InterfEE& aEE=aEEs.Appended(); |
471 | iX=aEEs.Length()-1; |
a942f2da |
472 | aEE.SetIndices(nE1, nE2); |
473 | aEE.SetCommonPart(aCPart); |
474 | // 2 |
475 | myDS->AddInterf(nE1, nE2); |
476 | // |
edfa30de |
477 | BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), TColStd_MapTransientHasher>(aPB1, aPB2, aMPBLPB, aAllocator); |
a942f2da |
478 | }//case TopAbs_EDGE |
479 | break; |
480 | default: |
481 | break; |
482 | }//switch (aType) { |
483 | }//for (i=1; i<=aNbCPrts; i++) { |
484 | }//for (k=0; k < aNbFdgeEdge; ++k) { |
4e57c75e |
485 | // |
486 | //========================================= |
487 | // post treatment |
488 | //========================================= |
d3578357 |
489 | BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS, myContext); |
490 | // Update vertices of common blocks with real CB tolerances |
491 | UpdateVerticesOfCB(); |
492 | |
8ae442a8 |
493 | PerformNewVertices(aMVCPB, aAllocator); |
494 | // |
495 | if (aMEdges.Extent()) { |
496 | Standard_Integer aNbV = aMVCPB.Extent(); |
497 | for (i = 1; i <= aNbV; ++i) { |
498 | Handle(BOPDS_PaveBlock) aPB1, aPB2; |
499 | const BOPDS_CoupleOfPaveBlocks& aCPB = aMVCPB.FindFromIndex(i); |
500 | aCPB.PaveBlocks(aPB1, aPB2); |
a3476a9f |
501 | // |
8ae442a8 |
502 | aMEdges.Remove(aPB1->OriginalEdge()); |
503 | aMEdges.Remove(aPB2->OriginalEdge()); |
b4109929 |
504 | } |
8ae442a8 |
505 | // |
506 | SplitPaveBlocks(aMEdges, Standard_False); |
b4109929 |
507 | } |
508 | // |
4e57c75e |
509 | //-----------------------------------------------------scope t |
510 | aMPBLPB.Clear(); |
511 | aMVCPB.Clear(); |
4e57c75e |
512 | } |
513 | //======================================================================= |
3510db62 |
514 | //function : PerformVerticesEE |
4e57c75e |
515 | //purpose : |
516 | //======================================================================= |
8ae442a8 |
517 | void BOPAlgo_PaveFiller::PerformNewVertices |
db8e4b9a |
518 | (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, |
8ae442a8 |
519 | const Handle(NCollection_BaseAllocator)& theAllocator, |
520 | const Standard_Boolean bIsEEIntersection) |
4e57c75e |
521 | { |
8ae442a8 |
522 | Standard_Integer aNbV = theMVCPB.Extent(); |
4e57c75e |
523 | if (!aNbV) { |
8ae442a8 |
524 | return; |
4e57c75e |
525 | } |
526 | // |
8ae442a8 |
527 | Standard_Real aTolAdd = myFuzzyValue / 2.; |
4e57c75e |
528 | // |
8ae442a8 |
529 | // 1. Fuse the new vertices |
1155d05a |
530 | TopTools_IndexedDataMapOfShapeListOfShape aImages; |
3510db62 |
531 | TreatNewVertices(theMVCPB, aImages); |
4e57c75e |
532 | // |
8ae442a8 |
533 | // 2. Add new vertices to myDS and connect indices to CPB structure |
534 | BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE(); |
535 | BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF(); |
536 | // |
537 | Standard_Integer i, aNb = aImages.Extent(); |
538 | for (i = 1; i <= aNb; ++i) { |
539 | const TopoDS_Vertex& aV = TopoDS::Vertex(aImages.FindKey(i)); |
1155d05a |
540 | const TopTools_ListOfShape& aLVSD = aImages.FindFromIndex(i); |
4e57c75e |
541 | // |
8ae442a8 |
542 | BOPDS_ShapeInfo aSI; |
543 | aSI.SetShapeType(TopAbs_VERTEX); |
4e57c75e |
544 | aSI.SetShape(aV); |
8ae442a8 |
545 | Standard_Integer iV = myDS->Append(aSI); |
4e57c75e |
546 | // |
8ae442a8 |
547 | BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV); |
548 | Bnd_Box& aBox = aSIDS.ChangeBox(); |
549 | aBox.Add(BRep_Tool::Pnt(aV)); |
550 | aBox.SetGap(BRep_Tool::Tolerance(aV) + aTolAdd); |
4e57c75e |
551 | // |
1155d05a |
552 | TopTools_ListIteratorOfListOfShape aItLS(aLVSD); |
4e57c75e |
553 | for (; aItLS.More(); aItLS.Next()) { |
554 | const TopoDS_Shape& aVx = aItLS.Value(); |
8ae442a8 |
555 | BOPDS_CoupleOfPaveBlocks &aCPB = theMVCPB.ChangeFromKey(aVx); |
4e57c75e |
556 | aCPB.SetIndex(iV); |
8ae442a8 |
557 | // update interference |
558 | Standard_Integer iX = aCPB.IndexInterf(); |
559 | BOPDS_Interf *aInt = bIsEEIntersection ? (BOPDS_Interf*)(&aEEs(iX)) : (BOPDS_Interf*) (&aEFs(iX)); |
560 | aInt->SetIndexNew(iV); |
4e57c75e |
561 | } |
562 | } |
563 | // |
8ae442a8 |
564 | // 3. Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI |
565 | BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator); |
566 | for (i = 1; i <= aNbV; ++i) { |
567 | const BOPDS_CoupleOfPaveBlocks& aCPB = theMVCPB.FindFromIndex(i); |
568 | Standard_Integer iV = aCPB.Index(); |
4e57c75e |
569 | // |
8ae442a8 |
570 | Handle(BOPDS_PaveBlock) aPB[2]; |
571 | aCPB.PaveBlocks(aPB[0], aPB[1]); |
572 | for (Standard_Integer j = 0; j < 2; ++j) { |
1155d05a |
573 | TColStd_ListOfInteger *pLI = aMPBLI.ChangeSeek(aPB[j]); |
8ae442a8 |
574 | if (!pLI) { |
1155d05a |
575 | pLI = &aMPBLI(aMPBLI.Add(aPB[j], TColStd_ListOfInteger(theAllocator))); |
4e57c75e |
576 | } |
8ae442a8 |
577 | pLI->Append(iV); |
4e57c75e |
578 | // |
8ae442a8 |
579 | if (aPB[0] == aPB[1]) { |
580 | break; |
581 | } |
4e57c75e |
582 | } |
583 | } |
4e57c75e |
584 | // |
8ae442a8 |
585 | // 4. Compute Extra Paves and split Pave blocks by the Extra paves |
586 | IntersectVE(aMPBLI, Standard_False); |
4e57c75e |
587 | } |
4e57c75e |
588 | //======================================================================= |
589 | //function : TreatNewVertices |
590 | //purpose : |
591 | //======================================================================= |
db8e4b9a |
592 | void BOPAlgo_PaveFiller::TreatNewVertices |
8ae442a8 |
593 | (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, |
1155d05a |
594 | TopTools_IndexedDataMapOfShapeListOfShape& myImages) |
4e57c75e |
595 | { |
4e57c75e |
596 | // |
8ae442a8 |
597 | // Prepare for intersection |
1155d05a |
598 | TopTools_IndexedDataMapOfShapeReal aVerts; |
8ae442a8 |
599 | Standard_Integer i, aNbV = theMVCPB.Extent(); |
600 | for (i = 1; i <= aNbV; ++i) { |
601 | const TopoDS_Shape& aV = theMVCPB.FindKey(i); |
602 | Standard_Real aTol = theMVCPB.FindFromIndex(i).Tolerance(); |
603 | aVerts.Add(aV, aTol); |
4e57c75e |
604 | } |
605 | // |
8ae442a8 |
606 | // Perform intersection |
1155d05a |
607 | TopTools_ListOfListOfShape aChains; |
8ae442a8 |
608 | BOPAlgo_Tools::IntersectVertices(aVerts, myRunParallel, myFuzzyValue, aChains); |
a2098360 |
609 | // |
8ae442a8 |
610 | // Treat the results - make new vertices for each chain |
1155d05a |
611 | TopTools_ListOfListOfShape::Iterator aItC(aChains); |
8ae442a8 |
612 | for (; aItC.More(); aItC.Next()) { |
1155d05a |
613 | const TopTools_ListOfShape& aLVSD = aItC.Value(); |
4e57c75e |
614 | // |
8ae442a8 |
615 | TopoDS_Vertex aVNew; |
616 | BOPTools_AlgoTools::MakeVertex(aLVSD, aVNew); |
617 | myImages.Add(aVNew, aLVSD); |
4e57c75e |
618 | } |
619 | } |
4e57c75e |
620 | //======================================================================= |
621 | //function : FillShrunkData |
622 | //purpose : |
623 | //======================================================================= |
db8e4b9a |
624 | void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB) |
4e57c75e |
625 | { |
33ba8565 |
626 | // Vertices |
627 | Standard_Integer nV1, nV2; |
628 | thePB->Indices(nV1, nV2); |
4e57c75e |
629 | const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
4e57c75e |
630 | const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
d3578357 |
631 | // Get the edge |
33ba8565 |
632 | Standard_Integer nE = thePB->OriginalEdge(); |
d3578357 |
633 | if (nE < 0 && !thePB->HasEdge(nE)) |
634 | return; |
635 | |
4e57c75e |
636 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
33ba8565 |
637 | // Range |
638 | Standard_Real aT1, aT2; |
639 | thePB->Range(aT1, aT2); |
4e57c75e |
640 | // |
33ba8565 |
641 | IntTools_ShrunkRange aSR; |
505abfb8 |
642 | aSR.SetContext(myContext); |
643 | aSR.SetData(aE, aT1, aT2, aV1, aV2); |
4e57c75e |
644 | aSR.Perform(); |
33ba8565 |
645 | // Analyze the results of computations |
646 | AnalyzeShrunkData(thePB, aSR); |
647 | } |
648 | //======================================================================= |
649 | // function: AnalyzeShrunkData |
650 | // purpose: |
651 | //======================================================================= |
652 | void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB, |
653 | const IntTools_ShrunkRange& theSR) |
654 | { |
655 | // in case of error treat the warning status |
656 | Standard_Boolean bWholeEdge = Standard_False; |
657 | TopoDS_Shape aWarnShape; |
658 | // |
659 | if (!theSR.IsDone() || !theSR.IsSplittable()) { |
660 | Standard_Real aEFirst, aELast, aPBFirst, aPBLast; |
661 | BRep_Tool::Range(theSR.Edge(), aEFirst, aELast); |
662 | thePB->Range(aPBFirst, aPBLast); |
663 | bWholeEdge = !(aPBFirst > aEFirst || aPBLast < aELast); |
d3578357 |
664 | if (bWholeEdge && thePB->OriginalEdge() >= 0) { |
33ba8565 |
665 | aWarnShape = theSR.Edge(); |
666 | } |
667 | else { |
668 | const TopoDS_Shape& aV1 = myDS->Shape(thePB->Pave1().Index()); |
669 | const TopoDS_Shape& aV2 = myDS->Shape(thePB->Pave2().Index()); |
670 | BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape)); |
671 | BRep_Builder().Add(aWarnShape, theSR.Edge()); |
672 | BRep_Builder().Add(aWarnShape, aV1); |
673 | BRep_Builder().Add(aWarnShape, aV2); |
674 | } |
675 | // |
676 | if (!theSR.IsDone()) { |
677 | if (bWholeEdge) |
678 | AddWarning (new BOPAlgo_AlertTooSmallEdge (aWarnShape)); |
679 | else |
680 | AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape)); |
4bc805bf |
681 | Standard_Real aTS1, aTS2; |
682 | theSR.ShrunkRange(aTS1, aTS2); |
683 | thePB->SetShrunkData(aTS1, aTS2, Bnd_Box(), Standard_False); |
33ba8565 |
684 | return; |
685 | } |
686 | // |
687 | if (bWholeEdge) |
688 | AddWarning (new BOPAlgo_AlertNotSplittableEdge (aWarnShape)); |
689 | else |
690 | AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape)); |
4e57c75e |
691 | } |
692 | // |
33ba8565 |
693 | Standard_Real aTS1, aTS2; |
694 | theSR.ShrunkRange(aTS1, aTS2); |
695 | Bnd_Box aBox = theSR.BndBox(); |
696 | aBox.SetGap(aBox.GetGap() + myFuzzyValue / 2.); |
697 | thePB->SetShrunkData(aTS1, aTS2, aBox, theSR.IsSplittable()); |
4e57c75e |
698 | } |
b4109929 |
699 | //======================================================================= |
700 | //function : ForceInterfVE |
701 | //purpose : |
702 | //======================================================================= |
b7cd7c2b |
703 | Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV, |
704 | Handle(BOPDS_PaveBlock)& aPB, |
1155d05a |
705 | TColStd_MapOfInteger& theMEdges) |
b4109929 |
706 | { |
3510db62 |
707 | Standard_Integer nE, nVx, nVSD, iFlag; |
708 | Standard_Real aT, aTolVNew; |
b4109929 |
709 | // |
710 | nE = aPB->OriginalEdge(); |
711 | // |
712 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
713 | if (aSIE.HasSubShape(nV)) { |
d3578357 |
714 | return Standard_True; |
b4109929 |
715 | } |
716 | // |
717 | if (myDS->HasInterf(nV, nE)) { |
d3578357 |
718 | return Standard_True; |
33ba8565 |
719 | } |
b4109929 |
720 | // |
721 | if (myDS->HasInterfShapeSubShapes(nV, nE)) { |
d3578357 |
722 | return Standard_True; |
b4109929 |
723 | } |
724 | // |
3510db62 |
725 | if (aPB->Pave1().Index() == nV || |
726 | aPB->Pave2().Index() == nV) { |
d3578357 |
727 | return Standard_True; |
b4109929 |
728 | } |
729 | // |
3510db62 |
730 | nVx = nV; |
731 | if (myDS->HasShapeSD(nV, nVSD)) { |
732 | nVx = nVSD; |
733 | } |
b4109929 |
734 | // |
3510db62 |
735 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx); |
736 | const TopoDS_Edge& aE = *(TopoDS_Edge*) &myDS->Shape(nE); |
b4109929 |
737 | // |
0d0481c7 |
738 | iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew, myFuzzyValue); |
3510db62 |
739 | if (iFlag == 0 || iFlag == -4) { |
b4109929 |
740 | BOPDS_Pave aPave; |
741 | // |
b4109929 |
742 | // |
743 | BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE(); |
a3476a9f |
744 | aVEs.SetIncrement(10); |
3510db62 |
745 | // 1 |
1155d05a |
746 | BOPDS_InterfVE& aVE=aVEs.Appended(); |
b4109929 |
747 | aVE.SetIndices(nV, nE); |
748 | aVE.SetParameter(aT); |
3510db62 |
749 | // 2 |
b4109929 |
750 | myDS->AddInterf(nV, nE); |
751 | // |
3510db62 |
752 | // 3 update vertex V/E if necessary |
753 | nVx=UpdateVertex(nV, aTolVNew); |
754 | // 4 |
755 | if (myDS->IsNewShape(nVx)) { |
756 | aVE.SetIndexNew(nVx); |
757 | } |
758 | // 5 append ext pave to pave block |
759 | aPave.SetIndex(nVx); |
b4109929 |
760 | aPave.SetParameter(aT); |
761 | aPB->AppendExtPave(aPave); |
762 | // |
8ae442a8 |
763 | theMEdges.Add(nE); |
33ba8565 |
764 | // |
765 | // check for self-interference |
766 | Standard_Integer iRV = myDS->Rank(nV); |
767 | if (iRV >= 0 && iRV == myDS->Rank(nE)) { |
768 | // add warning status |
769 | TopoDS_Compound aWC; |
770 | BRep_Builder().MakeCompound(aWC); |
771 | BRep_Builder().Add(aWC, aV); |
772 | BRep_Builder().Add(aWC, aE); |
773 | AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC)); |
774 | } |
b7cd7c2b |
775 | return Standard_True; |
b4109929 |
776 | } |
b7cd7c2b |
777 | return Standard_False; |
b4109929 |
778 | } |
01b5b3df |
779 | |
780 | //======================================================================= |
781 | //function : GetPBBox |
782 | //purpose : |
783 | //======================================================================= |
784 | Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE, |
785 | const Handle(BOPDS_PaveBlock)& thePB, |
786 | BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox, |
787 | Standard_Real& theFirst, |
788 | Standard_Real& theLast, |
789 | Standard_Real& theSFirst, |
790 | Standard_Real& theSLast, |
791 | Bnd_Box& theBox) |
792 | { |
793 | thePB->Range(theFirst, theLast); |
794 | // check the validity of PB's range |
795 | Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion(); |
796 | if (!bValid) { |
797 | return bValid; |
798 | } |
799 | // |
800 | // check shrunk data |
801 | if (thePB->HasShrunkData()) { |
802 | Standard_Boolean bIsSplittable; |
803 | thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable); |
804 | return bValid; |
805 | } |
806 | // |
807 | theSFirst = theFirst; |
808 | theSLast = theLast; |
809 | // check the map |
810 | if (thePBBox.IsBound(thePB)) { |
811 | theBox = thePBBox.Find(thePB); |
812 | } |
813 | else { |
814 | // build bounding box |
815 | BRepAdaptor_Curve aBAC(theE); |
816 | Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion(); |
817 | BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox); |
818 | thePBBox.Bind(thePB, theBox); |
819 | } |
820 | return bValid; |
821 | } |
b7cd7c2b |
822 | |
d3578357 |
823 | //======================================================================= |
824 | //function : UpdateVerticesOfCB |
825 | //purpose : |
826 | //======================================================================= |
827 | void BOPAlgo_PaveFiller::UpdateVerticesOfCB() |
828 | { |
829 | // Fence map to avoid checking same Common block twice |
830 | BOPDS_MapOfPaveBlock aMPBFence; |
831 | |
832 | BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); |
833 | const Standard_Integer aNbPBP = aPBP.Length(); |
834 | for (Standard_Integer i = 0; i < aNbPBP; ++i) |
835 | { |
836 | const BOPDS_ListOfPaveBlock& aLPB = aPBP(i); |
837 | BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPB); |
838 | for (; itPB.More(); itPB.Next()) |
839 | { |
840 | const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(itPB.Value()); |
841 | if (aCB.IsNull()) |
842 | continue; |
843 | |
844 | const Handle(BOPDS_PaveBlock)& aPBR = aCB->PaveBlock1(); |
845 | if (!aMPBFence.Add(aPBR)) |
846 | continue; |
847 | |
848 | Standard_Real aTolCB = aCB->Tolerance(); |
849 | if (aTolCB > 0.) |
850 | { |
851 | UpdateVertex(aPBR->Pave1().Index(), aTolCB); |
852 | UpdateVertex(aPBR->Pave2().Index(), aTolCB); |
853 | } |
854 | } |
855 | } |
856 | } |
857 | |
b7cd7c2b |
858 | //======================================================================= |
859 | //function : ForceInterfEE |
860 | //purpose : |
861 | //======================================================================= |
862 | void BOPAlgo_PaveFiller::ForceInterfEE() |
863 | { |
864 | // Now that we have vertices increased and unified, try to find additional |
d3578357 |
865 | // common blocks among the pairs of edges. |
866 | // Since all real intersections should have already happened, here we |
867 | // are interested in common blocks only, thus we need to check only |
868 | // those pairs of pave blocks with the same bounding vertices. |
b7cd7c2b |
869 | |
870 | Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; |
871 | |
d3578357 |
872 | // Initialize pave blocks for all vertices which participated in intersections |
f8163956 |
873 | const Standard_Integer aNbS = myDS->NbSourceShapes(); |
874 | for (Standard_Integer i = 0; i < aNbS; ++i) |
b7cd7c2b |
875 | { |
876 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
877 | if (aSI.ShapeType() == TopAbs_VERTEX) |
878 | { |
d3578357 |
879 | if (myDS->HasInterf(i)) |
b7cd7c2b |
880 | myDS->InitPaveBlocksForVertex(i); |
881 | } |
882 | } |
883 | |
d3578357 |
884 | // Fill the connection map from bounding vertices to pave blocks |
885 | // having those bounding vertices |
b7cd7c2b |
886 | NCollection_IndexedDataMap<BOPDS_Pair, |
887 | BOPDS_ListOfPaveBlock, |
888 | BOPDS_PairMapHasher> aPBMap(1, anAlloc); |
889 | // Fence map of pave blocks |
890 | BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc); |
891 | |
f8163956 |
892 | for (Standard_Integer i = 0; i < aNbS; ++i) |
b7cd7c2b |
893 | { |
f8163956 |
894 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
895 | if (aSI.ShapeType() != TopAbs_EDGE) |
896 | // Not an edge |
897 | continue; |
898 | |
899 | if (!aSI.HasReference()) |
900 | // Edge has no pave blocks |
901 | continue; |
902 | |
903 | if (aSI.HasFlag()) |
904 | // Degenerated edge |
905 | continue; |
906 | |
907 | const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(i); |
b7cd7c2b |
908 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
909 | for (; aItLPB.More(); aItLPB.Next()) |
910 | { |
911 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
912 | const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB); |
913 | if (!aMPBFence.Add(aPBR)) |
914 | continue; |
915 | |
916 | // Get indices |
917 | Standard_Integer nV1, nV2; |
918 | aPBR->Indices(nV1, nV2); |
919 | |
920 | // Add pave block to a map |
921 | BOPDS_Pair aPair(nV1, nV2); |
922 | BOPDS_ListOfPaveBlock *pList = aPBMap.ChangeSeek(aPair); |
923 | if (!pList) |
924 | pList = &aPBMap(aPBMap.Add(aPair, BOPDS_ListOfPaveBlock(anAlloc))); |
925 | pList->Append(aPBR); |
926 | } |
927 | } |
928 | |
929 | Standard_Integer aNbPB = aPBMap.Extent(); |
930 | if (!aNbPB) |
931 | return; |
932 | |
d3578357 |
933 | // Prepare pave blocks with the same vertices for intersection. |
b7cd7c2b |
934 | BOPAlgo_VectorOfEdgeEdge aVEdgeEdge; |
935 | |
f8163956 |
936 | for (Standard_Integer i = 1; i <= aNbPB; ++i) |
b7cd7c2b |
937 | { |
938 | const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i); |
939 | if (aLPB.Extent() < 2) |
940 | continue; |
941 | |
942 | const BOPDS_Pair& aPair = aPBMap.FindKey(i); |
943 | Standard_Integer nV1, nV2; |
944 | aPair.Indices(nV1, nV2); |
945 | |
946 | const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1)); |
947 | const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2)); |
948 | |
949 | // Use the max tolerance of vertices as Fuzzy value for intersection |
950 | // of edges |
951 | Standard_Real aTolAdd = 2 * Max(BRep_Tool::Tolerance(aV1), |
952 | BRep_Tool::Tolerance(aV2)); |
953 | |
954 | // All possible pairs combined from the list <aLPB> should be checked |
955 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB); |
956 | for (; aItLPB1.More(); aItLPB1.Next()) |
957 | { |
958 | const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value(); |
f8163956 |
959 | const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1); |
b7cd7c2b |
960 | const Standard_Integer nE1 = aPB1->OriginalEdge(); |
d3578357 |
961 | const Standard_Integer iR1 = myDS->Rank(nE1); |
b7cd7c2b |
962 | const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1)); |
963 | Standard_Real aT11, aT12; |
964 | aPB1->Range(aT11, aT12); |
d3578357 |
965 | BRepAdaptor_Curve aBAC1(aE1); |
966 | gp_Pnt aPm; |
967 | gp_Vec aVTgt1; |
968 | aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1); |
969 | if (aVTgt1.SquareMagnitude() < gp::Resolution()) |
970 | continue; |
b7cd7c2b |
971 | |
972 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1; |
973 | for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next()) |
974 | { |
975 | const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value(); |
f8163956 |
976 | const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2); |
b7cd7c2b |
977 | const Standard_Integer nE2 = aPB2->OriginalEdge(); |
d3578357 |
978 | const Standard_Integer iR2 = myDS->Rank(nE2); |
b7cd7c2b |
979 | |
d3578357 |
980 | // Check that the edges came from different arguments |
981 | if (iR1 == iR2) |
982 | { |
983 | // If the sharing of the vertices is not original, but has been acquired |
984 | // during the operation, check the coincidence of the edges even if |
985 | // they came from the same argument |
986 | if ((!myDS->IsNewShape(nV1) && (myDS->Rank(nV1) == iR1)) || |
987 | (!myDS->IsNewShape(nV2) && (myDS->Rank(nV2) == iR2))) |
988 | continue; |
989 | } |
b7cd7c2b |
990 | |
f8163956 |
991 | // Check that the Pave blocks do not form the Common block already |
992 | if (!aCB1.IsNull() && !aCB2.IsNull()) |
993 | { |
994 | if (aCB1 == aCB2) |
995 | continue; |
996 | } |
997 | |
b7cd7c2b |
998 | const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2)); |
999 | Standard_Real aT21, aT22; |
1000 | aPB2->Range(aT21, aT22); |
1001 | |
d3578357 |
1002 | // Check the angle between edges in the middle point. |
1003 | // If the angle is more than 10 degrees, do not use the additional |
1004 | // tolerance, as it may lead to undesired unification of edges |
1005 | Standard_Boolean bUseAddTol = Standard_True; |
1006 | { |
1007 | GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2); |
1008 | aProjPC.Perform(aPm); |
1009 | if (!aProjPC.NbPoints()) |
1010 | continue; |
1011 | |
1012 | BRepAdaptor_Curve aBAC2(aE2); |
1013 | gp_Pnt aPm2; |
1014 | gp_Vec aVTgt2; |
1015 | aBAC2.D1(aProjPC.LowerDistanceParameter(), aPm2, aVTgt2); |
1016 | if (aVTgt2.SquareMagnitude() < gp::Resolution()) |
1017 | continue; |
1018 | // The angle should be close to zero |
1019 | Standard_Real aCos = aVTgt1.Dot(aVTgt2); |
1020 | if (Abs(aCos) < 0.984) |
1021 | bUseAddTol = Standard_False; |
1022 | } |
1023 | |
b7cd7c2b |
1024 | // Add pair for intersection |
1155d05a |
1025 | BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge.Appended(); |
b7cd7c2b |
1026 | anEdgeEdge.UseQuickCoincidenceCheck(Standard_True); |
1027 | anEdgeEdge.SetPaveBlock1(aPB1); |
1028 | anEdgeEdge.SetPaveBlock2(aPB2); |
1029 | anEdgeEdge.SetEdge1(aE1, aT11, aT12); |
1030 | anEdgeEdge.SetEdge2(aE2, aT21, aT22); |
d3578357 |
1031 | if (bUseAddTol) |
1032 | anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd); |
1033 | else |
1034 | anEdgeEdge.SetFuzzyValue(myFuzzyValue); |
b7cd7c2b |
1035 | anEdgeEdge.SetProgressIndicator(myProgressIndicator); |
1036 | } |
1037 | } |
1038 | } |
1039 | |
1155d05a |
1040 | Standard_Integer aNbPairs = aVEdgeEdge.Length(); |
b7cd7c2b |
1041 | if (!aNbPairs) |
1042 | return; |
1043 | |
1044 | aPBMap.Clear(); |
1045 | aMPBFence.Clear(); |
b7cd7c2b |
1046 | anAlloc->Reset(); |
1047 | |
1048 | // Perform intersection of the found pairs |
1049 | BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge); |
1050 | |
1051 | BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE(); |
1052 | if (aEEs.IsEmpty()) |
1053 | aEEs.SetIncrement(10); |
1054 | |
1055 | // Analyze the results of intersection looking for TopAbs_EDGE |
1056 | // intersection type only. |
1057 | |
1058 | BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc); |
1059 | |
f8163956 |
1060 | for (Standard_Integer i = 0; i < aNbPairs; ++i) |
b7cd7c2b |
1061 | { |
1062 | BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i); |
1063 | if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors()) |
1064 | { |
1065 | // Warn about failed intersection of sub-shapes |
1066 | const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge()); |
1067 | const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge()); |
1068 | AddIntersectionFailedWarning(aE1, aE2); |
1069 | continue; |
1070 | } |
1071 | |
1072 | const IntTools_SequenceOfCommonPrts& aCParts = anEdgeEdge.CommonParts(); |
1073 | if (aCParts.Length() != 1) |
1074 | continue; |
1075 | |
1076 | const IntTools_CommonPrt& aCP = aCParts(1); |
1077 | if (aCP.Type() != TopAbs_EDGE) |
1078 | continue; |
1079 | |
1080 | Handle(BOPDS_PaveBlock) aPB[] = {anEdgeEdge.PaveBlock1(), anEdgeEdge.PaveBlock2()}; |
1081 | const Standard_Integer nE1 = aPB[0]->OriginalEdge(); |
1082 | const Standard_Integer nE2 = aPB[1]->OriginalEdge(); |
1083 | |
d3578357 |
1084 | if (myDS->Rank(nE1) == myDS->Rank(nE2)) |
1085 | { |
1086 | // Add acquired self-interference warning |
1087 | TopoDS_Compound aWC; |
1088 | BRep_Builder().MakeCompound(aWC); |
1089 | BRep_Builder().Add(aWC, myDS->Shape(nE1)); |
1090 | BRep_Builder().Add(aWC, myDS->Shape(nE2)); |
1091 | AddWarning(new BOPAlgo_AlertAcquiredSelfIntersection(aWC)); |
1092 | } |
1093 | |
1155d05a |
1094 | BOPDS_InterfEE& aEE = aEEs.Appended(); |
b7cd7c2b |
1095 | aEE.SetIndices(nE1, nE2); |
1096 | aEE.SetCommonPart(aCP); |
1097 | myDS->AddInterf(nE1, nE2); |
1098 | |
1099 | // Fill map for common blocks creation |
1100 | for (Standard_Integer j = 0; j < 2; ++j) |
1101 | { |
1102 | if (myDS->IsCommonBlock(aPB[j])) |
1103 | { |
1104 | const BOPDS_ListOfPaveBlock& aLPBCB = myDS->CommonBlock(aPB[j])->PaveBlocks(); |
1105 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB); |
1106 | for (; aItLPB.More(); aItLPB.Next()) |
1107 | BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), |
1108 | TColStd_MapTransientHasher>(aPB[j], aItLPB.Value(), aMPBLPB, anAlloc); |
1109 | } |
1110 | } |
1111 | BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), |
1112 | TColStd_MapTransientHasher>(aPB[0], aPB[1], aMPBLPB, anAlloc); |
1113 | } |
1114 | |
1115 | // Create new common blocks of coinciding pairs. |
1116 | BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, anAlloc, myDS); |
1117 | } |