Blender V4.3
node_geo_input_mesh_face_neighbors.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
8#include "BLI_task.hh"
9
10#include "node_geometry_util.hh"
11
13
15{
16 b.add_output<decl::Int>("Vertex Count")
17 .field_source()
18 .description("Number of edges or points in the face");
19 b.add_output<decl::Int>("Face Count")
20 .field_source()
21 .description("Number of faces which share an edge with the face");
22}
23
25 const Span<int> indices,
26 const int max)
27{
28 int num = 0;
29 for (const int i : indices) {
30 num += values[i].size();
31 if (max <= num) {
32 return true;
33 }
34 }
35 return false;
36}
37
38static int unique_num(const GroupedSpan<int> values, const Span<int> indices)
39{
40 if (large_enough_total_size(values, indices, 100)) {
41 Set<int, 16> unique_values;
42 for (const int i : indices) {
43 unique_values.add_multiple(values[i]);
44 }
45 return unique_values.size();
46 }
47 Vector<int, 16> unique_values;
48 for (const int i : indices) {
49 unique_values.extend_non_duplicates(values[i]);
50 }
51 return unique_values.size();
52}
53
54static VArray<int> construct_neighbor_count_varray(const Mesh &mesh, const AttrDomain domain)
55{
56 const GroupedSpan<int> face_edges(mesh.faces(), mesh.corner_edges());
57
58 Array<int> offsets;
61 face_edges.offsets, face_edges.data, mesh.edges_num, offsets, indices);
62
63 Array<int> face_count(face_edges.size());
64 threading::parallel_for(face_edges.index_range(), 2048, [&](const IndexRange range) {
65 for (const int64_t face_i : range) {
66 face_count[face_i] = unique_num(edge_to_faces_map, face_edges[face_i]) - 1;
67 }
68 });
69 return mesh.attributes().adapt_domain<int>(
70 VArray<int>::ForContainer(std::move(face_count)), AttrDomain::Face, domain);
71}
72
74 public:
76 : bke::MeshFieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
77 {
78 category_ = Category::Generated;
79 }
80
82 const AttrDomain domain,
83 const IndexMask & /*mask*/) const final
84 {
85 return construct_neighbor_count_varray(mesh, domain);
86 }
87
88 uint64_t hash() const override
89 {
90 /* Some random constant hash. */
91 return 823543774;
92 }
93
94 bool is_equal_to(const fn::FieldNode &other) const override
95 {
96 return dynamic_cast<const FaceNeighborCountFieldInput *>(&other) != nullptr;
97 }
98
99 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
100 {
101 return AttrDomain::Face;
102 }
103};
104
105static VArray<int> construct_vertex_count_varray(const Mesh &mesh, const AttrDomain domain)
106{
107 const OffsetIndices faces = mesh.faces();
108 return mesh.attributes().adapt_domain<int>(
109 VArray<int>::ForFunc(faces.size(),
110 [faces](const int i) -> float { return faces[i].size(); }),
111 AttrDomain::Face,
112 domain);
113}
114
116 public:
117 FaceVertexCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Count Field")
118 {
119 category_ = Category::Generated;
120 }
121
123 const AttrDomain domain,
124 const IndexMask & /*mask*/) const final
125 {
126 return construct_vertex_count_varray(mesh, domain);
127 }
128
129 uint64_t hash() const override
130 {
131 /* Some random constant hash. */
132 return 236235463634;
133 }
134
135 bool is_equal_to(const fn::FieldNode &other) const override
136 {
137 return dynamic_cast<const FaceVertexCountFieldInput *>(&other) != nullptr;
138 }
139
140 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
141 {
142 return AttrDomain::Face;
143 }
144};
145
147{
148 Field<int> vertex_count_field{std::make_shared<FaceVertexCountFieldInput>()};
149 Field<int> neighbor_count_field{std::make_shared<FaceNeighborCountFieldInput>()};
150 params.set_output("Vertex Count", std::move(vertex_count_field));
151 params.set_output("Face Count", std::move(neighbor_count_field));
152}
153
154static void node_register()
155{
156 static blender::bke::bNodeType ntype;
158 &ntype, GEO_NODE_INPUT_MESH_FACE_NEIGHBORS, "Face Neighbors", NODE_CLASS_INPUT);
160 ntype.declare = node_declare;
163}
164NOD_REGISTER_NODE(node_register)
165
166} // namespace blender::nodes::node_geo_input_mesh_face_neighbors_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:404
#define NOD_REGISTER_NODE(REGISTER_FUNC)
int64_t size() const
Definition BLI_set.hh:564
void add_multiple(Span< Key > keys)
Definition BLI_set.hh:268
static VArray ForContainer(ContainerT container)
int64_t size() const
void extend_non_duplicates(Span< T > array)
GVArray get_varray_for_context(const Mesh &mesh, const AttrDomain domain, const IndexMask &) const final
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
static ushort indices[]
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_type_size_preset(bNodeType *ntype, eNodeSizePreset size)
Definition node.cc:4614
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static VArray< int > construct_vertex_count_varray(const Mesh &mesh, const AttrDomain domain)
static bool large_enough_total_size(const GroupedSpan< int > values, const Span< int > indices, const int max)
static VArray< int > construct_neighbor_count_varray(const Mesh &mesh, const AttrDomain domain)
static int unique_num(const GroupedSpan< int > values, const Span< int > indices)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
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