Offset Surface Discrepancy

I am finding a discrepancy in the behavior of the built-in offset surface grasshopper component and Surface.Offset as found here: .

Both should in theory be identical, however I am finding that the API version of offset surface is disregarding the normal direction of the surface and always offsetting the same direction.

I’ve attached a rhino file and script. You’ll see that with one direction of the surface, both operations are identical, while when I flip the surface, the two return different results.

NOTE: I’ve found this behavior seems to also occur with offsetting a curve normal to a surface. (

Thoughts? (17.1 KB) bug_offsetSrfNormal.3dm (25.7 KB)

Any suggestions here? @DavidRutten, perhaps? I’m having to add an awful lot of checks to my code to verify surface normal accuracy.

Control the orientation of your surfaces yourself , so you rely on your own code. But it is strange that when the flip component in Grasshopper is used RhinoCommon’s offset surface does not seem to follow the correct orientation. Anyways, check the file, I added some extra stuff so you can visualize the orientation as well.

private void RunScript(Surface x, bool flipDir, ref object A, ref object B, ref object C)

    double u, v;
    Vector3d normal = Vector3d.Zero;
    var bb = x.GetBoundingBox(true);
    Point3d p = bb.Center;

    if(flipDir) x.Transpose(true);

    if (x.ClosestPoint(p, out u, out v)) normal = x.NormalAt(u, v);

    A = x.Offset(5, 0.001);
    B = p;
    C = normal;
  } (6.3 KB)

@rawitscher-torres Thanks for this. I appreciate the code snippet. I may try to work this into our project. The thing is we handle surfaces in myriad ways throughout our GH assemblies and this is just an example of how things are going wrong in Rhino. It’s not a very good situation when we have to be copying around a “surface normal correction” band-aid in our code.

Isn’t this a bug that should be addressed? Can this be addressed? It seems like something that is particularly problematic.

Despite the issue, you could instead of flipping your surface, use your condition to make the offset distance negative rather than flip the surface.

@gruedisueli I think its not such a big problem if you control all surface directions from within your code, such that you know what is the “correct” orientation for you in every case. Also, the small code I sent is not really correcting any direction it just reverses it given a boolean.

This is kind of unclear for me though, what do you mean?

What Michael is suggesting is also an option, can save you allocating stack memory for the Transpose method.

I think computationally the most interesting thing you have to define in your code, is which surfaces will offset in what direction, and why.

1 Like

@rawitscher-torres Thank you for your response. I think I might have misinterpreted the issue on my end, because I assumed that the Grasshopper “Flip” component worked right, which apparently it doesn’t (never assume anything!).

Looking back at my solution now, I see that Grasshopper “Flip” does not actually flip the normal of the surface, or that at least when you evaluation a “flipped” surface you get the same normal before and after flipping. That would be a bug to fix. I can implement a workaround on my end.

So, I understand your solution as a resolution to that issue. I now see that I was probably mistaken about there being an issue with Surface.Offset. I’ll keep an eye on this on my end and let you know if I experience other surface normal issues that seem illogical.