diff --git a/src/BRepOffset/BRepOffset_Analyse.cxx b/src/BRepOffset/BRepOffset_Analyse.cxx index c8fc015966..a78d0b9f41 100644 --- a/src/BRepOffset/BRepOffset_Analyse.cxx +++ b/src/BRepOffset/BRepOffset_Analyse.cxx @@ -45,8 +45,17 @@ #include #include - - +#include +#include +// +static void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d); +// +static BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Real SinTol, + const Standard_Boolean CorrectPoint); +// static void CorrectOrientationOfTangent(gp_Vec& TangVec, const TopoDS_Vertex& aVertex, const TopoDS_Edge& anEdge) @@ -55,7 +64,6 @@ static void CorrectOrientationOfTangent(gp_Vec& TangVec, if (aVertex.IsSame(Vlast)) TangVec.Reverse(); } - //======================================================================= //function : BRepOffset_Analyse //purpose : @@ -85,99 +93,32 @@ BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S, //======================================================================= static void EdgeAnalyse(const TopoDS_Edge& E, - const TopoDS_Face& F1, - const TopoDS_Face& F2, - const Standard_Real SinTol, - BRepOffset_ListOfInterval& LI) + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Real SinTol, + BRepOffset_ListOfInterval& LI) { - - TopLoc_Location L; Standard_Real f,l; - - Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1); - Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2); - Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l); - Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l); - - BRepAdaptor_Curve C(E); - f = C.FirstParameter(); - l = C.LastParameter(); - + 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) { - BRepOffset_Interval I; - I.First(f); I.Last(l); I.Type(BRepOffset_Tangent); LI.Append(I); return; } } - // First stage : Type determined by one of ends. - // Calculate normals and tangents on the curves and surface. - // normals are oriented outwards. - - Standard_Real ParOnC = 0.5*(f+l); - gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation()); - if (T1.SquareMagnitude() > gp::Resolution()) { - T1.Normalize(); - } - - if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) { - T1.Reverse(); - } - if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse(); - - gp_Pnt2d P = C1->Value(ParOnC); - gp_Pnt P3; - gp_Vec D1U,D1V; - - S1->D1(P.X(),P.Y(),P3,D1U,D1V); - gp_Vec DN1(D1U^D1V); - if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse(); - - P = C2->Value(ParOnC); - S2->D1(P.X(),P.Y(),P3,D1U,D1V); - gp_Vec DN2(D1U^D1V); - if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse(); - - DN1.Normalize(); - DN2.Normalize(); - - gp_Vec ProVec = DN1^DN2; - Standard_Real NormProVec = ProVec.Magnitude(); - - BRepOffset_Interval I; - I.First(f); I.Last(l); - - if (Abs(NormProVec) < SinTol) { - // plane - if (DN1.Dot(DN2) > 0) { - //Tangent - I.Type(BRepOffset_Tangent); - } - else { - //Mixed not finished! -#ifdef OCCT_DEBUG - cout <<" faces locally mixed"< gp::Resolution()) - ProVec.Normalize(); - Standard_Real Prod = T1.Dot(DN1^DN2); - if (Prod > 0.) { - // - I.Type(BRepOffset_Convex); - } - else { - //reenters - I.Type(BRepOffset_Concave); - } + // + BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False); + if(aType != BRepOffset_Tangent) + { + aType = DefineConnectType(E, F1, F2, SinTol, Standard_True); } + I.Type(aType); LI.Append(I); } @@ -540,3 +481,130 @@ void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face, } } } + +//======================================================================= +//function : Correct2dPoint +//purpose : +//======================================================================= +void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d) +{ + const Standard_Real coeff = 0.01; + Standard_Real eps; + Standard_Real u1, u2, v1, v2; + if(theS.GetType() >= GeomAbs_BezierSurface) + { + u1 = theS.FirstUParameter(); + u2 = theS.LastUParameter(); + v1 = theS.FirstVParameter(); + v2 = theS.LastVParameter(); + if(!(Precision::IsInfinite(u1) || Precision::IsInfinite(u2))) + { + eps = Max(coeff*(u2-u1), Precision::PConfusion()); + if(Abs(theP2d.X()-u1) < eps) + { + theP2d.SetX(u1 + eps); + } + if(Abs(theP2d.X()-u2) < eps) + { + theP2d.SetX(u2 - eps); + } + } + if(!(Precision::IsInfinite(v1) || Precision::IsInfinite(v2))) + { + eps = Max(coeff*(v2-v1), Precision::PConfusion()); + if(Abs(theP2d.Y()-v1) < eps) + { + theP2d.SetY(v1 + eps); + } + if(Abs(theP2d.Y()-v2) < eps) + { + theP2d.SetY(v2 - eps); + } + } + } +} + +//======================================================================= +//function : DefineConnectType +//purpose : +//======================================================================= +BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Real SinTol, + const Standard_Boolean CorrectPoint) +{ + TopLoc_Location L; + Standard_Real f,l; + + BRepAdaptor_Surface S1(F1), S2(F2); + Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l); + Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l); + + 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()); + if (T1.SquareMagnitude() > gp::Resolution()) { + T1.Normalize(); + } + + if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) { + T1.Reverse(); + } + if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse(); + + gp_Pnt2d P = C1->Value(ParOnC); + gp_Pnt P3; + gp_Vec D1U,D1V; + + if(CorrectPoint) + Correct2dPoint(S1, P); + // + S1.D1(P.X(),P.Y(),P3,D1U,D1V); + gp_Vec DN1(D1U^D1V); + if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse(); + + P = C2->Value(ParOnC); + if(CorrectPoint) + Correct2dPoint(S2, P); + S2.D1(P.X(),P.Y(),P3,D1U,D1V); + gp_Vec DN2(D1U^D1V); + if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse(); + + DN1.Normalize(); + DN2.Normalize(); + + gp_Vec ProVec = DN1^DN2; + Standard_Real NormProVec = ProVec.Magnitude(); + + if (Abs(NormProVec) < SinTol) { + // plane + if (DN1.Dot(DN2) > 0) { + //Tangent + return BRepOffset_Tangent; + } + else { + //Mixed not finished! +#ifdef OCCT_DEBUG + cout <<" faces locally mixed"< gp::Resolution()) + ProVec.Normalize(); + Standard_Real Prod = T1.Dot(DN1^DN2); + if (Prod > 0.) { + // + return BRepOffset_Convex; + } + else { + //reenters + return BRepOffset_Concave; + } + } +} diff --git a/src/BRepOffset/BRepOffset_Inter2d.cxx b/src/BRepOffset/BRepOffset_Inter2d.cxx index 588cc13c8c..2c6c6438a2 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cxx +++ b/src/BRepOffset/BRepOffset_Inter2d.cxx @@ -83,7 +83,7 @@ #ifdef DRAW #include -Standard_IMPORT extern Standard_Boolean AffichInt2d; +Standard_Boolean Inter2dAffichInt2d; static Standard_Integer NbF2d = 0; static Standard_Integer NbE2d = 0; static Standard_Integer NbNewVertices = 0; @@ -245,7 +245,7 @@ static void Store (const TopoDS_Edge& E1, } #ifdef DRAW - if (AffichInt2d) { + if (Inter2dAffichInt2d) { if (!OnE1 && !OnE2) { char name[256]; sprintf(name,"VV_%d",NbNewVertices++); @@ -272,7 +272,7 @@ static void EdgeInter(const TopoDS_Face& F, Standard_Boolean WithOri) { #ifdef DRAW - if (AffichInt2d) { + if (Inter2dAffichInt2d) { char name[256]; sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++); DBRep::Set(name,E1); @@ -543,7 +543,7 @@ static void RefEdgeInter(const TopoDS_Face& F, gp_Pnt& Pref) { #ifdef DRAW - if (AffichInt2d) { + if (Inter2dAffichInt2d) { char name[256]; sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++); DBRep::Set(name,E1); diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index d2ff2f66e7..69ca982442 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -129,6 +129,9 @@ Standard_Boolean ChronBuild = Standard_False; Standard_Integer NbAE = 0; Standard_Integer NbAF = 0; + Standard_Integer NVP = 0; + Standard_Integer NVM = 0; + Standard_Integer NVN = 0; static OSD_Chronometer Clock; char name[100]; diff --git a/src/BRepOffset/BRepOffset_Offset.cxx b/src/BRepOffset/BRepOffset_Offset.cxx index f93e72658e..29fb26e7f5 100644 --- a/src/BRepOffset/BRepOffset_Offset.cxx +++ b/src/BRepOffset/BRepOffset_Offset.cxx @@ -1405,6 +1405,7 @@ void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex, for (it.Initialize(LEdge); it.More(); it.Next()) { sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++); #ifdef DRAW + const TopoDS_Shape& CurE = it.Value(); DBRep::Set(name, CurE); #endif } diff --git a/src/BiTgte/BiTgte_Blend.cxx b/src/BiTgte/BiTgte_Blend.cxx index e99e30bd57..e32cef73a0 100644 --- a/src/BiTgte/BiTgte_Blend.cxx +++ b/src/BiTgte/BiTgte_Blend.cxx @@ -2342,9 +2342,6 @@ void BiTgte_Blend::ComputeShape() BRep_Builder B; -#ifdef DRAW - Standard_Integer NbNT = 1; -#endif // Maj of the Map of created. // Update edges that do not change in the resulting shape diff --git a/tests/bugs/modalg_5/bug25729 b/tests/bugs/modalg_5/bug25729 new file mode 100644 index 0000000000..123cee632b --- /dev/null +++ b/tests/bugs/modalg_5/bug25729 @@ -0,0 +1,17 @@ +puts "=========" +puts "OCC25729" +puts "=========" +puts "" +############################################### +# algorith BRepOffset_MakeOffset(...) produces wrong result for join type Intersection +############################################### + +restore [locate_data_file bug25729_source_shape.brep] s + +offsetparameter 1.e-7 i i +offsetload s 0.14 +offsetperform result + +checkshape result + +set 2dviewer 1