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.
Objectcan be of type
OB_CURVES, and then uses a
Curvesdata-block as object data.
IDdata-block data-block used to store curves.
CurvesGeometrythat contains an array of curves and their control points.
CurvesGeometry struct contains curve and control point
attributes, the topology of curves, and any caches relating to that
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:
- 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.
- Poly Poly curves have no interpolation at all. The main reason for this type is reduced complexity and increased performance.
- 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
- 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 data-block contains an embedded
and a few more high-level variables like the selection domain for
Attachment & Deformation¶
Each curve can be attached to a mesh surface with UV coordinates stored
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
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 T96455.
The hair system is implemented with curves sculpt mode and geometry nodes.
- 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.
Algorithms that change point count but keep the same number of curves¶
- With an
IndexMaskselection of curves, find the inverse selection (
- Create the new curves with no points but the same curve count:
bke::curves::copy_only_curve_domain1. This avoids duplicating any data in the curves with implicit sharing.
- Copy sizes of unselected curves into the new curves offsets:
- Calculate the result sizes of the selected curves, store in the new curves offsets as well 1. Depending on the complexity of the algorithm, knowing the number of points in the result curve can require doing the majority of the work. When this is unavoidable, it's best to store a minimum of information that will allow filling the point attributes after the new curves are created with the correct point count.
- Transform the curve sizes into offsets with
- Create the curves with the calculated final point count (the last
- Copy point data for all unselected curve points with
- Do the operation & interpolate attributes to selected curves