Skip to content

Curve Object


These docs are based on code comments in BKE_spline.hh. When making changes, please keep that up to date too.

Curve data is a collection of Spline objects with the same attribute types and names. Most data and functionality is in splines, but this contains some helpers for working with them as a group.

As of December 2021 Curve code is going through a transition from the Curve data type to CurveEval. CurveEval simplifies code and supports generic attributes. Most operations on CurveEval are defined as geometry nodes.

A CurveEval corresponds to the Curve object data. The name is different for clarity, since more of the data is stored in the splines, but also just to be different than the name in DNA.

Curve cannot store generic attributes, but CurveEval can. Attributes on the control points of splines in CurveEval uphold a few invariants that can be checked with assert_valid_point_attributes:

  • The same set of attributes exists on every spline.
  • Attributes with the same name have the same type on every spline.
  • Attributes are in the same order on every spline.


A spline is an abstraction of a single branch-less curve section, its evaluation methods, and data. The spline data itself is just control points and a set of attributes by the set of "evaluated" data is often used instead. Conceptually, the derived vs. original data is an essential distinction. Derived data is usually calculated lazily and cached on the spline.

Any derived class of Spline has to manage two things:

  1. Interpolating arbitrary attribute data from the control points to evaluated points.
  2. Evaluating the positions based on the stored control point data.

Beyond that, everything is the base class's responsibility, with minor exceptions. Further evaluation happens in a layer on top of the evaluated points generated by the derived types.

There are a few methods to evaluate a spline:

  1. evaluated_positions and interpolate_to_evaluated give data for the initial evaluated points, depending on the resolution.
  2. lookup_evaluated_factor and lookup_evaluated_factor are meant for one-off lookups along the length of a curve.
  3. sample_uniform_index_factors returns an array that stores uniform-length samples along the spline which can be used to interpolate data from method 1.

Commonly used evaluated data is stored in caches on the spline itself so that operations on splines don't need to worry about taking ownership of evaluated data when they don't need to.

Bezier Spline

A Bézier spline (BezierSpline) is made up of a many curve segments, possibly achieving continuity of curvature by constraining the alignment of curve handles. Evaluation stores the positions and a map of factors and indices in a list of floats, which is then used to interpolate any other data.

NURB Splines

Data for Non-Uniform Rational B-Splines (NURBSpline). The mapping from control points to evaluated points is influenced by a vector of knots, weights for each point, and the order of the spline. Every mapping of data to evaluated points is handled the same way, but the positions are cached in the spline.

Poly Spline

A Poly spline (PolySpline) is like a Bézier spline with a resolution of one. The main reason to distinguish the two is for reduced complexity and increased performance, since interpolating data to control points does not change it.

Poly spline code is very simple, since it doesn't do anything that the base #Spline doesn't handle. So mostly it just worries about storing the data used by the base class.