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> |
a942f2da |
23 | #include <BOPCol_NCVector.hxx> |
c7b59798 |
24 | #include <BOPCol_Parallel.hxx> |
4e57c75e |
25 | #include <BOPDS_CommonBlock.hxx> |
26 | #include <BOPDS_CoupleOfPaveBlocks.hxx> |
42cf5bc1 |
27 | #include <BOPDS_DS.hxx> |
4e57c75e |
28 | #include <BOPDS_Interf.hxx> |
42cf5bc1 |
29 | #include <BOPDS_Iterator.hxx> |
30 | #include <BOPDS_MapOfPaveBlock.hxx> |
4e57c75e |
31 | #include <BOPDS_Pave.hxx> |
42cf5bc1 |
32 | #include <BOPDS_PaveBlock.hxx> |
33 | #include <BOPDS_VectorOfInterfEE.hxx> |
34 | #include <BOPTools_AlgoTools.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> |
42cf5bc1 |
39 | #include <gp_Pnt.hxx> |
40 | #include <IntTools_CommonPrt.hxx> |
41 | #include <IntTools_Context.hxx> |
42 | #include <IntTools_EdgeEdge.hxx> |
43 | #include <IntTools_Range.hxx> |
44 | #include <IntTools_SequenceOfCommonPrts.hxx> |
45 | #include <IntTools_SequenceOfRanges.hxx> |
46 | #include <IntTools_ShrunkRange.hxx> |
47 | #include <IntTools_Tools.hxx> |
42cf5bc1 |
48 | #include <Precision.hxx> |
8ae442a8 |
49 | #include <TopoDS.hxx> |
42cf5bc1 |
50 | #include <TopoDS_Edge.hxx> |
42cf5bc1 |
51 | #include <TopoDS_Vertex.hxx> |
db8e4b9a |
52 | |
a2098360 |
53 | ///////////////////////////////////////////////////////////////////////// |
a942f2da |
54 | //======================================================================= |
55 | //class : BOPAlgo_EdgeEdge |
56 | //purpose : |
57 | //======================================================================= |
36f4947b |
58 | class BOPAlgo_EdgeEdge : |
59 | public IntTools_EdgeEdge, |
60 | public BOPAlgo_Algo { |
61 | |
a942f2da |
62 | public: |
36f4947b |
63 | |
64 | DEFINE_STANDARD_ALLOC |
65 | // |
66 | BOPAlgo_EdgeEdge(): |
67 | IntTools_EdgeEdge(), |
68 | BOPAlgo_Algo() { |
a942f2da |
69 | }; |
70 | // |
36f4947b |
71 | virtual ~BOPAlgo_EdgeEdge(){ |
a942f2da |
72 | }; |
73 | // |
74 | void SetPaveBlock1(const Handle(BOPDS_PaveBlock)& aPB) { |
75 | myPB1=aPB; |
76 | } |
77 | // |
78 | Handle(BOPDS_PaveBlock)& PaveBlock1() { |
79 | return myPB1; |
80 | } |
81 | // |
82 | void SetPaveBlock2(const Handle(BOPDS_PaveBlock)& aPB) { |
83 | myPB2=aPB; |
84 | } |
85 | // |
86 | Handle(BOPDS_PaveBlock)& PaveBlock2() { |
87 | return myPB2; |
88 | } |
36f4947b |
89 | // |
0d0481c7 |
90 | void SetFuzzyValue(const Standard_Real theFuzz) { |
91 | IntTools_EdgeEdge::SetFuzzyValue(theFuzz); |
92 | } |
93 | // |
36f4947b |
94 | virtual void Perform() { |
95 | BOPAlgo_Algo::UserBreak(); |
96 | IntTools_EdgeEdge::Perform(); |
97 | } |
a942f2da |
98 | // |
99 | protected: |
100 | Handle(BOPDS_PaveBlock) myPB1; |
101 | Handle(BOPDS_PaveBlock) myPB2; |
102 | }; |
103 | // |
505abfb8 |
104 | //======================================================================= |
105 | typedef BOPCol_NCVector |
106 | <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; |
a942f2da |
107 | // |
c7b59798 |
108 | typedef BOPCol_Functor |
505abfb8 |
109 | <BOPAlgo_EdgeEdge, |
110 | BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor; |
111 | // |
c7b59798 |
112 | typedef BOPCol_Cnt |
505abfb8 |
113 | <BOPAlgo_EdgeEdgeFunctor, |
114 | BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt; |
a942f2da |
115 | // |
a2098360 |
116 | ///////////////////////////////////////////////////////////////////////// |
117 | //======================================================================= |
4e57c75e |
118 | // function: PerformEE |
119 | // purpose: |
120 | //======================================================================= |
db8e4b9a |
121 | void BOPAlgo_PaveFiller::PerformEE() |
4e57c75e |
122 | { |
505abfb8 |
123 | FillShrunkData(TopAbs_EDGE, TopAbs_EDGE); |
124 | // |
4e57c75e |
125 | myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE); |
33ba8565 |
126 | Standard_Integer iSize = myIterator->ExpectedLength(); |
4e57c75e |
127 | if (!iSize) { |
128 | return; |
129 | } |
130 | // |
25dfc507 |
131 | Standard_Boolean bExpressCompute, bIsPBSplittable1, bIsPBSplittable2; |
01b5b3df |
132 | Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge; |
6dc83e21 |
133 | Standard_Integer nV11, nV12, nV21, nV22; |
a942f2da |
134 | Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22; |
135 | TopAbs_ShapeEnum aType; |
136 | BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2; |
488e5b9d |
137 | Handle(NCollection_BaseAllocator) aAllocator; |
a942f2da |
138 | BOPAlgo_VectorOfEdgeEdge aVEdgeEdge; |
139 | BOPDS_MapIteratorOfMapOfPaveBlock aItPB; |
8ae442a8 |
140 | // keep modified edges for further update |
141 | BOPCol_MapOfInteger aMEdges; |
a942f2da |
142 | // |
488e5b9d |
143 | aAllocator=NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
144 | //-----------------------------------------------------scope f |
4e57c75e |
145 | BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator); |
146 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator); |
01b5b3df |
147 | BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator); |
4e57c75e |
148 | // |
4e57c75e |
149 | BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); |
4e57c75e |
150 | aEEs.SetIncrement(iSize); |
4e57c75e |
151 | // |
152 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
153 | myIterator->Value(nE1, nE2); |
4e57c75e |
154 | // |
155 | const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1); |
156 | if (aSIE1.HasFlag()){ |
157 | continue; |
158 | } |
159 | const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2); |
160 | if (aSIE2.HasFlag()){ |
161 | continue; |
162 | } |
163 | // |
752f9d72 |
164 | BOPDS_ListOfPaveBlock& aLPB1 = myDS->ChangePaveBlocks(nE1); |
165 | if (aLPB1.IsEmpty()) { |
166 | continue; |
167 | } |
168 | // |
169 | BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE2); |
170 | if (aLPB2.IsEmpty()) { |
171 | continue; |
172 | } |
173 | // |
4e57c75e |
174 | const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape())); |
01b5b3df |
175 | const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape())); |
4e57c75e |
176 | // |
4e57c75e |
177 | aIt1.Initialize(aLPB1); |
178 | for (; aIt1.More(); aIt1.Next()) { |
179 | Bnd_Box aBB1; |
180 | // |
181 | Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue(); |
01b5b3df |
182 | // |
183 | if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) { |
505abfb8 |
184 | continue; |
4e57c75e |
185 | } |
4e57c75e |
186 | // |
6dc83e21 |
187 | aPB1->Indices(nV11, nV12); |
188 | // |
4e57c75e |
189 | aIt2.Initialize(aLPB2); |
190 | for (; aIt2.More(); aIt2.Next()) { |
191 | Bnd_Box aBB2; |
192 | // |
193 | Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue(); |
01b5b3df |
194 | // |
195 | if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) { |
505abfb8 |
196 | continue; |
4e57c75e |
197 | } |
4e57c75e |
198 | // |
199 | if (aBB1.IsOut(aBB2)) { |
200 | continue; |
201 | } |
202 | // |
6dc83e21 |
203 | aPB2->Indices(nV21, nV22); |
204 | // |
205 | bExpressCompute=((nV11==nV21 && nV12==nV22) || |
206 | (nV12==nV21 && nV11==nV22)); |
207 | // |
a942f2da |
208 | BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1(); |
6dc83e21 |
209 | // |
210 | anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute); |
211 | // |
a942f2da |
212 | anEdgeEdge.SetPaveBlock1(aPB1); |
213 | anEdgeEdge.SetPaveBlock2(aPB2); |
214 | // |
ec0cdc0e |
215 | anEdgeEdge.SetEdge1(aE1, aT11, aT12); |
216 | anEdgeEdge.SetEdge2(aE2, aT21, aT22); |
0d0481c7 |
217 | anEdgeEdge.SetFuzzyValue(myFuzzyValue); |
36f4947b |
218 | anEdgeEdge.SetProgressIndicator(myProgressIndicator); |
a942f2da |
219 | }//for (; aIt2.More(); aIt2.Next()) { |
220 | }//for (; aIt1.More(); aIt1.Next()) { |
221 | }//for (; myIterator->More(); myIterator->Next()) { |
222 | // |
01b5b3df |
223 | aNbEdgeEdge=aVEdgeEdge.Extent(); |
a942f2da |
224 | //====================================================== |
225 | BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge); |
226 | //====================================================== |
227 | // |
01b5b3df |
228 | for (k = 0; k < aNbEdgeEdge; ++k) { |
a942f2da |
229 | Bnd_Box aBB1, aBB2; |
230 | // |
231 | BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k); |
232 | if (!anEdgeEdge.IsDone()) { |
233 | continue; |
234 | } |
235 | // |
51db0179 |
236 | const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts(); |
237 | aNbCPrts = aCPrts.Length(); |
238 | if (!aNbCPrts) { |
239 | continue; |
240 | } |
a942f2da |
241 | //-------------------------------------------- |
242 | Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1(); |
243 | nE1=aPB1->OriginalEdge(); |
244 | aPB1->Range(aT11, aT12); |
01b5b3df |
245 | if (!aPB1->HasShrunkData()) { |
246 | aTS11 = aT11; |
247 | aTS12 = aT12; |
248 | bIsPBSplittable1 = Standard_False; |
249 | } |
250 | else { |
251 | aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1); |
252 | } |
a942f2da |
253 | // |
254 | Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2(); |
255 | nE2=aPB2->OriginalEdge(); |
256 | aPB2->Range(aT21, aT22); |
01b5b3df |
257 | if (!aPB2->HasShrunkData()) { |
258 | aTS21 = aT21; |
259 | aTS22 = aT22; |
260 | bIsPBSplittable2 = Standard_False; |
261 | } |
262 | else { |
263 | aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2); |
264 | } |
a942f2da |
265 | // |
266 | //-------------------------------------------- |
267 | IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12), |
268 | aR21(aT21, aTS21), aR22(aTS22, aT22); |
269 | // |
3065019c |
270 | Standard_Boolean bAnalytical = Standard_False; |
51db0179 |
271 | { |
3510db62 |
272 | const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1); |
273 | const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2); |
274 | // |
275 | BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2); |
276 | // |
3065019c |
277 | GeomAbs_CurveType aType1 = aBAC1.GetType(); |
278 | GeomAbs_CurveType aType2 = aBAC2.GetType(); |
279 | // |
280 | bAnalytical = (((aType1 == GeomAbs_Line) && |
281 | (aType2 == GeomAbs_Line || |
282 | aType2 == GeomAbs_Circle)) || |
283 | ((aType2 == GeomAbs_Line) && |
284 | (aType1 == GeomAbs_Line || |
285 | aType1 == GeomAbs_Circle))); |
3510db62 |
286 | } |
287 | // |
a942f2da |
288 | for (i=1; i<=aNbCPrts; ++i) { |
289 | const IntTools_CommonPrt& aCPart=aCPrts(i); |
290 | // |
291 | const TopoDS_Edge& aE1=aCPart.Edge1(); |
292 | const TopoDS_Edge& aE2=aCPart.Edge2(); |
293 | // |
294 | aType=aCPart.Type(); |
295 | switch (aType) { |
296 | case TopAbs_VERTEX: { |
01b5b3df |
297 | if (!bIsPBSplittable1 || !bIsPBSplittable2) { |
298 | continue; |
299 | } |
300 | // |
a942f2da |
301 | Standard_Boolean bIsOnPave[4], bFlag; |
302 | Standard_Integer nV[4], j; |
303 | Standard_Real aT1, aT2, aTol; |
304 | TopoDS_Vertex aVnew; |
305 | IntTools_Range aCR1, aCR2; |
306 | // |
1e143abb |
307 | IntTools_Tools::VertexParameters(aCPart, aT1, aT2); |
a942f2da |
308 | aTol = Precision::Confusion(); |
309 | aCR1 = aCPart.Range1(); |
310 | aCR2 = aCPart.Ranges2()(1); |
311 | // |
312 | //decide to keep the pave or not |
1e143abb |
313 | bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) || |
314 | IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol); |
315 | bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || |
316 | IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol); |
317 | bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) || |
318 | IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol); |
319 | bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) || |
320 | IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol); |
a942f2da |
321 | // |
322 | aPB1->Indices(nV[0], nV[1]); |
323 | aPB2->Indices(nV[2], nV[3]); |
324 | // |
325 | if((bIsOnPave[0] && bIsOnPave[2]) || |
326 | (bIsOnPave[0] && bIsOnPave[3]) || |
327 | (bIsOnPave[1] && bIsOnPave[2]) || |
328 | (bIsOnPave[1] && bIsOnPave[3])) { |
329 | continue; |
330 | } |
331 | // |
332 | bFlag = Standard_False; |
333 | for (j = 0; j < 4; ++j) { |
334 | if (bIsOnPave[j]) { |
335 | //add interf VE(nV[j], nE) |
336 | Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1; |
8ae442a8 |
337 | ForceInterfVE(nV[j], aPB, aMEdges); |
a942f2da |
338 | bFlag = Standard_True; |
339 | break; |
340 | } |
341 | } |
342 | if (bFlag) { |
24542bc0 |
343 | BOPDS_InterfEE& aEE = aEEs.Append1(); |
344 | aEE.SetIndices(nE1, nE2); |
345 | aEE.SetCommonPart(aCPart); |
a942f2da |
346 | continue; |
347 | } |
348 | // |
349 | BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew); |
3510db62 |
350 | Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew); |
3065019c |
351 | if (bAnalytical) { |
3510db62 |
352 | // increase tolerance for Line/Line intersection, but do not update |
353 | // the vertex till its intersection with some other shape |
3065019c |
354 | Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ? |
355 | (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.; |
8bb8064e |
356 | if (aTolMin > aTolVnew) { |
357 | aTolVnew = aTolMin; |
3510db62 |
358 | } |
359 | } |
a942f2da |
360 | // <-LXBR |
361 | { |
51740958 |
362 | Standard_Integer nVS[2], iFound; |
3510db62 |
363 | Standard_Real aTolVx, aD2, aDT2; |
a942f2da |
364 | BOPCol_MapOfInteger aMV; |
365 | gp_Pnt aPnew, aPx; |
4e57c75e |
366 | // |
a942f2da |
367 | iFound=0; |
368 | j=-1; |
369 | aMV.Add(nV[0]); |
370 | aMV.Add(nV[1]); |
371 | // |
372 | if (aMV.Contains(nV[2])) { |
373 | ++j; |
374 | nVS[j]=nV[2]; |
375 | } |
376 | if (aMV.Contains(nV[3])) { |
377 | ++j; |
378 | nVS[j]=nV[3]; |
379 | } |
380 | // |
a942f2da |
381 | aPnew=BRep_Tool::Pnt(aVnew); |
382 | // |
51740958 |
383 | for (Standard_Integer k1=0; k1<=j; ++k1) { |
384 | const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1])); |
a942f2da |
385 | aTolVx=BRep_Tool::Tolerance(aVx); |
386 | aPx=BRep_Tool::Pnt(aVx); |
387 | aD2=aPnew.SquareDistance(aPx); |
388 | // |
389 | aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx); |
7eed5d29 |
390 | // |
a942f2da |
391 | if (aD2<aDT2) { |
392 | iFound=1; |
4e57c75e |
393 | break; |
394 | } |
a942f2da |
395 | } |
396 | // |
397 | if (iFound) { |
398 | continue; |
399 | } |
400 | } |
402bfe81 |
401 | // |
a942f2da |
402 | // 1 |
402bfe81 |
403 | BOPDS_InterfEE& aEE=aEEs.Append1(); |
404 | iX=aEEs.Extent()-1; |
a942f2da |
405 | aEE.SetIndices(nE1, nE2); |
406 | aEE.SetCommonPart(aCPart); |
407 | // 2 |
408 | myDS->AddInterf(nE1, nE2); |
409 | // |
410 | BOPDS_CoupleOfPaveBlocks aCPB; |
411 | // |
412 | aCPB.SetPaveBlocks(aPB1, aPB2); |
413 | aCPB.SetIndexInterf(iX); |
3510db62 |
414 | aCPB.SetTolerance(aTolVnew); |
a942f2da |
415 | aMVCPB.Add(aVnew, aCPB); |
416 | }//case TopAbs_VERTEX: |
417 | break; |
418 | // |
419 | case TopAbs_EDGE: { |
420 | if (aNbCPrts > 1) { |
4e57c75e |
421 | break; |
a942f2da |
422 | } |
423 | // |
424 | Standard_Boolean bHasSameBounds; |
425 | bHasSameBounds=aPB1->HasSameBounds(aPB2); |
426 | if (!bHasSameBounds) { |
427 | break; |
428 | } |
429 | // 1 |
402bfe81 |
430 | BOPDS_InterfEE& aEE=aEEs.Append1(); |
431 | iX=aEEs.Extent()-1; |
a942f2da |
432 | aEE.SetIndices(nE1, nE2); |
433 | aEE.SetCommonPart(aCPart); |
434 | // 2 |
435 | myDS->AddInterf(nE1, nE2); |
436 | // |
edfa30de |
437 | BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), TColStd_MapTransientHasher>(aPB1, aPB2, aMPBLPB, aAllocator); |
a942f2da |
438 | }//case TopAbs_EDGE |
439 | break; |
440 | default: |
441 | break; |
442 | }//switch (aType) { |
443 | }//for (i=1; i<=aNbCPrts; i++) { |
444 | }//for (k=0; k < aNbFdgeEdge; ++k) { |
4e57c75e |
445 | // |
446 | //========================================= |
447 | // post treatment |
448 | //========================================= |
8ae442a8 |
449 | BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS); |
450 | PerformNewVertices(aMVCPB, aAllocator); |
451 | // |
452 | if (aMEdges.Extent()) { |
453 | Standard_Integer aNbV = aMVCPB.Extent(); |
454 | for (i = 1; i <= aNbV; ++i) { |
455 | Handle(BOPDS_PaveBlock) aPB1, aPB2; |
456 | const BOPDS_CoupleOfPaveBlocks& aCPB = aMVCPB.FindFromIndex(i); |
457 | aCPB.PaveBlocks(aPB1, aPB2); |
a3476a9f |
458 | // |
8ae442a8 |
459 | aMEdges.Remove(aPB1->OriginalEdge()); |
460 | aMEdges.Remove(aPB2->OriginalEdge()); |
b4109929 |
461 | } |
8ae442a8 |
462 | // |
463 | SplitPaveBlocks(aMEdges, Standard_False); |
b4109929 |
464 | } |
465 | // |
4e57c75e |
466 | //-----------------------------------------------------scope t |
467 | aMPBLPB.Clear(); |
468 | aMVCPB.Clear(); |
4e57c75e |
469 | } |
470 | //======================================================================= |
3510db62 |
471 | //function : PerformVerticesEE |
4e57c75e |
472 | //purpose : |
473 | //======================================================================= |
8ae442a8 |
474 | void BOPAlgo_PaveFiller::PerformNewVertices |
db8e4b9a |
475 | (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, |
8ae442a8 |
476 | const Handle(NCollection_BaseAllocator)& theAllocator, |
477 | const Standard_Boolean bIsEEIntersection) |
4e57c75e |
478 | { |
8ae442a8 |
479 | Standard_Integer aNbV = theMVCPB.Extent(); |
4e57c75e |
480 | if (!aNbV) { |
8ae442a8 |
481 | return; |
4e57c75e |
482 | } |
483 | // |
8ae442a8 |
484 | Standard_Real aTolAdd = myFuzzyValue / 2.; |
4e57c75e |
485 | // |
8ae442a8 |
486 | // 1. Fuse the new vertices |
4e57c75e |
487 | BOPCol_IndexedDataMapOfShapeListOfShape aImages; |
3510db62 |
488 | TreatNewVertices(theMVCPB, aImages); |
4e57c75e |
489 | // |
8ae442a8 |
490 | // 2. Add new vertices to myDS and connect indices to CPB structure |
491 | BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE(); |
492 | BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF(); |
493 | // |
494 | Standard_Integer i, aNb = aImages.Extent(); |
495 | for (i = 1; i <= aNb; ++i) { |
496 | const TopoDS_Vertex& aV = TopoDS::Vertex(aImages.FindKey(i)); |
497 | const BOPCol_ListOfShape& aLVSD = aImages.FindFromIndex(i); |
4e57c75e |
498 | // |
8ae442a8 |
499 | BOPDS_ShapeInfo aSI; |
500 | aSI.SetShapeType(TopAbs_VERTEX); |
4e57c75e |
501 | aSI.SetShape(aV); |
8ae442a8 |
502 | Standard_Integer iV = myDS->Append(aSI); |
4e57c75e |
503 | // |
8ae442a8 |
504 | BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV); |
505 | Bnd_Box& aBox = aSIDS.ChangeBox(); |
506 | aBox.Add(BRep_Tool::Pnt(aV)); |
507 | aBox.SetGap(BRep_Tool::Tolerance(aV) + aTolAdd); |
4e57c75e |
508 | // |
8ae442a8 |
509 | BOPCol_ListIteratorOfListOfShape aItLS(aLVSD); |
4e57c75e |
510 | for (; aItLS.More(); aItLS.Next()) { |
511 | const TopoDS_Shape& aVx = aItLS.Value(); |
8ae442a8 |
512 | BOPDS_CoupleOfPaveBlocks &aCPB = theMVCPB.ChangeFromKey(aVx); |
4e57c75e |
513 | aCPB.SetIndex(iV); |
8ae442a8 |
514 | // update interference |
515 | Standard_Integer iX = aCPB.IndexInterf(); |
516 | BOPDS_Interf *aInt = bIsEEIntersection ? (BOPDS_Interf*)(&aEEs(iX)) : (BOPDS_Interf*) (&aEFs(iX)); |
517 | aInt->SetIndexNew(iV); |
4e57c75e |
518 | } |
519 | } |
520 | // |
8ae442a8 |
521 | // 3. Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI |
522 | BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator); |
523 | for (i = 1; i <= aNbV; ++i) { |
524 | const BOPDS_CoupleOfPaveBlocks& aCPB = theMVCPB.FindFromIndex(i); |
525 | Standard_Integer iV = aCPB.Index(); |
4e57c75e |
526 | // |
8ae442a8 |
527 | Handle(BOPDS_PaveBlock) aPB[2]; |
528 | aCPB.PaveBlocks(aPB[0], aPB[1]); |
529 | for (Standard_Integer j = 0; j < 2; ++j) { |
530 | BOPCol_ListOfInteger *pLI = aMPBLI.ChangeSeek(aPB[j]); |
531 | if (!pLI) { |
532 | pLI = &aMPBLI(aMPBLI.Add(aPB[j], BOPCol_ListOfInteger(theAllocator))); |
4e57c75e |
533 | } |
8ae442a8 |
534 | pLI->Append(iV); |
4e57c75e |
535 | // |
8ae442a8 |
536 | if (aPB[0] == aPB[1]) { |
537 | break; |
538 | } |
4e57c75e |
539 | } |
540 | } |
4e57c75e |
541 | // |
8ae442a8 |
542 | // 4. Compute Extra Paves and split Pave blocks by the Extra paves |
543 | IntersectVE(aMPBLI, Standard_False); |
4e57c75e |
544 | } |
4e57c75e |
545 | //======================================================================= |
546 | //function : TreatNewVertices |
547 | //purpose : |
548 | //======================================================================= |
db8e4b9a |
549 | void BOPAlgo_PaveFiller::TreatNewVertices |
8ae442a8 |
550 | (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, |
db8e4b9a |
551 | BOPCol_IndexedDataMapOfShapeListOfShape& myImages) |
4e57c75e |
552 | { |
4e57c75e |
553 | // |
8ae442a8 |
554 | // Prepare for intersection |
555 | BOPCol_IndexedDataMapOfShapeReal aVerts; |
556 | Standard_Integer i, aNbV = theMVCPB.Extent(); |
557 | for (i = 1; i <= aNbV; ++i) { |
558 | const TopoDS_Shape& aV = theMVCPB.FindKey(i); |
559 | Standard_Real aTol = theMVCPB.FindFromIndex(i).Tolerance(); |
560 | aVerts.Add(aV, aTol); |
4e57c75e |
561 | } |
562 | // |
8ae442a8 |
563 | // Perform intersection |
564 | BOPCol_ListOfListOfShape aChains; |
565 | BOPAlgo_Tools::IntersectVertices(aVerts, myRunParallel, myFuzzyValue, aChains); |
a2098360 |
566 | // |
8ae442a8 |
567 | // Treat the results - make new vertices for each chain |
568 | BOPCol_ListOfListOfShape::Iterator aItC(aChains); |
569 | for (; aItC.More(); aItC.Next()) { |
570 | const BOPCol_ListOfShape& aLVSD = aItC.Value(); |
4e57c75e |
571 | // |
8ae442a8 |
572 | TopoDS_Vertex aVNew; |
573 | BOPTools_AlgoTools::MakeVertex(aLVSD, aVNew); |
574 | myImages.Add(aVNew, aLVSD); |
4e57c75e |
575 | } |
576 | } |
4e57c75e |
577 | //======================================================================= |
578 | //function : FillShrunkData |
579 | //purpose : |
580 | //======================================================================= |
db8e4b9a |
581 | void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB) |
4e57c75e |
582 | { |
33ba8565 |
583 | // Vertices |
584 | Standard_Integer nV1, nV2; |
585 | thePB->Indices(nV1, nV2); |
4e57c75e |
586 | const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
4e57c75e |
587 | const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
33ba8565 |
588 | // Original edge |
589 | Standard_Integer nE = thePB->OriginalEdge(); |
4e57c75e |
590 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
33ba8565 |
591 | // Range |
592 | Standard_Real aT1, aT2; |
593 | thePB->Range(aT1, aT2); |
4e57c75e |
594 | // |
33ba8565 |
595 | IntTools_ShrunkRange aSR; |
505abfb8 |
596 | aSR.SetContext(myContext); |
597 | aSR.SetData(aE, aT1, aT2, aV1, aV2); |
4e57c75e |
598 | aSR.Perform(); |
33ba8565 |
599 | // Analyze the results of computations |
600 | AnalyzeShrunkData(thePB, aSR); |
601 | } |
602 | //======================================================================= |
603 | // function: AnalyzeShrunkData |
604 | // purpose: |
605 | //======================================================================= |
606 | void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB, |
607 | const IntTools_ShrunkRange& theSR) |
608 | { |
609 | // in case of error treat the warning status |
610 | Standard_Boolean bWholeEdge = Standard_False; |
611 | TopoDS_Shape aWarnShape; |
612 | // |
613 | if (!theSR.IsDone() || !theSR.IsSplittable()) { |
614 | Standard_Real aEFirst, aELast, aPBFirst, aPBLast; |
615 | BRep_Tool::Range(theSR.Edge(), aEFirst, aELast); |
616 | thePB->Range(aPBFirst, aPBLast); |
617 | bWholeEdge = !(aPBFirst > aEFirst || aPBLast < aELast); |
618 | if (bWholeEdge) { |
619 | aWarnShape = theSR.Edge(); |
620 | } |
621 | else { |
622 | const TopoDS_Shape& aV1 = myDS->Shape(thePB->Pave1().Index()); |
623 | const TopoDS_Shape& aV2 = myDS->Shape(thePB->Pave2().Index()); |
624 | BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape)); |
625 | BRep_Builder().Add(aWarnShape, theSR.Edge()); |
626 | BRep_Builder().Add(aWarnShape, aV1); |
627 | BRep_Builder().Add(aWarnShape, aV2); |
628 | } |
629 | // |
630 | if (!theSR.IsDone()) { |
631 | if (bWholeEdge) |
632 | AddWarning (new BOPAlgo_AlertTooSmallEdge (aWarnShape)); |
633 | else |
634 | AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape)); |
635 | return; |
636 | } |
637 | // |
638 | if (bWholeEdge) |
639 | AddWarning (new BOPAlgo_AlertNotSplittableEdge (aWarnShape)); |
640 | else |
641 | AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape)); |
4e57c75e |
642 | } |
643 | // |
33ba8565 |
644 | Standard_Real aTS1, aTS2; |
645 | theSR.ShrunkRange(aTS1, aTS2); |
646 | Bnd_Box aBox = theSR.BndBox(); |
647 | aBox.SetGap(aBox.GetGap() + myFuzzyValue / 2.); |
648 | thePB->SetShrunkData(aTS1, aTS2, aBox, theSR.IsSplittable()); |
4e57c75e |
649 | } |
b4109929 |
650 | //======================================================================= |
651 | //function : ForceInterfVE |
652 | //purpose : |
653 | //======================================================================= |
654 | void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV, |
655 | Handle(BOPDS_PaveBlock)& aPB, |
8ae442a8 |
656 | BOPCol_MapOfInteger& theMEdges) |
b4109929 |
657 | { |
3510db62 |
658 | Standard_Integer nE, nVx, nVSD, iFlag; |
659 | Standard_Real aT, aTolVNew; |
b4109929 |
660 | // |
661 | nE = aPB->OriginalEdge(); |
662 | // |
663 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
664 | if (aSIE.HasSubShape(nV)) { |
665 | return; |
666 | } |
667 | // |
668 | if (myDS->HasInterf(nV, nE)) { |
669 | return; |
33ba8565 |
670 | } |
b4109929 |
671 | // |
672 | if (myDS->HasInterfShapeSubShapes(nV, nE)) { |
673 | return; |
674 | } |
675 | // |
3510db62 |
676 | if (aPB->Pave1().Index() == nV || |
677 | aPB->Pave2().Index() == nV) { |
b4109929 |
678 | return; |
679 | } |
680 | // |
3510db62 |
681 | nVx = nV; |
682 | if (myDS->HasShapeSD(nV, nVSD)) { |
683 | nVx = nVSD; |
684 | } |
b4109929 |
685 | // |
3510db62 |
686 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx); |
687 | const TopoDS_Edge& aE = *(TopoDS_Edge*) &myDS->Shape(nE); |
b4109929 |
688 | // |
0d0481c7 |
689 | iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew, myFuzzyValue); |
3510db62 |
690 | if (iFlag == 0 || iFlag == -4) { |
b4109929 |
691 | BOPDS_Pave aPave; |
692 | // |
b4109929 |
693 | // |
694 | BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE(); |
a3476a9f |
695 | aVEs.SetIncrement(10); |
3510db62 |
696 | // 1 |
402bfe81 |
697 | BOPDS_InterfVE& aVE=aVEs.Append1(); |
b4109929 |
698 | aVE.SetIndices(nV, nE); |
699 | aVE.SetParameter(aT); |
3510db62 |
700 | // 2 |
b4109929 |
701 | myDS->AddInterf(nV, nE); |
702 | // |
3510db62 |
703 | // 3 update vertex V/E if necessary |
704 | nVx=UpdateVertex(nV, aTolVNew); |
705 | // 4 |
706 | if (myDS->IsNewShape(nVx)) { |
707 | aVE.SetIndexNew(nVx); |
708 | } |
709 | // 5 append ext pave to pave block |
710 | aPave.SetIndex(nVx); |
b4109929 |
711 | aPave.SetParameter(aT); |
712 | aPB->AppendExtPave(aPave); |
713 | // |
8ae442a8 |
714 | theMEdges.Add(nE); |
33ba8565 |
715 | // |
716 | // check for self-interference |
717 | Standard_Integer iRV = myDS->Rank(nV); |
718 | if (iRV >= 0 && iRV == myDS->Rank(nE)) { |
719 | // add warning status |
720 | TopoDS_Compound aWC; |
721 | BRep_Builder().MakeCompound(aWC); |
722 | BRep_Builder().Add(aWC, aV); |
723 | BRep_Builder().Add(aWC, aE); |
724 | AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC)); |
725 | } |
b4109929 |
726 | } |
727 | } |
01b5b3df |
728 | |
729 | //======================================================================= |
730 | //function : GetPBBox |
731 | //purpose : |
732 | //======================================================================= |
733 | Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE, |
734 | const Handle(BOPDS_PaveBlock)& thePB, |
735 | BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox, |
736 | Standard_Real& theFirst, |
737 | Standard_Real& theLast, |
738 | Standard_Real& theSFirst, |
739 | Standard_Real& theSLast, |
740 | Bnd_Box& theBox) |
741 | { |
742 | thePB->Range(theFirst, theLast); |
743 | // check the validity of PB's range |
744 | Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion(); |
745 | if (!bValid) { |
746 | return bValid; |
747 | } |
748 | // |
749 | // check shrunk data |
750 | if (thePB->HasShrunkData()) { |
751 | Standard_Boolean bIsSplittable; |
752 | thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable); |
753 | return bValid; |
754 | } |
755 | // |
756 | theSFirst = theFirst; |
757 | theSLast = theLast; |
758 | // check the map |
759 | if (thePBBox.IsBound(thePB)) { |
760 | theBox = thePBBox.Find(thePB); |
761 | } |
762 | else { |
763 | // build bounding box |
764 | BRepAdaptor_Curve aBAC(theE); |
765 | Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion(); |
766 | BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox); |
767 | thePBBox.Bind(thePB, theBox); |
768 | } |
769 | return bValid; |
770 | } |