0031836: Modeling Algorithms - Boolean cut failed between a Cone and a Torus
[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>
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//=======================================================================
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
fc867b96 105typedef NCollection_Vector<BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect;
7ff8f019 106
7fd59977 107//=======================================================================
4e57c75e 108//function :
7fd59977 109//purpose :
110//=======================================================================
7ff8f019 111BOPAlgo_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 123BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI()
7fd59977 124{
7fd59977 125}
126//=======================================================================
c1fe53c6 127//function : SetLevelOfCheck
128//purpose :
129//=======================================================================
7ff8f019 130void 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 143void 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//=======================================================================
167void 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//=======================================================================
207void 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//=======================================================================
387void 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}