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