1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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
7 // This file is part of Open CASCADE Technology software library.
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
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.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
20 #include <BOPAlgo_CheckerSI.hxx>
21 #include <BOPAlgo_Alerts.hxx>
22 #include <BOPCol_MapOfShape.hxx>
23 #include <BOPCol_Parallel.hxx>
24 #include <BOPDS_DS.hxx>
25 #include <BOPDS_Interf.hxx>
26 #include <BOPDS_IteratorSI.hxx>
27 #include <BOPDS_MapOfPair.hxx>
28 #include <BOPDS_Pair.hxx>
29 #include <BOPDS_PIteratorSI.hxx>
30 #include <BOPDS_VectorOfInterfEF.hxx>
31 #include <BOPDS_VectorOfInterfFF.hxx>
32 #include <BOPDS_VectorOfInterfVE.hxx>
33 #include <BOPDS_VectorOfInterfVF.hxx>
34 #include <BOPDS_VectorOfInterfVV.hxx>
35 #include <BOPTools.hxx>
36 #include <BOPTools_AlgoTools.hxx>
37 #include <BRepBuilderAPI_Copy.hxx>
38 #include <IntTools_Context.hxx>
39 #include <IntTools_Tools.hxx>
40 #include <IntTools_FaceFace.hxx>
41 #include <Standard_ErrorHandler.hxx>
42 #include <Standard_Failure.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <BRep_Tool.hxx>
45 #include <gp_Torus.hxx>
47 //=======================================================================
48 //class : BOPAlgo_FaceSelfIntersect
50 //=======================================================================
51 class BOPAlgo_FaceSelfIntersect :
52 public IntTools_FaceFace,
58 BOPAlgo_FaceSelfIntersect() :
61 myIF(-1), myTolF(1.e-7) {
64 virtual ~BOPAlgo_FaceSelfIntersect() {
67 void SetIndex(const Standard_Integer nF) {
71 Standard_Integer IndexOfFace() const {
75 void SetFace(const TopoDS_Face& aF) {
79 const TopoDS_Face& Face()const {
83 void SetTolF(const Standard_Real aTolF) {
87 Standard_Real TolF() const{
91 virtual void Perform() {
92 BOPAlgo_Algo::UserBreak();
93 IntTools_FaceFace::Perform(myF, myF);
97 Standard_Integer myIF;
101 //end of definition of class BOPAlgo_FaceSelfIntersect
103 //=======================================================================
105 typedef BOPCol_NCVector
106 <BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect;
108 typedef BOPCol_Functor
109 <BOPAlgo_FaceSelfIntersect,
110 BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectFunctor;
113 <BOPAlgo_FaceSelfIntersectFunctor,
114 BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectCnt;
117 //=======================================================================
120 //=======================================================================
121 BOPAlgo_CheckerSI::BOPAlgo_CheckerSI()
125 myLevelOfCheck=BOPDS_DS::NbInterfTypes()-1;
126 myNonDestructive=Standard_True;
127 SetAvoidBuildPCurve(Standard_True);
129 //=======================================================================
132 //=======================================================================
133 BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI()
136 //=======================================================================
137 //function : SetLevelOfCheck
139 //=======================================================================
140 void BOPAlgo_CheckerSI::SetLevelOfCheck(const Standard_Integer theLevel)
142 Standard_Integer aNbLists;
144 aNbLists=BOPDS_DS::NbInterfTypes();
145 if (theLevel >= 0 && theLevel < aNbLists) {
146 myLevelOfCheck = theLevel;
149 //=======================================================================
152 //=======================================================================
153 void BOPAlgo_CheckerSI::Init()
158 myDS=new BOPDS_DS(myAllocator);
159 myDS->SetArguments(myArguments);
160 myDS->Init(myFuzzyValue);
163 BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
164 theIterSI->SetDS(myDS);
165 theIterSI->Prepare();
166 theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
168 myIterator=theIterSI;
171 myContext=new IntTools_Context;
173 //=======================================================================
176 //=======================================================================
177 void BOPAlgo_CheckerSI::Perform()
182 if (myArguments.Extent() != 1) {
183 AddError (new BOPAlgo_AlertMultipleArguments);
187 // Perform intersection of sub shapes
188 BOPAlgo_PaveFiller::Perform();
190 CheckFaceSelfIntersection();
192 // Perform intersection with solids
205 // Treat the intersection results
209 catch (Standard_Failure) {
210 AddError (new BOPAlgo_AlertIntersectionFailed);
213 //=======================================================================
214 //function : PostTreat
216 //=======================================================================
217 void BOPAlgo_CheckerSI::PostTreat()
219 Standard_Integer i, aNb, n1, n2;
222 BOPDS_MapOfPair& aMPK=
223 *((BOPDS_MapOfPair*)&myDS->Interferences());
226 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
228 for (i=0; i!=aNb; ++i) {
229 const BOPDS_InterfVV& aVV=aVVs(i);
231 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
234 aPK.SetIndices(n1, n2);
239 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
241 for (i=0; i!=aNb; ++i) {
242 const BOPDS_InterfVE& aVE=aVEs(i);
244 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
247 aPK.SetIndices(n1, n2);
252 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
254 for (i=0; i!=aNb; ++i) {
255 const BOPDS_InterfEE& aEE=aEEs(i);
257 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
260 aPK.SetIndices(n1, n2);
265 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
267 for (i=0; i!=aNb; ++i) {
268 const BOPDS_InterfVF& aVF=aVFs(i);
270 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
273 aPK.SetIndices(n1, n2);
278 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
280 for (i=0; i!=aNb; ++i) {
281 const BOPDS_InterfEF& aEF=aEFs(i);
282 if (aEF.CommonPart().Type()==TopAbs_SHAPE) {
286 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
289 aPK.SetIndices(n1, n2);
294 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
296 for (i=0; i!=aNb; ++i) {
297 Standard_Boolean bTangentFaces, bFlag;
298 Standard_Integer aNbC, aNbP, j, iFound;
300 const BOPDS_InterfFF& aFF=aFFs(i);
303 bTangentFaces=aFF.TangentFaces();
304 aNbP=aFF.Points().Extent();
305 const BOPDS_VectorOfCurve& aVC=aFF.Curves();
307 if (!aNbP && !aNbC && !bTangentFaces) {
311 iFound = (n1 == n2) ? 1 : 0;
312 //case of self-intersection inside one face
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);
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()) {
340 aPK.SetIndices(n1, n2);
346 BOPDS_VectorOfInterfVZ& aVZs=myDS->InterfVZ();
348 for (i=0; i!=aNb; ++i) {
350 const BOPDS_InterfVZ& aVZ=aVZs(i);
352 if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
355 aPK.SetIndices(n1, n2);
360 BOPDS_VectorOfInterfEZ& aEZs=myDS->InterfEZ();
362 for (i=0; i!=aNb; ++i) {
364 const BOPDS_InterfEZ& aEZ=aEZs(i);
366 aPK.SetIndices(n1, n2);
371 BOPDS_VectorOfInterfFZ& aFZs=myDS->InterfFZ();
373 for (i=0; i!=aNb; ++i) {
375 const BOPDS_InterfFZ& aFZ=aFZs(i);
377 aPK.SetIndices(n1, n2);
382 BOPDS_VectorOfInterfZZ& aZZs=myDS->InterfZZ();
384 for (i=0; i!=aNb; ++i) {
386 const BOPDS_InterfZZ& aZZ=aZZs(i);
388 aPK.SetIndices(n1, n2);
393 //=======================================================================
394 //function : CheckFaceSelfIntersection
396 //=======================================================================
397 void BOPAlgo_CheckerSI::CheckFaceSelfIntersection()
399 if (myLevelOfCheck < 5)
404 BOPDS_MapOfPair& aMPK=
405 *((BOPDS_MapOfPair*)&myDS->Interferences());
408 BOPAlgo_VectorOfFaceSelfIntersect aVFace;
410 Standard_Integer aNbS=myDS->NbSourceShapes();
413 for (Standard_Integer i = 0; i < aNbS; i++)
415 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
416 if (aSI.ShapeType() != TopAbs_FACE)
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)
428 if (aSurfType == GeomAbs_Torus)
430 gp_Torus aTorus = BAsurf.Torus();
431 Standard_Real aMajorRadius = aTorus.MajorRadius();
432 Standard_Real aMinorRadius = aTorus.MinorRadius();
433 if (aMajorRadius > aMinorRadius + Precision::Confusion())
437 Standard_Real aTolF = BRep_Tool::Tolerance(aF);
439 BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace.Append1();
441 aFaceSelfIntersect.SetIndex(i);
442 aFaceSelfIntersect.SetFace(aF);
443 aFaceSelfIntersect.SetTolF(aTolF);
445 aFaceSelfIntersect.SetProgressIndicator(myProgressIndicator);
448 Standard_Integer aNbFace = aVFace.Extent();
449 //======================================================
450 BOPAlgo_FaceSelfIntersectCnt::Perform(myRunParallel, aVFace);
451 //======================================================
453 for (Standard_Integer k = 0; k < aNbFace; k++)
455 BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace(k);
457 Standard_Integer nF = aFaceSelfIntersect.IndexOfFace();
459 Standard_Boolean bIsDone = aFaceSelfIntersect.IsDone();
462 const IntTools_SequenceOfCurves& aCvsX = aFaceSelfIntersect.Lines();
463 const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceSelfIntersect.Points();
465 Standard_Integer aNbCurves = aCvsX.Length();
466 Standard_Integer aNbPoints = aPntsX.Length();
468 if (aNbCurves || aNbPoints)
470 aPK.SetIndices(nF, nF);