From d804b26d7746d1dbdc6ea57981db8162c0a5347f Mon Sep 17 00:00:00 2001 From: jgv Date: Thu, 25 Sep 2014 13:41:27 +0400 Subject: [PATCH] 0024910: Offset of solid is not created Optimization of local function Test case for issue #24910 --- src/BRepOffset/BRepOffset_Analyse.cxx | 13 +++- src/BRepOffset/BRepOffset_Offset.cxx | 71 +++++++++++++++------ src/GeomFill/GeomFill_CircularBlendFunc.cxx | 11 ++-- tests/bugs/modalg_5/bug24910 | 20 ++++++ 4 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 tests/bugs/modalg_5/bug24910 diff --git a/src/BRepOffset/BRepOffset_Analyse.cxx b/src/BRepOffset/BRepOffset_Analyse.cxx index 4b57f8f300..5fc6f1ca63 100644 --- a/src/BRepOffset/BRepOffset_Analyse.cxx +++ b/src/BRepOffset/BRepOffset_Analyse.cxx @@ -47,6 +47,15 @@ #include +static void CorrectOrientationOfTangent(gp_Vec& TangVec, + const TopoDS_Vertex& aVertex, + const TopoDS_Edge& anEdge) +{ + TopoDS_Vertex Vlast = TopExp::LastVertex(anEdge); + if (aVertex.IsSame(Vlast)) + TangVec.Reverse(); +} + //======================================================================= //function : BRepOffset_Analyse //purpose : @@ -367,6 +376,7 @@ void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge , URef = BRep_Tool::Parameter(Vertex,Edge); C3dRef = BRepAdaptor_Curve(Edge); VRef = C3dRef.DN(URef,1); + CorrectOrientationOfTangent(VRef, Vertex, Edge); if (VRef.SquareMagnitude() < gp::Resolution()) return; Edges.Clear(); @@ -379,8 +389,9 @@ void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge , U = BRep_Tool::Parameter(Vertex,CurE); C3d = BRepAdaptor_Curve(CurE); V = C3d.DN(U,1); + CorrectOrientationOfTangent(V, Vertex, CurE); if (V.SquareMagnitude() < gp::Resolution()) continue; - if (V.IsParallel(VRef,angle)) { + if (V.IsOpposite(VRef,angle)) { Edges.Append(CurE); } } diff --git a/src/BRepOffset/BRepOffset_Offset.cxx b/src/BRepOffset/BRepOffset_Offset.cxx index cbfce6be6c..17e07088d7 100644 --- a/src/BRepOffset/BRepOffset_Offset.cxx +++ b/src/BRepOffset/BRepOffset_Offset.cxx @@ -73,6 +73,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #ifdef DEB static Standard_Boolean Affich = Standard_False; static Standard_Integer NbOFFSET = 0; @@ -83,6 +90,32 @@ static Standard_Integer NbOFFSET = 0; #endif #include + +static gp_Pnt GetFarestCorner(const TopoDS_Wire& aWire) +{ + TopTools_IndexedMapOfShape Vertices; + TopExp::MapShapes(aWire, TopAbs_VERTEX, Vertices); + + Standard_Real MaxDist = 0.; + gp_Pnt thePoint; + for (Standard_Integer i = 1; i <= Vertices.Extent(); i++) + for (Standard_Integer j = 1; j <= Vertices.Extent(); j++) + { + const TopoDS_Vertex& V1 = TopoDS::Vertex(Vertices(i)); + const TopoDS_Vertex& V2 = TopoDS::Vertex(Vertices(j)); + gp_Pnt P1 = BRep_Tool::Pnt(V1); + gp_Pnt P2 = BRep_Tool::Pnt(V2); + Standard_Real aDist = P1.SquareDistance(P2); + if (aDist > MaxDist) + { + MaxDist = aDist; + thePoint = P1; + } + } + + return thePoint; +} + //======================================================================= //function : UpdateEdge //purpose : @@ -1316,29 +1349,29 @@ void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex, } #endif + gp_Pnt Origin = BRep_Tool::Pnt(Vertex); - it.Initialize(LEdge); - TopExp::Vertices(TopoDS::Edge(it.Value()), V1, V2); - P1 = BRep_Tool::Pnt(V1); - P2 = BRep_Tool::Pnt(V2); + //// Find the axis of the sphere to exclude + //// degenerated and seam edges from the face under construction + BRepLib_MakeWire MW; + MW.Add(LEdge); + TopoDS_Wire theWire = MW.Wire(); - if ( !it.More()) { - Standard_ConstructionError::Raise("BRepOffset_Sphere"); - } - it.Next(); - TopExp::Vertices(TopoDS::Edge(it.Value()), V3, V4); + ShapeFix_Shape Fixer(theWire); + Fixer.Perform(); + theWire = TopoDS::Wire(Fixer.Shape()); - P3 = BRep_Tool::Pnt(V3); - Standard_Real eps = 1.e-8; - if ( P1.Distance(P3) < eps || P2.Distance(P3) < eps) - P3 = BRep_Tool::Pnt(V4); - - P = BRep_Tool::Pnt(Vertex); - - gp_Vec X = gp_Vec(P1,P2) ^ gp_Vec(P1,P3); - if ( X * gp_Vec(P1,P) < 0.) X.Reverse(); + GProp_GProps GlobalProps; + BRepGProp::LinearProperties(theWire, GlobalProps); + gp_Pnt BaryCenter = GlobalProps.CentreOfMass(); + gp_Vec Xdir(BaryCenter, Origin); + + gp_Pnt FarestCorner = GetFarestCorner(theWire); + gp_Pln thePlane = gce_MakePln(Origin, BaryCenter, FarestCorner); + gp_Dir Vdir = thePlane.Axis().Direction(); - gp_Ax3 Axis( P, gp_Dir(gp_Vec(P1,P2)), gp_Dir(X)); + gp_Ax3 Axis(Origin, Vdir, Xdir); + Handle(Geom_Surface) S = new Geom_SphericalSurface( Axis, Abs(Offset)); diff --git a/src/GeomFill/GeomFill_CircularBlendFunc.cxx b/src/GeomFill/GeomFill_CircularBlendFunc.cxx index 498000d117..1aae63263d 100644 --- a/src/GeomFill/GeomFill_CircularBlendFunc.cxx +++ b/src/GeomFill/GeomFill_CircularBlendFunc.cxx @@ -31,6 +31,8 @@ static Standard_Integer NbSections = 0; #endif +const Standard_Real TolAng = 1.e-6; + GeomAbs_Shape GeomFillNextShape(const GeomAbs_Shape S) { switch (S) { @@ -228,7 +230,8 @@ void GeomFill_CircularBlendFunc::Discret() ns1.SetXYZ( Center.XYZ() - P1.XYZ()); ns2.SetXYZ( Center.XYZ() - P2.XYZ()); - myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0); + //myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0); + myreverse = Standard_False; } @@ -250,7 +253,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D0(const Standard_Real Param, myTCurve2->D0(Param, P2); ns1.SetXYZ( Center.XYZ() - P1.XYZ()); ns2.SetXYZ( Center.XYZ() - P2.XYZ()); - if (!ns1.IsParallel(ns2,1.e-9)) nplan = ns1.Crossed(ns2); + if (!ns1.IsParallel(ns2, TolAng)) nplan = ns1.Crossed(ns2); else { myTPath->D1(Param, Center, nplan); if (myreverse) nplan.Reverse(); @@ -316,7 +319,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D1(const Standard_Real Param, Dns1 = DCenter - DP1; Dns2 = DCenter - DP2; - if (!ns1.IsParallel(ns2,1.e-9)) { + if (!ns1.IsParallel(ns2, TolAng)) { nplan = ns1.Crossed(ns2); dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2)); } @@ -404,7 +407,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D2(const Standard_Real Param, Dns2 = DCenter - DP2; D2ns2 = D2Center - D2P2; - if (!ns1.IsParallel(ns2,1.e-9)) { + if (!ns1.IsParallel(ns2, TolAng)) { nplan = ns1.Crossed(ns2); dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2)); d2nplan.SetLinearForm(1, D2ns1.Crossed(ns2), diff --git a/tests/bugs/modalg_5/bug24910 b/tests/bugs/modalg_5/bug24910 new file mode 100644 index 0000000000..82ebd178a3 --- /dev/null +++ b/tests/bugs/modalg_5/bug24910 @@ -0,0 +1,20 @@ +puts "================" +puts "OCC24910" +puts "================" +puts "" +################################## +# Offset of solid is not created +################################## + +restore [locate_data_file bug24910_Solid_4.brep] a +offsetshape result a 1 + +set nb_v_good 46 +set nb_e_good 88 +set nb_w_good 44 +set nb_f_good 44 +set nb_sh_good 1 +set nb_sol_good 1 +set nb_compsol_good 0 +set nb_compound_good 0 +set nb_shape_good 224 -- 2.20.1