Commit: 301119619c96aac2c6c3ec3a83bc16c5b3110469 Author: Hans Goudey Date: Tue Jan 17 14:40:01 2023 -0600 Branches: master https://developer.blender.org/rB301119619c96aac2c6c3ec3a83bc16c5b3110469
Curves: Remove attribute retrieval, deduplicate evaluation logic Avoid calling `interpolate_to_evaluate` while evaluating normals, which has to look up attributes by name for every curve. Also avoid duplicating the curve type switch in a few functions. I didn't observe a performance difference, but theoretically this could reduce overhead for many small curves. =================================================================== M source/blender/blenkernel/intern/curves_geometry.cc =================================================================== diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 0dc6a24fd9e..133521bc298 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -716,14 +716,57 @@ static void rotate_directions_around_axes(MutableSpan<float3> directions, } } +static void evaluate_generic_data_for_curve( + const int curve_index, + const IndexRange points, + const VArray<int8_t> &types, + const VArray<bool> &cyclic, + const VArray<int> &resolution, + const Span<int> bezier_evaluated_offsets, + const Span<curves::nurbs::BasisCache> nurbs_basis_cache, + const VArray<int8_t> &nurbs_orders, + const Span<float> nurbs_weights, + const GSpan src, + GMutableSpan dst) +{ + switch (types[curve_index]) { + case CURVE_TYPE_CATMULL_ROM: + curves::catmull_rom::interpolate_to_evaluated( + src, cyclic[curve_index], resolution[curve_index], dst); + break; + case CURVE_TYPE_POLY: + dst.copy_from(src); + break; + case CURVE_TYPE_BEZIER: + curves::bezier::interpolate_to_evaluated(src, bezier_evaluated_offsets.slice(points), dst); + break; + case CURVE_TYPE_NURBS: + curves::nurbs::interpolate_to_evaluated(nurbs_basis_cache[curve_index], + nurbs_orders[curve_index], + nurbs_weights.slice_safe(points), + src, + dst); + break; + } +} + Span<float3> CurvesGeometry::evaluated_normals() const { this->runtime->normal_cache_mutex.ensure([&]() { - const Span<float3> evaluated_tangents = this->evaluated_tangents(); + const VArray<int8_t> types = this->curve_types(); const VArray<bool> cyclic = this->cyclic(); const VArray<int8_t> normal_mode = this->normal_mode(); - const VArray<int8_t> types = this->curve_types(); + const VArray<int> resolution = this->resolution(); + const VArray<int8_t> nurbs_orders = this->nurbs_orders(); + const Span<float> nurbs_weights = this->nurbs_weights(); + + const Span<float3> evaluated_tangents = this->evaluated_tangents(); const VArray<float> tilt = this->tilt(); + VArraySpan<float> tilt_span; + const bool use_tilt = !(tilt.is_single() && tilt.get_internal_single() == 0.0f); + if (use_tilt) { + tilt_span = tilt; + } this->runtime->evaluated_normal_cache.resize(this->evaluated_points_num()); MutableSpan<float3> evaluated_normals = this->runtime->evaluated_normal_cache; @@ -748,19 +791,26 @@ Span<float3> CurvesGeometry::evaluated_normals() const /* If the "tilt" attribute exists, rotate the normals around the tangents by the * evaluated angles. We can avoid copying the tilts to evaluate them for poly curves. */ - if (!(tilt.is_single() && tilt.get_internal_single() == 0.0f)) { + if (use_tilt) { const IndexRange points = this->points_for_curve(curve_index); - Span<float> curve_tilt = tilt.get_internal_span().slice(points); if (types[curve_index] == CURVE_TYPE_POLY) { rotate_directions_around_axes(evaluated_normals.slice(evaluated_points), evaluated_tangents.slice(evaluated_points), - curve_tilt); + tilt_span.slice(points)); } else { - evaluated_tilts.clear(); - evaluated_tilts.resize(evaluated_points.size()); - this->interpolate_to_evaluated( - curve_index, curve_tilt, evaluated_tilts.as_mutable_span()); + evaluated_tilts.reinitialize(evaluated_points.size()); + evaluate_generic_data_for_curve(curve_index, + points, + types, + cyclic, + resolution, + this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->nurbs_basis_cache.as_span(), + nurbs_orders, + nurbs_weights, + tilt_span.slice(points), + evaluated_tilts.as_mutable_span()); rotate_directions_around_axes(evaluated_normals.slice(evaluated_points), evaluated_tangents.slice(evaluated_points), evaluated_tilts.as_span()); @@ -781,27 +831,17 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index, const IndexRange points = this->points_for_curve(curve_index); BLI_assert(src.size() == points.size()); BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size()); - switch (this->curve_types()[curve_index]) { - case CURVE_TYPE_CATMULL_ROM: - curves::catmull_rom::interpolate_to_evaluated( - src, this->cyclic()[curve_index], this->resolution()[curve_index], dst); - return; - case CURVE_TYPE_POLY: - dst.type().copy_assign_n(src.data(), dst.data(), src.size()); - return; - case CURVE_TYPE_BEZIER: - curves::bezier::interpolate_to_evaluated( - src, this->runtime->bezier_evaluated_offsets.as_span().slice(points), dst); - return; - case CURVE_TYPE_NURBS: - curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], - this->nurbs_orders()[curve_index], - this->nurbs_weights().slice_safe(points), - src, - dst); - return; - } - BLI_assert_unreachable(); + evaluate_generic_data_for_curve(curve_index, + points, + this->curve_types(), + this->cyclic(), + this->resolution(), + this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->nurbs_basis_cache.as_span(), + this->nurbs_orders(), + this->nurbs_weights(), + src, + dst); } void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) const @@ -818,30 +858,17 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) for (const int curve_index : curves_range) { const IndexRange points = this->points_for_curve(curve_index); const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); - switch (types[curve_index]) { - case CURVE_TYPE_CATMULL_ROM: - curves::catmull_rom::interpolate_to_evaluated(src.slice(points), - cyclic[curve_index], - resolution[curve_index], - dst.slice(evaluated_points)); - continue; - case CURVE_TYPE_POLY: - dst.slice(evaluated_points).copy_from(src.slice(points)); - continue; - case CURVE_TYPE_BEZIER: - curves::bezier::interpolate_to_evaluated( - src.slice(points), - this->runtime->bezier_evaluated_offsets.as_span().slice(points), - dst.slice(evaluated_points)); - continue; - case CURVE_TYPE_NURBS: - curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], - nurbs_orders[curve_index], - nurbs_weights.slice_safe(points), - src.slice(points), - dst.slice(evaluated_points)); - continue; - } + evaluate_generic_data_for_curve(curve_index, + points, + types, + cyclic, + resolution, + this->runtime->bezier_evaluated_offsets, + this->runtime->nurbs_basis_cache, + nurbs_orders, + nurbs_weights, + src.slice(points), + dst.slice(evaluated_points)); } }); } _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs