Blender V4.5
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
12#include "GEO_mesh_to_volume.hh"
13
14#include "NOD_rna_define.hh"
15
16#include "UI_interface.hh"
17#include "UI_resources.hh"
18
20
22
24{
25 b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
26 b.add_input<decl::Float>("Density").default_value(1.0f).min(0.01f).max(FLT_MAX);
27 auto &voxel_size = b.add_input<decl::Float>("Voxel Size")
28 .default_value(0.3f)
29 .min(0.01f)
30 .max(FLT_MAX)
31 .subtype(PROP_DISTANCE);
32 auto &voxel_amount =
33 b.add_input<decl::Float>("Voxel Amount").default_value(64.0f).min(0.0f).max(FLT_MAX);
34 b.add_input<decl::Float>("Interior Band Width")
35 .default_value(0.2f)
36 .min(0.0001f)
37 .max(FLT_MAX)
38 .subtype(PROP_DISTANCE)
39 .description("Width of the gradient inside of the mesh");
41
42 const bNode *node = b.node_or_null();
43 if (node != nullptr) {
44 const NodeGeometryMeshToVolume &data = node_storage(*node);
45 voxel_size.available(data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE);
46 voxel_amount.available(data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT);
47 }
48}
49
50static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
51{
52 uiLayoutSetPropSep(layout, true);
53 uiLayoutSetPropDecorate(layout, false);
54 layout->prop(ptr, "resolution_mode", UI_ITEM_NONE, IFACE_("Resolution"), ICON_NONE);
55}
56
57static void node_init(bNodeTree * /*tree*/, bNode *node)
58{
61 node->storage = data;
62}
63
64#ifdef WITH_OPENVDB
65
66static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &params)
67{
68 const NodeGeometryMeshToVolume &storage =
69 *(const NodeGeometryMeshToVolume *)params.node().storage;
70
71 const float density = params.get_input<float>("Density");
72 const float interior_band_width = params.get_input<float>("Interior Band Width");
73
76 if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
77 resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
78 if (resolution.settings.voxel_amount <= 0.0f) {
79 return nullptr;
80 }
81 }
82 else if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
83 resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
84 if (resolution.settings.voxel_size <= 0.0f) {
85 return nullptr;
86 }
87 }
88
89 if (mesh.verts_num == 0 || mesh.faces_num == 0) {
90 return nullptr;
91 }
92
93 const float4x4 mesh_to_volume_space_transform = float4x4::identity();
94
95 const float voxel_size = geometry::volume_compute_voxel_size(
96 params.depsgraph(),
97 [&]() { return *mesh.bounds_min_max(); },
98 resolution,
99 0.0f,
100 mesh_to_volume_space_transform);
101
102 Volume *volume = BKE_id_new_nomain<Volume>(nullptr);
103
104 /* Convert mesh to grid and add to volume. */
105 geometry::fog_volume_grid_add_from_mesh(volume,
106 "density",
107 mesh.vert_positions(),
108 mesh.corner_verts(),
109 mesh.corner_tris(),
110 mesh_to_volume_space_transform,
111 voxel_size,
112 interior_band_width,
113 density);
114
115 return volume;
116}
117
118#endif /* WITH_OPENVDB */
119
121{
122#ifdef WITH_OPENVDB
123 GeometrySet geometry_set(params.extract_input<GeometrySet>("Mesh"));
124 geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
125 if (geometry_set.has_mesh()) {
126 Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh(), params);
127 geometry_set.replace_volume(volume);
128 geometry_set.keep_only_during_modify({GeometryComponent::Type::Volume});
129 }
130 });
131 params.set_output("Volume", std::move(geometry_set));
132#else
134 return;
135#endif
136}
137
138static void node_rna(StructRNA *srna)
139{
140 static EnumPropertyItem resolution_mode_items[] = {
142 "VOXEL_AMOUNT",
143 0,
144 "Amount",
145 "Desired number of voxels along one axis"},
147 "VOXEL_SIZE",
148 0,
149 "Size",
150 "Desired voxel side length"},
151 {0, nullptr, 0, nullptr, nullptr},
152 };
153
155 "resolution_mode",
156 "Resolution Mode",
157 "How the voxel size is specified",
158 resolution_mode_items,
159 NOD_storage_enum_accessors(resolution_mode),
161}
162
163static void node_register()
164{
165 static blender::bke::bNodeType ntype;
166
167 geo_node_type_base(&ntype, "GeometryNodeMeshToVolume", GEO_NODE_MESH_TO_VOLUME);
168 ntype.ui_name = "Mesh to Volume";
169 ntype.ui_description = "Create a fog volume with the shape of the input mesh's surface";
170 ntype.enum_name_legacy = "MESH_TO_VOLUME";
172 ntype.declare = node_declare;
173 bke::node_type_size(ntype, 200, 120, 700);
174 ntype.initfunc = node_init;
178 ntype, "NodeGeometryMeshToVolume", node_free_standard_storage, node_copy_standard_storage);
180
181 node_rna(ntype.rna_ext.srna);
182}
184
185} // namespace blender::nodes::node_geo_mesh_to_volume_cc
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1500
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1215
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:447
#define GEO_NODE_MESH_TO_VOLUME
#define BLT_I18NCONTEXT_ID_ID
#define IFACE_(msgid)
MeshToVolumeModifierResolutionMode
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT
struct Volume Volume
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
@ PROP_DISTANCE
Definition RNA_types.hh:244
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
BMesh const char void * data
std::optional< std::string > translation_context
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:5573
void node_register_type(bNodeType &ntype)
Definition node.cc:2748
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:5603
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, 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 min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
StructRNA * srna
Definition RNA_types.hh:909
void * storage
void replace_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only_during_modify(Span< GeometryComponent::Type > component_types)
const Mesh * get_mesh() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
Defines a node type.
Definition BKE_node.hh:226
std::string ui_description
Definition BKE_node.hh:232
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:347
const char * enum_name_legacy
Definition BKE_node.hh:235
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:355
MeshToVolumeModifierResolutionMode mode
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4226