Blender  V2.93
node_geo_volume_to_mesh.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "DEG_depsgraph_query.h"
18 #ifdef WITH_OPENVDB
19 # include <openvdb/tools/GridTransformer.h>
20 # include <openvdb/tools/VolumeToMesh.h>
21 #endif
22 
23 #include "node_geometry_util.hh"
24 
25 #include "BKE_lib_id.h"
26 #include "BKE_mesh.h"
27 #include "BKE_mesh_runtime.h"
28 #include "BKE_volume.h"
29 #include "BKE_volume_to_mesh.hh"
30 
31 #include "DNA_mesh_types.h"
32 #include "DNA_meshdata_types.h"
33 
34 #include "UI_interface.h"
35 #include "UI_resources.h"
36 
38  {SOCK_GEOMETRY, N_("Geometry")},
39  {SOCK_STRING, N_("Density")},
40  {SOCK_FLOAT, N_("Voxel Size"), 0.3f, 0.0f, 0.0f, 0.0f, 0.01f, FLT_MAX, PROP_DISTANCE},
41  {SOCK_FLOAT, N_("Voxel Amount"), 64.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
42  {SOCK_FLOAT, N_("Threshold"), 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
43  {SOCK_FLOAT, N_("Adaptivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
44  {-1, ""},
45 };
46 
48  {SOCK_GEOMETRY, N_("Geometry")},
49  {-1, ""},
50 };
51 
53 {
54  uiLayoutSetPropSep(layout, true);
55  uiLayoutSetPropDecorate(layout, false);
56  uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
57 }
58 
59 namespace blender::nodes {
60 
62 {
64  sizeof(NodeGeometryVolumeToMesh), __func__);
65  data->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
66 
67  bNodeSocket *grid_socket = nodeFindSocket(node, SOCK_IN, "Density");
68  bNodeSocketValueString *grid_socket_value = (bNodeSocketValueString *)grid_socket->default_value;
69  STRNCPY(grid_socket_value->value, "density");
70 
71  node->storage = data;
72 }
73 
75 {
77 
78  bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
79  bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
80  nodeSetSocketAvailability(voxel_amount_socket,
82  nodeSetSocketAvailability(voxel_size_socket,
84 }
85 
86 #ifdef WITH_OPENVDB
87 
88 static void create_mesh_from_volume(GeometrySet &geometry_set_in,
89  GeometrySet &geometry_set_out,
90  GeoNodeExecParams &params)
91 {
92  if (!geometry_set_in.has<VolumeComponent>()) {
93  return;
94  }
95 
96  const NodeGeometryVolumeToMesh &storage =
97  *(const NodeGeometryVolumeToMesh *)params.node().storage;
98 
99  bke::VolumeToMeshResolution resolution;
100  resolution.mode = (VolumeToMeshResolutionMode)storage.resolution_mode;
101  if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
102  resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
103  if (resolution.settings.voxel_amount <= 0.0f) {
104  return;
105  }
106  }
107  else if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
108  resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
109  if (resolution.settings.voxel_size <= 0.0f) {
110  return;
111  }
112  }
113 
115  const Volume *volume = component->get_for_read();
116  if (volume == nullptr) {
117  return;
118  }
119 
120  const Main *bmain = DEG_get_bmain(params.depsgraph());
121  BKE_volume_load(volume, bmain);
122 
123  const std::string grid_name = params.get_input<std::string>("Density");
124  const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, grid_name.c_str());
125  if (volume_grid == nullptr) {
126  return;
127  }
128 
129  float threshold = params.get_input<float>("Threshold");
130  float adaptivity = params.get_input<float>("Adaptivity");
131 
132  const openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
133  Mesh *mesh = bke::volume_to_mesh(*grid, resolution, threshold, adaptivity);
134  if (mesh == nullptr) {
135  return;
136  }
137  MeshComponent &dst_component = geometry_set_out.get_component_for_write<MeshComponent>();
138  dst_component.replace(mesh);
139 }
140 
141 #endif /* WITH_OPENVDB */
142 
144 {
145  GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
146  GeometrySet geometry_set_out;
147 
148 #ifdef WITH_OPENVDB
149  create_mesh_from_volume(geometry_set_in, geometry_set_out, params);
150 #endif
151 
152  params.set_output("Geometry", geometry_set_out);
153 }
154 
155 } // namespace blender::nodes
156 
158 {
159  static bNodeType ntype;
160 
161  geo_node_type_base(&ntype, GEO_NODE_VOLUME_TO_MESH, "Volume to Mesh", NODE_CLASS_GEOMETRY, 0);
164  &ntype, "NodeGeometryVolumeToMesh", node_free_standard_storage, node_copy_standard_storage);
165  node_type_size(&ntype, 200, 120, 700);
170  nodeRegisterType(&ntype);
171 }
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3726
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4565
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
#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:4599
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
#define GEO_NODE_VOLUME_TO_MESH
Definition: BKE_node.h:1402
Volume datablock.
const VolumeGrid * BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name)
bool BKE_volume_load(const struct Volume *volume, const struct Main *bmain)
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
#define UNUSED(x)
#define IFACE_(msgid)
#define N_(msgid)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:126
struct Main * DEG_get_bmain(const Depsgraph *graph)
VolumeToMeshResolutionMode
@ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE
@ VOLUME_TO_MESH_RESOLUTION_MODE_GRID
@ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT
@ SOCK_IN
@ SOCK_FLOAT
@ SOCK_GEOMETRY
@ SOCK_STRING
@ PROP_DISTANCE
Definition: RNA_types.h:135
@ PROP_FACTOR
Definition: RNA_types.h:131
#define C
Definition: RandGen.cpp:39
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)
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
OperationNode * node
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
static void geo_node_volume_to_mesh_update(bNodeTree *UNUSED(ntree), bNode *node)
static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
static bNodeSocketTemplate geo_node_volume_to_mesh_out[]
void register_node_type_geo_volume_to_mesh()
static bNodeSocketTemplate geo_node_volume_to_mesh_in[]
static void geo_node_volume_to_mesh_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:67
void node_free_standard_storage(bNode *node)
Definition: node_util.c:55
GeometryComponent & get_component_for_write(GeometryComponentType component_type)
bool has(const GeometryComponentType component_type) const
const GeometryComponent * get_component_for_read(GeometryComponentType component_type) const
Definition: BKE_main.h:116
Compact definition of a node socket.
Definition: BKE_node.h:95
void * default_value
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:253
PointerRNA * ptr
Definition: wm_files.c:3157