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>2021-09-29 23:29:29 +0300
committerHans Goudey <h.goudey@me.com>2021-09-29 23:29:29 +0300
commit81f552e9ad1ab5705ef69cf8e7ff7ee67575d45f (patch)
tree86b0af42effc17db26b41a7bd1df795f7d520e25 /source/blender/blenkernel/intern/spline_bezier.cc
parentcd03f5b6e572640f6e182c4989fe20ced156effa (diff)
Geometry Nodes: Expose Bezier handle positions as an attribute
This commit exposes left and right bezier handles as an attribute. Interaction basically works like edit mode. If you move an aligned handle, it also moves the opposite handle of the control point. The difference is that you can't edit "Auto" or "Vector" handles, you have to first use the "Set Handle Type" node. That gives the handle types a bit more meaning in the node tree-- changing them in edit mod is more like a "UI override". The attributes are named `handle_start` and `handle_end`, which is the same name used in the curve RNA API. A new virtual array implementation is added which handles the case of splines that don't have these attributes, and it also calls two new functions on `BezierSpline` to set the handle position accounting for aligned handles. The virtual arrays and attribute providers will be refactored (probably templated) in the future, as a next step after the last built-in curve attribute provider has landed. Differential Revision: https://developer.blender.org/D12005
Diffstat (limited to 'source/blender/blenkernel/intern/spline_bezier.cc')
-rw-r--r--source/blender/blenkernel/intern/spline_bezier.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index b36d7a21669..f719a1cfda2 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -289,6 +289,56 @@ void BezierSpline::transform(const blender::float4x4 &matrix)
this->mark_cache_invalid();
}
+static void set_handle_position(const float3 &position,
+ const BezierSpline::HandleType type,
+ const BezierSpline::HandleType type_other,
+ const float3 &new_value,
+ float3 &handle,
+ float3 &handle_other)
+{
+ /* Don't bother when the handle positions are calculated automatically anyway. */
+ if (ELEM(type, BezierSpline::HandleType::Auto, BezierSpline::HandleType::Vector)) {
+ return;
+ }
+
+ handle = new_value;
+ if (type_other == BezierSpline::HandleType::Align) {
+ /* Keep track of the old length of the opposite handle. */
+ const float length = float3::distance(handle_other, position);
+ /* Set the other handle to directly opposite from the current handle. */
+ const float3 dir = (handle - position).normalized();
+ handle_other = position - dir * length;
+ }
+}
+
+/**
+ * Set positions for the right handle of the control point, ensuring that
+ * aligned handles stay aligned. Has no effect for auto and vector type handles.
+ */
+void BezierSpline::set_handle_position_right(const int index, const blender::float3 &value)
+{
+ set_handle_position(positions_[index],
+ handle_types_right_[index],
+ handle_types_left_[index],
+ value,
+ handle_positions_right_[index],
+ handle_positions_left_[index]);
+}
+
+/**
+ * Set positions for the left handle of the control point, ensuring that
+ * aligned handles stay aligned. Has no effect for auto and vector type handles.
+ */
+void BezierSpline::set_handle_position_left(const int index, const blender::float3 &value)
+{
+ set_handle_position(positions_[index],
+ handle_types_left_[index],
+ handle_types_right_[index],
+ value,
+ handle_positions_left_[index],
+ handle_positions_right_[index]);
+}
+
bool BezierSpline::point_is_sharp(const int index) const
{
return ELEM(handle_types_left_[index], HandleType::Vector, HandleType::Free) ||