PointAt CurveOnSurface

Unfortunately I get a wrong result when calling the PointAt function on a ON_CurveOnSurface class.

Is there something I need to consider of the used surface or curve?

Hi Andreas,

I’m by no means familiar with openNURBS so FWIW:

Based on your question It might be you get the point in “surface”-space rather than in “world”-space.
What does you point that is returned look like? Does it have 0 for it’s Zcoordinate by any change, do the X and Y fall within the U V Domaind of the surface?

If so I’d try if the coordinates of the PointAt correspond with surface parameters at the expected location and you could query the surface PointAt with the U,V parameters as the X,Y parameters of your PointAt ON_CurveOnSurface.

Again, I’m not familiar with openNURBS so I moght be sending you on a wild goose chase

Does this make sense?

Hi @Andreas2,

Can you provide some sample code that doesn’t work for you?


– Dale

Here is a small example:

ON_NurbsSurface surface;
ON_NurbsCurve curve;

ON_Sphere sphere(ON_3dPoint(0, 0, 0), 1.0);

double radius = 0.5;
ON_Circle circ(ON_3dPoint(0, 0, 1.1), radius);

ON_CurveOnSurface cOnS(&curve, nullptr, &surface);
auto pOnS = cOnS.PointAt(cOnS.Domain().Mid());

auto radiusOnSurface = std::sqrt(pOnS.x*pOnS.x + pOnS.y*pOnS.y);

// radius != radiusOnSurface 

This is the reason:

ON_CurveOnSurface cOnS(&curve, nullptr, &surface)

Also, unless the inputs are proxy objects, your code is destine to crash because of this:

    p2dCurve - [in] ~ON_CurveOnSurface() will delete this curve.
       Use an ON_CurveProxy if you don't want the original deleted.
    p3dCurve - [in] ~ON_CurveOnSurface() will delete this curve.
       Use an ON_CurveProxy if you don't want the original deleted.
    pSurface - [in] ~ON_CurveOnSurface() will delete this surface.
       Use an ON_SurfaceProxy if you don't want the original deleted.
  ON_CurveOnSurface( ON_Curve* p2dCurve,  // required 2d curve
                     ON_Curve* p3dCurve,  // optional 3d curve
                     ON_Surface* pSurface // required surface

Why do you want or need to use this class?

– Dale

Thanks for the hint with the proxies.

But why I need to set an optional 3D curve?

In the IsValid() function of ON_CurveOnSurface I saw that the dimension of the 2D curve hast to be 2 (yeah make sense). So I also changed the dimension of the curve.


But the result is the same.

The reason to use the class is that I need some specific z-values for given x and y-coordinates of a complex 3D nurbs surface.

From the source code I see that the Evaluate() function will be called from PointAt(). Based on the parameter t first the curve point of the 2D curve will be calculated, Source.

With the calculated coordinates of the curve c the surface point s will be calculated, but not of the specifc parameters u and v. Instead the x and y values will be used, Source.

Even the 3D curve m_c3 is not used anywhere in the class for the calculation? So I think the class cannot work?

Hi @Andreas2,

My mistake - I transposed the first two parameters.

I am able to reproduce the bug, and I’ve reported the issue.


– Dale

1 Like

Thanks for the help so far :slight_smile:

ON_CurveOnSurface seems like a half baked class. At the very least it is missing any description of what it is supposed to do. However after looking at the code it seems clear to me that it represents a curve on a parameterized surface, defined by its parameter space curve m_c2. Specifically the curve is
C(t) = m_s->Evaluate( m_c2->PointAt(t) ) for t in m_c2->Domain()

This assumes m_c2 is in Domain of m_S, but there is no error detection in this class.

From your post I assume you are trying to get a curve on a surface by projecting a 3d curve with some constant direction, say -z , (0,0,-1). I would try extruding the curve in the “view direction” and intersecting the result with the surface.

1 Like