Blender V5.0
node_geo_transform_geometry.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_base.h"
6#include "BLI_math_matrix.hh"
8
9#include "GEO_transform.hh"
10
11#include "node_geometry_util.hh"
12
14
17 "COMPONENTS",
18 0,
19 N_("Components"),
20 N_("Provide separate location, rotation and scale")},
21 {GEO_NODE_TRANSFORM_MODE_MATRIX, "MATRIX", 0, N_("Matrix"), N_("Use a transformation matrix")},
22 {0, nullptr, 0, nullptr, nullptr},
23};
24
26{
27 b.use_custom_socket_order();
28 b.allow_any_socket_order();
29
30 b.add_input<decl::Geometry>("Geometry")
31 .is_default_link_socket()
32 .description("Geometry to transform");
33 b.add_output<decl::Geometry>("Geometry").propagate_all().align_with_previous();
34 b.add_input<decl::Menu>("Mode")
35 .static_items(mode_items)
37 .description("How the transformation is specified");
38 b.add_input<decl::Vector>("Translation")
39 .subtype(PROP_TRANSLATION)
40 .usage_by_single_menu(GEO_NODE_TRANSFORM_MODE_COMPONENTS);
41 b.add_input<decl::Rotation>("Rotation").usage_by_single_menu(GEO_NODE_TRANSFORM_MODE_COMPONENTS);
42 b.add_input<decl::Vector>("Scale")
43 .default_value({1, 1, 1})
44 .subtype(PROP_XYZ)
45 .usage_by_single_menu(GEO_NODE_TRANSFORM_MODE_COMPONENTS);
46 b.add_input<decl::Matrix>("Transform").usage_by_single_menu(GEO_NODE_TRANSFORM_MODE_MATRIX);
47}
48
49static bool use_translate(const math::Quaternion &rotation, const float3 scale)
50{
51 if (math::angle_of(rotation).radian() > 1e-7f) {
52 return false;
53 }
54 if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 ||
55 compare_ff(scale.z, 1.0f, 1e-9f) != 1)
56 {
57 return false;
58 }
59 return true;
60}
61
64{
65 if (errors.bad_volume_transform) {
66 params.error_message_add(NodeWarningType::Warning,
67 TIP_("Invalid transformation for volume grids"));
68 }
69 else if (errors.volume_too_small) {
70 params.error_message_add(NodeWarningType::Warning,
71 TIP_("Volume scale is lower than permitted by OpenVDB"));
72 }
73}
74
76{
77 const auto mode = params.get_input<NodeGeometryTransformMode>("Mode");
78 GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
79
81 const float4x4 transform = params.extract_input<float4x4>("Transform");
82 if (auto errors = geometry::transform_geometry(geometry_set, transform)) {
83 report_errors(params, *errors);
84 }
85 }
86 else {
87 const float3 translation = params.extract_input<float3>("Translation");
88 const math::Quaternion rotation = params.extract_input<math::Quaternion>("Rotation");
89 const float3 scale = params.extract_input<float3>("Scale");
90
91 /* Use only translation if rotation and scale don't apply. */
92 if (use_translate(rotation, scale)) {
93 geometry::translate_geometry(geometry_set, translation);
94 }
95 else {
96 if (auto errors = geometry::transform_geometry(
97 geometry_set, math::from_loc_rot_scale<float4x4>(translation, rotation, scale)))
98 {
99 report_errors(params, *errors);
100 }
101 }
102 }
103
104 params.set_output("Geometry", std::move(geometry_set));
105}
106
107static void register_node()
108{
109 static blender::bke::bNodeType ntype;
110 geo_node_type_base(&ntype, "GeometryNodeTransform", GEO_NODE_TRANSFORM_GEOMETRY);
111 ntype.ui_name = "Transform Geometry";
112 ntype.ui_description = "Translate, rotate or scale the geometry";
113 ntype.enum_name_legacy = "TRANSFORM_GEOMETRY";
115 ntype.declare = node_declare;
118}
120
121} // namespace blender::nodes::node_geo_transform_geometry_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_TRANSFORM_GEOMETRY
MINLINE int compare_ff(float a, float b, float max_diff)
#define TIP_(msgid)
NodeGeometryTransformMode
@ GEO_NODE_TRANSFORM_MODE_MATRIX
@ GEO_NODE_TRANSFORM_MODE_COMPONENTS
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_XYZ
Definition RNA_types.hh:269
@ PROP_TRANSLATION
Definition RNA_types.hh:261
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void translate_geometry(bke::GeometrySet &geometry, const float3 translation)
std::optional< TransformGeometryErrors > transform_geometry(bke::GeometrySet &geometry, const float4x4 &transform)
QuaternionBase< float > Quaternion
AngleRadianBase< T > angle_of(const QuaternionBase< T > &q)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
static bool use_translate(const math::Quaternion &rotation, const float3 scale)
static void node_declare(NodeDeclarationBuilder &b)
static void report_errors(GeoNodeExecParams &params, const geometry::TransformGeometryErrors &errors)
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
#define N_(msgid)