diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_spline.hh | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve_deform.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/spline_base.cc | 32 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 11 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 16 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_curve.c | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc | 356 |
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 ¶ms, - 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 ¶ms, - 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); } |