diff --git a/src/BRepOffset/BRepOffset_Analyse.cxx b/src/BRepOffset/BRepOffset_Analyse.cxx index 070c38adca..ae28e0de4b 100644 --- a/src/BRepOffset/BRepOffset_Analyse.cxx +++ b/src/BRepOffset/BRepOffset_Analyse.cxx @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -44,6 +47,8 @@ #include #include #include +#include +#include // static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d); @@ -53,6 +58,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, @@ -96,27 +106,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); } @@ -520,21 +540,30 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, const Standard_Real SinTol, const Standard_Boolean CorrectPoint) { - TopLoc_Location L; - Standard_Real f,l; - const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1); const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2); // + Standard_Real f,l; Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l); - Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l); + //For the case of seam edge + TopoDS_Edge EE = E; + if (F1.IsSame(F2)) + EE.Reverse(); + Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(EE,F2,f,l); + if (C1.IsNull() || C2.IsNull()) + return BRepOffset_Other; BRepAdaptor_Curve C(E); f = C.FirstParameter(); l = C.LastParameter(); // Standard_Real ParOnC = 0.5*(f+l); - gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation()); + gp_Vec T1 = C.DN(ParOnC,1); + if (T1.SquareMagnitude() <= gp::Resolution()) + { + ParOnC = IntTools_Tools::IntermediatePoint(f,l); + T1 = C.DN(ParOnC,1); + } if (T1.SquareMagnitude() > gp::Resolution()) { T1.Normalize(); } @@ -567,8 +596,7 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, gp_Vec ProVec = DN1^DN2; Standard_Real NormProVec = ProVec.Magnitude(); - - if (Abs(NormProVec) < SinTol) { + if (NormProVec < SinTol) { // plane if (DN1.Dot(DN2) > 0) { //Tangent @@ -596,3 +624,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; +}