Blender V4.3
node_geo_mesh_to_volume.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "BKE_lib_id.hh"
8#include "BKE_mesh.hh"
9
10#include "GEO_mesh_to_volume.hh"
11
12#include "NOD_rna_define.hh"
13
14#include "UI_interface.hh"
15#include "UI_resources.hh"
16
18
20
22{
23 b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
24 b.add_input<decl::Float>("Density").default_value(1.0f).min(0.01f).max(FLT_MAX);
25 auto &voxel_size = b.add_input<decl::Float>("Voxel Size")
26 .default_value(0.3f)
27 .min(0.01f)
28 .max(FLT_MAX)
30 auto &voxel_amount =
31 b.add_input<decl::Float>("Voxel Amount").default_value(64.0f).min(0.0f).max(FLT_MAX);
32 b.add_input<decl::Float>("Interior Band Width")
33 .default_value(0.2f)
34 .min(0.0001f)
35 .max(FLT_MAX)
37 .description("Width of the gradient inside of the mesh");
38 b.add_output<decl::Geometry>("Volume").translation_context(BLT_I18NCONTEXT_ID_ID);
39
40 const bNode *node = b.node_or_null();
41 if (node != nullptr) {
42 const NodeGeometryMeshToVolume &data = node_storage(*node);
43 voxel_size.available(data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE);
44 voxel_amount.available(data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT);
45 }
46}
47
48static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
49{
50 uiLayoutSetPropSep(layout, true);
51 uiLayoutSetPropDecorate(layout, false);
52 uiItemR(layout, ptr, "resolution_mode", UI_ITEM_NONE, IFACE_("Resolution"), ICON_NONE);
53}
54
55static void node_init(bNodeTree * /*tree*/, bNode *node)
56{
57 NodeGeometryMeshToVolume *data = MEM_cnew<NodeGeometryMeshToVolume>(__func__);
58 data->resolution_mode = MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT;
59 node->storage = data;
60}
61
62#ifdef WITH_OPENVDB
63
64static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &params)
65{
66 const NodeGeometryMeshToVolume &storage =
67 *(const NodeGeometryMeshToVolume *)params.node().storage;
68
69 const float density = params.get_input<float>("Density");
70 const float interior_band_width = params.get_input<float>("Interior Band Width");
71
74 if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
75 resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
76 if (resolution.settings.voxel_amount <= 0.0f) {
77 return nullptr;
78 }
79 }
80 else if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
81 resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
82 if (resolution.settings.voxel_size <= 0.0f) {
83 return nullptr;
84 }
85 }
86
87 if (mesh.verts_num == 0 || mesh.faces_num == 0) {
88 return nullptr;
89 }
90
91 const float4x4 mesh_to_volume_space_transform = float4x4::identity();
92
93 const float voxel_size = geometry::volume_compute_voxel_size(
94 params.depsgraph(),
95 [&]() { return *mesh.bounds_min_max(); },
96 resolution,
97 0.0f,
98 mesh_to_volume_space_transform);
99
100 Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
101
102 /* Convert mesh to grid and add to volume. */
103 geometry::fog_volume_grid_add_from_mesh(volume,
104 "density",
105 mesh.vert_positions(),
106 mesh.corner_verts(),
107 mesh.corner_tris(),
108 mesh_to_volume_space_transform,
109 voxel_size,
110 interior_band_width,
111 density);
112
113 return volume;
114}
115
116#endif /* WITH_OPENVDB */
117
119{
120#ifdef WITH_OPENVDB
121 GeometrySet geometry_set(params.extract_input<GeometrySet>("Mesh"));
122 geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
123 if (geometry_set.has_mesh()) {
124 Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh(), params);
125 geometry_set.replace_volume(volume);
126 geometry_set.keep_only_during_modify({GeometryComponent::Type::Volume});
127 }
128 });
129 params.set_output("Volume", std::move(geometry_set));
130#else
132 return;
133#endif
134}
135
136static void node_rna(StructRNA *srna)
137{
138 static EnumPropertyItem resolution_mode_items[] = {
140 "VOXEL_AMOUNT",
141 0,
142 "Amount",
143 "Desired number of voxels along one axis"},
145 "VOXEL_SIZE",
146 0,
147 "Size",
148 "Desired voxel side length"},
149 {0, nullptr, 0, nullptr, nullptr},
150 };
151
153 "resolution_mode",
154 "Resolution Mode",
155 "How the voxel size is specified",
156 resolution_mode_items,
157 NOD_storage_enum_accessors(resolution_mode),
159}
160
161static void node_register()
162{
163 static blender::bke::bNodeType ntype;
164
165 geo_node_type_base(&ntype, GEO_NODE_MESH_TO_VOLUME, "Mesh to Volume", NODE_CLASS_GEOMETRY);
166 ntype.declare = node_declare;
167 bke::node_type_size(&ntype, 200, 120, 700);
168 ntype.initfunc = node_init;
172 &ntype, "NodeGeometryMeshToVolume", node_free_standard_storage, node_copy_standard_storage);
174
175 node_rna(ntype.rna_ext.srna);
176}
177NOD_REGISTER_NODE(node_register)
178
179} // namespace blender::nodes::node_geo_mesh_to_volume_cc
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1487
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
#define BLT_I18NCONTEXT_ID_ID
#define IFACE_(msgid)
@ ID_VO
MeshToVolumeModifierResolutionMode
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
@ PROP_DISTANCE
Definition RNA_types.hh:159
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_init(bNodeTree *, bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams &params)
MatBase< float, 4, 4 > float4x4
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:46
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:58
#define FLT_MAX
Definition stdcycles.h:14
StructRNA * srna
Definition RNA_types.hh:780
void modify_geometry_sets(ForeachSubGeometryCallback callback)
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
MeshToVolumeModifierResolutionMode mode
PointerRNA * ptr
Definition wm_files.cc:4126