[Bf-blender-cvs] [5b8cd24863d] temp-geometry-nodes-curve-deform-node: Curve deform working slightly better
Hans Goudey
noreply at git.blender.org
Fri Jun 4 23:35:44 CEST 2021
Commit: 5b8cd24863dc9a66d0847fd3cbfcc8563723b87d
Author: Hans Goudey
Date: Fri Jun 4 17:22:16 2021 -0400
Branches: temp-geometry-nodes-curve-deform-node
https://developer.blender.org/rB5b8cd24863dc9a66d0847fd3cbfcc8563723b87d
Curve deform working slightly better
===================================================================
M source/blender/blenkernel/BKE_spline.hh
M source/blender/blenkernel/intern/spline_base.cc
M source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index a0a6834a652..92aa9313ef7 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -172,13 +172,9 @@ class Spline {
blender::Array<float> sample_uniform_index_factors(const int samples_size) const;
struct Parameter {
- float factor;
+ /* Used as an "index factor" after the function. */
+ float length;
int data_index;
-
- friend bool operator<(const Parameter &a, const Parameter &b)
- {
- return a.factor < b.factor;
- }
};
void sample_parameters_to_index_factors(
blender::MutableSpan<Parameter> sample_index_factors) const;
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 316ca04b438..45238c2a45b 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -313,45 +313,38 @@ Array<float> Spline::sample_uniform_index_factors(const int samples_size) const
return samples;
}
-static void verify_parameters_assert(Span<Spline::Parameter> parameters)
-{
- float last = 0.0f;
- for (const Spline::Parameter ¶meter : parameters) {
- BLI_assert(parameter.factor >= last);
- last = parameter.factor;
- }
- BLI_assert(last <= 1.0f);
-}
-
void Spline::sample_parameters_to_index_factors(MutableSpan<Parameter> sample_index_factors) const
{
const Span<float> lengths = this->evaluated_lengths();
-
- verify_parameters_assert(sample_index_factors);
-
- const int samples_size = sample_index_factors.size();
const float total_length = this->length();
+ {
+ float last = 0.0f;
+ for (const Spline::Parameter ¶meter : sample_index_factors) {
+ /* Parameters must be provided in increasing order. */
+ BLI_assert(parameter.length >= last);
+ last = parameter.length;
+ }
+ /* Parameters must be in the 0-total_length range. */
+ BLI_assert(last <= total_length);
+ BLI_assert(sample_index_factors.first().length >= 0.0f);
+ }
+
/* Store the length at the previous evaluated point in a variable so it can
* start out at zero (the lengths array doesn't contain 0 for the first point). */
float prev_length = 0.0f;
- int i_sample = 0;
- for (const int i_evaluated : IndexRange(this->evaluated_edges_size())) {
- const float length = lengths[i_evaluated];
- const float sample_length = sample_index_factors[i_sample].factor * total_length;
-
- /* Add every sample that fits in this evaluated edge. */
- while ((sample_length * i_sample) < length && i_sample < samples_size) {
- const float factor = (sample_length * i_sample - prev_length) / (length - prev_length);
- sample_index_factors[i_sample].factor = i_evaluated + factor;
- i_sample++;
- }
-
- if (i_sample >= samples_size) {
- break;
+ int i_evaluated = 0;
+ for (const int i_sample : sample_index_factors.index_range()) {
+ const float sample_length = sample_index_factors[i_sample].length;
+
+ /* Skip over every evaluated point that fits before this sample. */
+ while (lengths[i_evaluated] < sample_length) {
+ prev_length = lengths[i_evaluated];
+ i_evaluated++;
}
- prev_length = length;
+ const float factor = (sample_length - prev_length) / (lengths[i_evaluated] - prev_length);
+ sample_index_factors[i_sample].length = i_evaluated + factor;
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
index 2b64d08ca04..4e73e767f6b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
@@ -92,12 +92,10 @@ static void geo_node_curve_deform_update(bNodeTree *UNUSED(ntree), bNode *node)
}
static void spline_deform(const Spline &spline,
- MutableSpan<Spline::Parameter> parameters,
- VMutableArray<float3> &positions)
+ Span<Spline::Parameter> index_factors,
+ const int axis_index,
+ MutableSpan<float3> positions)
{
- spline.sample_parameters_to_index_factors(parameters);
- MutableSpan<Spline::Parameter> index_factors = std::move(parameters);
-
Span<float3> spline_positions = spline.evaluated_positions();
Span<float3> spline_tangents = spline.evaluated_tangents();
Span<float3> spline_normals = spline.evaluated_normals();
@@ -105,24 +103,84 @@ static void spline_deform(const Spline &spline,
parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
for (const int i : range) {
+ const int i_position = index_factors[i].data_index;
+ float3 position = positions[i_position];
+ position[axis_index] = 0.0f;
+
const Spline::LookupResult interp = spline.lookup_data_from_index_factor(
- index_factors[i].factor);
+ index_factors[i].length);
const int index = interp.evaluated_index;
const int next_index = interp.next_evaluated_index;
+ const float factor = interp.factor;
float4x4 matrix = float4x4::from_normalized_axis_data(
- spline_positions[index], spline_normals[index], spline_tangents[index]);
- matrix.apply_scale(radii[index]);
+ {0, 0, 0},
+ float3::interpolate(spline_normals[index], spline_normals[next_index], factor)
+ .normalized(),
+ float3::interpolate(spline_tangents[index], spline_tangents[next_index], factor)
+ .normalized());
+ matrix.apply_scale(interpf(radii[next_index], radii[index], factor));
+
+ positions[i_position] = matrix * position;
+ positions[i_position] += float3::interpolate(
+ spline_positions[index], spline_positions[next_index], factor);
+ }
+ });
+}
- float4x4 next_matrix = float4x4::from_normalized_axis_data(
- spline_positions[next_index], spline_normals[next_index], spline_tangents[next_index]);
- matrix.apply_scale(radii[next_index]);
+static int axis_to_index(const GeometryNodeCurveDeformPositionAxis axis)
+{
+ switch (axis) {
+ case GEO_NODE_CURVE_DEFORM_POSX:
+ case GEO_NODE_CURVE_DEFORM_NEGX:
+ return 0;
+ case GEO_NODE_CURVE_DEFORM_POSY:
+ case GEO_NODE_CURVE_DEFORM_NEGY:
+ return 1;
+ case GEO_NODE_CURVE_DEFORM_POSZ:
+ case GEO_NODE_CURVE_DEFORM_NEGZ:
+ return 2;
+ }
+ BLI_assert_unreachable();
+ return -1;
+}
- const float4x4 deform_matrix = float4x4::interpolate(matrix, next_matrix, interp.factor);
+static bool axis_is_negative(const GeometryNodeCurveDeformPositionAxis axis)
+{
+ switch (axis) {
+ case GEO_NODE_CURVE_DEFORM_POSX:
+ case GEO_NODE_CURVE_DEFORM_POSY:
+ case GEO_NODE_CURVE_DEFORM_POSZ:
+ return false;
+ case GEO_NODE_CURVE_DEFORM_NEGX:
+ case GEO_NODE_CURVE_DEFORM_NEGY:
+ case GEO_NODE_CURVE_DEFORM_NEGZ:
+ return true;
+ }
+ BLI_assert_unreachable();
+ return false;
+}
- positions[parameters[i].data_index] = deform_matrix * positions[parameters[i].data_index];
+static float find_upper_bound(Span<float3> positions, const int index)
+{
+ float max = FLT_MIN;
+ for (const float3 &position : positions) {
+ if (position[index] > max) {
+ max = position[index];
}
- });
+ }
+ return max;
+}
+
+static float find_lower_bound(Span<float3> positions, const int index)
+{
+ float min = FLT_MAX;
+ for (const float3 &position : positions) {
+ if (position[index] < min) {
+ min = position[index];
+ }
+ }
+ return min;
}
static void execute_on_component(const GeoNodeExecParams ¶ms,
@@ -131,38 +189,47 @@ static void execute_on_component(const GeoNodeExecParams ¶ms,
{
const NodeGeometryCurveDeform &node_storage = *(NodeGeometryCurveDeform *)params.node().storage;
const GeometryNodeCurveDeformMode mode = (GeometryNodeCurveDeformMode)node_storage.input_mode;
+ const GeometryNodeCurveDeformPositionAxis axis = (GeometryNodeCurveDeformPositionAxis)
+ node_storage.position_axis;
+ const int axis_index = axis_to_index(axis);
if (curve.splines().size() == 0) {
- params.error_message_add(NodeWarningType::Error, TIP_("Curve does not contain a spline"));
+ BLI_assert_unreachable();
return;
}
+ const Spline &spline = *curve.splines().first();
+ const float total_length = spline.length();
+
const int size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ OutputAttribute_Typed<float3> position_attribute =
+ component.attribute_try_get_for_output<float3>("position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ MutableSpan<float3> positions = position_attribute.as_span();
Array<Spline::Parameter> parameters(size);
if (mode == GEO_NODE_CURVE_DEFORM_POSITION) {
- switch ((GeometryNodeCurveDeformPositionAxis)node_storage.position_axis) {
- case GEO_NODE_CURVE_DEFORM_POSX:
- // parallel_for(positions.index_range(), 4096, [&](IndexRange range) {
- // for (const int i : range) {
- // parameters[i] = { positions }
- // }
- // });
- break;
- case GEO_NODE_CURVE_DEFORM_POSY:
- break;
- case GEO_NODE_CURVE_DEFORM_POSZ:
- break;
- case GEO_NODE_CURVE_DEFORM_NEGX:
- break;
- case GEO_NODE_CURVE_DEFORM_NEGY:
- break;
- case GEO_NODE_CURVE_DEFORM_NEGZ:
- break;
+ if (axis_is_negative(axis)) {
+ parallel_for(positions.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ parameters[i] = {std::clamp(positions[i][axis_index], 0.0f, total_length), i};
+ }
+ });
+ }
+ else {
+ parallel_for(positions.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ parameters[i] = {total_length - std::clamp(positions[i][axis_index], 0.0f, total_length),
+ i};
+ }
+ });
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list