Blender V5.0
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 "DNA_mesh_types.h"
8#include "DNA_volume_types.h"
9
10#include "BKE_lib_id.hh"
11
13#include "GEO_mesh_to_volume.hh"
14
15#include "NOD_rna_define.hh"
16
18#include "UI_resources.hh"
19
21
23
26 "VOXEL_AMOUNT",
27 0,
29 N_("Desired number of voxels along one axis")},
31 "VOXEL_SIZE",
32 0,
34 N_("Desired voxel side length")},
35 {0, nullptr, 0, nullptr, nullptr},
36};
37
39{
40 b.add_input<decl::Geometry>("Mesh")
41 .supported_type(GeometryComponent::Type::Mesh)
42 .description("Mesh to convert the inner volume to a fog volume geometry");
43 b.add_input<decl::Float>("Density").default_value(1.0f).min(0.01f).max(FLT_MAX);
44 b.add_input<decl::Menu>("Resolution Mode")
45 .static_items(resolution_mode_items)
47 .description("How the voxel size is specified")
48 .translation_context(BLT_I18NCONTEXT_COUNTABLE);
49 b.add_input<decl::Float>("Voxel Size")
50 .default_value(0.3f)
51 .min(0.01f)
52 .max(FLT_MAX)
54 .usage_by_single_menu(MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE);
55 b.add_input<decl::Float>("Voxel Amount")
56 .default_value(64.0f)
57 .min(0.0f)
58 .max(FLT_MAX)
60 b.add_input<decl::Float>("Interior Band Width")
61 .default_value(0.2f)
62 .min(0.0001f)
63 .max(FLT_MAX)
65 .description("Width of the gradient inside of the mesh");
66 b.add_output<decl::Geometry>("Volume").translation_context(BLT_I18NCONTEXT_ID_ID);
67}
68
69static void node_init(bNodeTree * /*tree*/, bNode *node)
70{
71 /* Still used for forward compatibility. */
73}
74
75#ifdef WITH_OPENVDB
76
77static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &params)
78{
79 const float density = params.get_input<float>("Density");
80 const float interior_band_width = params.get_input<float>("Interior Band Width");
81 const auto mode = params.get_input<MeshToVolumeModifierResolutionMode>("Resolution Mode");
82
84 resolution.mode = mode;
85 if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
86 resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
87 if (resolution.settings.voxel_amount <= 0.0f) {
88 return nullptr;
89 }
90 }
91 else if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
92 resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
93 if (resolution.settings.voxel_size <= 0.0f) {
94 return nullptr;
95 }
96 }
97
98 if (mesh.verts_num == 0 || mesh.faces_num == 0) {
99 return nullptr;
100 }
101
102 const float4x4 mesh_to_volume_space_transform = float4x4::identity();
103
104 const float voxel_size = geometry::volume_compute_voxel_size(
105 params.depsgraph(),
106 [&]() { return *mesh.bounds_min_max(); },
107 resolution,
108 0.0f,
109 mesh_to_volume_space_transform);
110
111 Volume *volume = BKE_id_new_nomain<Volume>(nullptr);
112
113 /* Convert mesh to grid and add to volume. */
114 geometry::fog_volume_grid_add_from_mesh(volume,
115 "density",
116 mesh.vert_positions(),
117 mesh.corner_verts(),
118 mesh.corner_tris(),
119 mesh_to_volume_space_transform,
120 voxel_size,
121 interior_band_width,
122 density);
123
124 return volume;
125}
126
127#endif /* WITH_OPENVDB */
128
130{
131#ifdef WITH_OPENVDB
132 GeometrySet geometry_set(params.extract_input<GeometrySet>("Mesh"));
133 geometry::foreach_real_geometry(geometry_set, [&](GeometrySet &geometry_set) {
134 if (geometry_set.has_mesh()) {
135 Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh(), params);
136 geometry_set.replace_volume(volume);
137 geometry_set.keep_only({GeometryComponent::Type::Volume, GeometryComponent::Type::Edit});
138 }
139 });
140 params.set_output("Volume", std::move(geometry_set));
141#else
143 return;
144#endif
145}
146
147static void node_register()
148{
149 static blender::bke::bNodeType ntype;
150
151 geo_node_type_base(&ntype, "GeometryNodeMeshToVolume", GEO_NODE_MESH_TO_VOLUME);
152 ntype.ui_name = "Mesh to Volume";
153 ntype.ui_description = "Create a fog volume with the shape of the input mesh's surface";
154 ntype.enum_name_legacy = "MESH_TO_VOLUME";
156 ntype.declare = node_declare;
157 bke::node_type_size(ntype, 200, 120, 700);
158 ntype.initfunc = node_init;
161 ntype, "NodeGeometryMeshToVolume", node_free_standard_storage, node_copy_standard_storage);
163}
165
166} // namespace blender::nodes::node_geo_mesh_to_volume_cc
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1519
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_MESH_TO_VOLUME
#define CTX_N_(context, msgid)
#define BLT_I18NCONTEXT_ID_ID
#define BLT_I18NCONTEXT_COUNTABLE
MeshToVolumeModifierResolutionMode
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT
struct Volume Volume
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_DISTANCE
Definition RNA_types.hh:256
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_type_size(bNodeType &ntype, int width, int minwidth, int maxwidth)
Definition node.cc:5384
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
static void node_init(bNodeTree *, bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams &params)
MatBase< float, 4, 4 > float4x4
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define FLT_MAX
Definition stdcycles.h:14
int faces_num
int verts_num
void * storage
void replace_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only(Span< GeometryComponent::Type > component_types)
const Mesh * get_mesh() const
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
MeshToVolumeModifierResolutionMode mode
#define N_(msgid)