Blender V4.3
node_geo_scale_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_math_matrix.h"
6#include "BLI_math_matrix.hh"
7
8#include "BLI_task.hh"
9
10#include "BKE_instances.hh"
11
12#include "node_geometry_util.hh"
13
15
17{
18 b.add_input<decl::Geometry>("Instances").only_instances();
19 b.add_input<decl::Bool>("Selection").default_value(true).hide_value().field_on_all();
20 b.add_input<decl::Vector>("Scale").subtype(PROP_XYZ).default_value({1, 1, 1}).field_on_all();
21 b.add_input<decl::Vector>("Center").subtype(PROP_TRANSLATION).field_on_all();
22 b.add_input<decl::Bool>("Local Space").default_value(true).field_on_all();
23 b.add_output<decl::Geometry>("Instances").propagate_all();
24}
25
27{
28 const bke::InstancesFieldContext context{instances};
29 fn::FieldEvaluator evaluator{context, instances.instances_num()};
30 evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
31 evaluator.add(params.extract_input<Field<float3>>("Scale"));
32 evaluator.add(params.extract_input<Field<float3>>("Center"));
33 evaluator.add(params.extract_input<Field<bool>>("Local Space"));
34 evaluator.evaluate();
35
36 const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
37 const VArray<float3> scales = evaluator.get_evaluated<float3>(0);
38 const VArray<float3> pivots = evaluator.get_evaluated<float3>(1);
39 const VArray<bool> local_spaces = evaluator.get_evaluated<bool>(2);
40
41 MutableSpan<float4x4> transforms = instances.transforms_for_write();
42
43 selection.foreach_index(GrainSize(512), [&](const int64_t i) {
44 const float3 pivot = pivots[i];
45 float4x4 &instance_transform = transforms[i];
46
47 if (local_spaces[i]) {
48 instance_transform *= math::from_location<float4x4>(pivot);
49 rescale_m4(instance_transform.ptr(), scales[i]);
50 instance_transform *= math::from_location<float4x4>(-pivot);
51 }
52 else {
53 const float4x4 original_transform = instance_transform;
54 instance_transform = math::from_location<float4x4>(pivot);
55 rescale_m4(instance_transform.ptr(), scales[i]);
56 instance_transform *= math::from_location<float4x4>(-pivot);
57 instance_transform *= original_transform;
58 }
59 });
60}
61
63{
64 GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
65 if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
66 scale_instances(params, *instances);
67 }
68 params.set_output("Instances", std::move(geometry_set));
69}
70
71static void node_register()
72{
73 static blender::bke::bNodeType ntype;
74
75 geo_node_type_base(&ntype, GEO_NODE_SCALE_INSTANCES, "Scale Instances", NODE_CLASS_GEOMETRY);
77 ntype.declare = node_declare;
79}
81
82} // namespace blender::nodes::node_geo_scale_instances_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
void rescale_m4(float mat[4][4], const float scale[3])
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_TRANSLATION
Definition RNA_types.hh:164
void set_selection(Field< bool > selection)
Definition FN_field.hh:385
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
MatT from_location(const typename MatT::loc_type &location)
static void scale_instances(GeoNodeExecParams &params, bke::Instances &instances)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
__int64 int64_t
Definition stdint.h:89
Instances * get_instances_for_write()
Defines a node type.
Definition BKE_node.hh:218
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
NodeDeclareFunction declare
Definition BKE_node.hh:347