diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index fe2c6196221..ca92ad7480f 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -48,6 +48,13 @@ struct BasisCache { * In other words, the index of the first control point that influences this evaluated point. */ Vector start_indices; + + /** + * The result of #check_valid_size_and_order, to avoid retrieving its inputs later on. + * If this is true, the data above will be invalid, and original data should be copied + * to the evaluated result. + */ + bool invalid = false; }; } // namespace curves::nurbs @@ -760,7 +767,7 @@ inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index, BLI_assert(cyclic == this->cyclic()[curve_index]); const IndexRange points = this->evaluated_points_for_curve(curve_index); const int start = points.start() + curve_index; - return {start, points.is_empty() ? 0 : curves::curve_segment_size(points.size(), cyclic)}; + return {start, curves::curve_segment_size(points.size(), cyclic)}; } inline Span CurvesGeometry::evaluated_lengths_for_curve(const int curve_index, @@ -775,8 +782,7 @@ inline float CurvesGeometry::evaluated_length_total_for_curve(const int curve_in const bool cyclic) const { const Span lengths = this->evaluated_lengths_for_curve(curve_index, cyclic); - /* Check for curves that have no evaluated segments. */ - return lengths.is_empty() ? 0.0f : lengths.last(); + return lengths.last(); } /** \} */ diff --git a/source/blender/blenkernel/intern/curve_nurbs.cc b/source/blender/blenkernel/intern/curve_nurbs.cc index 0114c0b45f4..45440358221 100644 --- a/source/blender/blenkernel/intern/curve_nurbs.cc +++ b/source/blender/blenkernel/intern/curve_nurbs.cc @@ -36,7 +36,7 @@ int calculate_evaluated_size(const int points_num, const KnotsMode knots_mode) { if (!check_valid_size_and_order(points_num, order, cyclic, knots_mode)) { - return 0; + return points_num; } return resolution * curve_segment_size(points_num, cyclic); } @@ -232,8 +232,12 @@ void interpolate_to_evaluated(const BasisCache &basis_cache, const GSpan src, GMutableSpan dst) { - BLI_assert(dst.size() == basis_cache.start_indices.size()); + if (basis_cache.invalid) { + dst.copy_from(src); + return; + } + BLI_assert(dst.size() == basis_cache.start_indices.size()); attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_void_v>) { diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 7a09b87490b..3ec5ee928f4 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -577,6 +577,11 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const const bool is_cyclic = cyclic[curve_index]; const KnotsMode mode = KnotsMode(knots_modes[curve_index]); + if (!curves::nurbs::check_valid_size_and_order(points.size(), order, is_cyclic, mode)) { + basis_caches[curve_index].invalid = true; + continue; + } + const int knots_size = curves::nurbs::knots_size(points.size(), order, is_cyclic); Array knots(knots_size); curves::nurbs::calculate_knots(points.size(), mode, order, is_cyclic, knots); @@ -696,9 +701,6 @@ Span CurvesGeometry::evaluated_tangents() const threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); - if (UNLIKELY(evaluated_points.is_empty())) { - continue; - } curves::poly::calculate_tangents(evaluated_positions.slice(evaluated_points), cyclic[curve_index], tangents.slice(evaluated_points)); @@ -773,9 +775,6 @@ Span CurvesGeometry::evaluated_normals() const for (const int curve_index : curves_range) { const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); - if (UNLIKELY(evaluated_points.is_empty())) { - continue; - } switch (normal_mode[curve_index]) { case NORMAL_MODE_Z_UP: curves::poly::calculate_normals_z_up(evaluated_tangents.slice(evaluated_points), @@ -916,9 +915,6 @@ void CurvesGeometry::ensure_evaluated_lengths() const for (const int curve_index : curves_range) { const bool cyclic = curves_cyclic[curve_index]; const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); - if (UNLIKELY(evaluated_points.is_empty())) { - continue; - } const IndexRange lengths_range = this->lengths_range_for_curve(curve_index, cyclic); length_parameterize::accumulate_lengths(evaluated_positions.slice(evaluated_points), cyclic,