Blender  V2.93
node_geo_point_rotate.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "BLI_math_rotation.h"
18 
19 #include "UI_interface.h"
20 #include "UI_resources.h"
21 
22 #include "node_geometry_util.hh"
23 
25  {SOCK_GEOMETRY, N_("Geometry")},
26  {SOCK_STRING, N_("Axis")},
27  {SOCK_VECTOR, N_("Axis"), 0.0, 0.0, 1.0, 0.0, -FLT_MAX, FLT_MAX, PROP_XYZ},
28  {SOCK_STRING, N_("Angle")},
29  {SOCK_FLOAT, N_("Angle"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX, PROP_ANGLE},
30  {SOCK_STRING, N_("Rotation")},
31  {SOCK_VECTOR, N_("Rotation"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX, PROP_EULER},
32  {-1, ""},
33 };
34 
36  {SOCK_GEOMETRY, N_("Geometry")},
37  {-1, ""},
38 };
39 
41 {
42  NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
43 
44  uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
45  uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
46 
47  uiLayoutSetPropSep(layout, true);
48  uiLayoutSetPropDecorate(layout, false);
49 
50  uiLayout *col = uiLayoutColumn(layout, false);
52  uiItemR(col, ptr, "input_type_axis", 0, IFACE_("Axis"), ICON_NONE);
53  uiItemR(col, ptr, "input_type_angle", 0, IFACE_("Angle"), ICON_NONE);
54  }
55  else {
56  uiItemR(col, ptr, "input_type_rotation", 0, IFACE_("Rotation"), ICON_NONE);
57  }
58 }
59 
60 namespace blender::nodes {
61 
62 static void point_rotate__axis_angle__object_space(const int domain_size,
63  const Float3ReadAttribute &axis,
64  const FloatReadAttribute &angles,
65  MutableSpan<float3> rotations)
66 {
67  for (const int i : IndexRange(domain_size)) {
68  float old_rotation[3][3];
69  eul_to_mat3(old_rotation, rotations[i]);
70  float rotation[3][3];
71  axis_angle_to_mat3(rotation, axis[i], angles[i]);
72  float new_rotation[3][3];
73  mul_m3_m3m3(new_rotation, rotation, old_rotation);
74  mat3_to_eul(rotations[i], new_rotation);
75  }
76 }
77 
78 static void point_rotate__axis_angle__point_space(const int domain_size,
79  const Float3ReadAttribute &axis,
80  const FloatReadAttribute &angles,
81  MutableSpan<float3> rotations)
82 {
83  for (const int i : IndexRange(domain_size)) {
84  float old_rotation[3][3];
85  eul_to_mat3(old_rotation, rotations[i]);
86  float rotation[3][3];
87  axis_angle_to_mat3(rotation, axis[i], angles[i]);
88  float new_rotation[3][3];
89  mul_m3_m3m3(new_rotation, old_rotation, rotation);
90  mat3_to_eul(rotations[i], new_rotation);
91  }
92 }
93 
94 static void point_rotate__euler__object_space(const int domain_size,
95  const Float3ReadAttribute &eulers,
96  MutableSpan<float3> rotations)
97 {
98  for (const int i : IndexRange(domain_size)) {
99  float old_rotation[3][3];
100  eul_to_mat3(old_rotation, rotations[i]);
101  float rotation[3][3];
102  eul_to_mat3(rotation, eulers[i]);
103  float new_rotation[3][3];
104  mul_m3_m3m3(new_rotation, rotation, old_rotation);
105  mat3_to_eul(rotations[i], new_rotation);
106  }
107 }
108 
109 static void point_rotate__euler__point_space(const int domain_size,
110  const Float3ReadAttribute &eulers,
111  MutableSpan<float3> rotations)
112 {
113  for (const int i : IndexRange(domain_size)) {
114  float old_rotation[3][3];
115  eul_to_mat3(old_rotation, rotations[i]);
116  float rotation[3][3];
117  eul_to_mat3(rotation, eulers[i]);
118  float new_rotation[3][3];
119  mul_m3_m3m3(new_rotation, old_rotation, rotation);
120  mat3_to_eul(rotations[i], new_rotation);
121  }
122 }
123 
125  const GeoNodeExecParams &params)
126 {
127  const bNode &node = params.node();
128  const NodeGeometryRotatePoints &storage = *(const NodeGeometryRotatePoints *)node.storage;
129 
130  OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
131  "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
132  if (!rotation_attribute) {
133  return;
134  }
135 
136  MutableSpan<float3> rotations = rotation_attribute->get_span<float3>();
137  const int domain_size = rotations.size();
138 
140  Float3ReadAttribute axis = params.get_input_attribute<float3>(
141  "Axis", component, ATTR_DOMAIN_POINT, {0, 0, 1});
142  FloatReadAttribute angles = params.get_input_attribute<float>(
143  "Angle", component, ATTR_DOMAIN_POINT, 0);
144 
145  if (storage.space == GEO_NODE_POINT_ROTATE_SPACE_OBJECT) {
146  point_rotate__axis_angle__object_space(domain_size, axis, angles, rotations);
147  }
148  else {
149  point_rotate__axis_angle__point_space(domain_size, axis, angles, rotations);
150  }
151  }
152  else {
153  Float3ReadAttribute eulers = params.get_input_attribute<float3>(
154  "Rotation", component, ATTR_DOMAIN_POINT, {0, 0, 0});
155 
156  if (storage.space == GEO_NODE_POINT_ROTATE_SPACE_OBJECT) {
157  point_rotate__euler__object_space(domain_size, eulers, rotations);
158  }
159  else {
160  point_rotate__euler__point_space(domain_size, eulers, rotations);
161  }
162  }
163 
164  rotation_attribute.apply_span_and_save();
165 }
166 
168 {
169  GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
170 
171  geometry_set = geometry_set_realize_instances(geometry_set);
172 
173  if (geometry_set.has<MeshComponent>()) {
175  }
176  if (geometry_set.has<PointCloudComponent>()) {
178  }
179 
180  params.set_output("Geometry", geometry_set);
181 }
182 
184 {
186  sizeof(NodeGeometryRotatePoints), __func__);
187 
188  node_storage->type = GEO_NODE_POINT_ROTATE_TYPE_EULER;
193 
194  node->storage = node_storage;
195 }
196 
198 {
199  NodeGeometryRotatePoints *node_storage = (NodeGeometryRotatePoints *)node->storage;
201  *node,
202  "Axis",
206  *node,
207  "Angle",
211  *node,
212  "Rotation",
214  node_storage->type == GEO_NODE_POINT_ROTATE_TYPE_EULER);
215 }
216 
217 } // namespace blender::nodes
218 
220 {
221  static bNodeType ntype;
222 
223  geo_node_type_base(&ntype, GEO_NODE_POINT_ROTATE, "Point Rotate", NODE_CLASS_GEOMETRY, 0);
228  &ntype, "NodeGeometryRotatePoints", node_free_standard_storage, node_copy_standard_storage);
231  nodeRegisterType(&ntype);
232 }
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:43
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
#define GEO_NODE_POINT_ROTATE
Definition: BKE_node.h:1392
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4599
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void eul_to_mat3(float mat[3][3], const float eul[3])
void mat3_to_eul(float eul[3], const float mat[3][3])
void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle)
#define UNUSED(x)
#define IFACE_(msgid)
#define N_(msgid)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:126
@ CD_PROP_FLOAT3
@ GEO_NODE_POINT_ROTATE_SPACE_OBJECT
@ GEO_NODE_POINT_ROTATE_TYPE_EULER
@ GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_GEOMETRY
@ SOCK_STRING
GeometryNodeAttributeInputMode
@ GEO_NODE_ATTRIBUTE_INPUT_VECTOR
@ GEO_NODE_ATTRIBUTE_INPUT_FLOAT
@ PROP_XYZ
Definition: RNA_types.h:148
@ PROP_ANGLE
Definition: RNA_types.h:132
@ PROP_EULER
Definition: RNA_types.h:145
#define C
Definition: RandGen.cpp:39
@ UI_ITEM_R_EXPAND
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
constexpr int64_t size() const
Definition: BLI_span.hh:524
OperationNode * node
bNodeTree * ntree
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
TypedReadAttribute< float > FloatReadAttribute
TypedReadAttribute< float3 > Float3ReadAttribute
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
static void point_rotate__euler__object_space(const int domain_size, const Float3ReadAttribute &eulers, MutableSpan< float3 > rotations)
static void geo_node_point_rotate_update(bNodeTree *UNUSED(ntree), bNode *node)
void update_attribute_input_socket_availabilities(bNode &node, const StringRef name, const GeometryNodeAttributeInputMode mode, const bool name_is_available)
static void point_rotate_on_component(GeometryComponent &component, const GeoNodeExecParams &params)
static void point_rotate__axis_angle__object_space(const int domain_size, const Float3ReadAttribute &axis, const FloatReadAttribute &angles, MutableSpan< float3 > rotations)
static void geo_node_point_rotate_exec(GeoNodeExecParams params)
static void point_rotate__euler__point_space(const int domain_size, const Float3ReadAttribute &eulers, MutableSpan< float3 > rotations)
static void geo_node_point_rotate_init(bNodeTree *UNUSED(ntree), bNode *node)
static void point_rotate__axis_angle__point_space(const int domain_size, const Float3ReadAttribute &axis, const FloatReadAttribute &angles, MutableSpan< float3 > rotations)
void register_node_type_geo_point_rotate()
static bNodeSocketTemplate geo_node_point_rotate_out[]
static bNodeSocketTemplate geo_node_point_rotate_in[]
static void geo_node_point_rotate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:67
void node_free_standard_storage(bNode *node)
Definition: node_util.c:55
GeometryComponent & get_component_for_write(GeometryComponentType component_type)
bool has(const GeometryComponentType component_type) const
void * data
Definition: RNA_types.h:52
Compact definition of a node socket.
Definition: BKE_node.h:95
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:253
PointerRNA * ptr
Definition: wm_files.c:3157