Geometry Nodes: Add Transform Order to the Transform Geometry node #110251

Closed
Charlie Jolly wants to merge 1 commits from CharlieJolly/blender:gn-transform-order into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 79 additions and 5 deletions

View File

@ -2181,6 +2181,15 @@ typedef enum NodeCompareMode {
NODE_COMPARE_MODE_DIRECTION = 4
} NodeCompareMode;
typedef enum NodeTransformOrder {
NODE_TRANSFORM_ORDER_SRT = 0,
NODE_TRANSFORM_ORDER_RST = 1,
NODE_TRANSFORM_ORDER_TSR = 2,
NODE_TRANSFORM_ORDER_TRS = 3,
NODE_TRANSFORM_ORDER_STR = 4,
NODE_TRANSFORM_ORDER_RTS = 5,
} NodeTransformOrder;
typedef enum NodeCompareOperation {
NODE_COMPARE_LESS_THAN = 0,
NODE_COMPARE_LESS_EQUAL = 1,

View File

@ -4766,6 +4766,27 @@ static void def_boolean_math(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_transform(StructRNA *srna)
{
static const EnumPropertyItem rna_enum_node_transform_order_items[] = {
{NODE_TRANSFORM_ORDER_SRT, "SRT", 0, "SRT", "Scale > Rotate > Translate"},
{NODE_TRANSFORM_ORDER_STR, "STR", 0, "STR", "Scale > Translate > Rotate"},
{NODE_TRANSFORM_ORDER_RST, "RST", 0, "RST", "Rotate > Scale > Translate"},
{NODE_TRANSFORM_ORDER_RTS, "RTS", 0, "RTS", "Rotate > Translate > Scale"},
{NODE_TRANSFORM_ORDER_TSR, "TSR", 0, "TSR", "Translate > Scale > Rotate"},
{NODE_TRANSFORM_ORDER_TRS, "TRS", 0, "TRS", "Translate > Rotate > Scale"},
{0, nullptr, 0, nullptr, nullptr},
};
PropertyRNA *prop;
prop = RNA_def_property(srna, "transform_order", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_transform_order_items);
RNA_def_property_ui_text(prop, "Transform Order", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_compare(StructRNA *srna)
{

View File

@ -436,7 +436,7 @@ DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_CURVE, 0, "SUBDIVIDE_CURVE", SubdivideC
DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_MESH, 0, "SUBDIVIDE_MESH", SubdivideMesh, "Subdivide Mesh", "Divide mesh faces into smaller ones without changing the shape or volume, using linear interpolation to place the new vertices")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface", "Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "Switch between two inputs")
DefNode(GeometryNode, GEO_NODE_TRANSFORM_GEOMETRY, 0, "TRANSFORM_GEOMETRY", Transform, "Transform Geometry", "Translate, rotate or scale the geometry")
DefNode(GeometryNode, GEO_NODE_TRANSFORM_GEOMETRY, def_transform, "TRANSFORM_GEOMETRY", Transform, "Transform Geometry", "Translate, rotate or scale the geometry")
DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances", "Move top-level geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "Convert all faces in a mesh to triangular faces")
DefNode(GeometryNode, GEO_NODE_TRIM_CURVE, def_geo_curve_trim, "TRIM_CURVE", TrimCurve, "Trim Curve", "Shorten curves by removing portions at the start or end")

View File

@ -23,6 +23,9 @@
#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "node_geometry_util.hh"
namespace blender::nodes {
@ -273,6 +276,11 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Geometry").propagate_all();
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_order", 0, "", ICON_NONE);
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@ -285,10 +293,45 @@ static void node_geo_exec(GeoNodeExecParams params)
translate_geometry_set(params, geometry_set, translation, *params.depsgraph());
}
else {
transform_geometry_set(params,
geometry_set,
math::from_loc_rot_scale<float4x4>(translation, rotation, scale),
*params.depsgraph());
const int transform_order = params.node().custom1;
BLI_assert(transform_order >= 0 && transform_order <= 5);
float4x4 mat = float4x4::identity();
/* Scale (S), Rotate (R), Translate (T)
* Transform Order transform_order 0-SRT, 1-RST, 2-TSR, 3-TRS, 4-STR, 5-RTS */
switch (transform_order) {
case NODE_TRANSFORM_ORDER_RST: { /* 1-RST */
mat = math::from_scale<float4x4>(scale) * math::from_rotation<float4x4>(rotation);
mat.location() = translation;
break;
}
case NODE_TRANSFORM_ORDER_TSR: { /* 2-TSR */
mat = math::from_rotation<float4x4>(rotation) * math::from_scale<float4x4>(scale) *
math::from_location<float4x4>(translation);
break;
}
case NODE_TRANSFORM_ORDER_TRS: { /* 3-TRS */
mat = math::from_scale<float4x4>(scale) * math::from_rotation<float4x4>(rotation) *
math::from_location<float4x4>(translation);
break;
}
case NODE_TRANSFORM_ORDER_STR: { /* 4-STR */
mat = math::from_rotation<float4x4>(rotation) *
math::from_location<float4x4>(translation) * math::from_scale<float4x4>(scale);
break;
}
case NODE_TRANSFORM_ORDER_RTS: { /* 5-RTS */
mat = math::from_scale<float4x4>(scale) * math::from_location<float4x4>(translation) *
math::from_rotation<float4x4>(rotation);
break;
}
case NODE_TRANSFORM_ORDER_SRT:
default: { /* 0-SRT Default */
mat = math::from_rotation<float4x4>(rotation) * math::from_scale<float4x4>(scale);
mat.location() = translation;
break;
}
}
transform_geometry_set(params, geometry_set, mat, *params.depsgraph());
}
params.set_output("Geometry", std::move(geometry_set));
@ -304,6 +347,7 @@ void register_node_type_geo_transform_geometry()
geo_node_type_base(
&ntype, GEO_NODE_TRANSFORM_GEOMETRY, "Transform Geometry", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}