Geometry Nodes: Sample Materials #106666
|
@ -307,6 +307,7 @@ class NODE_MT_geometry_node_GEO_MATERIAL(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeReplaceMaterial")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSampleMaterial")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMaterialIndex")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeMaterialSelection")
|
||||
|
|
|
@ -1575,6 +1575,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define GEO_NODE_SDF_VOLUME_SPHERE 1196
|
||||
#define GEO_NODE_MEAN_FILTER_SDF_VOLUME 1197
|
||||
#define GEO_NODE_OFFSET_SDF_VOLUME 1198
|
||||
#define GEO_NODE_SAMPLE_MATERIAL 1199
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -397,6 +397,7 @@ DefNode(GeometryNode, GEO_NODE_REVERSE_CURVE, 0, "REVERSE_CURVE", ReverseCurve,
|
|||
DefNode(GeometryNode, GEO_NODE_ROTATE_INSTANCES, 0, "ROTATE_INSTANCES", RotateInstances, "Rotate Instances", "Rotate geometry instances in local or global space")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_CURVE, def_geo_curve_sample, "SAMPLE_CURVE", SampleCurve, "Sample Curve", "Retrieve data from a point on a curve at a certain distance from its start")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_INDEX, def_geo_sample_index, "SAMPLE_INDEX", SampleIndex, "Sample Index", "Retrieve values from specific geometry elements")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_MATERIAL, 0, "SAMPLE_MATERIAL", SampleMaterial, "Sample Material", "")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST_SURFACE, def_geo_sample_nearest_surface, "SAMPLE_NEAREST_SURFACE", SampleNearestSurface, "Sample Nearest Surface", "Calculate the interpolated value of a mesh attribute on the closest point of its surface")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST, def_geo_sample_nearest, "SAMPLE_NEAREST", SampleNearest, "Sample Nearest", "Find the element of a geometry closest to a position")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_UV_SURFACE, def_geo_sample_uv_surface, "SAMPLE_UV_SURFACE", SampleUVSurface, "Sample UV Surface", "Calculate the interpolated values of a mesh attribute at a UV coordinate")
|
||||
|
|
|
@ -148,6 +148,7 @@ set(SRC
|
|||
nodes/node_geo_remove_attribute.cc
|
||||
nodes/node_geo_rotate_instances.cc
|
||||
nodes/node_geo_sample_index.cc
|
||||
nodes/node_geo_sample_material.cc
|
||||
nodes/node_geo_sample_nearest.cc
|
||||
nodes/node_geo_sample_nearest_surface.cc
|
||||
nodes/node_geo_sample_uv_surface.cc
|
||||
|
|
|
@ -132,6 +132,7 @@ void register_geometry_nodes()
|
|||
register_node_type_geo_remove_attribute();
|
||||
register_node_type_geo_rotate_instances();
|
||||
register_node_type_geo_sample_index();
|
||||
register_node_type_geo_sample_material();
|
||||
register_node_type_geo_sample_nearest_surface();
|
||||
register_node_type_geo_sample_nearest();
|
||||
register_node_type_geo_sample_uv_surface();
|
||||
|
|
|
@ -129,6 +129,7 @@ void register_node_type_geo_realize_instances();
|
|||
void register_node_type_geo_remove_attribute();
|
||||
void register_node_type_geo_rotate_instances();
|
||||
void register_node_type_geo_sample_index();
|
||||
void register_node_type_geo_sample_material();
|
||||
void register_node_type_geo_sample_nearest_surface();
|
||||
void register_node_type_geo_sample_nearest();
|
||||
void register_node_type_geo_sample_uv_surface();
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "BLI_task.hh"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_sample_material_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Geometry>(N_("Geometry"));
|
||||
b.add_input<decl::Geometry>(N_("Material Source"));
|
||||
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().field_on({0});
|
||||
b.add_input<decl::Int>(N_("Material Index")).default_value(1).field_on({0});
|
||||
/* TODO: It's possible to avoid propagation from second geometry input? Or i miss something? */
|
||||
b.add_output<decl::Geometry>(N_("Geometry")).propagate_all();
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
|
||||
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
|
||||
Field<int> index_field = params.extract_input<Field<int>>("Material Index");
|
||||
|
||||
geometry.modify_geometry_sets([&](GeometrySet &geometry_set) {
|
||||
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
|
||||
Mesh *mesh = geometry_set.get_mesh_for_write();
|
||||
if (!mesh) {
|
||||
return;
|
||||
}
|
||||
|
||||
bke::GeometryFieldContext field_context{*component, ATTR_DOMAIN_FACE};
|
||||
fn::FieldEvaluator evaluator{field_context, mesh->totpoly};
|
||||
evaluator.set_selection(selection_field);
|
||||
evaluator.add(index_field);
|
||||
evaluator.evaluate();
|
||||
|
||||
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
||||
if (selection.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
SpanAttributeWriter<int> dst_indices_attribute = attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
|
||||
MutableSpan<int> dst_indices = dst_indices_attribute.span;
|
||||
|
||||
const VArray<int> &indices = evaluator.get_evaluated<int>(0);
|
||||
|
||||
indices.materialize(selection, dst_indices);
|
||||
|
||||
dst_indices_attribute.finish();
|
||||
});
|
||||
|
||||
params.set_output("Geometry", std::move(geometry));
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_geo_sample_material_cc
|
||||
|
||||
void register_node_type_geo_sample_material()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_geo_sample_material_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, GEO_NODE_SAMPLE_MATERIAL, "Sample Material", NODE_CLASS_GEOMETRY);
|
||||
ntype.geometry_node_execute = file_ns::node_geo_exec;
|
||||
ntype.declare = file_ns::node_declare;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Loading…
Reference in New Issue