b311480e |
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 |
b311480e |
6 | // |
973c2be1 |
7 | // This file is part of Open CASCADE Technology software library. |
b311480e |
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. |
b311480e |
14 | // |
973c2be1 |
15 | // Alternatively, this file may be used under the terms of Open CASCADE |
16 | // commercial license or contractual agreement. |
17 | |
4e57c75e |
18 | // |
6f31882a |
19 | |
42cf5bc1 |
20 | #include <BOPAlgo_CheckerSI.hxx> |
33ba8565 |
21 | #include <BOPAlgo_Alerts.hxx> |
4e57c75e |
22 | #include <BOPDS_DS.hxx> |
7ff8f019 |
23 | #include <BOPDS_Interf.hxx> |
42cf5bc1 |
24 | #include <BOPDS_IteratorSI.hxx> |
25dfc507 |
25 | #include <BOPDS_MapOfPair.hxx> |
26 | #include <BOPDS_Pair.hxx> |
42cf5bc1 |
27 | #include <BOPDS_PIteratorSI.hxx> |
7ff8f019 |
28 | #include <BOPDS_VectorOfInterfEF.hxx> |
29 | #include <BOPDS_VectorOfInterfFF.hxx> |
42cf5bc1 |
30 | #include <BOPDS_VectorOfInterfVE.hxx> |
31 | #include <BOPDS_VectorOfInterfVF.hxx> |
32 | #include <BOPDS_VectorOfInterfVV.hxx> |
1155d05a |
33 | #include <BRep_Tool.hxx> |
34 | #include <gp_Torus.hxx> |
35 | #include <TopExp.hxx> |
7ff8f019 |
36 | #include <BOPTools_AlgoTools.hxx> |
1155d05a |
37 | #include <BOPTools_Parallel.hxx> |
42cf5bc1 |
38 | #include <BRepBuilderAPI_Copy.hxx> |
39 | #include <IntTools_Context.hxx> |
f48cb55d |
40 | #include <IntTools_Tools.hxx> |
41 | #include <IntTools_FaceFace.hxx> |
42cf5bc1 |
42 | #include <Standard_ErrorHandler.hxx> |
43 | #include <Standard_Failure.hxx> |
44 | #include <TopTools_ListOfShape.hxx> |
1155d05a |
45 | #include <TopTools_MapOfShape.hxx> |
f48cb55d |
46 | |
47 | //======================================================================= |
48 | //class : BOPAlgo_FaceSelfIntersect |
49 | //purpose : |
50 | //======================================================================= |
51 | class BOPAlgo_FaceSelfIntersect : |
52 | public IntTools_FaceFace, |
53 | public BOPAlgo_Algo { |
54 | |
55 | public: |
56 | DEFINE_STANDARD_ALLOC |
57 | |
58 | BOPAlgo_FaceSelfIntersect() : |
59 | IntTools_FaceFace(), |
60 | BOPAlgo_Algo(), |
61 | myIF(-1), myTolF(1.e-7) { |
62 | } |
63 | // |
64 | virtual ~BOPAlgo_FaceSelfIntersect() { |
65 | } |
66 | // |
67 | void SetIndex(const Standard_Integer nF) { |
68 | myIF = nF; |
69 | } |
70 | // |
71 | Standard_Integer IndexOfFace() const { |
72 | return myIF; |
73 | } |
74 | // |
75 | void SetFace(const TopoDS_Face& aF) { |
76 | myF = aF; |
77 | } |
78 | // |
79 | const TopoDS_Face& Face()const { |
80 | return myF; |
81 | } |
82 | // |
83 | void SetTolF(const Standard_Real aTolF) { |
84 | myTolF = aTolF; |
85 | } |
86 | // |
87 | Standard_Real TolF() const{ |
88 | return myTolF; |
89 | } |
90 | // |
91 | virtual void Perform() { |
92 | BOPAlgo_Algo::UserBreak(); |
93 | IntTools_FaceFace::Perform(myF, myF); |
94 | } |
95 | // |
96 | protected: |
97 | Standard_Integer myIF; |
98 | Standard_Real myTolF; |
99 | TopoDS_Face myF; |
100 | }; |
101 | //end of definition of class BOPAlgo_FaceSelfIntersect |
102 | |
103 | //======================================================================= |
104 | |
1155d05a |
105 | typedef NCollection_Vector |
f48cb55d |
106 | <BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect; |
107 | // |
1155d05a |
108 | typedef BOPTools_Functor |
f48cb55d |
109 | <BOPAlgo_FaceSelfIntersect, |
110 | BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectFunctor; |
111 | // |
1155d05a |
112 | typedef BOPTools_Cnt |
f48cb55d |
113 | <BOPAlgo_FaceSelfIntersectFunctor, |
114 | BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectCnt; |
115 | |
7ff8f019 |
116 | |
7fd59977 |
117 | //======================================================================= |
4e57c75e |
118 | //function : |
7fd59977 |
119 | //purpose : |
120 | //======================================================================= |
7ff8f019 |
121 | BOPAlgo_CheckerSI::BOPAlgo_CheckerSI() |
7fd59977 |
122 | : |
ceaa5e27 |
123 | BOPAlgo_PaveFiller() |
4e57c75e |
124 | { |
ceaa5e27 |
125 | myLevelOfCheck=BOPDS_DS::NbInterfTypes()-1; |
6f31882a |
126 | myNonDestructive=Standard_True; |
0c5a6d47 |
127 | SetAvoidBuildPCurve(Standard_True); |
4e57c75e |
128 | } |
7fd59977 |
129 | //======================================================================= |
4e57c75e |
130 | //function : ~ |
7fd59977 |
131 | //purpose : |
132 | //======================================================================= |
7ff8f019 |
133 | BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI() |
7fd59977 |
134 | { |
7fd59977 |
135 | } |
136 | //======================================================================= |
c1fe53c6 |
137 | //function : SetLevelOfCheck |
138 | //purpose : |
139 | //======================================================================= |
7ff8f019 |
140 | void BOPAlgo_CheckerSI::SetLevelOfCheck(const Standard_Integer theLevel) |
c1fe53c6 |
141 | { |
ceaa5e27 |
142 | Standard_Integer aNbLists; |
143 | // |
144 | aNbLists=BOPDS_DS::NbInterfTypes(); |
145 | if (theLevel >= 0 && theLevel < aNbLists) { |
c1fe53c6 |
146 | myLevelOfCheck = theLevel; |
147 | } |
148 | } |
149 | //======================================================================= |
4e57c75e |
150 | //function : Init |
7fd59977 |
151 | //purpose : |
152 | //======================================================================= |
7ff8f019 |
153 | void BOPAlgo_CheckerSI::Init() |
7fd59977 |
154 | { |
4e57c75e |
155 | Clear(); |
156 | // |
157 | // 1. myDS |
158 | myDS=new BOPDS_DS(myAllocator); |
159 | myDS->SetArguments(myArguments); |
0d0481c7 |
160 | myDS->Init(myFuzzyValue); |
4e57c75e |
161 | // |
944768d2 |
162 | // 2 myContext |
163 | myContext=new IntTools_Context; |
164 | // |
165 | // 3.myIterator |
c1fe53c6 |
166 | BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator); |
167 | theIterSI->SetDS(myDS); |
944768d2 |
168 | theIterSI->Prepare(myContext, myUseOBB, myFuzzyValue); |
c1fe53c6 |
169 | theIterSI->UpdateByLevelOfCheck(myLevelOfCheck); |
170 | // |
171 | myIterator=theIterSI; |
7fd59977 |
172 | } |
7ff8f019 |
173 | //======================================================================= |
174 | //function : Perform |
175 | //purpose : |
176 | //======================================================================= |
177 | void BOPAlgo_CheckerSI::Perform() |
178 | { |
b62b3e07 |
179 | try { |
180 | OCC_CATCH_SIGNALS |
181 | // |
25dfc507 |
182 | if (myArguments.Extent() != 1) { |
33ba8565 |
183 | AddError (new BOPAlgo_AlertMultipleArguments); |
6f31882a |
184 | return; |
185 | } |
186 | // |
25dfc507 |
187 | // Perform intersection of sub shapes |
b62b3e07 |
188 | BOPAlgo_PaveFiller::Perform(); |
b62b3e07 |
189 | // |
f48cb55d |
190 | CheckFaceSelfIntersection(); |
191 | |
25dfc507 |
192 | // Perform intersection with solids |
33ba8565 |
193 | if (!HasErrors()) |
25dfc507 |
194 | PerformVZ(); |
6f31882a |
195 | // |
33ba8565 |
196 | if (!HasErrors()) |
25dfc507 |
197 | PerformEZ(); |
63def8e6 |
198 | // |
33ba8565 |
199 | if (!HasErrors()) |
25dfc507 |
200 | PerformFZ(); |
201 | // |
33ba8565 |
202 | if (!HasErrors()) |
25dfc507 |
203 | PerformZZ(); |
204 | // |
205 | // Treat the intersection results |
206 | PostTreat(); |
b62b3e07 |
207 | } |
80db5701 |
208 | // |
b62b3e07 |
209 | catch (Standard_Failure) { |
33ba8565 |
210 | AddError (new BOPAlgo_AlertIntersectionFailed); |
80db5701 |
211 | } |
7ff8f019 |
212 | } |
213 | //======================================================================= |
214 | //function : PostTreat |
215 | //purpose : |
216 | //======================================================================= |
217 | void BOPAlgo_CheckerSI::PostTreat() |
218 | { |
219 | Standard_Integer i, aNb, n1, n2; |
25dfc507 |
220 | BOPDS_Pair aPK; |
7ff8f019 |
221 | // |
25dfc507 |
222 | BOPDS_MapOfPair& aMPK= |
223 | *((BOPDS_MapOfPair*)&myDS->Interferences()); |
f48cb55d |
224 | |
7ff8f019 |
225 | // 0 |
226 | BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV(); |
1155d05a |
227 | aNb=aVVs.Length(); |
7ff8f019 |
228 | for (i=0; i!=aNb; ++i) { |
229 | const BOPDS_InterfVV& aVV=aVVs(i); |
230 | aVV.Indices(n1, n2); |
80db5701 |
231 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
232 | continue; |
233 | } |
25dfc507 |
234 | aPK.SetIndices(n1, n2); |
7ff8f019 |
235 | aMPK.Add(aPK); |
236 | } |
237 | // |
238 | // 1 |
239 | BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE(); |
1155d05a |
240 | aNb=aVEs.Length(); |
7ff8f019 |
241 | for (i=0; i!=aNb; ++i) { |
242 | const BOPDS_InterfVE& aVE=aVEs(i); |
243 | aVE.Indices(n1, n2); |
80db5701 |
244 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
245 | continue; |
246 | } |
25dfc507 |
247 | aPK.SetIndices(n1, n2); |
7ff8f019 |
248 | aMPK.Add(aPK); |
249 | } |
250 | // |
251 | // 2 |
252 | BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); |
1155d05a |
253 | aNb=aEEs.Length(); |
7ff8f019 |
254 | for (i=0; i!=aNb; ++i) { |
255 | const BOPDS_InterfEE& aEE=aEEs(i); |
256 | aEE.Indices(n1, n2); |
80db5701 |
257 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
258 | continue; |
259 | } |
25dfc507 |
260 | aPK.SetIndices(n1, n2); |
7ff8f019 |
261 | aMPK.Add(aPK); |
262 | } |
263 | // |
264 | // 3 |
265 | BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF(); |
1155d05a |
266 | aNb=aVFs.Length(); |
7ff8f019 |
267 | for (i=0; i!=aNb; ++i) { |
268 | const BOPDS_InterfVF& aVF=aVFs(i); |
269 | aVF.Indices(n1, n2); |
80db5701 |
270 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
271 | continue; |
272 | } |
25dfc507 |
273 | aPK.SetIndices(n1, n2); |
7ff8f019 |
274 | aMPK.Add(aPK); |
275 | } |
276 | // |
277 | // 4 |
278 | BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); |
1155d05a |
279 | aNb=aEFs.Length(); |
7ff8f019 |
280 | for (i=0; i!=aNb; ++i) { |
281 | const BOPDS_InterfEF& aEF=aEFs(i); |
282 | if (aEF.CommonPart().Type()==TopAbs_SHAPE) { |
283 | continue; |
284 | } |
285 | aEF.Indices(n1, n2); |
80db5701 |
286 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
287 | continue; |
288 | } |
25dfc507 |
289 | aPK.SetIndices(n1, n2); |
7ff8f019 |
290 | aMPK.Add(aPK); |
291 | } |
292 | // |
293 | // 5 |
294 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
1155d05a |
295 | aNb=aFFs.Length(); |
7ff8f019 |
296 | for (i=0; i!=aNb; ++i) { |
297 | Standard_Boolean bTangentFaces, bFlag; |
298 | Standard_Integer aNbC, aNbP, j, iFound; |
299 | // |
300 | const BOPDS_InterfFF& aFF=aFFs(i); |
301 | aFF.Indices(n1, n2); |
302 | // |
303 | bTangentFaces=aFF.TangentFaces(); |
1155d05a |
304 | aNbP=aFF.Points().Length(); |
7ff8f019 |
305 | const BOPDS_VectorOfCurve& aVC=aFF.Curves(); |
1155d05a |
306 | aNbC=aVC.Length(); |
7ff8f019 |
307 | if (!aNbP && !aNbC && !bTangentFaces) { |
308 | continue; |
309 | } |
310 | // |
f48cb55d |
311 | iFound = (n1 == n2) ? 1 : 0; |
312 | //case of self-intersection inside one face |
313 | if (!iFound) |
314 | { |
315 | if (bTangentFaces) { |
316 | const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1)); |
317 | const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2)); |
318 | bFlag=BOPTools_AlgoTools::AreFacesSameDomain |
319 | (aF1, aF2, myContext, myFuzzyValue); |
320 | if (bFlag) { |
6f31882a |
321 | ++iFound; |
f48cb55d |
322 | } |
323 | } |
324 | else { |
325 | for (j=0; j!=aNbC; ++j) { |
326 | const BOPDS_Curve& aNC=aVC(j); |
327 | const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks(); |
328 | if (aLPBC.Extent()) { |
329 | ++iFound; |
330 | break; |
331 | } |
6f31882a |
332 | } |
7ff8f019 |
333 | } |
334 | } |
335 | // |
336 | if (!iFound) { |
337 | continue; |
338 | } |
339 | // |
25dfc507 |
340 | aPK.SetIndices(n1, n2); |
7ff8f019 |
341 | aMPK.Add(aPK); |
342 | } |
ceaa5e27 |
343 | // |
344 | // |
345 | // 6 |
346 | BOPDS_VectorOfInterfVZ& aVZs=myDS->InterfVZ(); |
1155d05a |
347 | aNb=aVZs.Length(); |
ceaa5e27 |
348 | for (i=0; i!=aNb; ++i) { |
349 | // |
350 | const BOPDS_InterfVZ& aVZ=aVZs(i); |
351 | aVZ.Indices(n1, n2); |
80db5701 |
352 | if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) { |
353 | continue; |
354 | } |
25dfc507 |
355 | aPK.SetIndices(n1, n2); |
ceaa5e27 |
356 | aMPK.Add(aPK); |
357 | } |
358 | // |
359 | // 7 |
360 | BOPDS_VectorOfInterfEZ& aEZs=myDS->InterfEZ(); |
1155d05a |
361 | aNb=aEZs.Length(); |
ceaa5e27 |
362 | for (i=0; i!=aNb; ++i) { |
363 | // |
364 | const BOPDS_InterfEZ& aEZ=aEZs(i); |
365 | aEZ.Indices(n1, n2); |
25dfc507 |
366 | aPK.SetIndices(n1, n2); |
ceaa5e27 |
367 | aMPK.Add(aPK); |
368 | } |
369 | // |
370 | // 8 |
371 | BOPDS_VectorOfInterfFZ& aFZs=myDS->InterfFZ(); |
1155d05a |
372 | aNb=aFZs.Length(); |
ceaa5e27 |
373 | for (i=0; i!=aNb; ++i) { |
374 | // |
375 | const BOPDS_InterfFZ& aFZ=aFZs(i); |
376 | aFZ.Indices(n1, n2); |
25dfc507 |
377 | aPK.SetIndices(n1, n2); |
ceaa5e27 |
378 | aMPK.Add(aPK); |
379 | } |
380 | // |
381 | // 9 |
382 | BOPDS_VectorOfInterfZZ& aZZs=myDS->InterfZZ(); |
1155d05a |
383 | aNb=aZZs.Length(); |
ceaa5e27 |
384 | for (i=0; i!=aNb; ++i) { |
385 | // |
386 | const BOPDS_InterfZZ& aZZ=aZZs(i); |
387 | aZZ.Indices(n1, n2); |
25dfc507 |
388 | aPK.SetIndices(n1, n2); |
ceaa5e27 |
389 | aMPK.Add(aPK); |
390 | } |
7ff8f019 |
391 | } |
f48cb55d |
392 | |
393 | //======================================================================= |
394 | //function : CheckFaceSelfIntersection |
395 | //purpose : |
396 | //======================================================================= |
397 | void BOPAlgo_CheckerSI::CheckFaceSelfIntersection() |
398 | { |
399 | if (myLevelOfCheck < 5) |
400 | return; |
401 | |
402 | BOPDS_Pair aPK; |
403 | |
404 | BOPDS_MapOfPair& aMPK= |
405 | *((BOPDS_MapOfPair*)&myDS->Interferences()); |
406 | aMPK.Clear(); |
407 | |
408 | BOPAlgo_VectorOfFaceSelfIntersect aVFace; |
409 | |
410 | Standard_Integer aNbS=myDS->NbSourceShapes(); |
411 | |
412 | // |
413 | for (Standard_Integer i = 0; i < aNbS; i++) |
414 | { |
415 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
416 | if (aSI.ShapeType() != TopAbs_FACE) |
417 | continue; |
418 | // |
419 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape())); |
420 | BRepAdaptor_Surface BAsurf(aF, Standard_False); |
421 | GeomAbs_SurfaceType aSurfType = BAsurf.GetType(); |
422 | if (aSurfType == GeomAbs_Plane || |
423 | aSurfType == GeomAbs_Cylinder || |
424 | aSurfType == GeomAbs_Cone || |
425 | aSurfType == GeomAbs_Sphere) |
426 | continue; |
427 | |
428 | if (aSurfType == GeomAbs_Torus) |
429 | { |
430 | gp_Torus aTorus = BAsurf.Torus(); |
431 | Standard_Real aMajorRadius = aTorus.MajorRadius(); |
432 | Standard_Real aMinorRadius = aTorus.MinorRadius(); |
433 | if (aMajorRadius > aMinorRadius + Precision::Confusion()) |
434 | continue; |
435 | } |
436 | |
437 | Standard_Real aTolF = BRep_Tool::Tolerance(aF); |
438 | |
1155d05a |
439 | BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace.Appended(); |
f48cb55d |
440 | // |
441 | aFaceSelfIntersect.SetIndex(i); |
442 | aFaceSelfIntersect.SetFace(aF); |
443 | aFaceSelfIntersect.SetTolF(aTolF); |
444 | // |
445 | aFaceSelfIntersect.SetProgressIndicator(myProgressIndicator); |
446 | } |
447 | |
1155d05a |
448 | Standard_Integer aNbFace = aVFace.Length(); |
f48cb55d |
449 | //====================================================== |
450 | BOPAlgo_FaceSelfIntersectCnt::Perform(myRunParallel, aVFace); |
451 | //====================================================== |
452 | // |
453 | for (Standard_Integer k = 0; k < aNbFace; k++) |
454 | { |
455 | BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace(k); |
456 | // |
457 | Standard_Integer nF = aFaceSelfIntersect.IndexOfFace(); |
458 | |
459 | Standard_Boolean bIsDone = aFaceSelfIntersect.IsDone(); |
460 | if (bIsDone) |
461 | { |
462 | const IntTools_SequenceOfCurves& aCvsX = aFaceSelfIntersect.Lines(); |
463 | const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceSelfIntersect.Points(); |
464 | // |
465 | Standard_Integer aNbCurves = aCvsX.Length(); |
466 | Standard_Integer aNbPoints = aPntsX.Length(); |
467 | // |
468 | if (aNbCurves || aNbPoints) |
469 | { |
470 | aPK.SetIndices(nF, nF); |
471 | aMPK.Add(aPK); |
472 | } |
473 | } |
474 | } |
475 | } |