Geometry Nodes: new Set Instance Transform node

This node allows replacing the transformation of every instance by providing a matrix.

Before, this was only possible by using the Store Named Attribute node. It's more common
in Blender to have specialized built-in nodes for built-in attributes (e.g. Set Position, and Set ID).

Pull Request: https://projects.blender.org/blender/blender/pulls/121473
This commit is contained in:
Jacques Lucke 2024-05-28 16:34:37 +02:00
parent 6e50aebd74
commit 905aaf439c
5 changed files with 49 additions and 0 deletions

@ -317,6 +317,7 @@ class NODE_MT_geometry_node_GEO_INSTANCE(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeRotateInstances")
node_add_menu.add_node_type(layout, "GeometryNodeScaleInstances")
node_add_menu.add_node_type(layout, "GeometryNodeTranslateInstances")
node_add_menu.add_node_type(layout, "GeometryNodeSetInstanceTransform")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeInputInstanceRotation")
node_add_menu.add_node_type(layout, "GeometryNodeInputInstanceScale")

@ -1331,6 +1331,7 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index
#define GEO_NODE_TOOL_MOUSE_POSITION 2133
#define GEO_NODE_SAMPLE_GRID_INDEX 2134
#define GEO_NODE_TOOL_ACTIVE_ELEMENT 2135
#define GEO_NODE_SET_INSTANCE_TRANSFORM 2136
/** \} */

@ -458,6 +458,7 @@ DefNode(GeometryNode, GEO_NODE_SET_POSITION, 0, "SET_POSITION", SetPosition, "Se
DefNode(GeometryNode, GEO_NODE_SET_SHADE_SMOOTH, 0, "SET_SHADE_SMOOTH", SetShadeSmooth, "Set Shade Smooth", "Control the smoothness of mesh normals around each face by changing the \"shade smooth\" attribute")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_CYCLIC, 0, "SET_SPLINE_CYCLIC", SetSplineCyclic, "Set Spline Cyclic", "Control whether each spline loops back on itself by changing the \"cyclic\" attribute")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_RESOLUTION, 0, "SET_SPLINE_RESOLUTION", SetSplineResolution, "Set Spline Resolution", "Control how many evaluated points should be generated on every curve segment")
DefNode(GeometryNode, GEO_NODE_SET_INSTANCE_TRANSFORM, 0, "SET_INSTANCE_TRANSFORM", SetInstanceTransform, "Set Instance Transform", "Set the transformation matrix of every instance")
DefNode(GeometryNode, GEO_NODE_SIMULATION_INPUT, def_geo_simulation_input, "SIMULATION_INPUT", SimulationInput, "Simulation Input", "Input data for the simulation zone")
DefNode(GeometryNode, GEO_NODE_SIMULATION_OUTPUT, def_geo_simulation_output, "SIMULATION_OUTPUT", SimulationOutput, "Simulation Output", "Output data from the simulation zone")
DefNode(GeometryNode, GEO_NODE_SORT_ELEMENTS, 0, "SORT_ELEMENTS", SortElements, "Sort Elements", "Rearrange geometry elements, changing their indices")

@ -180,6 +180,7 @@ set(SRC
nodes/node_geo_set_curve_radius.cc
nodes/node_geo_set_curve_tilt.cc
nodes/node_geo_set_id.cc
nodes/node_geo_set_instance_transform.cc
nodes/node_geo_set_material.cc
nodes/node_geo_set_material_index.cc
nodes/node_geo_set_point_radius.cc

@ -0,0 +1,45 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_set_instance_transform_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Instances").only_instances();
b.add_input<decl::Bool>("Selection").default_value(true).hide_value().field_on_all();
b.add_input<decl::Matrix>("Transform").field_on_all();
b.add_output<decl::Geometry>("Instances").propagate_all();
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
Field<float4x4> transform_field = params.extract_input<Field<float4x4>>("Transform");
if (geometry_set.has_instances()) {
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
bke::try_capture_field_on_geometry(
instances, "instance_transform", AttrDomain::Instance, selection_field, transform_field);
}
params.set_output("Instances", std::move(geometry_set));
}
static void node_register()
{
static bke::bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_INSTANCE_TRANSFORM, "Set Instance Transform", NODE_CLASS_GEOMETRY);
ntype.geometry_node_execute = node_geo_exec;
ntype.declare = node_declare;
bke::node_type_size(&ntype, 160, 100, 700);
nodeRegisterType(&ntype);
}
NOD_REGISTER_NODE(node_register)
} // namespace blender::nodes::node_geo_set_instance_transform_cc