mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Geometry Nodes: Add Geometry Materials node
This adds a new `Geometry Materials` node that can get the list of materials from any geometry component that has them (i.e., Mesh, Point Cloud, Curve, Grease Pencil). <img width="259" alt="image.png" src="attachments/f2742cdf-aef1-443c-a41e-0809c7430f0b"> This is a follow up to a PR that I closed about a half year ago (https://projects.blender.org/blender/blender/pulls/144628) now that lists are out of experimental! Pull Request: https://projects.blender.org/blender/blender/pulls/161451 --------- Co-authored-by: Colin Basnett <5035660+cmbasnett@users.noreply.github.com>
This commit is contained in:
parent
1d51ce8478
commit
b3d62684bc
4 changed files with 110 additions and 0 deletions
|
|
@ -458,6 +458,8 @@ class NODE_MT_gn_material_base(node_add_menu.NodeMenu):
|
|||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
self.node_operator(layout, "GeometryNodeGeometryMaterials")
|
||||
layout.separator()
|
||||
self.node_operator(layout, "GeometryNodeReplaceMaterial")
|
||||
layout.separator()
|
||||
self.node_operator(layout, "GeometryNodeInputMaterialIndex")
|
||||
|
|
|
|||
|
|
@ -11003,6 +11003,7 @@ static void rna_def_nodes(BlenderRNA *brna)
|
|||
define("GeometryNode", "GeometryNodeJoinGeometry");
|
||||
define("GeometryNode", "GeometryNodeListGetItem");
|
||||
define("GeometryNode", "GeometryNodeListLength");
|
||||
define("GeometryNode", "GeometryNodeGeometryMaterials");
|
||||
define("GeometryNode", "GeometryNodeMaterialSelection");
|
||||
define("GeometryNode", "GeometryNodeMenuSwitch", def_geo_menu_switch);
|
||||
define("GeometryNode", "GeometryNodeMergeByDistance");
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ set(SRC
|
|||
nodes/node_geo_filter_list.cc
|
||||
nodes/node_geo_flip_faces.cc
|
||||
nodes/node_geo_foreach_geometry_element.cc
|
||||
nodes/node_geo_geometry_materials.cc
|
||||
nodes/node_geo_geometry_to_instance.cc
|
||||
nodes/node_geo_get_attribute_names.cc
|
||||
nodes/node_geo_get_bundle_item.cc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_material.hh"
|
||||
|
||||
#include "DNA_curves_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_pointcloud_types.h"
|
||||
|
||||
#include "NOD_geometry_nodes_list.hh"
|
||||
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
#include "UI_interface_icons.hh"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_geometry_materials {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Geometry>("Geometry"_ustr);
|
||||
b.add_input<decl::Menu>("Component Type"_ustr)
|
||||
.static_items(rna_enum_geometry_component_type_items,
|
||||
[](const EnumPropertyItem &item) {
|
||||
return ELEM(GeometryComponent::Type(item.value),
|
||||
GeometryComponent::Type::Mesh,
|
||||
GeometryComponent::Type::PointCloud,
|
||||
GeometryComponent::Type::Curve,
|
||||
GeometryComponent::Type::GreasePencil);
|
||||
})
|
||||
.optional_label();
|
||||
b.add_output<decl::Material>("Materials"_ustr).structure_type(StructureType::List);
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
const GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"_ustr);
|
||||
const GeometryComponent::Type component = params.extract_input<GeometryComponent::Type>(
|
||||
"Component Type"_ustr);
|
||||
|
||||
Material **materials = nullptr;
|
||||
int count = 0;
|
||||
|
||||
switch (component) {
|
||||
case GeometryComponent::Type::Curve: {
|
||||
if (const Curves *curves = geometry_set.get_curves()) {
|
||||
materials = curves->mat;
|
||||
count = curves->totcol;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryComponent::Type::GreasePencil: {
|
||||
if (const GreasePencil *grease_pencil = geometry_set.get_grease_pencil()) {
|
||||
materials = grease_pencil->material_array;
|
||||
count = grease_pencil->material_array_num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryComponent::Type::Mesh: {
|
||||
if (const Mesh *mesh = geometry_set.get_mesh()) {
|
||||
materials = mesh->mat;
|
||||
count = mesh->totcol;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryComponent::Type::PointCloud: {
|
||||
if (const PointCloud *point_cloud = geometry_set.get_pointcloud()) {
|
||||
materials = point_cloud->mat;
|
||||
count = point_cloud->totcol;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (count == 0 || materials == nullptr) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
const CPPType &type = CPPType::get<Material *>();
|
||||
GArray<> array(type, count, NoInitialization());
|
||||
type.copy_construct_n(materials, array.data(), count);
|
||||
params.set_output("Materials"_ustr, GList::from_garray(std::move(array)));
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, "GeometryNodeGeometryMaterials"_ustr);
|
||||
ntype.ui_name = "Geometry Materials";
|
||||
ntype.ui_description = "Get a list of the materials used by a geometry component";
|
||||
ntype.nclass = NODE_CLASS_GEOMETRY;
|
||||
ntype.geometry_node_execute = node_geo_exec;
|
||||
ntype.declare = node_declare;
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_geo_geometry_materials
|
||||
Loading…
Add table
Add a link
Reference in a new issue