Blender  V3.3
node_geo_material_selection.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "node_geometry_util.hh"
4 
5 #include "UI_interface.h"
6 #include "UI_resources.h"
7 
8 #include "DNA_mesh_types.h"
9 #include "DNA_meshdata_types.h"
10 
11 #include "BLI_task.hh"
12 
13 #include "BKE_material.h"
14 
16 
18 {
19  b.add_input<decl::Material>(N_("Material")).hide_label(true);
20  b.add_output<decl::Bool>(N_("Selection")).field_source();
21 }
22 
23 static void select_mesh_by_material(const Mesh &mesh,
24  const Material *material,
25  const IndexMask mask,
26  const MutableSpan<bool> r_selection)
27 {
28  BLI_assert(mesh.totpoly >= r_selection.size());
29  Vector<int> material_indices;
30  for (const int i : IndexRange(mesh.totcol)) {
31  if (mesh.mat[i] == material) {
32  material_indices.append(i);
33  }
34  }
35  threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) {
36  for (const int i : range) {
37  const int face_index = mask[i];
38  r_selection[i] = material_indices.contains(mesh.mpoly[face_index].mat_nr);
39  }
40  });
41 }
42 
44  Material *material_;
45 
46  public:
48  : GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
49  {
50  category_ = Category::Generated;
51  }
52 
54  const eAttrDomain domain,
55  IndexMask mask) const final
56  {
57  if (component.type() != GEO_COMPONENT_TYPE_MESH) {
58  return {};
59  }
60  const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
61  const Mesh *mesh = mesh_component.get_for_read();
62  if (mesh == nullptr) {
63  return {};
64  }
65 
66  if (domain == ATTR_DOMAIN_FACE) {
67  Array<bool> selection(mask.min_array_size());
68  select_mesh_by_material(*mesh, material_, mask, selection);
69  return VArray<bool>::ForContainer(std::move(selection));
70  }
71 
72  Array<bool> selection(mesh->totpoly);
73  select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
74  return mesh_component.attributes()->adapt_domain<bool>(
75  VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
76 
77  return nullptr;
78  }
79 
80  uint64_t hash() const override
81  {
82  return get_default_hash(material_);
83  }
84 
85  bool is_equal_to(const fn::FieldNode &other) const override
86  {
87  if (const MaterialSelectionFieldInput *other_material_selection =
88  dynamic_cast<const MaterialSelectionFieldInput *>(&other)) {
89  return material_ == other_material_selection->material_;
90  }
91  return false;
92  }
93 };
94 
96 {
97  Material *material = params.extract_input<Material *>("Material");
98  Field<bool> material_field{std::make_shared<MaterialSelectionFieldInput>(material)};
99  params.set_output("Selection", std::move(material_field));
100 }
101 
102 } // namespace blender::nodes::node_geo_material_selection_cc
103 
105 {
107 
108  static bNodeType ntype;
109 
111  &ntype, GEO_NODE_MATERIAL_SELECTION, "Material Selection", NODE_CLASS_GEOMETRY);
114  nodeRegisterType(&ntype);
115 }
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_FACE
Definition: BKE_attribute.h:29
@ GEO_COMPONENT_TYPE_MESH
General operations, lookup, etc. for materials.
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define GEO_NODE_MATERIAL_SELECTION
Definition: BKE_node.h:1423
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define final(a, b, c)
Definition: BLI_hash.h:21
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
const Mesh * get_for_read() const
std::optional< blender::bke::AttributeAccessor > attributes() const final
constexpr int64_t size() const
Definition: BLI_span.hh:511
void append(const T &value)
Definition: BLI_vector.hh:433
GVArray get_varray_for_context(const GeometryComponent &component, const eAttrDomain domain, IndexMask mask) const final
Material material
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
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 select_mesh_by_material(const Mesh &mesh, const Material *material, const IndexMask mask, const MutableSpan< bool > r_selection)
static void node_declare(NodeDeclarationBuilder &b)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
uint64_t get_default_hash(const T &v)
Definition: BLI_hash.hh:218
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_geo_material_selection()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
unsigned __int64 uint64_t
Definition: stdint.h:90
struct Material ** mat
int totpoly
short totcol
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)