Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-03-30 03:44:01 +0300
committerHans Goudey <h.goudey@me.com>2022-03-30 03:45:59 +0300
commit72d25fa41d8c5753e4cdc1293d407e16c1431119 (patch)
treec074afbdab6a1b274ef659e2aeb463ef12c578b4 /source/blender/blenlib/BLI_length_parameterize.hh
parentbcb9379c6dfadbc7883f6f93bcca6a8b2a113419 (diff)
Curves: Add length cache, length paramerterize utility
This commit adds calculation of lengths along the curve for each evaluated point. This is used for sampling, resampling, the "curve parameter" node, and potentially more places in the future. This commit also includes a utility for calculation of uniform samples in blenlib. It can find evenlyspaced samples along a sequence of points and use linear interpolation to move data from those points to the samples. Making the utility more general aligns better with the more functional approach of the new curves code and makes the behavior available elsewhere. A "color math" header is added to allow very basic interpolation between two colors in the `blender::math` namespace. Differential Revision: https://developer.blender.org/D14382
Diffstat (limited to 'source/blender/blenlib/BLI_length_parameterize.hh')
-rw-r--r--source/blender/blenlib/BLI_length_parameterize.hh80
1 files changed, 80 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_length_parameterize.hh b/source/blender/blenlib/BLI_length_parameterize.hh
new file mode 100644
index 00000000000..e4a4e9cbb9c
--- /dev/null
+++ b/source/blender/blenlib/BLI_length_parameterize.hh
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_math_base.hh"
+#include "BLI_math_color.hh"
+#include "BLI_math_vector.hh"
+#include "BLI_vector.hh"
+
+namespace blender::length_parameterize {
+
+/**
+ * Return the size of the necessary lengths array for a group of points, taking into account the
+ * possible last cyclic segment.
+ *
+ * \note This is the same as #bke::curves::curve_segment_size.
+ */
+inline int lengths_num(const int points_num, const bool cyclic)
+{
+ return cyclic ? points_num : points_num - 1;
+}
+
+/**
+ * Accumulate the length of the next segment into each point.
+ */
+template<typename T>
+void accumulate_lengths(const Span<T> values, const bool cyclic, MutableSpan<float> lengths)
+{
+ BLI_assert(lengths.size() == lengths_num(values.size(), cyclic));
+ float length = 0.0f;
+ for (const int i : IndexRange(values.size() - 1)) {
+ length += math::distance(values[i], values[i + 1]);
+ lengths[i] = length;
+ }
+ if (cyclic) {
+ lengths.last() = length + math::distance(values.last(), values.first());
+ }
+}
+
+template<typename T>
+void linear_interpolation(const Span<T> src,
+ const Span<int> indices,
+ const Span<float> factors,
+ MutableSpan<T> dst)
+{
+ BLI_assert(indices.size() == factors.size());
+ BLI_assert(indices.size() == dst.size());
+ const int last_src_index = src.index_range().last();
+
+ int cyclic_sample_count = 0;
+ for (int i = indices.index_range().last(); i > 0; i--) {
+ if (indices[i] != last_src_index) {
+ break;
+ }
+ dst[i] = math::interpolate(src.last(), src.first(), factors[i]);
+ cyclic_sample_count++;
+ }
+
+ for (const int i : dst.index_range().drop_back(cyclic_sample_count)) {
+ dst[i] = math::interpolate(src[indices[i]], src[indices[i] + 1], factors[i]);
+ }
+}
+
+/**
+ * Find the given number of points, evenly spaced along the provided length. For non-cyclic
+ * sequences, the first point will always be included, and last point will always be included if
+ * the #count is greater than zero. For cyclic sequences, the first point will always be included.
+ *
+ * \warning The #count argument must be greater than zero.
+ */
+void create_uniform_samples(Span<float> lengths,
+ bool cyclic,
+ MutableSpan<int> indices,
+ MutableSpan<float> factors);
+
+} // namespace blender::length_parameterize