Blender V5.0
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 "DNA_mesh_types.h"
6
7#include "BKE_mesh_mapping.hh"
8
9#include "BLI_task.hh"
10
11#include "node_geometry_util.hh"
12
14
16{
17 b.add_output<decl::Int>("Vertex Count")
18 .field_source()
19 .description("Number of edges or points in the face");
20 b.add_output<decl::Int>("Face Count")
21 .field_source()
22 .description("Number of faces which share an edge with the face");
23}
24
26 const Span<int> indices,
27 const int max)
28{
29 int num = 0;
30 for (const int i : indices) {
31 num += values[i].size();
32 if (max <= num) {
33 return true;
34 }
35 }
36 return false;
37}
38
39static int unique_num(const GroupedSpan<int> values, const Span<int> indices)
40{
41 if (large_enough_total_size(values, indices, 100)) {
42 Set<int, 16> unique_values;
43 for (const int i : indices) {
44 unique_values.add_multiple(values[i]);
45 }
46 return unique_values.size();
47 }
48 Vector<int, 16> unique_values;
49 for (const int i : indices) {
50 unique_values.extend_non_duplicates(values[i]);
51 }
52 return unique_values.size();
53}
54
56{
57 const GroupedSpan<int> face_edges(mesh.faces(), mesh.corner_edges());
58
59 Array<int> offsets;
62 face_edges.offsets, face_edges.data, mesh.edges_num, offsets, indices);
63
64 Array<int> face_count(face_edges.size());
65 threading::parallel_for(face_edges.index_range(), 2048, [&](const IndexRange range) {
66 for (const int64_t face_i : range) {
67 face_count[face_i] = unique_num(edge_to_faces_map, face_edges[face_i]) - 1;
68 }
69 });
70 return mesh.attributes().adapt_domain<int>(
71 VArray<int>::from_container(std::move(face_count)), AttrDomain::Face, domain);
72}
73
75 public:
77 : bke::MeshFieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
78 {
80 }
81
83 const AttrDomain domain,
84 const IndexMask & /*mask*/) const final
85 {
86 return construct_neighbor_count_varray(mesh, domain);
87 }
88
89 uint64_t hash() const override
90 {
91 /* Some random constant hash. */
92 return 823543774;
93 }
94
95 bool is_equal_to(const fn::FieldNode &other) const override
96 {
97 return dynamic_cast<const FaceNeighborCountFieldInput *>(&other) != nullptr;
98 }
99
100 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
101 {
102 return AttrDomain::Face;
103 }
104};
105
107{
108 const OffsetIndices faces = mesh.faces();
109 return mesh.attributes().adapt_domain<int>(
111 [faces](const int i) -> float { return faces[i].size(); }),
112 AttrDomain::Face,
113 domain);
114}
115
117 public:
118 FaceVertexCountFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Count Field")
119 {
121 }
122
124 const AttrDomain domain,
125 const IndexMask & /*mask*/) const final
126 {
127 return construct_vertex_count_varray(mesh, domain);
128 }
129
130 uint64_t hash() const override
131 {
132 /* Some random constant hash. */
133 return 236235463634;
134 }
135
136 bool is_equal_to(const fn::FieldNode &other) const override
137 {
138 return dynamic_cast<const FaceVertexCountFieldInput *>(&other) != nullptr;
139 }
140
141 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
142 {
143 return AttrDomain::Face;
144 }
145};
146
148{
149 Field<int> vertex_count_field{std::make_shared<FaceVertexCountFieldInput>()};
150 Field<int> neighbor_count_field{std::make_shared<FaceNeighborCountFieldInput>()};
151 params.set_output("Vertex Count", std::move(vertex_count_field));
152 params.set_output("Face Count", std::move(neighbor_count_field));
153}
154
155static void node_register()
156{
157 static blender::bke::bNodeType ntype;
159 &ntype, "GeometryNodeInputMeshFaceNeighbors", GEO_NODE_INPUT_MESH_FACE_NEIGHBORS);
160 ntype.ui_name = "Face Neighbors";
161 ntype.ui_description = "Retrieve topology information relating to each face of a mesh";
162 ntype.enum_name_legacy = "MESH_FACE_NEIGHBORS";
163 ntype.nclass = NODE_CLASS_INPUT;
164 ntype.declare = node_declare;
167}
168NOD_REGISTER_NODE(node_register)
169
170} // namespace blender::nodes::node_geo_input_mesh_face_neighbors_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:447
#define GEO_NODE_INPUT_MESH_FACE_NEIGHBORS
#define final(a, b, c)
Definition BLI_hash.h:19
ATTR_WARN_UNUSED_RESULT const size_t num
#define NOD_REGISTER_NODE(REGISTER_FUNC)
unsigned long long int uint64_t
AttributeSet attributes
static VArray from_func(const int64_t size, GetFunc get_func)
int64_t size() const
Definition BLI_set.hh:587
void add_multiple(Span< Key > keys)
Definition BLI_set.hh:287
static VArray from_container(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
static ushort indices[]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static char faces[256]
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:2416
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:93
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
int edges_num
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251