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 | |
4e57c75e |
19 | #include <Bnd_Box.hxx> |
9324aa2d |
20 | #include <Bnd_Tools.hxx> |
42cf5bc1 |
21 | #include <BOPAlgo_PaveFiller.hxx> |
33ba8565 |
22 | #include <BOPAlgo_Alerts.hxx> |
42cf5bc1 |
23 | #include <BOPAlgo_Tools.hxx> |
42cf5bc1 |
24 | #include <BOPDS_CommonBlock.hxx> |
25 | #include <BOPDS_CoupleOfPaveBlocks.hxx> |
26 | #include <BOPDS_Curve.hxx> |
42cf5bc1 |
27 | #include <BOPDS_DS.hxx> |
28 | #include <BOPDS_Interf.hxx> |
29 | #include <BOPDS_Iterator.hxx> |
30 | #include <BOPDS_MapOfPaveBlock.hxx> |
31 | #include <BOPDS_Pave.hxx> |
32 | #include <BOPDS_PaveBlock.hxx> |
33 | #include <BOPTools_AlgoTools.hxx> |
d3578357 |
34 | #include <BOPTools_AlgoTools2D.hxx> |
1155d05a |
35 | #include <BOPTools_Parallel.hxx> |
42cf5bc1 |
36 | #include <BRep_Builder.hxx> |
4e57c75e |
37 | #include <BRep_Tool.hxx> |
e30616a7 |
38 | #include <BRepAdaptor_Curve.hxx> |
d3578357 |
39 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
42cf5bc1 |
40 | #include <gp_Pnt.hxx> |
41 | #include <IntTools_CommonPrt.hxx> |
42 | #include <IntTools_Context.hxx> |
4e57c75e |
43 | #include <IntTools_EdgeFace.hxx> |
44 | #include <IntTools_Range.hxx> |
45 | #include <IntTools_SequenceOfCommonPrts.hxx> |
42cf5bc1 |
46 | #include <IntTools_Tools.hxx> |
d3578357 |
47 | #include <NCollection_IncAllocator.hxx> |
1155d05a |
48 | #include <NCollection_Vector.hxx> |
8ae442a8 |
49 | #include <Precision.hxx> |
1155d05a |
50 | #include <TColStd_MapOfInteger.hxx> |
3510db62 |
51 | #include <TopoDS.hxx> |
42cf5bc1 |
52 | #include <TopoDS_Edge.hxx> |
53 | #include <TopoDS_Face.hxx> |
54 | #include <TopoDS_Vertex.hxx> |
55 | |
e30616a7 |
56 | //======================================================================= |
57 | //class : BOPAlgo_EdgeFace |
58 | //purpose : |
59 | //======================================================================= |
36f4947b |
60 | class BOPAlgo_EdgeFace : |
61 | public IntTools_EdgeFace, |
62 | public BOPAlgo_Algo { |
63 | |
e30616a7 |
64 | public: |
36f4947b |
65 | DEFINE_STANDARD_ALLOC |
66 | |
67 | BOPAlgo_EdgeFace() : |
68 | IntTools_EdgeFace(), |
69 | BOPAlgo_Algo(), |
70 | myIE(-1), myIF(-1) { |
e30616a7 |
71 | }; |
72 | // |
36f4947b |
73 | virtual ~BOPAlgo_EdgeFace(){ |
e30616a7 |
74 | }; |
75 | // |
76 | void SetIndices(const Standard_Integer nE, |
77 | const Standard_Integer nF) { |
78 | myIE=nE; |
79 | myIF=nF; |
80 | } |
81 | // |
82 | void Indices(Standard_Integer& nE, |
83 | Standard_Integer& nF) { |
84 | nE=myIE; |
85 | nF=myIF; |
86 | } |
87 | // |
88 | void SetNewSR(const IntTools_Range& aR){ |
89 | myNewSR=aR; |
90 | } |
91 | // |
92 | IntTools_Range& NewSR(){ |
93 | return myNewSR; |
94 | } |
95 | // |
96 | void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) { |
97 | myPB=aPB; |
98 | } |
99 | // |
100 | Handle(BOPDS_PaveBlock)& PaveBlock() { |
101 | return myPB; |
102 | } |
103 | // |
0d0481c7 |
104 | void SetFuzzyValue(const Standard_Real theFuzz) { |
105 | IntTools_EdgeFace::SetFuzzyValue(theFuzz); |
106 | } |
107 | // |
c08fd127 |
108 | void SetBoxes (const Bnd_Box& theBox1, |
109 | const Bnd_Box& theBox2) |
110 | { |
111 | myBox1 = theBox1; |
112 | myBox2 = theBox2; |
113 | } |
114 | // |
36f4947b |
115 | virtual void Perform() { |
116 | BOPAlgo_Algo::UserBreak(); |
c08fd127 |
117 | TopoDS_Face aFace = myFace; |
118 | TopoDS_Edge anEdge = myEdge; |
119 | Standard_Boolean hasTrsf = false; |
ad8b073e |
120 | try |
121 | { |
122 | OCC_CATCH_SIGNALS |
123 | |
c08fd127 |
124 | gp_Trsf aTrsf; |
125 | if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf)) |
126 | { |
127 | // Shapes are located far from origin, move the shapes to the origin, |
128 | // to increase the accuracy of intersection. |
129 | TopLoc_Location aLoc (aTrsf); |
130 | myEdge.Move (aLoc); |
131 | myFace.Move (aLoc); |
132 | hasTrsf = Standard_True; |
133 | } |
134 | |
ad8b073e |
135 | IntTools_EdgeFace::Perform(); |
136 | } |
a738b534 |
137 | catch (Standard_Failure const&) |
ad8b073e |
138 | { |
139 | AddError(new BOPAlgo_AlertIntersectionFailed); |
140 | } |
c08fd127 |
141 | myFace = aFace; |
142 | myEdge = anEdge; |
143 | |
144 | if (hasTrsf) |
145 | { |
146 | for (Standard_Integer i = 1; i <= mySeqOfCommonPrts.Length(); ++i) |
147 | { |
148 | IntTools_CommonPrt& aCPart = mySeqOfCommonPrts (i); |
149 | aCPart.SetEdge1 (myEdge); |
150 | } |
151 | } |
36f4947b |
152 | } |
153 | // |
e30616a7 |
154 | protected: |
155 | Standard_Integer myIE; |
156 | Standard_Integer myIF; |
157 | IntTools_Range myNewSR; |
158 | Handle(BOPDS_PaveBlock) myPB; |
c08fd127 |
159 | Bnd_Box myBox1; |
160 | Bnd_Box myBox2; |
e30616a7 |
161 | }; |
162 | // |
163 | //======================================================================= |
1155d05a |
164 | typedef NCollection_Vector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; |
fc867b96 |
165 | |
4e57c75e |
166 | //======================================================================= |
167 | //function : PerformEF |
168 | //purpose : |
169 | //======================================================================= |
e30616a7 |
170 | void BOPAlgo_PaveFiller::PerformEF() |
4e57c75e |
171 | { |
e30616a7 |
172 | FillShrunkData(TopAbs_EDGE, TopAbs_FACE); |
173 | // |
4e57c75e |
174 | myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE); |
483ce1bd |
175 | Standard_Integer iSize = myIterator->ExpectedLength(); |
4e57c75e |
176 | if (!iSize) { |
177 | return; |
178 | } |
e30616a7 |
179 | // |
483ce1bd |
180 | Standard_Integer nE, nF; |
181 | // |
182 | if (myGlue == BOPAlgo_GlueFull) { |
183 | // there is no need to intersect edges with faces in this mode |
184 | // just initialize FaceInfo for faces |
185 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
186 | myIterator->Value(nE, nF); |
187 | if (!myDS->ShapeInfo(nE).HasFlag()) { |
483ce1bd |
188 | myDS->ChangeFaceInfo(nF); |
189 | } |
190 | } |
191 | return; |
192 | } |
193 | // |
194 | Standard_Boolean bV[2], bIsPBSplittable; |
6dc83e21 |
195 | Standard_Boolean bV1, bV2, bExpressCompute; |
196 | Standard_Integer nV1, nV2; |
03cca6f7 |
197 | Standard_Integer i, aNbCPrts, iX, nV[2]; |
e30616a7 |
198 | Standard_Integer aNbEdgeFace, k; |
03cca6f7 |
199 | Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2; |
488e5b9d |
200 | Handle(NCollection_BaseAllocator) aAllocator; |
4e57c75e |
201 | TopAbs_ShapeEnum aType; |
202 | BOPDS_ListIteratorOfListOfPaveBlock aIt; |
e30616a7 |
203 | BOPAlgo_VectorOfEdgeFace aVEdgeFace; |
e30616a7 |
204 | //-----------------------------------------------------scope f |
4e57c75e |
205 | // |
488e5b9d |
206 | aAllocator=NCollection_BaseAllocator::CommonBaseAllocator(); |
207 | // |
1155d05a |
208 | TColStd_MapOfInteger aMIEFC(100, aAllocator); |
4e57c75e |
209 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator); |
210 | BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator); |
01b5b3df |
211 | BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator); |
4e57c75e |
212 | // |
4e57c75e |
213 | BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); |
4e57c75e |
214 | aEFs.SetIncrement(iSize); |
4e57c75e |
215 | // |
216 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
217 | myIterator->Value(nE, nF); |
4e57c75e |
218 | // |
219 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
220 | if (aSIE.HasFlag()){//degenerated |
221 | continue; |
222 | } |
223 | // |
224 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape())); |
225 | const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); |
226 | const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box(); |
227 | // |
228 | BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); |
229 | const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn(); |
4e57c75e |
230 | // |
1155d05a |
231 | const TColStd_MapOfInteger& aMVIn=aFI.VerticesIn(); |
232 | const TColStd_MapOfInteger& aMVOn=aFI.VerticesOn(); |
6dc83e21 |
233 | // |
4e57c75e |
234 | aTolE=BRep_Tool::Tolerance(aE); |
235 | aTolF=BRep_Tool::Tolerance(aF); |
236 | // |
237 | BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE); |
238 | aIt.Initialize(aLPB); |
239 | for (; aIt.More(); aIt.Next()) { |
240 | Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue(); |
241 | // |
5a77460e |
242 | const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB); |
4e57c75e |
243 | if (aMPBF.Contains(aPBR)) { |
244 | continue; |
245 | } |
246 | // |
01b5b3df |
247 | Bnd_Box aBBE; |
248 | if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) { |
e30616a7 |
249 | continue; |
4e57c75e |
250 | } |
251 | // |
4e57c75e |
252 | if (aBBF.IsOut (aBBE)) { |
253 | continue; |
254 | } |
255 | // |
6dc83e21 |
256 | aPBR->Indices(nV1, nV2); |
257 | bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1); |
258 | bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2); |
259 | bExpressCompute=bV1 && bV2; |
260 | // |
1155d05a |
261 | BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Appended(); |
e30616a7 |
262 | // |
263 | aEdgeFace.SetIndices(nE, nF); |
264 | aEdgeFace.SetPaveBlock(aPB); |
4e57c75e |
265 | // |
266 | aEdgeFace.SetEdge (aE); |
267 | aEdgeFace.SetFace (aF); |
c08fd127 |
268 | aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box()); |
0d0481c7 |
269 | aEdgeFace.SetFuzzyValue(myFuzzyValue); |
6dc83e21 |
270 | aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute); |
4e57c75e |
271 | // |
272 | IntTools_Range aSR(aTS1, aTS2); |
273 | IntTools_Range anewSR=aSR; |
4e57c75e |
274 | BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR); |
e30616a7 |
275 | aEdgeFace.SetNewSR(anewSR); |
b4109929 |
276 | // |
b4109929 |
277 | IntTools_Range aPBRange(aT1, aT2); |
278 | aSR = aPBRange; |
279 | BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange); |
b4109929 |
280 | aEdgeFace.SetRange (aPBRange); |
36f4947b |
281 | aEdgeFace.SetProgressIndicator(myProgressIndicator); |
d3578357 |
282 | // Save the pair to avoid their forced intersection |
283 | BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF); |
284 | if (!pMPB) |
285 | pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock()); |
286 | pMPB->Add(aPB); |
e30616a7 |
287 | }//for (; aIt.More(); aIt.Next()) { |
288 | }//for (; myIterator->More(); myIterator->Next()) { |
289 | // |
1155d05a |
290 | aNbEdgeFace=aVEdgeFace.Length(); |
e30616a7 |
291 | //================================================================= |
fc867b96 |
292 | BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext); |
e30616a7 |
293 | //================================================================= |
294 | // |
295 | for (k=0; k < aNbEdgeFace; ++k) { |
296 | BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k); |
ad8b073e |
297 | if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) { |
298 | // Warn about failed intersection of sub-shapes |
299 | AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face()); |
e30616a7 |
300 | continue; |
301 | } |
51db0179 |
302 | // |
303 | const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts(); |
304 | aNbCPrts = aCPrts.Length(); |
305 | if (!aNbCPrts) { |
306 | continue; |
307 | } |
308 | // |
e30616a7 |
309 | aEdgeFace.Indices(nE, nF); |
310 | // |
311 | const TopoDS_Edge& aE=aEdgeFace.Edge(); |
312 | const TopoDS_Face& aF=aEdgeFace.Face(); |
313 | // |
0d0481c7 |
314 | aTolE=BRep_Tool::Tolerance(aE); |
315 | aTolF=BRep_Tool::Tolerance(aF); |
e30616a7 |
316 | const IntTools_Range& anewSR=aEdgeFace.NewSR(); |
317 | Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock(); |
318 | // |
319 | aPB->Range(aT1, aT2); |
320 | aPB->Indices(nV[0], nV[1]); |
01b5b3df |
321 | bIsPBSplittable = aPB->IsSplittable(); |
322 | // |
01b5b3df |
323 | anewSR.Range(aTS1, aTS2); |
324 | // |
51db0179 |
325 | if (aCPrts(1).Type() == TopAbs_VERTEX) { |
326 | // for the intersection type VERTEX |
327 | // extend vertices ranges using Edge/Edge intersections |
328 | // between the edge aE and the edges of the face aF. |
329 | // thereby the edge's intersection range is reduced |
330 | ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2); |
331 | } |
01b5b3df |
332 | // |
333 | IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2); |
e30616a7 |
334 | // |
335 | BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); |
1155d05a |
336 | const TColStd_MapOfInteger& aMIFOn=aFI.VerticesOn(); |
337 | const TColStd_MapOfInteger& aMIFIn=aFI.VerticesIn(); |
3510db62 |
338 | // |
339 | Standard_Boolean bLinePlane = Standard_False; |
340 | if (aNbCPrts) { |
341 | BRepAdaptor_Curve aBAC(aE); |
3510db62 |
342 | bLinePlane = (aBAC.GetType() == GeomAbs_Line && |
51db0179 |
343 | myContext->SurfaceAdaptor(aF).GetType() == GeomAbs_Plane); |
3510db62 |
344 | } |
51db0179 |
345 | // |
e30616a7 |
346 | for (i=1; i<=aNbCPrts; ++i) { |
347 | const IntTools_CommonPrt& aCPart=aCPrts(i); |
348 | aType=aCPart.Type(); |
349 | switch (aType) { |
01b5b3df |
350 | case TopAbs_VERTEX: { |
b4109929 |
351 | Standard_Boolean bIsOnPave[2]; |
352 | Standard_Integer j; |
4e57c75e |
353 | Standard_Real aT, aTolToDecide; |
354 | TopoDS_Vertex aVnew; |
e30616a7 |
355 | // |
1e143abb |
356 | IntTools_Tools::VertexParameter(aCPart, aT); |
4e57c75e |
357 | BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew); |
358 | // |
359 | const IntTools_Range& aR=aCPart.Range1(); |
360 | aTolToDecide=5.e-8; |
4e57c75e |
361 | // |
1e143abb |
362 | bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide); |
363 | bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide); |
b4109929 |
364 | // |
3510db62 |
365 | if ((bIsOnPave[0] && bIsOnPave[1]) || |
366 | (bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) { |
b4109929 |
367 | bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn); |
368 | bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn); |
369 | if (bV[0] && bV[1]) { |
4e57c75e |
370 | IntTools_CommonPrt aCP = aCPart; |
371 | aCP.SetType(TopAbs_EDGE); |
1155d05a |
372 | BOPDS_InterfEF& aEF=aEFs.Appended(); |
373 | iX=aEFs.Length()-1; |
4e57c75e |
374 | aEF.SetIndices(nE, nF); |
375 | aEF.SetCommonPart(aCP); |
376 | myDS->AddInterf(nE, nF); |
ceb31c61 |
377 | // |
378 | aMIEFC.Add(nF); |
379 | // |
4e57c75e |
380 | BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator); |
381 | break; |
382 | } |
383 | } |
01b5b3df |
384 | // |
385 | if (!bIsPBSplittable) { |
386 | continue; |
387 | } |
388 | // |
d3578357 |
389 | for (j = 0; j < 2; ++j) |
390 | { |
391 | if (bIsOnPave[j]) |
392 | { |
393 | bV[j] = CheckFacePaves(nV[j], aMIFOn, aMIFIn); |
394 | if (!bV[j]) |
b4109929 |
395 | bIsOnPave[j] = ForceInterfVF(nV[j], nF); |
4e57c75e |
396 | } |
4e57c75e |
397 | } |
d3578357 |
398 | |
399 | if (bIsOnPave[0] || bIsOnPave[1]) |
400 | { |
401 | // The found intersection point is located closely to one of the pave block's |
402 | // bounds. So, do not create the new vertex in this point. |
403 | // Check if this point is a real intersection, or just a touching point. |
404 | // If it is a touching point, do nothing. |
405 | // If it is an intersection point, update the existing vertex to cover the |
406 | // intersection point. |
407 | GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF); |
408 | const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew); |
409 | aProjPS.Perform(aPnew); |
410 | Standard_Real aMinDistEF = (aProjPS.IsDone() && aProjPS.NbPoints()) ? |
411 | aProjPS.LowerDistance() : Precision::Infinite(); |
412 | Standard_Boolean hasRealIntersection = aMinDistEF < Precision::Intersection(); |
413 | |
414 | if (!hasRealIntersection) |
415 | // no intersection point |
4e57c75e |
416 | continue; |
d3578357 |
417 | |
418 | // Real intersection is present. |
419 | // Update the existing vertex to cover the intersection point. |
420 | for (j = 0; j < 2; ++j) |
421 | { |
422 | if (bIsOnPave[j]) |
423 | { |
424 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j])); |
425 | const gp_Pnt aP = BRep_Tool::Pnt(aV); |
426 | Standard_Real aDistPP = aP.Distance(aPnew); |
427 | UpdateVertex(nV[j], aDistPP); |
428 | myVertsToAvoidExtension.Add(nV[j]); |
429 | } |
4e57c75e |
430 | } |
d3578357 |
431 | continue; |
432 | } |
433 | |
434 | if (CheckFacePaves(aVnew, aMIFOn)) { |
435 | continue; |
436 | } |
437 | // |
438 | Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew); |
439 | aTolVnew = Max(aTolVnew, Max(aTolE, aTolF)); |
440 | BRep_Builder().UpdateVertex(aVnew, aTolVnew); |
441 | if (bLinePlane) { |
442 | // increase tolerance for Line/Plane intersection, but do not update |
443 | // the vertex till its intersection with some other shape |
444 | IntTools_Range aCR = aCPart.Range1(); |
445 | aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.); |
4e57c75e |
446 | } |
d3578357 |
447 | // |
448 | const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew); |
449 | // |
450 | if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) { |
451 | continue; |
452 | } |
453 | // |
454 | aMIEFC.Add(nF); |
455 | // 1 |
456 | BOPDS_InterfEF& aEF = aEFs.Appended(); |
457 | iX = aEFs.Length() - 1; |
458 | aEF.SetIndices(nE, nF); |
459 | aEF.SetCommonPart(aCPart); |
460 | // 2 |
461 | myDS->AddInterf(nE, nF); |
462 | // 3 |
463 | BOPDS_CoupleOfPaveBlocks aCPB; |
464 | // |
465 | aCPB.SetPaveBlocks(aPB, aPB); |
466 | aCPB.SetIndexInterf(iX); |
467 | aCPB.SetTolerance(aTolVnew); |
468 | aMVCPB.Add(aVnew, aCPB); |
4e57c75e |
469 | } |
470 | break; |
471 | case TopAbs_EDGE: { |
472 | aMIEFC.Add(nF); |
473 | // |
474 | // 1 |
1155d05a |
475 | BOPDS_InterfEF& aEF=aEFs.Appended(); |
476 | iX=aEFs.Length()-1; |
4e57c75e |
477 | aEF.SetIndices(nE, nF); |
478 | // |
b4109929 |
479 | bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn); |
480 | bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn); |
481 | if (!bV[0] || !bV[1]) { |
4e57c75e |
482 | myDS->AddInterf(nE, nF); |
483 | break; |
484 | } |
4e57c75e |
485 | aEF.SetCommonPart(aCPart); |
486 | // 2 |
487 | myDS->AddInterf(nE, nF); |
488 | // 3 |
489 | BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator); |
490 | |
491 | } |
492 | break; |
493 | default: |
494 | break; |
e30616a7 |
495 | }//switch (aType) { |
496 | }//for (i=1; i<=aNbCPrts; ++i) { |
497 | }// for (k=0; k < aNbEdgeEdge; ++k) { |
4e57c75e |
498 | // |
499 | //========================================= |
500 | // post treatment |
501 | //========================================= |
d3578357 |
502 | BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS, myContext); |
503 | UpdateVerticesOfCB(); |
8ae442a8 |
504 | PerformNewVertices(aMVCPB, aAllocator, Standard_False); |
4e57c75e |
505 | // |
506 | // Update FaceInfoIn for all faces having EF common parts |
47cd8af2 |
507 | myDS->UpdateFaceInfoIn (aMIEFC); |
508 | |
4e57c75e |
509 | //-----------------------------------------------------scope t |
510 | aMIEFC.Clear(); |
511 | aMVCPB.Clear(); |
512 | aMPBLI.Clear(); |
e30616a7 |
513 | ////aAllocator.Nullify(); |
4e57c75e |
514 | } |
515 | //======================================================================= |
4e57c75e |
516 | // function: CheckFacePaves |
517 | // purpose: |
518 | //======================================================================= |
e30616a7 |
519 | Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves |
520 | (const Standard_Integer nVx, |
1155d05a |
521 | const TColStd_MapOfInteger& aMIFOn, |
522 | const TColStd_MapOfInteger& aMIFIn) |
4e57c75e |
523 | { |
524 | Standard_Boolean bRet; |
525 | Standard_Integer nV; |
1155d05a |
526 | TColStd_MapIteratorOfMapOfInteger aIt; |
4e57c75e |
527 | // |
528 | bRet=Standard_False; |
529 | // |
530 | aIt.Initialize(aMIFOn); |
531 | for (; aIt.More(); aIt.Next()) { |
532 | nV=aIt.Value(); |
533 | if (nV==nVx) { |
534 | bRet=!bRet; |
535 | return bRet; |
536 | } |
537 | } |
538 | aIt.Initialize(aMIFIn); |
539 | for (; aIt.More(); aIt.Next()) { |
540 | nV=aIt.Value(); |
541 | if (nV==nVx) { |
542 | bRet=!bRet; |
543 | return bRet; |
544 | } |
545 | } |
546 | // |
547 | return bRet; |
548 | } |
549 | //======================================================================= |
550 | // function: CheckFacePaves |
551 | // purpose: |
552 | //======================================================================= |
e30616a7 |
553 | Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves |
554 | (const TopoDS_Vertex& aVnew, |
1155d05a |
555 | const TColStd_MapOfInteger& aMIF) |
4e57c75e |
556 | { |
557 | Standard_Boolean bRet; |
558 | Standard_Integer nV, iFlag; |
1155d05a |
559 | TColStd_MapIteratorOfMapOfInteger aIt; |
4e57c75e |
560 | // |
561 | bRet=Standard_True; |
562 | // |
563 | aIt.Initialize(aMIF); |
564 | for (; aIt.More(); aIt.Next()) { |
565 | nV=aIt.Value(); |
566 | const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
567 | iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV); |
568 | if (!iFlag) { |
569 | return bRet; |
570 | } |
571 | } |
572 | // |
573 | return !bRet; |
574 | } |
b4109929 |
575 | //======================================================================= |
576 | //function : ForceInterfVF |
577 | //purpose : |
578 | //======================================================================= |
e30616a7 |
579 | Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF |
580 | (const Standard_Integer nV, |
581 | const Standard_Integer nF) |
b4109929 |
582 | { |
583 | Standard_Boolean bRet; |
3510db62 |
584 | Standard_Integer iFlag, nVx; |
585 | Standard_Real U, V, aTolVNew; |
b4109929 |
586 | // |
587 | bRet = Standard_False; |
588 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV); |
589 | const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF); |
590 | // |
0d0481c7 |
591 | iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue); |
3510db62 |
592 | if (iFlag == 0 || iFlag == -2) { |
593 | bRet=!bRet; |
b4109929 |
594 | // |
b4109929 |
595 | BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF(); |
a3476a9f |
596 | aVFs.SetIncrement(10); |
3510db62 |
597 | // 1 |
1155d05a |
598 | BOPDS_InterfVF& aVF=aVFs.Appended(); |
3510db62 |
599 | // |
b4109929 |
600 | aVF.SetIndices(nV, nF); |
601 | aVF.SetUV(U, V); |
3510db62 |
602 | // 2 |
b4109929 |
603 | myDS->AddInterf(nV, nF); |
604 | // |
3510db62 |
605 | // 3 update vertex V/F if necessary |
606 | nVx=UpdateVertex(nV, aTolVNew); |
607 | // 4 |
608 | if (myDS->IsNewShape(nVx)) { |
609 | aVF.SetIndexNew(nVx); |
610 | } |
b4109929 |
611 | // |
612 | BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); |
1155d05a |
613 | TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn(); |
3510db62 |
614 | aMVIn.Add(nVx); |
33ba8565 |
615 | // |
616 | // check for self-interference |
617 | Standard_Integer iRV = myDS->Rank(nV); |
618 | if (iRV >= 0 && iRV == myDS->Rank(nF)) { |
619 | // add warning status |
620 | TopoDS_Compound aWC; |
621 | BRep_Builder().MakeCompound(aWC); |
622 | BRep_Builder().Add(aWC, aV); |
623 | BRep_Builder().Add(aWC, aF); |
624 | AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC)); |
625 | } |
626 | |
b4109929 |
627 | } |
b4109929 |
628 | return bRet; |
629 | } |
01b5b3df |
630 | //======================================================================= |
631 | //function : ReduceIntersectionRange |
632 | //purpose : |
633 | //======================================================================= |
634 | void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1, |
635 | const Standard_Integer theV2, |
636 | const Standard_Integer theE, |
637 | const Standard_Integer theF, |
638 | Standard_Real& theTS1, |
639 | Standard_Real& theTS2) |
640 | { |
641 | if (!myDS->IsNewShape(theV1) && |
642 | !myDS->IsNewShape(theV2)) { |
643 | return; |
644 | } |
645 | // |
51db0179 |
646 | if (!myDS->HasInterfShapeSubShapes(theE, theF)) { |
647 | return; |
648 | } |
649 | // |
01b5b3df |
650 | BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE(); |
1155d05a |
651 | Standard_Integer aNbEEs = aEEs.Length(); |
01b5b3df |
652 | if (!aNbEEs) { |
653 | return; |
654 | } |
655 | // |
656 | Standard_Integer i, nV, nE1, nE2; |
657 | Standard_Real aTR1, aTR2; |
658 | // |
659 | // get face's edges to check that E/E contains the edge from the face |
1155d05a |
660 | TColStd_MapOfInteger aMFE; |
661 | const TColStd_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes(); |
662 | TColStd_ListIteratorOfListOfInteger aItLI(aLI); |
01b5b3df |
663 | for (; aItLI.More(); aItLI.Next()) { |
664 | nE1 = aItLI.Value(); |
665 | if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) { |
666 | aMFE.Add(nE1); |
667 | } |
668 | } |
669 | // |
670 | for (i = 0; i < aNbEEs; ++i) { |
671 | BOPDS_InterfEE& aEE = aEEs(i); |
672 | if (!aEE.HasIndexNew()) { |
673 | continue; |
674 | } |
675 | // |
676 | // check the vertex |
677 | nV = aEE.IndexNew(); |
678 | if (nV != theV1 && nV != theV2) { |
679 | continue; |
680 | } |
681 | // |
682 | // check that the intersection is between the edge |
683 | // and one of the face's edge |
684 | aEE.Indices(nE1, nE2); |
685 | if (((theE != nE1) && (theE != nE2)) || |
686 | (!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) { |
687 | continue; |
688 | } |
689 | // |
690 | // update the intersection range |
691 | const IntTools_CommonPrt& aCPart = aEE.CommonPart(); |
692 | const IntTools_Range& aCRange = |
693 | (theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First(); |
694 | aCRange.Range(aTR1, aTR2); |
695 | // |
696 | if (nV == theV1) { |
697 | if (theTS1 < aTR2) { |
698 | theTS1 = aTR2; |
699 | } |
700 | } |
701 | else { |
702 | if (theTS2 > aTR1) { |
703 | theTS2 = aTR1; |
704 | } |
705 | } |
706 | } |
707 | } |
d3578357 |
708 | |
709 | //======================================================================= |
710 | //function : ForceInterfEF |
711 | //purpose : |
712 | //======================================================================= |
713 | void BOPAlgo_PaveFiller::ForceInterfEF() |
714 | { |
715 | if (!myIsPrimary) |
716 | return; |
717 | |
718 | // Now that we have vertices increased and unified, try to find additional |
719 | // edge/face common blocks among the pairs of edge/face. |
720 | // Here, we are interested in common blocks only, as all real intersections |
721 | // should have happened already. Thus, we need to check only those pairs |
722 | // of edge/face which have the same vertices. |
723 | |
724 | // Collect all pave blocks |
725 | BOPDS_IndexedMapOfPaveBlock aMPB; |
726 | const Standard_Integer aNbS = myDS->NbSourceShapes(); |
727 | for (Standard_Integer nE = 0; nE < aNbS; ++nE) |
728 | { |
729 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE); |
730 | if (aSI.ShapeType() != TopAbs_EDGE) |
731 | // Not an edge |
732 | continue; |
733 | |
734 | if (!aSI.HasReference()) |
735 | // Edge has no pave blocks |
736 | continue; |
737 | |
738 | if (aSI.HasFlag()) |
739 | // Degenerated edge |
740 | continue; |
741 | |
742 | const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE); |
743 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
744 | for (; aItLPB.More(); aItLPB.Next()) |
745 | { |
746 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
747 | const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB); |
748 | aMPB.Add(aPBR); |
749 | } |
750 | } |
751 | |
752 | // Perform intersection of collected pave blocks with faces |
753 | ForceInterfEF(aMPB, Standard_True); |
754 | } |
755 | |
756 | //======================================================================= |
757 | //function : ForceInterfEF |
758 | //purpose : |
759 | //======================================================================= |
760 | void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB, |
761 | const Standard_Boolean theAddInterf) |
762 | { |
763 | if (theMPB.IsEmpty()) |
764 | return; |
765 | |
766 | // Fill the tree with bounding boxes of the pave blocks |
9324aa2d |
767 | BOPTools_BoxTree aBBTree; |
d3578357 |
768 | |
769 | Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; |
770 | BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc); |
771 | |
772 | Standard_Integer aNbPB = theMPB.Extent(); |
773 | for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB) |
774 | { |
775 | Handle(BOPDS_PaveBlock) aPB = theMPB(iPB); |
776 | if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB)) |
777 | { |
778 | FillShrunkData(aPB); |
779 | if (!aPB->HasShrunkData()) |
780 | continue; |
781 | } |
782 | |
783 | Standard_Real f, l; |
784 | Bnd_Box aPBBox; |
785 | Standard_Boolean isSplit; |
786 | aPB->ShrunkData(f, l, aPBBox, isSplit); |
787 | |
9324aa2d |
788 | aBBTree.Add(aPBMap.Add(aPB), Bnd_Tools::Bnd2BVH(aPBBox)); |
d3578357 |
789 | } |
790 | |
791 | // Shake the tree |
9324aa2d |
792 | aBBTree.Build(); |
d3578357 |
793 | |
c08fd127 |
794 | const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1); |
795 | |
d3578357 |
796 | // Find pairs of Face/PaveBlock containing the same vertices |
797 | // and prepare those pairs for intersection. |
798 | BOPAlgo_VectorOfEdgeFace aVEdgeFace; |
799 | |
800 | const Standard_Integer aNbS = myDS->NbSourceShapes(); |
801 | for (Standard_Integer nF = 0; nF < aNbS; ++nF) |
802 | { |
803 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF); |
804 | if (aSI.ShapeType() != TopAbs_FACE) |
805 | // Not a face |
806 | continue; |
807 | |
808 | if (!aSI.HasReference()) |
809 | // Face has no face info |
810 | continue; |
811 | |
812 | const Bnd_Box& aBoxF = aSI.Box(); |
9324aa2d |
813 | BOPTools_BoxTreeSelector aSelector; |
814 | aSelector.SetBox(Bnd_Tools::Bnd2BVH(aBoxF)); |
815 | aSelector.SetBVHSet (&aBBTree); |
816 | if (!aSelector.Select()) |
d3578357 |
817 | continue; |
818 | |
819 | const TopoDS_Face& aF = TopoDS::Face(aSI.Shape()); |
820 | const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF); |
821 | // Vertices of the face |
822 | TColStd_MapOfInteger aMVF; |
823 | const TColStd_MapOfInteger* pMVF[] = { &aFI.VerticesOn(), |
824 | &aFI.VerticesIn(), |
825 | &aFI.VerticesSc() }; |
826 | for (Standard_Integer iM = 0; iM < 3; ++iM) |
827 | { |
828 | TColStd_MapIteratorOfMapOfInteger itM(*pMVF[iM]); |
829 | for (; itM.More(); itM.Next()) |
830 | aMVF.Add(itM.Value()); |
831 | } |
832 | |
833 | // Pave Blocks of the face |
834 | const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(), |
835 | &aFI.PaveBlocksIn(), |
836 | &aFI.PaveBlocksSc() }; |
837 | for (Standard_Integer iM = 0; iM < 3; ++iM) |
838 | { |
839 | const Standard_Integer aNb = pMPBF[iM]->Extent(); |
840 | for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB) |
841 | { |
842 | const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB); |
843 | aMVF.Add(aPB->Pave1().Index()); |
844 | aMVF.Add(aPB->Pave2().Index()); |
845 | } |
846 | } |
847 | |
848 | // Projection tool |
849 | GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF); |
62fbfa98 |
850 | BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF); |
d3578357 |
851 | |
852 | // Iterate on pave blocks and combine pairs containing |
853 | // the same vertices |
854 | const TColStd_ListOfInteger& aLIPB = aSelector.Indices(); |
855 | TColStd_ListOfInteger::Iterator itLIPB(aLIPB); |
856 | for (; itLIPB.More(); itLIPB.Next()) |
857 | { |
858 | const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value()); |
859 | if (pMPBF[0]->Contains(aPB) || |
860 | pMPBF[1]->Contains(aPB) || |
861 | pMPBF[2]->Contains(aPB)) |
862 | continue; |
863 | |
864 | // Check if the face contains both vertices of the pave block |
865 | Standard_Integer nV1, nV2; |
866 | aPB->Indices(nV1, nV2); |
867 | if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2)) |
868 | // Face does not contain the vertices |
869 | continue; |
870 | |
871 | // Get the edge |
872 | Standard_Integer nE; |
873 | if (!aPB->HasEdge(nE)) |
874 | { |
875 | nE = aPB->OriginalEdge(); |
876 | if (nE < 0) |
877 | continue; |
878 | |
879 | // Make sure that the edge and face came from different arguments |
880 | if (myDS->Rank(nF) == myDS->Rank(nE)) |
881 | continue; |
882 | } |
883 | |
884 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); |
885 | BRepAdaptor_Curve aBAC(aE); |
886 | |
887 | // Check directions coincidence at middle point on the edge |
888 | // and projection of that point on the face. |
889 | // If the angle between tangent vector to the curve and normal |
62fbfa98 |
890 | // of the face is not in the range of 65 - 115 degrees, do not use the additional |
d3578357 |
891 | // tolerance, as it may lead to undesired unification of edge with the face. |
892 | Standard_Boolean bUseAddTol = Standard_True; |
893 | |
894 | Standard_Real aTS[2]; |
895 | Bnd_Box aPBBox; |
896 | Standard_Boolean isSplit; |
897 | aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit); |
898 | |
899 | // Middle point |
900 | gp_Pnt aPOnE; |
901 | // Tangent vector in the middle point |
902 | gp_Vec aVETgt; |
903 | aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt); |
904 | if (aVETgt.SquareMagnitude() < gp::Resolution()) |
905 | continue; |
906 | |
907 | aProjPS.Perform(aPOnE); |
908 | if (!aProjPS.NbPoints()) |
909 | continue; |
910 | |
911 | // Check the distance in the middle point, using the max vertices |
912 | // tolerance as the criteria. |
913 | const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1)); |
914 | const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2)); |
c08fd127 |
915 | |
916 | // In the Self-Interference check mode we are interested in real |
917 | // intersections only, so use only the real tolerance of edges, |
918 | // no need to use the extended tolerance. |
919 | Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue : |
920 | 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2))); |
d3578357 |
921 | |
922 | if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue) |
923 | continue; |
924 | |
925 | Standard_Real U, V; |
926 | aProjPS.LowerDistanceParameters(U, V); |
927 | if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V))) |
928 | continue; |
929 | |
62fbfa98 |
930 | if (aSurfAdaptor.GetType() != GeomAbs_Plane || |
931 | aBAC.GetType() != GeomAbs_Line) |
d3578357 |
932 | { |
62fbfa98 |
933 | gp_Pnt aPOnS = aProjPS.NearestPoint(); |
934 | gp_Vec aVFNorm(aPOnS, aPOnE); |
935 | if (aVFNorm.SquareMagnitude() > gp::Resolution()) |
936 | { |
937 | // Angle between vectors should be close to 90 degrees. |
938 | // We allow deviation of 25 degrees. |
939 | Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized()); |
940 | if (Abs(aCos) > 0.4226) |
941 | bUseAddTol = Standard_False; |
942 | } |
d3578357 |
943 | } |
944 | |
945 | // Compute an addition to Fuzzy value |
946 | Standard_Real aTolAdd = 0.0; |
947 | if (bUseAddTol) |
948 | { |
949 | // Compute the distance from the bounding points of the edge |
950 | // to the face and use the maximal of these distances as a |
951 | // fuzzy tolerance for the intersection. |
952 | // Use the maximal tolerance of the pave block's vertices |
953 | // as a max criteria for the computed distance. |
954 | |
955 | for (Standard_Integer iP = 0; iP < 2; ++iP) |
956 | { |
957 | gp_Pnt aP = aBAC.Value(aTS[iP]); |
958 | aProjPS.Perform(aP); |
959 | if (aProjPS.NbPoints()) |
960 | { |
961 | Standard_Real aDistEF = aProjPS.LowerDistance(); |
962 | if (aDistEF < aTolCheck && aDistEF > aTolAdd) |
963 | aTolAdd = aDistEF; |
964 | } |
965 | } |
966 | if (aTolAdd > 0.) |
967 | { |
968 | aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF)); |
969 | if (aTolAdd < 0.) |
970 | aTolAdd = 0.; |
971 | } |
972 | } |
973 | |
974 | Standard_Boolean bIntersect = aTolAdd > 0; |
975 | if (!bIntersect) |
976 | { |
977 | const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF); |
978 | bIntersect = !pMPB || !(pMPB->Contains(aPB)); |
979 | } |
980 | |
981 | if (bIntersect) |
982 | { |
983 | // Prepare pair for intersection |
984 | BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Appended(); |
985 | aEdgeFace.SetIndices(nE, nF); |
986 | aEdgeFace.SetPaveBlock(aPB); |
987 | aEdgeFace.SetEdge(aE); |
988 | aEdgeFace.SetFace(aF); |
c08fd127 |
989 | aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box()); |
d3578357 |
990 | aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd); |
991 | aEdgeFace.UseQuickCoincidenceCheck(Standard_True); |
992 | aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter())); |
993 | aEdgeFace.SetProgressIndicator(myProgressIndicator); |
994 | } |
995 | } |
996 | } |
997 | |
998 | Standard_Integer aNbEFs = aVEdgeFace.Length(); |
999 | if (!aNbEFs) |
1000 | return; |
1001 | |
1002 | aPBMap.Clear(); |
1003 | anAlloc->Reset(); |
1004 | |
1005 | // Perform intersection of the found pairs |
fc867b96 |
1006 | BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext); |
d3578357 |
1007 | |
1008 | BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF(); |
1009 | if (theAddInterf && aEFs.IsEmpty()) |
1010 | aEFs.SetIncrement(10); |
1011 | |
1012 | // Analyze the results of intersection looking for TopAbs_EDGE |
1013 | // intersection type only. |
1014 | |
1015 | // Collect all pairs for common block creation |
1016 | BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc); |
1017 | |
1018 | for (Standard_Integer i = 0; i < aNbEFs; ++i) |
1019 | { |
1020 | BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i); |
1021 | if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors()) |
1022 | { |
1023 | // Warn about failed intersection of sub-shapes |
1024 | AddIntersectionFailedWarning(anEdgeFace.Edge(), anEdgeFace.Face()); |
1025 | continue; |
1026 | } |
1027 | |
1028 | const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts(); |
1029 | if (aCParts.Length() != 1) |
1030 | continue; |
1031 | |
1032 | const IntTools_CommonPrt& aCP = aCParts(1); |
1033 | if (aCP.Type() != TopAbs_EDGE) |
1034 | continue; |
1035 | |
1036 | Standard_Integer nE, nF; |
1037 | anEdgeFace.Indices(nE, nF); |
1038 | if (theAddInterf) |
1039 | { |
1040 | // Add interference |
1041 | BOPDS_InterfEF& aEF = aEFs.Appended(); |
1042 | aEF.SetIndices(nE, nF); |
1043 | aEF.SetCommonPart(aCP); |
1044 | myDS->AddInterf(nE, nF); |
1045 | } |
1046 | |
1047 | const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock(); |
1048 | // Update face information with new IN pave block |
1049 | myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB); |
1050 | if (theAddInterf) |
1051 | // Fill map for common blocks creation |
1052 | BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc); |
1053 | } |
1054 | |
1055 | if (aMPBLI.Extent()) |
1056 | // Create new common blocks for coinciding pairs |
1057 | BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS); |
1058 | } |