Source/Objects/Curves

= Curves Object =

The curves object is intended to replace the hair particle system and the existing curve object type. Geometry sets allow flexibility of object types from mesh objects with geometry nodes.


 * : New curves object type
 * : New Curves data block

Data Structures

 * `Object` can be of type `OB_CURVES`, and then uses a `Curves` data-block as object data.
 * `Curves` is an `ID` data-block data-block used to store curves.
 * `CurvesGeometry` that contains an array of curves and their control points.

Curves Geometry
The `CurvesGeometry` struct contains curve and control point attributes, the topology of curves, and any caches relating to that data. `CurvesGeometry` is a separate type from `Curves` so it can have C++ RAII semantics and so it can be embedded in other Blender ID data-blocks in the future.

Topology is encoded with a single array of integers: each value is each curve's offset into the point array. The number of points in the curve is retrieved from an offset and the next offset. Arbitrary attributes can be created on both curves and points.

Multiple curve types are supported:
 * 1) Catmull Rom: Catmull Rom curves are like Bezier curves but use the four neighboring control points to describe the tangents at each point. They provide simple continuity and local control.
 * 2) Poly Poly curves have no interpolation at all. The main reason for this type is reduced complexity and increased performance.
 * 3) Bezier A Bézier curve is made up of a many curve segments, possibly achieving continuity of curvature by constraining the alignment of curve handles. In order to correspond with user expectations, "handle" control points are stored in separate `handle_{position/type}_{left/right}` attributes.
 * 4) NURBS Non-Uniform Rational B-Splines are a superset of the other types-- more advanced but more flexible. The mapping from control points to evaluated points is influenced by a vector of knots, weights for each point, and the order/degree of the curve.

These types can be mixed together in a single curves data-block, though generally code should prioritize performance when all types are the same rather than when they are mixed.

Curves
The `Curves` data-block contains an embedded `CurvesGeometry` struct and a few more high-level variables like the selection domain for editing.

Attachment & Deformation
Each curve can be attached to a mesh surface with UV coordinates stored in the `surface_uv_coords` attribute. The attachment information can be used to interpolate mesh attributes to curves or to find the position at the surface.

Using a UV map works well because:
 * Many mesh editing operations, even ones that change topology, keep UV maps intact.
 * UV maps are a concept that is well known to users and thus no new concept has to be learned.
 * UV maps can be generated, accessed and modified using geometry nodes.
 * UV maps exist on surface usually anyway, so there is no extra cost on propagating it for other usages.
 * Tangents for curve deformation are clearer, since they can take the UV map into account.

The main downsides to using UV maps are:
 * A UV coordinate can correspond to an arbitrary number points on a surface. UV islands shouldn’t overlap for predictable results.
 * Doing a reverse lookup from UV coordinates to positions on a mesh comes at a cost. This is implemented with `ReverseUVSampler`.

Rendering
Cycles and EEVEE can render hair and their attributes natively as Catmull-Rom curves, for memory efficiency. However, there are still many limitations like no support for cyclic curves or other curve types. EEVEE always resamples curves to have a small number of control points.

Improving rendering support is tracked in.

Hair System
The hair system is implemented with curves sculpt mode and geometry nodes.

Future Work

 * Edit mode still needs to be implemented
 * Node group operators will allow custom edit/sculpt mode tools
 * A generic simulation system will allow physics simulations
 * More geometry nodes will make it possible to build procedural hair generation node groups.