Blender  V3.3
node_geo_mesh_to_volume.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "DEG_depsgraph_query.h"
4 #include "node_geometry_util.hh"
5 
6 #include "BKE_lib_id.h"
7 #include "BKE_mesh.h"
8 #include "BKE_mesh_runtime.h"
9 #include "BKE_mesh_wrapper.h"
10 #include "BKE_object.h"
11 #include "BKE_volume.h"
12 
13 #include "GEO_mesh_to_volume.hh"
14 
15 #include "DNA_mesh_types.h"
16 #include "DNA_meshdata_types.h"
17 
18 #include "UI_interface.h"
19 #include "UI_resources.h"
20 
22 
24 
26 {
27  b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
28  b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.01f).max(FLT_MAX);
29  b.add_input<decl::Float>(N_("Voxel Size"))
30  .default_value(0.3f)
31  .min(0.01f)
32  .max(FLT_MAX)
33  .subtype(PROP_DISTANCE);
34  b.add_input<decl::Float>(N_("Voxel Amount")).default_value(64.0f).min(0.0f).max(FLT_MAX);
35  b.add_input<decl::Float>(N_("Exterior Band Width"))
36  .default_value(0.1f)
37  .min(0.0f)
38  .max(FLT_MAX)
39  .subtype(PROP_DISTANCE)
40  .description(N_("Width of the volume outside of the mesh"));
41  b.add_input<decl::Float>(N_("Interior Band Width"))
42  .default_value(0.0f)
43  .min(0.0f)
44  .max(FLT_MAX)
45  .subtype(PROP_DISTANCE)
46  .description(N_("Width of the volume inside of the mesh"));
47  b.add_input<decl::Bool>(N_("Fill Volume"))
48  .default_value(true)
49  .description(N_("Initialize the density grid in every cell inside the enclosed volume"));
50  b.add_output<decl::Geometry>(N_("Volume"));
51 }
52 
53 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
54 {
55  uiLayoutSetPropSep(layout, true);
56  uiLayoutSetPropDecorate(layout, false);
57  uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
58 }
59 
61 {
63  sizeof(NodeGeometryMeshToVolume), __func__);
65  node->storage = data;
66 }
67 
69 {
71 
72  bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
73  bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
75  voxel_amount_socket,
78  voxel_size_socket,
80 }
81 
82 #ifdef WITH_OPENVDB
83 
84 static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &params)
85 {
86  const NodeGeometryMeshToVolume &storage =
87  *(const NodeGeometryMeshToVolume *)params.node().storage;
88 
89  const float density = params.get_input<float>("Density");
90  const float exterior_band_width = params.get_input<float>("Exterior Band Width");
91  const float interior_band_width = params.get_input<float>("Interior Band Width");
92  const bool fill_volume = params.get_input<bool>("Fill Volume");
93 
96  if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
97  resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
98  if (resolution.settings.voxel_amount <= 0.0f) {
99  return nullptr;
100  }
101  }
102  else if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
103  resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
104  if (resolution.settings.voxel_size <= 0.0f) {
105  return nullptr;
106  }
107  }
108 
109  if (mesh.totvert == 0 || mesh.totpoly == 0) {
110  return nullptr;
111  }
112 
113  const float4x4 mesh_to_volume_space_transform = float4x4::identity();
114 
115  auto bounds_fn = [&](float3 &r_min, float3 &r_max) {
119  r_min = min;
120  r_max = max;
121  };
122 
123  const float voxel_size = geometry::volume_compute_voxel_size(params.depsgraph(),
124  bounds_fn,
125  resolution,
126  exterior_band_width,
127  mesh_to_volume_space_transform);
128 
129  Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
130  BKE_volume_init_grids(volume);
131 
132  /* Convert mesh to grid and add to volume. */
133  geometry::volume_grid_add_from_mesh(volume,
134  "density",
135  &mesh,
136  mesh_to_volume_space_transform,
137  voxel_size,
138  fill_volume,
139  exterior_band_width,
140  interior_band_width,
141  density);
142 
143  return volume;
144 }
145 
146 #endif /* WITH_OPENVDB */
147 
149 {
150 #ifdef WITH_OPENVDB
151  GeometrySet geometry_set(params.extract_input<GeometrySet>("Mesh"));
152 
153  geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
154  if (geometry_set.has_mesh()) {
155  Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh_for_read(), params);
156  geometry_set.replace_volume(volume);
157  geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_VOLUME});
158  }
159  });
160  params.set_output("Volume", std::move(geometry_set));
161 #else
162  params.error_message_add(NodeWarningType::Error,
163  TIP_("Disabled, Blender was compiled without OpenVDB"));
164  params.set_default_remaining_outputs();
165  return;
166 #endif
167 }
168 
169 } // namespace blender::nodes::node_geo_mesh_to_volume_cc
170 
172 {
173  namespace file_ns = blender::nodes::node_geo_mesh_to_volume_cc;
174 
175  static bNodeType ntype;
176 
179  node_type_size(&ntype, 200, 120, 700);
185  &ntype, "NodeGeometryMeshToVolume", node_free_standard_storage, node_copy_standard_storage);
186  nodeRegisterType(&ntype);
187 }
@ GEO_COMPONENT_TYPE_MESH
void * BKE_id_new_nomain(short type, const char *name)
Definition: lib_id.c:1173
bool BKE_mesh_wrapper_minmax(const struct Mesh *me, float min[3], float max[3])
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4396
#define GEO_NODE_MESH_TO_VOLUME
Definition: BKE_node.h:1505
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
General operations, lookup, etc. for blender objects.
Volume data-block.
void BKE_volume_init_grids(struct Volume *volume)
Definition: volume.cc:679
#define UNUSED(x)
#define TIP_(msgid)
#define IFACE_(msgid)
@ ID_VO
Definition: DNA_ID_enums.h:83
MeshToVolumeModifierResolutionMode
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT
@ SOCK_IN
float float4x4[4][4]
@ PROP_DISTANCE
Definition: RNA_types.h:149
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
OperationNode * node
void * tree
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static void node_update(bNodeTree *ntree, bNode *node)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void register_node_type_geo_mesh_to_volume()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
#define min(a, b)
Definition: sort.c:35
void modify_geometry_sets(ForeachSubGeometryCallback callback)
bool has_mesh() const
int totvert
int totpoly
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
static float4x4 identity()
Definition: BLI_float4x4.hh:80
MeshToVolumeModifierResolutionMode mode
float max
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480