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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_spline.hh1
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c2
-rw-r--r--source/blender/blenkernel/intern/spline_base.cc32
-rw-r--r--source/blender/makesdna/DNA_node_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c16
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc356
7 files changed, 148 insertions, 271 deletions
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index eb944fc8b5c..60a9b9bb89a 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -170,6 +170,7 @@ class Spline {
};
LookupResult lookup_evaluated_factor(const float factor) const;
LookupResult lookup_evaluated_length(const float length) const;
+ LookupResult lookup_evaluated_length_cyclic(const float length) const;
blender::Array<float> sample_uniform_index_factors(const int samples_size) const;
void sample_length_parameters_to_index_factors(blender::MutableSpan<float> parameters) const;
diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c
index 10c6d2213ff..dc5a093f74a 100644
--- a/source/blender/blenkernel/intern/curve_deform.c
+++ b/source/blender/blenkernel/intern/curve_deform.c
@@ -137,6 +137,8 @@ static bool calc_curve_deform(
}
}
+ printf("FAC: %.5f\n", fac);
+
if (BKE_where_on_path(ob_curve, fac, loc, dir, new_quat, &radius, NULL)) { /* returns OK */
float quat[4], cent[3];
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 389420e3ff7..8956ba6adae 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -255,21 +255,33 @@ Spline::LookupResult Spline::lookup_evaluated_factor(const float factor) const
return this->lookup_evaluated_length(this->length() * factor);
}
-/**
- * \note This does not support extrapolation currently.
- */
Spline::LookupResult Spline::lookup_evaluated_length(const float length) const
{
- BLI_assert(length >= 0.0f && length <= this->length());
-
+ const int64_t evaluated_size = this->evaluated_points_size();
Span<float> lengths = this->evaluated_lengths();
+ if (is_cyclic_) {
+ const float *offset = std::lower_bound(
+ lengths.begin(), lengths.end(), std::remainder(length, this->length()));
+ const int index = offset - lengths.begin();
+ const int next_index = (index == evaluated_size - 1) ? 0 : index + 1;
+
+ const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
+ const float factor = (lengths[index] == previous_length) ?
+ 0.0f :
+ (length - previous_length) / (lengths[index] - previous_length);
+
+ return LookupResult{index, next_index, factor};
+ }
+
const float *offset = std::lower_bound(lengths.begin(), lengths.end(), length);
- const int index = offset - lengths.begin();
- const int next_index = (index == this->size() - 1) ? 0 : index + 1;
+ const int index = std::min(offset - lengths.begin(), evaluated_size - 2);
+ const int next_index = index + 1;
const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
- const float factor = (length - previous_length) / (lengths[index] - previous_length);
+ const float factor = (lengths[index] == previous_length) ?
+ 0.0f :
+ (length - previous_length) / (lengths[index] - previous_length);
return LookupResult{index, next_index, factor};
}
@@ -319,6 +331,7 @@ Array<float> Spline::sample_uniform_index_factors(const int samples_size) const
return samples;
}
+#ifdef DEBUG
static void assert_sorted_array_in_range(Span<float> data, const float min, const float max)
{
BLI_assert(data.first() >= min);
@@ -327,6 +340,7 @@ static void assert_sorted_array_in_range(Span<float> data, const float min, cons
}
BLI_assert(data.last() <= max);
}
+#endif
/**
* Transform an array of sorted length parameters into index factors. The result is indices
@@ -342,7 +356,9 @@ static void assert_sorted_array_in_range(Span<float> data, const float min, cons
void Spline::sample_length_parameters_to_index_factors(MutableSpan<float> parameters) const
{
const Span<float> lengths = this->evaluated_lengths();
+#ifdef DEBUG
assert_sorted_array_in_range(parameters, 0.0f, this->length());
+#endif
/* 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). */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a3cb0215406..6c1a141448f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1363,14 +1363,8 @@ typedef struct NodeGeometryCurveResample {
} NodeGeometryCurveResample;
typedef struct NodeGeometryCurveDeform {
- /* GeometryNodeCurveDeformMode. */
- uint8_t input_mode;
/* GeometryNodeCurveDeformAxis. */
uint8_t axis;
- /* GeometryNodeAttributeInputMode (float or attribute). */
- uint8_t attribute_input_type;
-
- char _pad[5];
} NodeGeometryCurveDeform;
typedef struct NodeGeometryAttributeTransfer {
@@ -1891,11 +1885,6 @@ typedef enum GeometryNodeAttributeTransferMapMode {
GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST = 1,
} GeometryNodeAttributeTransferMapMode;
-typedef enum GeometryNodeCurveDeformMode {
- GEO_NODE_CURVE_DEFORM_POSITION = 0,
- GEO_NODE_CURVE_DEFORM_ATTRIBUTE = 1,
-} GeometryNodeCurveDeformMode;
-
typedef enum GeometryNodeCurveDeformAxis {
GEO_NODE_CURVE_DEFORM_POSX = 0,
GEO_NODE_CURVE_DEFORM_POSY = 1,
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 5dea9a69ff7..1a0a6a9514d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9846,12 +9846,6 @@ static void def_geo_curve_deform(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem mode_items[] = {
- {GEO_NODE_CURVE_DEFORM_POSITION, "POSITION", 0, "Position", ""},
- {GEO_NODE_CURVE_DEFORM_ATTRIBUTE, "ATTRIBUTE", 0, "Attribute", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
static const EnumPropertyItem axis_items[] = {
{GEO_NODE_CURVE_DEFORM_POSX, "POS_X", 0, "X", ""},
{GEO_NODE_CURVE_DEFORM_POSY, "POS_Y", 0, "Y", ""},
@@ -9864,20 +9858,10 @@ static void def_geo_curve_deform(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeGeometryCurveDeform", "storage");
- prop = RNA_def_property(srna, "input_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, mode_items);
- RNA_def_property_ui_text(prop, "Input Mode", "How to specify the curve parameter at each point");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, axis_items);
RNA_def_property_ui_text(prop, "Position Axis", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "attribute_input_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Attribute Input Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_geo_attribute_transfer(StructRNA *srna)
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 20dbb299767..1019839c4c7 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -24,6 +24,7 @@
#include <string.h>
#include "BLI_utildefines.h"
+#include "PIL_time.h"
#include "BLT_translation.h"
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 7c60eb6debf..e5227c38156 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
@@ -16,6 +16,7 @@
#include "BLI_array.hh"
#include "BLI_float4x4.hh"
+#include "BLI_resource_scope.hh"
#include "BLI_task.hh"
#include "BLI_timeit.hh"
@@ -36,7 +37,8 @@ static bNodeSocketTemplate geo_node_curve_deform_in[] = {
{SOCK_GEOMETRY, N_("Curve")},
{SOCK_STRING, N_("Factor")},
{SOCK_FLOAT, N_("Factor"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_BOOLEAN, N_("Stretch to Fit")},
+ {SOCK_BOOLEAN, N_("Use Bounds")},
+ {SOCK_BOOLEAN, N_("Stretch")},
{-1, ""},
};
@@ -47,19 +49,7 @@ static bNodeSocketTemplate geo_node_curve_deform_out[] = {
static void geo_node_curve_deform_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- const bNode *node = (bNode *)ptr->data;
- NodeGeometryCurveDeform &node_storage = *(NodeGeometryCurveDeform *)node->storage;
- const GeometryNodeCurveDeformMode mode = (GeometryNodeCurveDeformMode)node_storage.input_mode;
-
uiItemR(layout, ptr, "axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
-
- uiItemR(layout, ptr, "input_mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
-
- if (mode == GEO_NODE_CURVE_DEFORM_ATTRIBUTE) {
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "attribute_input_type", 0, IFACE_("Factor"), ICON_NONE);
- }
}
static void geo_node_curve_deform_init(bNodeTree *UNUSED(tree), bNode *node)
@@ -67,48 +57,64 @@ static void geo_node_curve_deform_init(bNodeTree *UNUSED(tree), bNode *node)
NodeGeometryCurveDeform *data = (NodeGeometryCurveDeform *)MEM_callocN(
sizeof(NodeGeometryCurveDeform), __func__);
- data->input_mode = GEO_NODE_CURVE_DEFORM_POSITION;
data->axis = GEO_NODE_CURVE_DEFORM_POSX;
- data->attribute_input_type = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
node->storage = data;
}
namespace blender::nodes {
-static void geo_node_curve_deform_update(bNodeTree *UNUSED(ntree), bNode *node)
+static constexpr int deform_axis_index(const GeometryNodeCurveDeformAxis axis)
{
- NodeGeometryCurveDeform &node_storage = *(NodeGeometryCurveDeform *)node->storage;
- const GeometryNodeCurveDeformMode mode = (GeometryNodeCurveDeformMode)node_storage.input_mode;
-
- bNodeSocket *attribute_socket = ((bNodeSocket *)node->inputs.first)->next->next;
+ 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 0;
+}
- nodeSetSocketAvailability(attribute_socket, mode == GEO_NODE_CURVE_DEFORM_ATTRIBUTE);
- update_attribute_input_socket_availabilities(
- *node,
- "Factor",
- (GeometryNodeAttributeInputMode)node_storage.attribute_input_type,
- mode == GEO_NODE_CURVE_DEFORM_ATTRIBUTE);
+static constexpr int deform_next_axis_index(const GeometryNodeCurveDeformAxis axis)
+{
+ switch (axis) {
+ case GEO_NODE_CURVE_DEFORM_POSX:
+ case GEO_NODE_CURVE_DEFORM_NEGX:
+ return 1;
+ case GEO_NODE_CURVE_DEFORM_POSY:
+ case GEO_NODE_CURVE_DEFORM_NEGY:
+ return 2;
+ case GEO_NODE_CURVE_DEFORM_POSZ:
+ case GEO_NODE_CURVE_DEFORM_NEGZ:
+ return 0;
+ }
+ BLI_assert_unreachable();
+ return 0;
}
-enum class Axis { X, Y, Z };
-static Axis axis_from_deform_axis(const GeometryNodeCurveDeformAxis axis)
+static constexpr int deform_other_axis_index(const GeometryNodeCurveDeformAxis axis)
{
switch (axis) {
case GEO_NODE_CURVE_DEFORM_POSX:
case GEO_NODE_CURVE_DEFORM_NEGX:
- return Axis::X;
+ return 2;
case GEO_NODE_CURVE_DEFORM_POSY:
case GEO_NODE_CURVE_DEFORM_NEGY:
- return Axis::Y;
+ return 0;
case GEO_NODE_CURVE_DEFORM_POSZ:
case GEO_NODE_CURVE_DEFORM_NEGZ:
- return Axis::Z;
+ return 1;
}
BLI_assert_unreachable();
- return Axis::X;
+ return 0;
}
-static bool axis_is_negative(const GeometryNodeCurveDeformAxis axis)
+static constexpr bool axis_is_negative(const GeometryNodeCurveDeformAxis axis)
{
switch (axis) {
case GEO_NODE_CURVE_DEFORM_POSX:
@@ -124,31 +130,39 @@ static bool axis_is_negative(const GeometryNodeCurveDeformAxis axis)
return false;
}
-struct SplineDataInput {
+struct SplineDeformInput {
const Spline &spline;
Span<float3> positions;
Span<float3> tangents;
Span<float3> normals;
GVArray_Typed<float> radii;
+ float total_length;
+ bool use_stretch;
+ bool use_bounds;
};
-static float3 deform_position(const SplineDataInput &in,
- const float index_factor,
+static float3 deform_position(const SplineDeformInput &in,
+ const Spline::LookupResult &lookup,
const float cotangent_factor,
- const float normal_factor)
+ const float normal_factor,
+ const bool is_negative)
{
- const Spline::LookupResult interp = in.spline.lookup_data_from_index_factor(index_factor);
- const int index = interp.evaluated_index;
- const int next = interp.next_evaluated_index;
- const float factor = interp.factor;
+ const int index = lookup.evaluated_index;
+ const int next = lookup.next_evaluated_index;
+ const float factor = lookup.factor;
+ const float clamped = std::clamp(lookup.factor, 0.0f, 1.0f);
const float3 position = float3::interpolate(in.positions[index], in.positions[next], factor);
- const float3 tangent = float3::interpolate(in.tangents[index], in.tangents[next], factor);
- const float3 normal = float3::interpolate(in.normals[index], in.normals[next], factor);
+ const float3 tangent = float3::interpolate(in.tangents[index], in.tangents[next], clamped);
+ const float3 normal = float3::interpolate(in.normals[index], in.normals[next], clamped);
const float3 cotangent = float3::cross(tangent, normal).normalized();
- const float radius = interpf(in.radii[next], in.radii[index], factor);
+ const float radius = interpf(in.radii[next], in.radii[index], clamped);
+
+ if (is_negative) {
+ return position + (cotangent * cotangent_factor + normal * normal_factor) * radius;
+ }
- return position + (cotangent * cotangent_factor + normal * normal_factor) * radius;
+ return position - (cotangent * cotangent_factor + normal * normal_factor) * radius;
}
struct Bounds {
@@ -167,240 +181,111 @@ static Bounds position_bounds(const Span<float3> positions)
return {min, max, float3::safe_divide(float3(1), max - min)};
}
-static void spline_deform(const SplineDataInput &spline_data,
- const Span<float> index_factors,
- const Span<int> indices,
- const Axis axis,
- const Bounds &bounds,
- MutableSpan<float3> positions)
+static Bounds dummy_parameter_bounds(const GeometryNodeCurveDeformAxis deform_axis)
{
- switch (axis) {
- case Axis::X:
- parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const float3 co = (positions[indices[i]] - bounds.min) * bounds.inv_size - float3(0.5f);
- positions[indices[i]] = deform_position(spline_data, index_factors[i], co.y, co.z);
- }
- });
- break;
- case Axis::Y:
- parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const float3 co = (positions[indices[i]] - bounds.min) * bounds.inv_size - float3(0.5f);
- positions[indices[i]] = deform_position(spline_data, index_factors[i], co.z, co.x);
- }
- });
- break;
- case Axis::Z:
- parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const float3 co = (positions[indices[i]] - bounds.min) * bounds.inv_size - float3(0.5f);
- positions[indices[i]] = deform_position(spline_data, index_factors[i], co.x, co.y);
- }
- });
- break;
+ if (axis_is_negative(deform_axis)) {
+ return {float3(-1), float3(0), float3(-1)};
}
+ return {float3(0), float3(1), float3(1)};
}
-static void retrieve_position_parameters(const Span<float3> positions,
- const Axis axis,
- MutableSpan<float> parameters,
- MutableSpan<int> indices)
+static float process_parameter(const float3 position,
+ const int axis_index,
+ const bool is_negative,
+ const SplineDeformInput &input,
+ const Bounds &bounds)
{
- Span co{positions};
- switch (axis) {
- case Axis::X:
- std::sort(indices.begin(), indices.end(), [&](int a, int b) { return co[a].x < co[b].x; });
- parallel_for(IndexRange(positions.size()), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = positions[indices[i]].x;
- }
- });
- break;
- case Axis::Y:
- std::sort(indices.begin(), indices.end(), [&](int a, int b) { return co[a].y < co[b].y; });
- parallel_for(IndexRange(positions.size()), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = positions[indices[i]].y;
- }
- });
- break;
- case Axis::Z:
- std::sort(indices.begin(), indices.end(), [&](int a, int b) { return co[a].z < co[b].z; });
- parallel_for(IndexRange(positions.size()), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = positions[indices[i]].z;
- }
- });
- break;
+ const float parameter = is_negative ? -(position[axis_index] - bounds.max[axis_index]) :
+ position[axis_index] - bounds.min[axis_index];
+ if (input.use_stretch) {
+ return parameter * bounds.inv_size[axis_index] * input.total_length;
}
+ return parameter;
}
-static void retrieve_attribute_parameters(const GVArray_Typed<float> attribute,
- const float total_length,
- MutableSpan<float> parameters,
- MutableSpan<int> indices)
-{
- VArray_Span<float> span{*attribute};
-
- std::sort(indices.begin(), indices.end(), [&](int a, int b) { return span[a] < span[b]; });
-
- parallel_for(IndexRange(attribute.size()), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = span[indices[i]] * total_length;
- }
- });
-}
-
-static void process_parameters(const GeoNodeExecParams &params,
- const GeometryNodeCurveDeformAxis deform_axis,
- const float total_length,
- MutableSpan<float> parameters,
- MutableSpan<int> indices)
-{
- const int size = parameters.size();
- if (params.get_input<bool>("Stretch to Fit")) {
- const double min = parameters.first();
- const double max = parameters.last();
- const double parameter_range = max - min;
- const double factor = (parameter_range == 0.0f) ? 0.0f : total_length / parameter_range;
- parallel_for(IndexRange(size), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = (double(parameters[i]) - min) * factor;
- }
- });
- /* Prevent overflow in some cases. */
- parameters.last() = total_length;
- }
- else {
- parallel_for(IndexRange(size), 2048, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = std::clamp(parameters[i], 0.0f, total_length);
- }
- });
- }
-
- /* TODO: Broken. */
- /* Reverse parameters if necessary (also the indices to maintain the sorted input to deform). */
- if (axis_is_negative(deform_axis)) {
- parallel_for(IndexRange(size), 1024, [&](IndexRange range) {
- for (const int i : range) {
- parameters[i] = total_length - parameters[size - i - 1];
- indices[i] = indices[size - i - 1];
- }
- });
- }
-}
-
-// struct ExtrapolationSpans {
-// Span<int> start;
-// Span<int> spline;
-// Span<int> end;
-// };
-// static ExtrapolationSpans find_extrapolation_points(const Span<float> parameters,
-// const Span<int> indices,
-// const float total_length)
-// {
-// const float *start = std::lower_bound(parameters.begin(), parameters.end(), 0.0f);
-// const float *end = std::lower_bound(parameters.begin(), parameters.end(), total_length);
-// const int start_index = start - parameters.begin();
-// const int end_index = end - parameters.begin();
-
-// return {indices.take_front(start_index),
-// indices.slice(start_index, end_index - start_index),
-// indices.take_back(indices.size() - end_index)};
-// }
-
static void execute_on_component(const GeoNodeExecParams &params,
- const CurveEval &curve,
+ const SplineDeformInput &input,
GeometryComponent &component)
{
const NodeGeometryCurveDeform &node_storage = *(NodeGeometryCurveDeform *)params.node().storage;
- const GeometryNodeCurveDeformMode mode = (GeometryNodeCurveDeformMode)node_storage.input_mode;
const GeometryNodeCurveDeformAxis deform_axis = (GeometryNodeCurveDeformAxis)node_storage.axis;
- const Axis axis = axis_from_deform_axis(deform_axis);
-
- const Spline &spline = *curve.splines().first();
- const float total_length = spline.length();
+ const int axis_index = deform_axis_index(deform_axis);
+ const int next_axis = deform_next_axis_index(deform_axis);
+ const int other_axis = deform_other_axis_index(deform_axis);
+ const bool is_negative = axis_is_negative(deform_axis);
- const int size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
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();
const Bounds bounds = position_bounds(positions);
+ const Bounds parameter_bounds = input.use_bounds ? bounds : dummy_parameter_bounds(deform_axis);
- /* #sample_length_parameters_to_index_factors requires an array of sorted parameters.
- * Sort indices based on the parameters before processing, build the parameters final
- * parameters, then use the indices to map back to the orignal positions. */
- Array<float> parameters(size);
- Array<int> sorted_indices(size);
- for (const int i : sorted_indices.index_range()) {
- sorted_indices[i] = i;
- }
-
- switch (mode) {
- case GEO_NODE_CURVE_DEFORM_POSITION: {
- retrieve_position_parameters(positions, axis, parameters, sorted_indices);
- break;
- }
- case GEO_NODE_CURVE_DEFORM_ATTRIBUTE: {
- retrieve_attribute_parameters(
- params.get_input_attribute<float>("Factor", component, ATTR_DOMAIN_POINT, 0.0f),
- total_length,
- parameters,
- sorted_indices);
- break;
+ parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
+ for (const int i : range) {
+ const float parameter = process_parameter(
+ positions[i], axis_index, is_negative, input, parameter_bounds);
+ std::cout << "Parameter: " << parameter << "\n";
+ const Spline::LookupResult lookup = input.spline.lookup_evaluated_length(parameter);
+
+ const float3 co = (positions[i] - bounds.min) * bounds.inv_size * 2.0f - float3(1);
+ if (is_negative) {
+ positions[i] = deform_position(input, lookup, co[next_axis], co[other_axis], is_negative);
+ }
+ else {
+ positions[i] = deform_position(input, lookup, co[other_axis], co[next_axis], is_negative);
+ }
}
- }
-
- process_parameters(params, deform_axis, total_length, parameters, sorted_indices);
-
- const SplineDataInput spline_data{spline,
- spline.evaluated_positions(),
- spline.evaluated_tangents(),
- spline.evaluated_normals(),
- spline.interpolate_to_evaluated_points(spline.radii())};
-
- // const ExtrapolationSpans index_spans = find_extrapolation_points(
- // parameters, sorted_indices, total_length);
-
- spline.sample_length_parameters_to_index_factors(parameters);
- spline_deform(spline_data, parameters, sorted_indices, axis, bounds, positions);
- // deform_start_extrapolation(spline_data, parameters, index_spans.start, axis);
+ });
position_attribute.save();
}
static void geo_node_curve_deform_exec(GeoNodeExecParams params)
{
- GeometrySet deform_geometry_set = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
GeometrySet curve_geometry_set = params.extract_input<GeometrySet>("Curve");
- deform_geometry_set = bke::geometry_set_realize_instances(deform_geometry_set);
+ geometry_set = bke::geometry_set_realize_instances(geometry_set);
/* TODO: Theoretically this could be easily avoided. */
curve_geometry_set = bke::geometry_set_realize_instances(curve_geometry_set);
const CurveEval *curve = curve_geometry_set.get_curve_for_read();
if (curve == nullptr || curve->splines().size() == 0) {
- params.set_output("Geometry", deform_geometry_set);
+ params.set_output("Geometry", geometry_set);
+ return;
+ }
+
+ const Spline &spline = *curve->splines().first();
+ const float total_length = spline.length();
+ if (total_length == 0.0f) {
+ params.set_output("Geometry", geometry_set);
return;
}
- if (deform_geometry_set.has<MeshComponent>()) {
+ const SplineDeformInput spline_data{spline,
+ spline.evaluated_positions(),
+ spline.evaluated_tangents(),
+ spline.evaluated_normals(),
+ spline.interpolate_to_evaluated_points(spline.radii()),
+ total_length,
+ params.extract_input<bool>("Stretch"),
+ params.extract_input<bool>("Use Bounds")};
+
+ if (geometry_set.has<MeshComponent>()) {
execute_on_component(
- params, *curve, deform_geometry_set.get_component_for_write<MeshComponent>());
+ params, spline_data, geometry_set.get_component_for_write<MeshComponent>());
}
- if (deform_geometry_set.has<PointCloudComponent>()) {
+ if (geometry_set.has<PointCloudComponent>()) {
execute_on_component(
- params, *curve, deform_geometry_set.get_component_for_write<PointCloudComponent>());
+ params, spline_data, geometry_set.get_component_for_write<PointCloudComponent>());
}
- if (deform_geometry_set.has<CurveComponent>()) {
+ if (geometry_set.has<CurveComponent>()) {
execute_on_component(
- params, *curve, deform_geometry_set.get_component_for_write<CurveComponent>());
+ params, spline_data, geometry_set.get_component_for_write<CurveComponent>());
}
- params.set_output("Geometry", deform_geometry_set);
+ params.set_output("Geometry", geometry_set);
}
} // namespace blender::nodes
@@ -415,7 +300,6 @@ void register_node_type_geo_curve_deform()
node_type_storage(
&ntype, "NodeGeometryCurveDeform", node_free_standard_storage, node_copy_standard_storage);
node_type_init(&ntype, geo_node_curve_deform_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_deform_update);
ntype.geometry_node_execute = blender::nodes::geo_node_curve_deform_exec;
nodeRegisterType(&ntype);
}