Blender  V3.3
node_geo_set_position.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "DEG_depsgraph_query.h"
4 
5 #include "BLI_task.hh"
6 
7 #include "DNA_mesh_types.h"
8 #include "DNA_meshdata_types.h"
9 
10 #include "BKE_curves.hh"
11 
12 #include "node_geometry_util.hh"
13 
15 
17 {
18  b.add_input<decl::Geometry>(N_("Geometry"));
19  b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
20  b.add_input<decl::Vector>(N_("Position")).implicit_field();
21  b.add_input<decl::Vector>(N_("Offset")).supports_field().subtype(PROP_TRANSLATION);
22  b.add_output<decl::Geometry>(N_("Geometry"));
23 }
24 
26  const VArray<float3> &in_positions,
27  const VArray<float3> &in_offsets,
28  const IndexMask selection)
29 {
30  MutableAttributeAccessor attributes = *component.attributes_for_write();
31  AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position");
32 
33  const int grain_size = 10000;
34 
35  switch (component.type()) {
37  Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write();
39  if (in_positions.is_same(positions.varray)) {
40  devirtualize_varray(in_offsets, [&](const auto in_offsets) {
42  selection.index_range(), grain_size, [&](const IndexRange range) {
43  for (const int i : selection.slice(range)) {
44  const float3 offset = in_offsets[i];
45  add_v3_v3(mverts[i].co, offset);
46  }
47  });
48  });
49  }
50  else {
52  in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
54  selection.index_range(), grain_size, [&](const IndexRange range) {
55  for (const int i : selection.slice(range)) {
56  const float3 new_position = in_positions[i] + in_offsets[i];
57  copy_v3_v3(mverts[i].co, new_position);
58  }
59  });
60  });
61  }
62  break;
63  }
65  CurveComponent &curve_component = static_cast<CurveComponent &>(component);
66  Curves &curves_id = *curve_component.get_for_write();
68  if (attributes.contains("handle_right") && attributes.contains("handle_left")) {
69  SpanAttributeWriter<float3> handle_right_attribute =
70  attributes.lookup_or_add_for_write_span<float3>("handle_right", ATTR_DOMAIN_POINT);
71  SpanAttributeWriter<float3> handle_left_attribute =
72  attributes.lookup_or_add_for_write_span<float3>("handle_left", ATTR_DOMAIN_POINT);
73 
74  MutableVArraySpan<float3> out_positions_span = positions.varray;
76  in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
78  selection.index_range(), grain_size, [&](const IndexRange range) {
79  for (const int i : selection.slice(range)) {
80  const float3 new_position = in_positions[i] + in_offsets[i];
81  const float3 delta = new_position - out_positions_span[i];
82  handle_right_attribute.span[i] += delta;
83  handle_left_attribute.span[i] += delta;
84  out_positions_span[i] = new_position;
85  }
86  });
87  });
88 
89  out_positions_span.save();
90  handle_right_attribute.finish();
91  handle_left_attribute.finish();
92 
93  /* Automatic Bezier handles must be recalculated based on the new positions. */
94  curves.calculate_bezier_auto_handles();
95  break;
96  }
97  else {
99  }
100  }
101  default: {
102  MutableVArraySpan<float3> out_positions_span = positions.varray;
103  if (in_positions.is_same(positions.varray)) {
104  devirtualize_varray(in_offsets, [&](const auto in_offsets) {
106  selection.index_range(), grain_size, [&](const IndexRange range) {
107  for (const int i : selection.slice(range)) {
108  out_positions_span[i] += in_offsets[i];
109  }
110  });
111  });
112  }
113  else {
115  in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
117  selection.index_range(), grain_size, [&](const IndexRange range) {
118  for (const int i : selection.slice(range)) {
119  out_positions_span[i] = in_positions[i] + in_offsets[i];
120  }
121  });
122  });
123  }
124  out_positions_span.save();
125  break;
126  }
127  }
128 
129  positions.finish();
130 }
131 
133  const Field<bool> &selection_field,
134  const Field<float3> &position_field,
135  const Field<float3> &offset_field)
136 {
139  GeometryComponentFieldContext field_context{component, domain};
140  const int domain_size = component.attribute_domain_size(domain);
141  if (domain_size == 0) {
142  return;
143  }
144 
145  fn::FieldEvaluator evaluator{field_context, domain_size};
146  evaluator.set_selection(selection_field);
147  evaluator.add(position_field);
148  evaluator.add(offset_field);
149  evaluator.evaluate();
150 
151  const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
152 
153  const VArray<float3> positions_input = evaluator.get_evaluated<float3>(0);
154  const VArray<float3> offsets_input = evaluator.get_evaluated<float3>(1);
155  set_computed_position_and_offset(component, positions_input, offsets_input, selection);
156 }
157 
159 {
160  GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
161  Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
162  Field<float3> offset_field = params.extract_input<Field<float3>>("Offset");
163  Field<float3> position_field = params.extract_input<Field<float3>>("Position");
164 
169  if (geometry.has(type)) {
171  geometry.get_component_for_write(type), selection_field, position_field, offset_field);
172  }
173  }
174 
175  params.set_output("Geometry", std::move(geometry));
176 }
177 
178 } // namespace blender::nodes::node_geo_set_position_cc
179 
181 {
182  namespace file_ns = blender::nodes::node_geo_set_position_cc;
183 
184  static bNodeType ntype;
185 
189  nodeRegisterType(&ntype);
190 }
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_INSTANCE
Definition: BKE_attribute.h:32
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
Low-level operations for curves.
GeometryComponentType
@ GEO_COMPONENT_TYPE_MESH
@ GEO_COMPONENT_TYPE_POINT_CLOUD
@ GEO_COMPONENT_TYPE_INSTANCES
@ GEO_COMPONENT_TYPE_CURVE
#define GEO_NODE_SET_POSITION
Definition: BKE_node.h:1419
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define ATTR_FALLTHROUGH
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
@ PROP_TRANSLATION
Definition: RNA_types.h:154
IndexRange index_range() const
bool is_same(const VArrayCommon< T > &other) const
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
Definition: BKE_curves.hh:138
GAttributeWriter lookup_for_write(const AttributeIDRef &attribute_id)
void set_selection(Field< bool > selection)
Definition: FN_field.hh:366
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void set_computed_position_and_offset(GeometryComponent &component, const VArray< float3 > &in_positions, const VArray< float3 > &in_offsets, const IndexMask selection)
static void set_position_in_component(GeometryComponent &component, const Field< bool > &selection_field, const Field< float3 > &position_field, const Field< float3 > &offset_field)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
void devirtualize_varray(const VArray< T > &varray, const Func &func, bool enable=true)
void devirtualize_varray2(const VArray< T1 > &varray1, const VArray< T2 > &varray2, const Func &func, bool enable=true)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MutableSpan< float3 > positions
void register_node_type_geo_set_position()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
CurvesGeometry geometry
GeometryComponent & get_component_for_write(GeometryComponentType component_type)
bool has(const GeometryComponentType component_type) const
struct MVert * mvert
int totvert
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)