From 83b55e577b4fc4a4c9cc46bc758e12065fa71527 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Tue, 18 Jan 2022 02:16:43 -0300 Subject: [PATCH] Part: Use Tools::getNormal to compute normal to surface --- src/Mod/Part/App/Attacher.cpp | 34 +++++++++++++++++-------- src/Mod/Part/App/Geometry.cpp | 10 +++++--- src/Mod/Part/App/TopoShapeFacePyImp.cpp | 21 +++++++-------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/Mod/Part/App/Attacher.cpp b/src/Mod/Part/App/Attacher.cpp index 441b5d6c07..eeb2901706 100644 --- a/src/Mod/Part/App/Attacher.cpp +++ b/src/Mod/Part/App/Attacher.cpp @@ -62,6 +62,7 @@ #include "Attacher.h" #include "AttachExtension.h" +#include "Tools.h" #include #include #include @@ -1177,7 +1178,6 @@ Base::Placement AttachEngine3D::calculateAttachedPlacement(const Base::Placement if (vertex.IsNull()) throw Base::ValueError("Null vertex in AttachEngine3D::calculateAttachedPlacement()!"); - BRepAdaptor_Surface surf (face); Handle (Geom_Surface) hSurf = BRep_Tool::Surface(face); gp_Pnt p = BRep_Tool::Pnt(vertex); @@ -1185,19 +1185,33 @@ Base::Placement AttachEngine3D::calculateAttachedPlacement(const Base::Placement double u, v; if (projector.NbPoints()==0) throw Base::ValueError("AttachEngine3D::calculateAttachedPlacement: projecting point onto surface failed."); + projector.LowerDistanceParameters(u, v); - - BRepLProp_SLProps prop(surf,u,v,1, Precision::Confusion()); - SketchNormal = prop.Normal(); - + BRepAdaptor_Surface surf(face); + BRepLProp_SLProps prop(surf, u, v, 1, Precision::Confusion()); gp_Dir dirX; - prop.TangentU(dirX); //if normal is defined, this should be defined too + Standard_Boolean done; + + Tools::getNormal(face, u, v, Precision::Confusion(), SketchNormal, done); + + if (!done) + throw Base::ValueError("AttachEngine3D::calculateAttachedPlacement: finding normal to surface at projected point failed."); + + // if getNormal succeeds, at least one of the tangent is defined + if (prop.IsTangentUDefined()) { + prop.TangentU(dirX); + if (face.Orientation() == TopAbs_REVERSED) + dirX.Reverse(); + } + // here the orientation of dirX is managed by SketchNormal orientation + else { + gp_Dir dirY; + prop.TangentV(dirY); + dirX = dirY.Crossed(SketchNormal); + } + SketchXAxis = gp_Vec(dirX).Reversed();//yields upside-down sketches less often. - if (face.Orientation() == TopAbs_REVERSED) { - SketchNormal.Reverse(); - SketchXAxis.Reverse(); - } if (bThruVertex) { SketchBasePoint = p; } else { diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index 757b3048a1..2aa0bf59a8 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -145,6 +145,7 @@ #include "GeometryMigrationExtension.h" #include "Geometry.h" +#include "Tools.h" #if OCC_VERSION_HEX >= 0x070600 using GeomAdaptor_HCurve = GeomAdaptor_Curve; @@ -4235,11 +4236,12 @@ bool GeomSurface::tangentV(double u, double v, gp_Dir& dirV) const bool GeomSurface::normal(double u, double v, gp_Dir& dir) const { Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); - GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); - if (prop.IsNormalDefined()) { - dir = prop.Normal(); + Standard_Boolean done; + + Tools::getNormal(s, u, v, Precision::Confusion(), dir, done); + + if (done) return true; - } return false; } diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index 089857d117..38aae52b2f 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -521,23 +521,20 @@ PyObject* TopoShapeFacePy::normalAt(PyObject *args) { double u,v; if (!PyArg_ParseTuple(args, "dd",&u,&v)) - return 0; + return nullptr; const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->getShape()); - BRepAdaptor_Surface adapt(f); + Standard_Boolean done; + gp_Dir dir; - 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(f).Normal(u,v,pnt,vec); - vec.Normalize(); - return new Base::VectorPy(new Base::Vector3d(vec.X(),vec.Y(),vec.Z())); - } - else { + Tools::getNormal(f, u, v, Precision::Confusion(), dir, done); + + if (!done) { PyErr_SetString(PartExceptionOCCError, "normal not defined"); - return 0; + return nullptr; } + + return new Base::VectorPy(new Base::Vector3d(dir.X(),dir.Y(),dir.Z())); } PyObject* TopoShapeFacePy::getUVNodes(PyObject *args)