---
breadcrumbs: Houdini 22.0 > VEX > VEX Functions
title: osd_limitnormal
nodeType: VEX function
source: https://www.sidefx.com/docs/houdini/vex/functions/osd_limitnormal
generated_at: 2026-07-30T14:46:52.758Z
---

# osd_limitnormal VEX function

> Compute the normal to a point attribute evaluated at the subdivision limit using Open Subdiv.

`osd_limitnormal` computes the normal to a point attribute in the geometry specified as a subdivision surface.

`int  osd_limitnormal(<geometry>geometry, string attrib_name, int patch_id, float u, float v, <type>&result)`

Show/hide arguments 

`<geometry>`

When running in the context of a node (such as a wrangle SOP), this argument can be an integer representing the input number (starting at 0) to read the geometry from.

Alternatively, the argument can be a string specifying a geometry file (for example, a `.bgeo`) to read from. When running inside Houdini, this can be an `op:/path/to/sop` reference.

`&result`

The normal vector with respect to the subdivision limit at the given attribute value is stored in the vector you pass to this argument.

Returns

`1` if computing the attribute was successful, `0` if it failed.

Possible reasons for failure are:

-   The geometry contains no polygons or the topology can’t be converted using Open Subdiv
    
-   The attribute doesn’t exist on the input geometry.
    
-   The attribute size/type doesn’t match the VEX type of the `result` argument.
    

<h2 id="examples">Examples</h2>

Evaluate the normal at the subdivision surface limit position at each point on the poly cage and set the normal as an attribute at the given point number.

```vex
int prims[] = pointprims(file, ptnum);
if (len(prims))
{
    int primnum = prims[0];
    float prim_u, prim_v;
    if (pointprimuv(file, ptnum, primnum, prim_u, prim_v))
    {
        int patch_id;
        float patch_u, patch_v;
        osd_lookuppatch(file, primnum, prim_u, prim_v, patch_id, patch_u, patch_v);
        vector N;
        if (osd_limitnormal(file, "P", patch_id, patch_u, patch_v, N))
        {
            setpointattrib(file, "N", ptnum, N);
        }
    }
}
```

## See Also

- [pointprimuv](/docs/houdini/vex/functions/pointprimuv)
- [osd_facecount](/docs/houdini/vex/functions/osd_facecount)
- [osd_firstpatch](/docs/houdini/vex/functions/osd_firstpatch)
- [osd_patchcount](/docs/houdini/vex/functions/osd_patchcount)
- [osd_limit](/docs/houdini/vex/functions/osd_limit)
- [osd_limitcurvature](/docs/houdini/vex/functions/osd_limitcurvature)
- [osd_limitgradient](/docs/houdini/vex/functions/osd_limitgradient)
- [osd_limitsurface](/docs/houdini/vex/functions/osd_limitsurface)

## Subd

- [osd_facecount](/docs/houdini/vex/functions/osd_facecount)
- [osd_firstpatch](/docs/houdini/vex/functions/osd_firstpatch)
- [osd_limit](/docs/houdini/vex/functions/osd_limit)
- [osd_limitcurvature](/docs/houdini/vex/functions/osd_limitcurvature)
- [osd_limitgradient](/docs/houdini/vex/functions/osd_limitgradient)
- [osd_limitnormal](/docs/houdini/vex/functions/osd_limitnormal)
- [osd_limitsurface](/docs/houdini/vex/functions/osd_limitsurface)
- [osd_limitsurfacevertex](/docs/houdini/vex/functions/osd_limitsurfacevertex)
- [osd_limitvertex](/docs/houdini/vex/functions/osd_limitvertex)
- [osd_lookupface](/docs/houdini/vex/functions/osd_lookupface)
- [osd_lookuppatch](/docs/houdini/vex/functions/osd_lookuppatch)
- [osd_patchcount](/docs/houdini/vex/functions/osd_patchcount)
- [osd_patches](/docs/houdini/vex/functions/osd_patches)