6# include <openvdb/tools/GridTransformer.h>
7# include <openvdb/tools/VolumeToMesh.h>
30 N_(
"Use resolution of the volume grid")},
35 N_(
"Desired number of voxels along one axis")},
40 N_(
"Desired voxel side length")},
41 {0,
nullptr, 0,
nullptr,
nullptr},
47 .supported_type(GeometryComponent::Type::Volume)
49 .is_default_link_socket()
50 .description(
"Volume to convert to a mesh");
54 .description(
"How the voxel size is specified")
67 .
description(
"Values larger than the threshold are inside the generated mesh");
94static Mesh *create_mesh_from_volume_grids(Span<const openvdb::GridBase *> grids,
96 const float threshold,
97 const float adaptivity,
98 const bke::VolumeToMeshResolution &resolution)
100 Array<bke::VolumeToMeshDataResult> mesh_data(grids.
size());
102 bke::VolumeToMeshDataResult &
result = mesh_data[
i];
103 result = bke::volume_to_mesh_data(*grids[
i], resolution, threshold, adaptivity);
104 if (!
result.error.empty()) {
112 Array<int> vert_offsets(mesh_data.size());
113 Array<int> face_offsets(mesh_data.size());
114 Array<int> loop_offsets(mesh_data.size());
116 const bke::OpenVDBMeshData &
data = mesh_data[
i].data;
117 vert_offsets[
i] = vert_offset;
118 face_offsets[
i] = face_offset;
119 loop_offsets[
i] = loop_offset;
120 vert_offset +=
data.verts.size();
121 face_offset += (
data.tris.size() +
data.quads.size());
122 loop_offset += (3 *
data.tris.size() + 4 *
data.quads.size());
127 MutableSpan<float3> positions = mesh->vert_positions_for_write();
128 MutableSpan<int> dst_face_offsets = mesh->face_offsets_for_write();
129 MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
132 const bke::OpenVDBMeshData &
data = mesh_data[
i].data;
133 bke::fill_mesh_from_openvdb_data(
data.verts,
147 mesh->tag_overlapping_none();
154static Mesh *create_mesh_from_volume(GeometrySet &geometry_set, GeoNodeExecParams &
params)
157 if (volume ==
nullptr) {
161 const bke::VolumeToMeshResolution resolution = get_resolution_param(
params);
164 resolution.settings.voxel_size <= 0.0f)
169 resolution.settings.voxel_amount <= 0)
176 Vector<bke::VolumeTreeAccessToken> tree_tokens;
177 Vector<const openvdb::GridBase *> grids;
181 grids.
append(&volume_grid->grid(tree_tokens.
last()));
188 return create_mesh_from_volume_grids(grids,
190 params.get_input<
float>(
"Threshold"),
191 params.get_input<
float>(
"Adaptivity"),
202 Mesh *mesh = create_mesh_from_volume(geometry_set,
params);
204 geometry_set.
keep_only({GeometryComponent::Type::Mesh, GeometryComponent::Type::Edit});
206 params.set_output(
"Mesh", std::move(geometry_set));
217 ntype.
ui_name =
"Volume to Mesh";
218 ntype.
ui_description =
"Generate a mesh on the \"surface\" of a volume";
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(ID *id)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_VOLUME_TO_MESH
int BKE_volume_num_grids(const Volume *volume)
bool BKE_volume_load(const Volume *volume, const Main *bmain)
const blender::bke::VolumeGridData * BKE_volume_grid_get(const Volume *volume, int grid_index)
#define CTX_N_(context, msgid)
#define BLT_I18NCONTEXT_ID_ID
#define BLT_I18NCONTEXT_COUNTABLE
VolumeToMeshResolutionMode
@ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE
@ VOLUME_TO_MESH_RESOLUTION_MODE_GRID
@ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
BMesh const char void * data
constexpr int64_t size() const
constexpr IndexRange index_range() const
void append(const T &value)
const T & last(const int64_t n=0) const
void append_as(ForwardValue &&...value)
std::optional< std::string > translation_context
void * MEM_callocN(size_t len, const char *str)
void node_type_size(bNodeType &ntype, int width, int minwidth, int maxwidth)
void node_register_type(bNodeType &ntype)
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
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))
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
void debug_randomize_mesh_order(Mesh *mesh)
static void node_register()
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static EnumPropertyItem resolution_mode_items[]
static void node_init(bNodeTree *, bNode *node)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams ¶ms)
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)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
const Volume * get_volume() const
void keep_only(Span< GeometryComponent::Type > component_types)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
VolumeToMeshResolutionMode mode
union blender::bke::VolumeToMeshResolution::@103176042355372060356022076152214323072307172372 settings
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
NodeDeclareFunction declare