[Bf-blender-cvs] [dd886fcc6d5] geometry-nodes-curve-support: Cleanup: Split spline implementations into separate files
Hans Goudey
noreply at git.blender.org
Tue Apr 20 00:07:26 CEST 2021
Commit: dd886fcc6d59af96b7e57ac3267f03283ac31b22
Author: Hans Goudey
Date: Mon Apr 19 17:07:17 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rBdd886fcc6d59af96b7e57ac3267f03283ac31b22
Cleanup: Split spline implementations into separate files
===================================================================
M source/blender/blenkernel/CMakeLists.txt
M source/blender/blenkernel/intern/derived_curve.cc
A source/blender/blenkernel/intern/derived_curve_spline_base.cc
A source/blender/blenkernel/intern/derived_curve_spline_bezier.cc
A source/blender/blenkernel/intern/derived_curve_spline_nurbs.cc
A source/blender/blenkernel/intern/derived_curve_spline_poly.cc
===================================================================
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 823d543cd26..40e1cb98a16 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -117,7 +117,11 @@ set(SRC
intern/customdata_file.c
intern/data_transfer.c
intern/deform.c
- intern/derived_curve.cc
+ intern/derived_curve.cc
+ intern/derived_curve_spline_base.cc
+ intern/derived_curve_spline_bezier.cc
+ intern/derived_curve_spline_nurbs.cc
+ intern/derived_curve_spline_poly.cc
intern/displist.cc
intern/displist_tangent.c
intern/dynamicpaint.c
diff --git a/source/blender/blenkernel/intern/derived_curve.cc b/source/blender/blenkernel/intern/derived_curve.cc
index 372d184b86a..ae217892ae8 100644
--- a/source/blender/blenkernel/intern/derived_curve.cc
+++ b/source/blender/blenkernel/intern/derived_curve.cc
@@ -31,16 +31,6 @@ using blender::MutableSpan;
using blender::Span;
using blender::Vector;
-/* -------------------------------------------------------------------- */
-/** \name Utilities
- * \{ */
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name General Curve Functions
- * \{ */
-
DCurve *DCurve::copy()
{
DCurve *new_curve = new DCurve();
@@ -195,915 +185,3 @@ DCurve *dcurve_from_dna_curve(const Curve &dna_curve)
}
/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Spline
- * \{ */
-
-/**
- * Mark all caches for recomputation. This must be called after any operation that would
- * change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
- */
-void Spline::mark_cache_invalid()
-{
- base_cache_dirty_ = true;
- tangent_cache_dirty_ = true;
- normal_cache_dirty_ = true;
- length_cache_dirty_ = true;
-}
-
-int Spline::evaluated_edges_size() const
-{
- const int points_len = this->evaluated_points_size();
-
- return this->is_cyclic ? points_len : points_len - 1;
-}
-
-float Spline::length() const
-{
- return this->evaluated_lengths().last();
-}
-
-Span<float3> Spline::evaluated_positions() const
-{
- this->ensure_base_cache();
- return evaluated_positions_cache_;
-}
-
-/**
- * Returns non-owning access to the cache of mappings from the evaluated points to
- * the corresponing control points. Unless the spline is cyclic, the last control point
- * index will never be included as an index.
- */
-Span<PointMapping> Spline::evaluated_mappings() const
-{
- this->ensure_base_cache();
-#ifdef DEBUG
- if (evaluated_mapping_cache_.last().control_point_index == this->size() - 1) {
- BLI_assert(this->is_cyclic);
- }
-#endif
- return evaluated_mapping_cache_;
-}
-
-static void accumulate_lengths(Span<float3> positions,
- const bool is_cyclic,
- MutableSpan<float> lengths)
-{
- float length = 0.0f;
- for (const int i : IndexRange(positions.size() - 1)) {
- length += float3::distance(positions[i], positions[i + 1]);
- lengths[i] = length;
- }
- if (is_cyclic) {
- lengths.last() = length + float3::distance(positions.last(), positions.first());
- }
-}
-
-/**
- * Return non-owning access to the cache of accumulated lengths along the spline. Each item is the
- * length of the subsequent segment, i.e. the first value is the length of the first segment rather
- * than 0. This calculation is rather trivial, and only depends on the evaluated positions.
- * However, the results are used often, so it makes sense to cache it.
- */
-Span<float> Spline::evaluated_lengths() const
-{
- if (!this->length_cache_dirty_) {
- return evaluated_lengths_cache_;
- }
-
- std::lock_guard lock{this->length_cache_mutex_};
- if (!this->length_cache_dirty_) {
- return evaluated_lengths_cache_;
- }
-
- const int total = this->evaluated_edges_size();
- this->evaluated_lengths_cache_.resize(total);
-
- Span<float3> positions = this->evaluated_positions();
- accumulate_lengths(positions, this->is_cyclic, this->evaluated_lengths_cache_);
-
- this->length_cache_dirty_ = false;
- return evaluated_lengths_cache_;
-}
-
-/* TODO: Optimize this along with the function below. */
-static float3 direction_bisect(const float3 &prev, const float3 &middle, const float3 &next)
-{
- const float3 dir_prev = (middle - prev).normalized();
- const float3 dir_next = (next - middle).normalized();
-
- return (dir_prev + dir_next).normalized();
-}
-
-static void calculate_tangents(Span<float3> positions,
- const bool is_cyclic,
- MutableSpan<float3> tangents)
-{
- if (positions.size() == 1) {
- return;
- }
-
- for (const int i : IndexRange(1, positions.size() - 2)) {
- tangents[i] = direction_bisect(positions[i - 1], positions[i], positions[i + 1]);
- }
-
- if (is_cyclic) {
- const float3 &second_to_last = positions[positions.size() - 2];
- const float3 &last = positions.last();
- const float3 &first = positions.first();
- const float3 &second = positions[1];
- tangents.first() = direction_bisect(last, first, second);
- tangents.last() = direction_bisect(second_to_last, last, first);
- }
- else {
- tangents.first() = (positions[1] - positions[0]).normalized();
- tangents.last() = (positions.last() - positions[positions.size() - 1]).normalized();
- }
-}
-
-/**
- * Return non-owning access to the direction of the curve at each evaluated point.
- */
-Span<float3> Spline::evaluated_tangents() const
-{
- if (!this->tangent_cache_dirty_) {
- return evaluated_tangents_cache_;
- }
-
- std::lock_guard lock{this->tangent_cache_mutex_};
- if (!this->tangent_cache_dirty_) {
- return evaluated_tangents_cache_;
- }
-
- const int total = this->evaluated_points_size();
- this->evaluated_tangents_cache_.resize(total);
-
- Span<float3> positions = this->evaluated_positions();
-
- calculate_tangents(positions, this->is_cyclic, this->evaluated_tangents_cache_);
-
- this->correct_end_tangents();
-
- this->tangent_cache_dirty_ = false;
- return evaluated_tangents_cache_;
-}
-
-static float3 initial_normal(const float3 first_tangent)
-{
- /* TODO: Should be is "almost" zero. */
- if (first_tangent.is_zero()) {
- return float3(0.0f, 0.0f, 1.0f);
- }
-
- const float3 normal = float3::cross(first_tangent, float3(0.0f, 0.0f, 1.0f));
- if (!normal.is_zero()) {
- return normal.normalized();
- }
-
- return float3::cross(first_tangent, float3(0.0f, 1.0f, 0.0f)).normalized();
-}
-
-static float3 rotate_around_axis(const float3 dir, const float3 axis, const float angle)
-{
- BLI_ASSERT_UNIT_V3(axis);
- const float3 scaled_axis = axis * float3::dot(dir, axis);
- const float3 sub = dir - scaled_axis;
- const float3 cross = float3::cross(sub, sub);
- const float sin = std::sin(angle);
- const float cos = std::cos(angle);
- return (scaled_axis + sub * cos + cross * sin).normalized();
-}
-
-static float3 project_on_center_plane(const float3 vector, const float3 plane_normal)
-{
- BLI_ASSERT_UNIT_V3(plane_normal);
- const float distance = float3::dot(vector, plane_normal);
- const float3 projection_vector = plane_normal * -distance;
- return vector + projection_vector;
-}
-
-static float3 propagate_normal(const float3 last_normal,
- const float3 last_tangent,
- const float3 current_tangent)
-{
- const float angle = angle_normalized_v3v3(last_tangent, current_tangent);
-
- if (angle == 0.0f) {
- return last_normal;
- }
-
- const float3 axis = float3::cross(last_tangent, current_tangent).normalized();
-
- const float3 new_normal = rotate_around_axis(last_normal, axis, angle);
-
- return project_on_center_plane(new_normal, current_tangent).normalized();
-}
-
-static void apply_rotation_gradient(Span<float3> tangents,
- MutableSpan<float3> normals,
- const float full_angle)
-{
-
- float remaining_rotation = full_angle;
- float done_rotation = 0.0f;
- for (const int i : IndexRange(1, normals.size() - 1)) {
- if (angle_v3v3(tangents[i], tangents[i - 1]) < 0.001f) {
- normals[i] = rotate_around_axis(normals[i], tangents[i], done_rotation);
- }
- else {
- const float angle = remaining_rotation / (normals.size() - i);
- normals[i] = rotate_around_axis(normals[i], tangents[i], angle + done_rotation);
- remaining_rotation -= angle;
- done_rotation += angle;
- }
- }
-}
-
-static void make_normals_cyclic(Span<float3> tangents, MutableSpan<float3> normals)
-{
- const float3 last_normal = propagate_normal(normals.last(), tangents.last(), tangents.first());
-
- float angle = angle_normalized_v3v3(normals.first(), last_normal);
-
- const float3 cross = float3::cross(normals.first(), last_normal);
- if (float3::dot(cross, tangents.first()) <= 0.0f) {
- angle = -angle;
- }
-
- apply_rotation_gradient(tangents, normals, -angle);
-}
-
-/* This algorithm is a copy from animation nodes bezier normal calculation.
- * TODO: Explore different methods, this also doesn't work right now. */
-static void calculate_normals_minimum_twist(Span<float3> tangents,
- const bool is_cyclic,
- MutableSpan<float3> normals)
-{
- if (normals.size() == 1) {
- normals.first() = float3(1.0f, 0.0f, 0.0f);
- return;
- }
-
- /* Start by calculating a simple normal for the first point. */
- normals[0] = initial_normal(tangents[0]);
-
- /* Then propogate that normal along the spline. */
- for (const int i : IndexRange(1, normals.size() - 1)) {
- normals[i] = propagate_normal(normals[i - 1], tangents[i - 1], tangents[i]);
- }
-
- if (is_cyclic) {
- make_normals_cyclic(tangents, normals);
- }
-}
-
-static void calculate_normals_z_up(Span<float3> tangents, MutableSpan<float3> normals)
-{
- for (const int i : normals.index_range()) {
- normals[i] = float3::cross(tangents[i], float3(0.0f, 0.0f, 1.0f)).normalized();
- }
-}
-
-/**
- * Return non-owning access to the direction vectors perpendicular to the tangents at every
- * evaluated point. The method used t
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list