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:
authorJohnny Matthews <guitargeek>2021-09-15 21:57:01 +0300
committerHans Goudey <h.goudey@me.com>2021-09-15 21:57:01 +0300
commit231948f33f8f3e79f7ae38ab9b3db3e597f13b4a (patch)
treeb0f47890380d5a48d10f697e33cbb5465aeb2be9 /source/blender
parenta866a32ff257fd9ff4d543adbddad283a189bbc6 (diff)
Splines: Add a method for reversing a Spline
This moved the spline reversing logic out of the Curve Reverse geometry node and into the spline class. This allows a spline to reverse itself with a call to `my_spline.reverse()` The base class will reverse position, radii & tilt, while specialized versions are created for Bezier and Nurbs splines to reverse the additional data that these classes encapsulate. Differential Revision: https://developer.blender.org/D12501
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_spline.hh11
-rw-r--r--source/blender/blenkernel/intern/spline_base.cc29
-rw-r--r--source/blender/blenkernel/intern/spline_bezier.cc11
-rw-r--r--source/blender/blenkernel/intern/spline_nurbs.cc5
-rw-r--r--source/blender/blenkernel/intern/spline_poly.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc42
6 files changed, 62 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index fc145f1ddf1..0fbf39a52fa 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -131,6 +131,11 @@ class Spline {
virtual void transform(const blender::float4x4 &matrix);
/**
+ * Change the direction of the spline (switch the start and end) without changing its shape.
+ */
+ void reverse();
+
+ /**
* Mark all caches for re-computation. This must be called after any operation that would
* change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
*/
@@ -210,6 +215,7 @@ class Spline {
virtual void correct_end_tangents() const = 0;
virtual void copy_settings(Spline &dst) const = 0;
virtual void copy_data(Spline &dst) const = 0;
+ virtual void reverse_impl() = 0;
};
/**
@@ -353,6 +359,9 @@ class BezierSpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
+
+ protected:
+ void reverse_impl() override;
};
/**
@@ -469,6 +478,7 @@ class NURBSpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
+ void reverse_impl() override;
void calculate_knots() const;
blender::Span<BasisCache> calculate_basis_cache() const;
@@ -519,6 +529,7 @@ class PolySpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
+ void reverse_impl() override;
};
/**
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 732fabc6582..a8871777420 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -19,6 +19,8 @@
#include "BLI_task.hh"
#include "BLI_timeit.hh"
+#include "BKE_attribute_access.hh"
+#include "BKE_attribute_math.hh"
#include "BKE_spline.hh"
#include "FN_generic_virtual_array.hh"
@@ -28,6 +30,8 @@ using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
+using blender::attribute_math::convert_to_static_type;
+using blender::bke::AttributeIDRef;
using blender::fn::GMutableSpan;
using blender::fn::GSpan;
using blender::fn::GVArray;
@@ -110,6 +114,31 @@ void Spline::transform(const blender::float4x4 &matrix)
this->mark_cache_invalid();
}
+void Spline::reverse()
+{
+ this->positions().reverse();
+ this->radii().reverse();
+ this->tilts().reverse();
+
+ this->attributes.foreach_attribute(
+ [&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
+ std::optional<blender::fn::GMutableSpan> attribute = this->attributes.get_for_write(id);
+ if (!attribute) {
+ BLI_assert_unreachable();
+ return false;
+ }
+ convert_to_static_type(meta_data.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ attribute->typed<T>().reverse();
+ });
+ return true;
+ },
+ ATTR_DOMAIN_POINT);
+
+ this->reverse_impl();
+ this->mark_cache_invalid();
+}
+
int Spline::evaluated_edges_size() const
{
const int eval_size = this->evaluated_points_size();
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index b6764f65631..79d2137ee84 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -166,6 +166,17 @@ MutableSpan<float3> BezierSpline::handle_positions_right()
return handle_positions_right_;
}
+void BezierSpline::reverse_impl()
+{
+ this->handle_positions_left().reverse();
+ this->handle_positions_right().reverse();
+ std::swap(this->handle_positions_left_, this->handle_positions_right_);
+
+ this->handle_types_left().reverse();
+ this->handle_types_right().reverse();
+ std::swap(this->handle_types_left_, this->handle_types_right_);
+}
+
static float3 previous_position(Span<float3> positions, const bool cyclic, const int i)
{
if (i == 0) {
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc
index ac6f1bd082c..6d30d8ba916 100644
--- a/source/blender/blenkernel/intern/spline_nurbs.cc
+++ b/source/blender/blenkernel/intern/spline_nurbs.cc
@@ -142,6 +142,11 @@ Span<float> NURBSpline::weights() const
return weights_;
}
+void NURBSpline::reverse_impl()
+{
+ this->weights().reverse();
+}
+
void NURBSpline::mark_cache_invalid()
{
basis_cache_dirty_ = true;
diff --git a/source/blender/blenkernel/intern/spline_poly.cc b/source/blender/blenkernel/intern/spline_poly.cc
index dfd24b2566e..338b5d0ac9e 100644
--- a/source/blender/blenkernel/intern/spline_poly.cc
+++ b/source/blender/blenkernel/intern/spline_poly.cc
@@ -91,6 +91,10 @@ Span<float> PolySpline::tilts() const
return tilts_;
}
+void PolySpline::reverse_impl()
+{
+}
+
void PolySpline::mark_cache_invalid()
{
tangent_cache_dirty_ = true;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 70bb9bd28f4..32bcbe2c608 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -49,47 +49,9 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
- if (!selection[i]) {
- continue;
+ if (selection[i]) {
+ splines[i]->reverse();
}
-
- splines[i]->positions().reverse();
- splines[i]->radii().reverse();
- splines[i]->tilts().reverse();
-
- splines[i]->attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<blender::fn::GMutableSpan> output_attribute =
- splines[i]->attributes.get_for_write(attribute_id);
- if (!output_attribute) {
- BLI_assert_unreachable();
- return false;
- }
- attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- output_attribute->typed<T>().reverse();
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- /* Deal with extra info on derived types. */
- if (BezierSpline *spline = dynamic_cast<BezierSpline *>(splines[i].get())) {
- spline->handle_types_left().reverse();
- spline->handle_types_right().reverse();
-
- spline->handle_positions_left().reverse();
- spline->handle_positions_right().reverse();
- for (int i : spline->handle_positions_left().index_range()) {
- std::swap(spline->handle_positions_left()[i], spline->handle_positions_right()[i]);
- }
- }
- else if (NURBSpline *spline = dynamic_cast<NURBSpline *>(splines[i].get())) {
- spline->weights().reverse();
- }
- /* Nothing to do for poly splines. */
-
- splines[i]->mark_cache_invalid();
}
});