Blender V4.3
node_geo_edges_to_face_groups.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 "BKE_mesh.hh"
6#include "BKE_mesh_mapping.hh"
7
9
10#include "node_geometry_util.hh"
11
13
15{
16 b.add_input<decl::Bool>("Boundary Edges")
17 .default_value(true)
18 .hide_value()
19 .supports_field()
20 .description("Edges used to split faces into separate groups");
21 b.add_output<decl::Int>("Face Group ID")
22 .dependent_field()
23 .description("Index of the face group inside each boundary edge region");
24}
25
27static void join_indices(AtomicDisjointSet &set, const Span<int> indices)
28{
29 for (const int i : indices.index_range().drop_back(1)) {
30 set.join(indices[i], indices[i + 1]);
31 }
32}
33
35 private:
36 Field<bool> non_boundary_edge_field_;
37
38 public:
40 : bke::MeshFieldInput(CPPType::get<int>(), "Edges to Face Groups"),
41 non_boundary_edge_field_(std::move(selection))
42 {
43 }
44
46 const AttrDomain domain,
47 const IndexMask & /*mask*/) const final
48 {
49 const bke::MeshFieldContext context{mesh, AttrDomain::Edge};
50 fn::FieldEvaluator evaluator{context, mesh.edges_num};
51 evaluator.add(non_boundary_edge_field_);
52 evaluator.evaluate();
53 const IndexMask non_boundary_edges = evaluator.get_evaluated_as_mask(0);
54
55 const OffsetIndices faces = mesh.faces();
56
57 Array<int> edge_to_face_offsets;
58 Array<int> edge_to_face_indices;
60 faces, mesh.corner_edges(), mesh.edges_num, edge_to_face_offsets, edge_to_face_indices);
61
62 AtomicDisjointSet islands(faces.size());
63 non_boundary_edges.foreach_index(
64 GrainSize(2048), [&](const int edge) { join_indices(islands, edge_to_face_map[edge]); });
65
66 Array<int> output(faces.size());
67 islands.calc_reduced_ids(output);
68
69 return mesh.attributes().adapt_domain(
70 VArray<int>::ForContainer(std::move(output)), AttrDomain::Face, domain);
71 }
72
73 uint64_t hash() const override
74 {
75 return non_boundary_edge_field_.hash();
76 }
77
78 bool is_equal_to(const fn::FieldNode &other) const override
79 {
80 if (const auto *other_field = dynamic_cast<const FaceSetFromBoundariesInput *>(&other)) {
81 return other_field->non_boundary_edge_field_ == non_boundary_edge_field_;
82 }
83 return false;
84 }
85
86 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
87 {
88 return AttrDomain::Face;
89 }
90};
91
93{
94 Field<bool> boundary_edges = params.extract_input<Field<bool>>("Boundary Edges");
95 Field<bool> non_boundary_edges = fn::invert_boolean_field(std::move(boundary_edges));
96 params.set_output(
97 "Face Group ID",
98 Field<int>(std::make_shared<FaceSetFromBoundariesInput>(std::move(non_boundary_edges))));
99}
100
101static void node_register()
102{
103 static blender::bke::bNodeType ntype;
104
106 &ntype, GEO_NODE_EDGES_TO_FACE_GROUPS, "Edges to Face Groups", NODE_CLASS_INPUT);
108 ntype.declare = node_declare;
109
111}
113
114} // namespace blender::nodes::node_geo_edges_to_face_groups_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:404
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define output
int add(GField field, GVArray *varray_ptr)
Definition field.cc:756
uint64_t hash() const
Definition FN_field.hh:127
void foreach_index(Fn &&fn) const
GVArray get_varray_for_context(const Mesh &mesh, const AttrDomain domain, const IndexMask &) const final
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
GroupedSpan< int > build_edge_to_face_map(OffsetIndices< int > faces, Span< int > corner_edges, int edges_num, Array< int > &r_offsets, Array< int > &r_indices)
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
Field< bool > invert_boolean_field(const Field< bool > &field)
Definition field.cc:525
static void join_indices(AtomicDisjointSet &set, const Span< int > indices)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
unsigned __int64 uint64_t
Definition stdint.h:90
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