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