Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Matthews <johnny.matthews@gmail.com>2022-01-21 17:30:02 +0300
committerJohnny Matthews <johnny.matthews@gmail.com>2022-01-21 17:30:02 +0300
commit87c5423c5e1e7b1907a336ce6b74dfd44bde5526 (patch)
tree3632e5b8a905047c0cc26b229a5f9799d5152e96
parentd68ce0e4754e4f4fc957fa702a2fb34535129d8b (diff)
Geometry Nodes: New Output for Number of Mesh Islands
Adds a second output to the Mesh Islands node that shows the total number of islands as a field. Differential Revision: https://developer.blender.org/D13700
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc60
1 files changed, 58 insertions, 2 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
index 629279a44e9..ba4295017bc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
@@ -31,6 +31,9 @@ static void node_declare(NodeDeclarationBuilder &b)
.field_source()
.description(N_("Island indices are based on the order of the lowest-numbered vertex "
"contained in each island"));
+ b.add_output<decl::Int>(N_("Island Count"))
+ .field_source()
+ .description(N_("The total number of mesh islands"));
}
class IslandFieldInput final : public GeometryFieldInput {
@@ -81,10 +84,63 @@ class IslandFieldInput final : public GeometryFieldInput {
}
};
+class IslandCountFieldInput final : public GeometryFieldInput {
+ public:
+ IslandCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Count")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() != GEO_COMPONENT_TYPE_MESH) {
+ return {};
+ }
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ DisjointSet islands(mesh->totvert);
+ for (const int i : IndexRange(mesh->totedge)) {
+ islands.join(mesh->medge[i].v1, mesh->medge[i].v2);
+ }
+
+ Set<int> island_list;
+ for (const int i_vert : IndexRange(mesh->totvert)) {
+ const int64_t root = islands.find_root(i_vert);
+ island_list.add(root);
+ }
+
+ return VArray<int>::ForSingle(island_list.size(),
+ mesh_component.attribute_domain_size(domain));
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random hash. */
+ return 45634572457;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const IslandCountFieldInput *>(&other) != nullptr;
+ }
+};
+
static void node_geo_exec(GeoNodeExecParams params)
{
- Field<int> island_field{std::make_shared<IslandFieldInput>()};
- params.set_output("Index", std::move(island_field));
+ if (params.output_is_required("Index")) {
+ Field<int> field{std::make_shared<IslandFieldInput>()};
+ params.set_output("Index", std::move(field));
+ }
+ if (params.output_is_required("Island Count")) {
+ Field<int> field{std::make_shared<IslandCountFieldInput>()};
+ params.set_output("Island Count", std::move(field));
+ }
}
} // namespace blender::nodes::node_geo_input_mesh_island_cc