Discretize contour and get surface normal

Hello,

If my edge is a surface contour, I'd like to compute a normal associated on each point of the discretization. I see many ways to obtain a CurveOnSurface, but can't manage to figure out the right way.

auto brep_adaptor_curve= BRepAdaptor_Curve(edge, face);
const Adaptor3d_CurveOnSurface& curve_on_surface_adaptor = brep_adaptor_curve.CurveOnSurface();
auto discretizer = GCPnts_UniformAbscissa(curve_on_surface_adaptor, max_edge_deflection);
for(Standard_Integer i = 1; i <= discretizer.NbPoints(); ++i)
{
     gp_Pnt point;
     gp_Vec first_derivative;
     curve_on_surface_adaptor.D1(discretizer.Parameter(i), point, first_derivative);
     /// Get normal ??? What's the V param ?
}

Thanks in advance for your help ! Best,

Mikhail Sazonov's picture

You need to get U,V parameters of each point on surface. Curve 2D will give you this. Then get D1 on surface to compute normal.

auto curve2d = BRep_Tool::CurveOnSurface(edge, face, first, last);
suto surf = BRep_Tool::Surface(face);
...
{
    ...
    gp_Pnt2d uv = curve2d->Value(discretizer.Parameter(i));
    gp_Pnt p3d;
    gp_Vec d1u, d1v;
    surf->D1(uv.X(), uv.Y(), p3d, d1u, d1v);
    gp_Vec normal = d1u ^ d1v;    
}
Antoine H's picture

Thanks for you insights. I implemented this, but it does not seem to work 100% of the time and it's quite difficult to locate the issue. Some normals are OK, but sometimes reversed or completely wrong.

I tried the code you provided and GeomLib::NormEstim(surface, uv, tolerance, normal); as well. Same results. I've attached some non working normals displayed in a viewer.

Antoine H's picture

Not using Geomlib butthe code you provided + reverting the normal if face.Orientation() == TopAbs_REVERSED did the trick ! Thanks again for the help ! Best,