Blender  V3.3
node_geo_input_mesh_island.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "DNA_mesh_types.h"
4 #include "DNA_meshdata_types.h"
5 
6 #include "BKE_mesh.h"
7 
8 #include "BLI_disjoint_set.hh"
9 
10 #include "node_geometry_util.hh"
11 
13 
15 {
16  b.add_output<decl::Int>(N_("Island Index"))
17  .field_source()
18  .description(N_("The index of the each vertex's island. Indices are based on the "
19  "lowest vertex index contained in each island"));
20  b.add_output<decl::Int>(N_("Island Count"))
21  .field_source()
22  .description(N_("The total number of mesh islands"));
23 }
24 
26  public:
27  IslandFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Index")
28  {
30  }
31 
33  const eAttrDomain domain,
34  IndexMask UNUSED(mask)) const final
35  {
36  if (component.type() != GEO_COMPONENT_TYPE_MESH) {
37  return {};
38  }
39  const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
40  const Mesh *mesh = mesh_component.get_for_read();
41  if (mesh == nullptr) {
42  return {};
43  }
44 
45  DisjointSet islands(mesh->totvert);
46  for (const int i : IndexRange(mesh->totedge)) {
47  islands.join(mesh->medge[i].v1, mesh->medge[i].v2);
48  }
49 
51  VectorSet<int> ordered_roots;
52  for (const int i : IndexRange(mesh->totvert)) {
53  const int64_t root = islands.find_root(i);
54  output[i] = ordered_roots.index_of_or_add(root);
55  }
56 
57  return mesh_component.attributes()->adapt_domain<int>(
59  }
60 
61  uint64_t hash() const override
62  {
63  /* Some random constant hash. */
64  return 635467354;
65  }
66 
67  bool is_equal_to(const fn::FieldNode &other) const override
68  {
69  return dynamic_cast<const IslandFieldInput *>(&other) != nullptr;
70  }
71 };
72 
74  public:
75  IslandCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Count")
76  {
78  }
79 
81  const eAttrDomain domain,
82  IndexMask UNUSED(mask)) const final
83  {
84  if (component.type() != GEO_COMPONENT_TYPE_MESH) {
85  return {};
86  }
87  const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
88  const Mesh *mesh = mesh_component.get_for_read();
89  if (mesh == nullptr) {
90  return {};
91  }
92 
93  DisjointSet islands(mesh->totvert);
94  for (const int i : IndexRange(mesh->totedge)) {
95  islands.join(mesh->medge[i].v1, mesh->medge[i].v2);
96  }
97 
98  Set<int> island_list;
99  for (const int i_vert : IndexRange(mesh->totvert)) {
100  const int64_t root = islands.find_root(i_vert);
101  island_list.add(root);
102  }
103 
104  return VArray<int>::ForSingle(island_list.size(),
105  mesh_component.attribute_domain_size(domain));
106  }
107 
108  uint64_t hash() const override
109  {
110  /* Some random hash. */
111  return 45634572457;
112  }
113 
114  bool is_equal_to(const fn::FieldNode &other) const override
115  {
116  return dynamic_cast<const IslandCountFieldInput *>(&other) != nullptr;
117  }
118 };
119 
121 {
122  if (params.output_is_required("Island Index")) {
123  Field<int> field{std::make_shared<IslandFieldInput>()};
124  params.set_output("Island Index", std::move(field));
125  }
126  if (params.output_is_required("Island Count")) {
127  Field<int> field{std::make_shared<IslandCountFieldInput>()};
128  params.set_output("Island Count", std::move(field));
129  }
130 }
131 
132 } // namespace blender::nodes::node_geo_input_mesh_island_cc
133 
135 {
137 
138  static bNodeType ntype;
142  nodeRegisterType(&ntype);
143 }
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
@ GEO_COMPONENT_TYPE_MESH
#define GEO_NODE_INPUT_MESH_ISLAND
Definition: BKE_node.h:1485
#define NODE_CLASS_INPUT
Definition: BKE_node.h:345
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define final(a, b, c)
Definition: BLI_hash.h:21
#define UNUSED(x)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
int attribute_domain_size(eAttrDomain domain) const
Definition: geometry_set.cc:63
const Mesh * get_for_read() const
std::optional< blender::bke::AttributeAccessor > attributes() const final
int64_t find_root(int64_t x)
void join(int64_t x, int64_t y)
int64_t size() const
Definition: BLI_set.hh:539
bool add(const Key &key)
Definition: BLI_set.hh:253
static VArray ForContainer(ContainerT container)
static VArray ForSingle(T value, const int64_t size)
int64_t index_of_or_add(const Key &key)
GVArray get_varray_for_context(const GeometryComponent &component, const eAttrDomain domain, IndexMask UNUSED(mask)) const final
GVArray get_varray_for_context(const GeometryComponent &component, const eAttrDomain domain, IndexMask UNUSED(mask)) const final
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_geo_input_mesh_island()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
__int64 int64_t
Definition: stdint.h:89
unsigned __int64 uint64_t
Definition: stdint.h:90
unsigned int v1
unsigned int v2
struct MEdge * medge
int totedge
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)