1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0027998: Self-intersection is not detected

New method CheckFaceSelfIntersection has been added to BOPAlgo_CheckerSI: now self-intersection of each face is found as well as pairs of intersecting faces;

-method IntPatch_Intersection::Perform(S1,D1,TolArc,TolTang) is modified for more effective search of self-interasections in case of Surface Of Extrusion;

-method IntCurve_IntPolyPolyGen::Perform(C1,D1,TolConf,Tol,NbIter) is modified to detect segments of intersections.

Small correction.

Test cases are corrected.

Correction of compiler error

Fix of regressions

Names of shapes correction
This commit is contained in:
jgv
2017-02-17 18:23:18 +03:00
committed by bugmaster
parent 15b2583e69
commit f48cb55d33
17 changed files with 551 additions and 81 deletions

View File

@@ -384,12 +384,14 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
if(ii == 0) {
aResult.SetShape1(myShape1);
aResult.AddFaultyShape1(aS1);
aResult.AddFaultyShape1(aS2);
if (!aS1.IsSame(aS2))
aResult.AddFaultyShape1(aS2);
}
else {
aResult.SetShape2(myShape2);
aResult.AddFaultyShape2(aS1);
aResult.AddFaultyShape2(aS2);
if (!aS1.IsSame(aS2))
aResult.AddFaultyShape2(aS2);
}
aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
myResult.Append(aResult);

View File

@@ -19,6 +19,7 @@
#include <BOPAlgo_CheckerSI.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_Parallel.hxx>
#include <BOPDS_DS.hxx>
#include <BOPDS_Interf.hxx>
#include <BOPDS_IteratorSI.hxx>
@@ -34,9 +35,83 @@
#include <BOPTools_AlgoTools.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_Tools.hxx>
#include <IntTools_FaceFace.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BRep_Tool.hxx>
#include <gp_Torus.hxx>
//=======================================================================
//class : BOPAlgo_FaceSelfIntersect
//purpose :
//=======================================================================
class BOPAlgo_FaceSelfIntersect :
public IntTools_FaceFace,
public BOPAlgo_Algo {
public:
DEFINE_STANDARD_ALLOC
BOPAlgo_FaceSelfIntersect() :
IntTools_FaceFace(),
BOPAlgo_Algo(),
myIF(-1), myTolF(1.e-7) {
}
//
virtual ~BOPAlgo_FaceSelfIntersect() {
}
//
void SetIndex(const Standard_Integer nF) {
myIF = nF;
}
//
Standard_Integer IndexOfFace() const {
return myIF;
}
//
void SetFace(const TopoDS_Face& aF) {
myF = aF;
}
//
const TopoDS_Face& Face()const {
return myF;
}
//
void SetTolF(const Standard_Real aTolF) {
myTolF = aTolF;
}
//
Standard_Real TolF() const{
return myTolF;
}
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
IntTools_FaceFace::Perform(myF, myF);
}
//
protected:
Standard_Integer myIF;
Standard_Real myTolF;
TopoDS_Face myF;
};
//end of definition of class BOPAlgo_FaceSelfIntersect
//=======================================================================
typedef BOPCol_NCVector
<BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect;
//
typedef BOPCol_Functor
<BOPAlgo_FaceSelfIntersect,
BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectFunctor;
//
typedef BOPCol_Cnt
<BOPAlgo_FaceSelfIntersectFunctor,
BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectCnt;
//=======================================================================
//function :
@@ -116,6 +191,8 @@ void BOPAlgo_CheckerSI::Perform()
// Perform intersection of sub shapes
BOPAlgo_PaveFiller::Perform();
//
CheckFaceSelfIntersection();
// Perform intersection with solids
if (!myErrorStatus)
PerformVZ();
@@ -150,8 +227,7 @@ void BOPAlgo_CheckerSI::PostTreat()
//
BOPDS_MapOfPair& aMPK=
*((BOPDS_MapOfPair*)&myDS->Interferences());
aMPK.Clear();
//
// 0
BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
aNb=aVVs.Extent();
@@ -238,23 +314,27 @@ void BOPAlgo_CheckerSI::PostTreat()
continue;
}
//
iFound=0;
if (bTangentFaces) {
const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1));
const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2));
bFlag=BOPTools_AlgoTools::AreFacesSameDomain
(aF1, aF2, myContext, myFuzzyValue);
if (bFlag) {
++iFound;
}
}
else {
for (j=0; j!=aNbC; ++j) {
const BOPDS_Curve& aNC=aVC(j);
const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks();
if (aLPBC.Extent()) {
iFound = (n1 == n2) ? 1 : 0;
//case of self-intersection inside one face
if (!iFound)
{
if (bTangentFaces) {
const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1));
const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2));
bFlag=BOPTools_AlgoTools::AreFacesSameDomain
(aF1, aF2, myContext, myFuzzyValue);
if (bFlag) {
++iFound;
break;
}
}
else {
for (j=0; j!=aNbC; ++j) {
const BOPDS_Curve& aNC=aVC(j);
const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks();
if (aLPBC.Extent()) {
++iFound;
break;
}
}
}
}
@@ -315,3 +395,87 @@ void BOPAlgo_CheckerSI::PostTreat()
aMPK.Add(aPK);
}
}
//=======================================================================
//function : CheckFaceSelfIntersection
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::CheckFaceSelfIntersection()
{
if (myLevelOfCheck < 5)
return;
BOPDS_Pair aPK;
BOPDS_MapOfPair& aMPK=
*((BOPDS_MapOfPair*)&myDS->Interferences());
aMPK.Clear();
BOPAlgo_VectorOfFaceSelfIntersect aVFace;
Standard_Integer aNbS=myDS->NbSourceShapes();
//
for (Standard_Integer i = 0; i < aNbS; i++)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_FACE)
continue;
//
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
BRepAdaptor_Surface BAsurf(aF, Standard_False);
GeomAbs_SurfaceType aSurfType = BAsurf.GetType();
if (aSurfType == GeomAbs_Plane ||
aSurfType == GeomAbs_Cylinder ||
aSurfType == GeomAbs_Cone ||
aSurfType == GeomAbs_Sphere)
continue;
if (aSurfType == GeomAbs_Torus)
{
gp_Torus aTorus = BAsurf.Torus();
Standard_Real aMajorRadius = aTorus.MajorRadius();
Standard_Real aMinorRadius = aTorus.MinorRadius();
if (aMajorRadius > aMinorRadius + Precision::Confusion())
continue;
}
Standard_Real aTolF = BRep_Tool::Tolerance(aF);
BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace.Append1();
//
aFaceSelfIntersect.SetIndex(i);
aFaceSelfIntersect.SetFace(aF);
aFaceSelfIntersect.SetTolF(aTolF);
//
aFaceSelfIntersect.SetProgressIndicator(myProgressIndicator);
}
Standard_Integer aNbFace = aVFace.Extent();
//======================================================
BOPAlgo_FaceSelfIntersectCnt::Perform(myRunParallel, aVFace);
//======================================================
//
for (Standard_Integer k = 0; k < aNbFace; k++)
{
BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace(k);
//
Standard_Integer nF = aFaceSelfIntersect.IndexOfFace();
Standard_Boolean bIsDone = aFaceSelfIntersect.IsDone();
if (bIsDone)
{
const IntTools_SequenceOfCurves& aCvsX = aFaceSelfIntersect.Lines();
const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceSelfIntersect.Points();
//
Standard_Integer aNbCurves = aCvsX.Length();
Standard_Integer aNbPoints = aPntsX.Length();
//
if (aNbCurves || aNbPoints)
{
aPK.SetIndices(nF, nF);
aMPK.Add(aPK);
}
}
}
}

View File

@@ -68,6 +68,8 @@ protected:
//! Treats the intersection results
Standard_EXPORT void PostTreat();
Standard_EXPORT void CheckFaceSelfIntersection();
//! Methods for intersection with solids
//! Vertex/Solid intersection