Geometry Nodes: Select by Component node #104602

Open
Iliya Katushenock wants to merge 6 commits from mod_moder/blender:for_component_new into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 94 additions and 0 deletions
Showing only changes of commit 1bbd19ab9a - Show all commits

View File

@ -518,6 +518,7 @@ class NODE_MT_category_GEO_UTILITIES_FIELD(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeAccumulateField")
node_add_menu.add_node_type(layout, "GeometryNodeSelectByComponent")
node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex")
node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)

View File

@ -1541,6 +1541,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define GEO_NODE_IMAGE 1191
#define GEO_NODE_INTERPOLATE_CURVES 1192
#define GEO_NODE_EDGES_TO_FACE_GROUPS 1193
#define GEO_NODE_SELECT_BY_COMPONENT 1194
/** \} */

View File

@ -286,6 +286,7 @@ DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic,
DefNode(GeometryNode, GEO_NODE_BLUR_ATTRIBUTE, def_geo_blur_attribute, "BLUR_ATTRIBUTE", BlurAttribute, "Blur Attribute", "Mix attribute values of neighboring elements")
DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "Calculate the limits of a geometry's positions and generate a box mesh with those dimensions")
DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture,"CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation")
DefNode(GeometryNode, GEO_NODE_SELECT_BY_COMPONENT, 0, "SELECT_BY_COMPONENT", SelectByComponent, "Select by Component", "")
mod_moder marked this conversation as resolved Outdated

For the description, how about Find the type of the currently evaluated geometry?

For the description, how about `Find the type of the currently evaluated geometry`?
DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "Retrieve geometry instances from a collection")
DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "Create a mesh that encloses all points in the input geometry with the smallest number of points")
DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINT_SELECTION, 0, "CURVE_ENDPOINT_SELECTION", CurveEndpointSelection, "Endpoint Selection", "Provide a selection for an arbitrary number of endpoints in each spline")

View File

@ -149,6 +149,7 @@ set(SRC
nodes/node_geo_sample_uv_surface.cc
nodes/node_geo_scale_elements.cc
nodes/node_geo_scale_instances.cc
nodes/node_geo_select_by_component.cc
nodes/node_geo_self_object.cc
nodes/node_geo_separate_components.cc
nodes/node_geo_separate_geometry.cc

View File

@ -133,6 +133,7 @@ void register_geometry_nodes()
register_node_type_geo_sample_uv_surface();
register_node_type_geo_scale_elements();
register_node_type_geo_scale_instances();
register_node_type_geo_select_by_component();
register_node_type_geo_self_object();
register_node_type_geo_separate_components();
register_node_type_geo_separate_geometry();

View File

@ -130,6 +130,7 @@ void register_node_type_geo_sample_nearest();
void register_node_type_geo_sample_uv_surface();
void register_node_type_geo_scale_elements();
void register_node_type_geo_scale_instances();
void register_node_type_geo_select_by_component();
void register_node_type_geo_select_by_handle_type();
void register_node_type_geo_self_object();
void register_node_type_geo_separate_components();

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_geometry_set.h"
#include "BLI_index_mask.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_select_by_component_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Bool>(N_("Is Mesh")).field_source_reference_all();
b.add_output<decl::Bool>(N_("Is Curve")).field_source_reference_all();
mod_moder marked this conversation as resolved Outdated

I think Is Curves would be more consistent with the current design for namingfor (still have to update other nodes for that though).

I think `Is Curves` would be more consistent with the current design for namingfor (still have to update other nodes for that though).
b.add_output<decl::Bool>(N_("Is Point Cloud")).field_source_reference_all();
b.add_output<decl::Bool>(N_("Is Instances")).field_source_reference_all();
}
class SelectByComponentFieldInput final : public bke::GeometryFieldInput {
private:
const GeometryComponentType type_;
public:
SelectByComponentFieldInput(const GeometryComponentType type)
: bke::GeometryFieldInput(CPPType::get<bool>(), "Select by Component"), type_(type)
{
}
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
const IndexMask mask) const final
{
const GeometryComponentType context_component_type = context.type();
return VArray<bool>::ForSingle(context_component_type == type_, mask.min_array_size());
}
uint64_t hash() const override
{
return type_;
}
bool is_equal_to(const fn::FieldNode &other) const override
{
if (const SelectByComponentFieldInput *other_mask =
dynamic_cast<const SelectByComponentFieldInput *>(&other)) {
return other_mask->type_ == this->type_;
}
return false;
}
};
static void node_geo_exec(GeoNodeExecParams params)
{
if (params.output_is_required("Is Mesh")) {
params.set_output(
"Is Mesh",
Field<bool>{std::make_shared<SelectByComponentFieldInput>(GEO_COMPONENT_TYPE_MESH)});
}
if (params.output_is_required("Is Curve")) {
params.set_output(
"Is Curve",
Field<bool>{std::make_shared<SelectByComponentFieldInput>(GEO_COMPONENT_TYPE_CURVE)});
}
if (params.output_is_required("Is Point Cloud")) {
params.set_output("Is Point Cloud",
Field<bool>{std::make_shared<SelectByComponentFieldInput>(
GEO_COMPONENT_TYPE_POINT_CLOUD)});
}
if (params.output_is_required("Is Instances")) {
params.set_output(
"Is Instances",
Field<bool>{std::make_shared<SelectByComponentFieldInput>(GEO_COMPONENT_TYPE_INSTANCES)});
}
}
} // namespace blender::nodes::node_geo_select_by_component_cc
void register_node_type_geo_select_by_component()
{
namespace file_ns = blender::nodes::node_geo_select_by_component_cc;
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SELECT_BY_COMPONENT, "Select by Component", NODE_CLASS_CONVERTER);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
nodeRegisterType(&ntype);
}