Blender V4.3
node_geo_points_to_vertices.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_array_utils.hh"
6
8
9#include "BKE_customdata.hh"
10#include "BKE_mesh.hh"
11
12#include "node_geometry_util.hh"
13
15
17{
18 b.add_input<decl::Geometry>("Points").supported_type(GeometryComponent::Type::PointCloud);
19 b.add_input<decl::Bool>("Selection").default_value(true).field_on_all().hide_value();
20 b.add_output<decl::Geometry>("Mesh").propagate_all();
21}
22
23/* One improvement would be to move the attribute arrays directly to the mesh when possible. */
25 Field<bool> &selection_field,
26 const AttributeFilter &attribute_filter)
27{
28 const PointCloud *points = geometry_set.get_pointcloud();
29 if (points == nullptr) {
30 geometry_set.remove_geometry_during_modify();
31 return;
32 }
33 if (points->totpoint == 0) {
34 geometry_set.remove_geometry_during_modify();
35 return;
36 }
37
38 const bke::PointCloudFieldContext field_context{*points};
39 fn::FieldEvaluator selection_evaluator{field_context, points->totpoint};
40 selection_evaluator.add(selection_field);
41 selection_evaluator.evaluate();
42 const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
43
47 false,
48 attribute_filter,
49 attributes);
50
51 Mesh *mesh;
52 if (selection.size() == points->totpoint) {
53 /* Create a mesh without positions so the attribute can be shared. */
54 mesh = BKE_mesh_new_nomain(0, 0, 0, 0);
55 CustomData_free_layer_named(&mesh->vert_data, "position", mesh->verts_num);
56 mesh->verts_num = selection.size();
57 }
58 else {
59 mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0);
60 }
61
62 const AttributeAccessor src_attributes = points->attributes();
63 MutableAttributeAccessor dst_attributes = mesh->attributes_for_write();
64
65 for (MapItem<StringRef, AttributeKind> entry : attributes.items()) {
66 const StringRef id = entry.key;
67 const eCustomDataType data_type = entry.value.data_type;
68 const GAttributeReader src = src_attributes.lookup(id);
69 if (selection.size() == points->totpoint && src.sharing_info && src.varray.is_span()) {
71 *src.sharing_info);
72 dst_attributes.add(id, AttrDomain::Point, data_type, init);
73 }
74 else {
76 id, AttrDomain::Point, data_type);
77 array_utils::gather(src.varray, selection, dst.span);
78 dst.finish();
79 }
80 }
81
82 mesh->tag_loose_edges_none();
83 mesh->tag_overlapping_none();
84
85 geometry_set.replace_mesh(mesh);
87}
88
90{
91 GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
92 Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
93
94 geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
96 geometry_set, selection_field, params.get_attribute_filter("Mesh"));
97 });
98
99 params.set_output("Mesh", std::move(geometry_set));
100}
101
102static void node_register()
103{
104 static blender::bke::bNodeType ntype;
105
107 &ntype, GEO_NODE_POINTS_TO_VERTICES, "Points to Vertices", NODE_CLASS_GEOMETRY);
108 ntype.declare = node_declare;
111}
113
114} // namespace blender::nodes::node_geo_points_to_vertices_cc
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name, const int totelem)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
#define NOD_REGISTER_NODE(REGISTER_FUNC)
void init()
const void * data() const
GAttributeReader lookup(const StringRef attribute_id) const
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
int add(GField field, GVArray *varray_ptr)
Definition field.cc:756
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void geometry_set_points_to_vertices(GeometrySet &geometry_set, Field< bool > &selection_field, const AttributeFilter &attribute_filter)
static void node_declare(NodeDeclarationBuilder &b)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
const ImplicitSharingInfo * sharing_info
void gather_attributes_for_propagation(Span< GeometryComponent::Type > component_types, GeometryComponent::Type dst_component_type, bool include_instances, const AttributeFilter &attribute_filter, Map< StringRef, AttributeKind > &r_attributes) const
void keep_only_during_modify(Span< GeometryComponent::Type > component_types)
const PointCloud * get_pointcloud() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
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