20 const OffsetIndices points_by_curve = curves.points_by_curve();
21 const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve();
23 const VArray<int> resolutions = curves.resolution();
27 const Span<float3> evaluated_tangents = curves.evaluated_tangents();
32 for (const int i_curve : range) {
33 const IndexRange points = points_by_curve[i_curve];
34 const IndexRange evaluated_points = evaluated_points_by_curve[i_curve];
36 MutableSpan<float3> curve_tangents = results.as_mutable_span().slice(points);
38 switch (types[i_curve]) {
39 case CURVE_TYPE_CATMULL_ROM: {
40 Span<float3> tangents = evaluated_tangents.slice(evaluated_points);
41 const int resolution = resolutions[i_curve];
42 for (const int i : IndexRange(points.size())) {
43 curve_tangents[i] = tangents[resolution * i];
48 curve_tangents.copy_from(evaluated_tangents.slice(evaluated_points));
50 case CURVE_TYPE_BEZIER: {
51 Span<float3> tangents = evaluated_tangents.slice(evaluated_points);
52 curve_tangents.first() = tangents.first();
53 const Span<int> offsets = curves.bezier_evaluated_offsets_for_curve(i_curve);
54 for (const int i : IndexRange(points.size()).drop_front(1)) {
55 curve_tangents[i] = tangents[offsets[i]];
59 case CURVE_TYPE_NURBS: {
60 const Span<float3> curve_positions = positions.slice(points);
61 bke::curves::poly::calculate_tangents(curve_positions, cyclic[i_curve], curve_tangents);