From 0a35cb5b01a8536ec4378d5356ea7cc807ef6040 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Wed, 9 Dec 2020 10:38:50 +0800 Subject: [PATCH] Part: improve TopoShape::findPlane() Make the returned plane normal consistent with the underlying face geometry. --- src/Mod/Part/App/TopoShape.cpp | 43 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index dfa107766f..3246fbe4b5 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -171,6 +171,8 @@ # include # include # include +# include +# include #if OCC_VERSION_HEX < 0x070300 # include @@ -4161,26 +4163,13 @@ bool TopoShape::findPlane(gp_Pln &pln, double tol) const { if(_Shape.IsNull()) return false; TopoDS_Shape shape = _Shape; - TopExp_Explorer exp(_Shape,TopAbs_FACE); + TopExp_Explorer exp(_Shape,TopAbs_EDGE); if(exp.More()) { - auto face = exp.Current(); + TopoDS_Shape edge = exp.Current(); exp.Next(); - if(!exp.More()) { - BRepAdaptor_Surface adapt(TopoDS::Face(face)); - if(adapt.GetType() != GeomAbs_Plane) - return false; - pln = adapt.Plane(); - return true; - } - }else{ - TopExp_Explorer exp(_Shape,TopAbs_EDGE); - if(exp.More()) { - TopoDS_Shape edge = exp.Current(); - exp.Next(); - if(!exp.More()) { - // To deal with OCCT bug of wrong edge transformation - shape = BRepBuilderAPI_Copy(edge).Shape(); - } + if (!exp.More()) { + // To deal with OCCT bug of wrong edge transformation + shape = BRepBuilderAPI_Copy(_Shape).Shape(); } } try { @@ -4188,6 +4177,24 @@ bool TopoShape::findPlane(gp_Pln &pln, double tol) const { if (!finder.Found()) return false; pln = GeomAdaptor_Surface(finder.Surface()).Plane(); + + // To make the returned plane normal more stable, if the shape has any + // face, use the normal of the first face. + TopExp_Explorer exp(shape, TopAbs_FACE); + if(exp.More()) { + BRepAdaptor_Surface adapt(TopoDS::Face(exp.Current())); + double u = adapt.FirstUParameter() + + (adapt.LastUParameter() - adapt.FirstUParameter())/2.; + double v = adapt.FirstVParameter() + + (adapt.LastVParameter() - adapt.FirstVParameter())/2.; + BRepLProp_SLProps prop(adapt,u,v,2,Precision::Confusion()); + if(prop.IsNormalDefined()) { + gp_Pnt pnt; gp_Vec vec; + // handles the orientation state of the shape + BRepGProp_Face(TopoDS::Face(exp.Current())).Normal(u,v,pnt,vec); + pln = gp_Pln(pnt, gp_Dir(vec)); + } + } return true; }catch (Standard_Failure &e) { // For some reason the above BRepBuilderAPI_Copy failed to copy