Blender V5.0
node_geo_translate_instances.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_task.hh"
6
7#include "BLI_math_matrix.hh"
8
9#include "BKE_instances.hh"
10
11#include "node_geometry_util.hh"
12
14
16{
17 b.use_custom_socket_order();
18 b.allow_any_socket_order();
19 b.add_input<decl::Geometry>("Instances")
20 .only_instances()
21 .description("Instances to translate individually");
22 b.add_output<decl::Geometry>("Instances").propagate_all().align_with_previous();
23 b.add_input<decl::Bool>("Selection").default_value(true).hide_value().field_on_all();
24 b.add_input<decl::Vector>("Translation").subtype(PROP_TRANSLATION).field_on_all();
25 b.add_input<decl::Bool>("Local Space").default_value(true).field_on_all();
26}
27
29{
30 const bke::InstancesFieldContext context{instances};
31 fn::FieldEvaluator evaluator{context, instances.instances_num()};
32 evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
33 evaluator.add(params.extract_input<Field<float3>>("Translation"));
34 evaluator.add(params.extract_input<Field<bool>>("Local Space"));
35 evaluator.evaluate();
36
37 const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
38 const VArray<float3> translations = evaluator.get_evaluated<float3>(0);
39 const VArray<bool> local_spaces = evaluator.get_evaluated<bool>(1);
40
41 MutableSpan<float4x4> transforms = instances.transforms_for_write();
42
43 selection.foreach_index(GrainSize(1024), [&](const int64_t i) {
44 if (local_spaces[i]) {
45 transforms[i] *= math::from_location<float4x4>(translations[i]);
46 }
47 else {
48 transforms[i].location() += translations[i];
49 }
50 });
51}
52
54{
55 GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
56 if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
57 translate_instances(params, *instances);
58 }
59 params.set_output("Instances", std::move(geometry_set));
60}
61
62static void register_node()
63{
64 static blender::bke::bNodeType ntype;
65
66 geo_node_type_base(&ntype, "GeometryNodeTranslateInstances", GEO_NODE_TRANSLATE_INSTANCES);
67 ntype.ui_name = "Translate Instances";
68 ntype.ui_description = "Move top-level geometry instances in local or global space";
69 ntype.enum_name_legacy = "TRANSLATE_INSTANCES";
72 ntype.declare = node_declare;
74}
76
77} // namespace blender::nodes::node_geo_translate_instances_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_TRANSLATE_INSTANCES
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_TRANSLATION
Definition RNA_types.hh:261
long long int int64_t
int instances_num() const
Definition instances.cc:393
MutableSpan< float4x4 > transforms_for_write()
Definition instances.cc:235
void set_selection(Field< bool > selection)
Definition FN_field.hh:383
int add(GField field, GVArray *varray_ptr)
Definition field.cc:751
IndexMask get_evaluated_selection_as_mask() const
Definition field.cc:817
const GVArray & get_evaluated(const int field_index) const
Definition FN_field.hh:448
void foreach_index(Fn &&fn) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
MatT from_location(const typename MatT::loc_type &location)
static void translate_instances(GeoNodeExecParams &params, bke::Instances &instances)
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
Instances * get_instances_for_write()
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
i
Definition text_draw.cc:230