0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPAlgo / BOPAlgo_CheckerSI.cxx
CommitLineData
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>
6f31882a 22#include <BOPCol_MapOfShape.hxx>
f48cb55d 23#include <BOPCol_Parallel.hxx>
4e57c75e 24#include <BOPDS_DS.hxx>
7ff8f019 25#include <BOPDS_Interf.hxx>
42cf5bc1 26#include <BOPDS_IteratorSI.hxx>
25dfc507 27#include <BOPDS_MapOfPair.hxx>
28#include <BOPDS_Pair.hxx>
42cf5bc1 29#include <BOPDS_PIteratorSI.hxx>
7ff8f019 30#include <BOPDS_VectorOfInterfEF.hxx>
31#include <BOPDS_VectorOfInterfFF.hxx>
42cf5bc1 32#include <BOPDS_VectorOfInterfVE.hxx>
33#include <BOPDS_VectorOfInterfVF.hxx>
34#include <BOPDS_VectorOfInterfVV.hxx>
6f31882a 35#include <BOPTools.hxx>
7ff8f019 36#include <BOPTools_AlgoTools.hxx>
42cf5bc1 37#include <BRepBuilderAPI_Copy.hxx>
38#include <IntTools_Context.hxx>
f48cb55d 39#include <IntTools_Tools.hxx>
40#include <IntTools_FaceFace.hxx>
42cf5bc1 41#include <Standard_ErrorHandler.hxx>
42#include <Standard_Failure.hxx>
43#include <TopTools_ListOfShape.hxx>
f48cb55d 44#include <BRep_Tool.hxx>
45#include <gp_Torus.hxx>
46
47//=======================================================================
48//class : BOPAlgo_FaceSelfIntersect
49//purpose :
50//=======================================================================
51class 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
105typedef BOPCol_NCVector
106 <BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect;
107//
108typedef BOPCol_Functor
109 <BOPAlgo_FaceSelfIntersect,
110 BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectFunctor;
111//
112typedef BOPCol_Cnt
113 <BOPAlgo_FaceSelfIntersectFunctor,
114 BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectCnt;
115
7ff8f019 116
7fd59977 117//=======================================================================
4e57c75e 118//function :
7fd59977 119//purpose :
120//=======================================================================
7ff8f019 121BOPAlgo_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 133BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI()
7fd59977 134{
7fd59977 135}
136//=======================================================================
c1fe53c6 137//function : SetLevelOfCheck
138//purpose :
139//=======================================================================
7ff8f019 140void 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 153void 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 //
162 // 2.myIterator
c1fe53c6 163 BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
164 theIterSI->SetDS(myDS);
165 theIterSI->Prepare();
166 theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
167 //
168 myIterator=theIterSI;
4e57c75e 169 //
170 // 3 myContext
1e143abb 171 myContext=new IntTools_Context;
7fd59977 172}
7ff8f019 173//=======================================================================
174//function : Perform
175//purpose :
176//=======================================================================
177void 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//=======================================================================
217void 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();
227 aNb=aVVs.Extent();
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();
240 aNb=aVEs.Extent();
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();
253 aNb=aEEs.Extent();
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();
266 aNb=aVFs.Extent();
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();
279 aNb=aEFs.Extent();
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();
295 aNb=aFFs.Extent();
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();
304 aNbP=aFF.Points().Extent();
305 const BOPDS_VectorOfCurve& aVC=aFF.Curves();
306 aNbC=aVC.Extent();
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();
347 aNb=aVZs.Extent();
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();
361 aNb=aEZs.Extent();
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();
372 aNb=aFZs.Extent();
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();
383 aNb=aZZs.Extent();
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//=======================================================================
397void 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
439 BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace.Append1();
440 //
441 aFaceSelfIntersect.SetIndex(i);
442 aFaceSelfIntersect.SetFace(aF);
443 aFaceSelfIntersect.SetTolF(aTolF);
444 //
445 aFaceSelfIntersect.SetProgressIndicator(myProgressIndicator);
446 }
447
448 Standard_Integer aNbFace = aVFace.Extent();
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}