[Bf-blender-cvs] [3ec74ee2300] temp-geometry-nodes-curve-deform-node: Merge branch 'master' into temp-geometry-nodes-curve-deform-node
Hans Goudey
noreply at git.blender.org
Thu Jun 10 16:07:08 CEST 2021
Commit: 3ec74ee230045a22599b514dbcb28338b8882782
Author: Hans Goudey
Date: Wed Jun 9 16:35:36 2021 -0500
Branches: temp-geometry-nodes-curve-deform-node
https://developer.blender.org/rB3ec74ee230045a22599b514dbcb28338b8882782
Merge branch 'master' into temp-geometry-nodes-curve-deform-node
===================================================================
===================================================================
diff --cc source/blender/blenkernel/BKE_spline.hh
index efc165a7198,dfbe82f31fd..eb944fc8b5c
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@@ -172,10 -170,27 +172,29 @@@ class Spline
LookupResult lookup_evaluated_length(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;
+
LookupResult lookup_data_from_index_factor(const float index_factor) const;
+ void sample_based_on_index_factors(const blender::fn::GVArray &src,
+ blender::Span<float> index_factors,
+ blender::fn::GMutableSpan dst) const;
+ template<typename T>
+ void sample_based_on_index_factors(const blender::VArray<T> &src,
+ blender::Span<float> index_factors,
+ blender::MutableSpan<T> dst) const
+ {
+ this->sample_based_on_index_factors(
+ blender::fn::GVArray_For_VArray(src), index_factors, blender::fn::GMutableSpan(dst));
+ }
+ template<typename T>
+ void sample_based_on_index_factors(blender::Span<T> src,
+ blender::Span<float> index_factors,
+ blender::MutableSpan<T> dst) const
+ {
+ this->sample_based_on_index_factors(blender::VArray_For_Span(src), index_factors, dst);
+ }
+
/**
* Interpolate a virtual array of data with the size of the number of control points to the
* evaluated points. For poly splines, the lifetime of the returned virtual array must not
diff --cc source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
index 0ed6264faa1,00000000000..8f57ef2d64a
mode 100644,000000..100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_deform.cc
@@@ -1,291 -1,0 +1,291 @@@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_array.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_task.hh"
+#include "BLI_timeit.hh"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_geometry_set_instances.hh"
+#include "BKE_spline.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+using blender::float4x4;
+using blender::bke::GeometryInstanceGroup;
+
+static bNodeSocketTemplate geo_node_curve_deform_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_GEOMETRY, N_("Curve")},
+ {SOCK_STRING, N_("Factor")},
+ {SOCK_FLOAT, N_("Factor"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ // {SOCK_BOOLEAN, N_("Use Radius")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_curve_deform_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+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, "position_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)
+{
+ NodeGeometryCurveDeform *data = (NodeGeometryCurveDeform *)MEM_callocN(
+ sizeof(NodeGeometryCurveDeform), __func__);
+
+ data->input_mode = GEO_NODE_CURVE_DEFORM_POSITION;
+ data->position_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)
+{
+ NodeGeometryCurveDeform &node_storage = *(NodeGeometryCurveDeform *)node->storage;
+ const GeometryNodeCurveDeformMode mode = (GeometryNodeCurveDeformMode)node_storage.input_mode;
+
+ bNodeSocket *attribute_socket = ((bNodeSocket *)node->inputs.first)->next->next;
+
+ 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 void spline_deform(const Spline &spline,
+ Span<float> index_factors,
+ const int axis_index,
+ MutableSpan<float3> positions)
+{
+ Span<float3> spline_positions = spline.evaluated_positions();
+ Span<float3> spline_tangents = spline.evaluated_tangents();
+ Span<float3> spline_normals = spline.evaluated_normals();
- GVArray_Typed<float> radii{spline.interpolate_to_evaluated_points(spline.radii())};
++ GVArray_Typed<float> radii = spline.interpolate_to_evaluated_points(spline.radii());
+
+ parallel_for(positions.index_range(), 1024, [&](IndexRange range) {
+ for (const int i : range) {
+ const Spline::LookupResult interp = spline.lookup_data_from_index_factor(index_factors[i]);
+ 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(
+ {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));
+
+ float3 position = positions[i];
+ position[axis_index] = 0.0f;
+
+ positions[i] = matrix * position;
+ positions[i] += float3::interpolate(
+ spline_positions[index], spline_positions[next_index], factor);
+ }
+ });
+}
+
+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;
+}
+
+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;
+}
+
+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,
+ const CurveEval &curve,
+ GeometryComponent &component)
+{
+ 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) {
+ 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> position_attribute =
+ component.attribute_try_get_for_output<float3>("position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ MutableSpan<float3> positions = position_attribute.as_span();
+
+ Array<float> parameters(size);
+
+ if (mode == GEO_NODE_CURVE_DEFORM_POSITION) {
+ 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);
+ }
+ });
+ }
+ 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);
+ }
+ });
+ }
+ }
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list