1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

Fix of crash in "thickshell" functionality

This commit is contained in:
jgv
2021-09-17 15:16:20 +03:00
parent 3b5ea8fb6b
commit 3ce6f88510

View File

@@ -46,7 +46,11 @@
#include <Precision.hxx>
#include <gp.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <Adaptor3d_Surface.hxx>
#include <BRepTopAdaptor_TopolTool.hxx>
#include <LocalAnalysis_SurfaceContinuity.hxx>
#include <TopOpeBRepTool_TOOL.hxx>
//
static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
//
@@ -58,6 +62,11 @@ static BRepOffset_Type DefineConnectType(const TopoDS_Edge& E,
const TopoDS_Face& F2,
const Standard_Real SinTol,
const Standard_Boolean CorrectPoint);
static Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
const TopoDS_Face &theFace1,
const TopoDS_Face &theFace2,
const GeomAbs_Shape Order);
//
static void CorrectOrientationOfTangent(gp_Vec& TangVec,
const TopoDS_Vertex& aVertex,
@@ -101,27 +110,37 @@ static void EdgeAnalyse(const TopoDS_Edge& E,
const Standard_Real SinTol,
BRepOffset_ListOfInterval& LI)
{
Standard_Real f,l;
BRep_Tool::Range(E, F1, f, l);
BRepOffset_Interval I;
I.First(f); I.Last(l);
//
// Tangent if the regularity is at least G1.
if (BRep_Tool::HasContinuity(E,F1,F2)) {
if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
I.Type(BRepOffset_Tangent);
LI.Append(I);
return;
}
}
//
BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
if(aType != BRepOffset_Tangent)
BRepAdaptor_Surface aBAsurf1(F1, Standard_False);
GeomAbs_SurfaceType aSurfType1 = aBAsurf1.GetType();
BRepAdaptor_Surface aBAsurf2(F2, Standard_False);
GeomAbs_SurfaceType aSurfType2 = aBAsurf2.GetType();
Standard_Boolean isTwoPlanes = (aSurfType1 == GeomAbs_Plane && aSurfType2 == GeomAbs_Plane);
BRepOffset_Type ConnectType = BRepOffset_Other;
if (isTwoPlanes) //then use only strong condition
{
aType = DefineConnectType(E, F1, F2, SinTol, Standard_True);
if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0)
ConnectType = BRepOffset_Tangent;
else
ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
}
I.Type(aType);
else
{
if (IsTangentFaces(E, F1, F2, GeomAbs_G1)) //weak condition
ConnectType = BRepOffset_Tangent;
else
ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
}
I.Type(ConnectType);
LI.Append(I);
}
@@ -176,7 +195,7 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
myShape = S;
angle = Angle;
Standard_Real SinTol = Abs(Sin(Angle));
Standard_Real SinTol = Sin(Angle);
// Build ancestors.
BuildAncestors (S,ancestors);
@@ -640,3 +659,90 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge& E,
}
}
}
//=======================================================================
//function : IsTangentFaces
//purpose :
//=======================================================================
Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
const TopoDS_Face &theFace1,
const TopoDS_Face &theFace2,
const GeomAbs_Shape Order)
{
if (Order == GeomAbs_G1 &&
BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
return Standard_True;
Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
Standard_Real aFirst;
Standard_Real aLast;
// Obtaining of pcurves of edge on two faces.
const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
(theEdge, theFace1, aFirst, aLast);
const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
(theEdge, theFace2, aFirst, aLast);
if (aC2d1.IsNull() || aC2d2.IsNull())
return Standard_False;
// Obtaining of two surfaces from adjacent faces.
Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
if (aSurf1.IsNull() || aSurf2.IsNull())
return Standard_False;
// Computation of the number of samples on the edge.
BRepAdaptor_Surface aBAS1(theFace1);
BRepAdaptor_Surface aBAS2(theFace2);
Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1);
Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2);
Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1);
Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2);
Standard_Integer aNbSamples1 = aTool1->NbSamples();
Standard_Integer aNbSamples2 = aTool2->NbSamples();
Standard_Integer aNbSamples = Max(aNbSamples1, aNbSamples2);
// Computation of the continuity.
Standard_Real aPar;
Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1);
Standard_Integer i, nbNotDone = 0;
for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
if (i == aNbSamples) aPar = aLast;
LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
aSurf1, aSurf2, Order,
0.001, TolC0, 0.1, 0.1, 0.1);
if (!aCont.IsDone())
{
nbNotDone++;
continue;
}
if (Order == GeomAbs_G1)
{
if (!aCont.IsG1())
return Standard_False;
}
else if (!aCont.IsG2())
return Standard_False;
}
if (nbNotDone == aNbSamples)
return Standard_False;
//Compare normals of tangent faces in the middle point
Standard_Real MidPar = (aFirst + aLast)/2.;
gp_Pnt2d uv1 = aC2d1->Value(MidPar);
gp_Pnt2d uv2 = aC2d2->Value(MidPar);
gp_Dir normal1, normal2;
TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
Standard_Real dot = normal1.Dot(normal2);
if (dot < 0.)
return Standard_False;
return Standard_True;
}