6# include <openvdb/tools/GridTransformer.h>
7# include <openvdb/tools/VolumeToMesh.h>
34 auto &voxel_size =
b.add_input<
decl::Float>(
"Voxel Size")
38 .make_available([](
bNode &node) {
39 node_storage(node).resolution_mode =
42 auto &voxel_amount =
b.add_input<
decl::Float>(
"Voxel Amount")
46 node_storage(node).resolution_mode =
51 .
description(
"Values larger than the threshold are inside the generated mesh");
55 const bNode *node =
b.node_or_null();
56 if (node !=
nullptr) {
87 resolution.settings.voxel_amount = std::max(
params.get_input<
float>(
"Voxel Amount"), 0.0f);
90 resolution.settings.voxel_size = std::max(
params.get_input<
float>(
"Voxel Size"), 0.0f);
96static Mesh *create_mesh_from_volume_grids(Span<const openvdb::GridBase *> grids,
98 const float threshold,
99 const float adaptivity,
100 const bke::VolumeToMeshResolution &resolution)
102 Array<bke::VolumeToMeshDataResult> mesh_data(grids.size());
103 for (
const int i : grids.index_range()) {
104 bke::VolumeToMeshDataResult &result = mesh_data[i];
105 result = bke::volume_to_mesh_data(*grids[i], resolution, threshold, adaptivity);
106 if (!result.error.empty()) {
107 params.error_message_add(NodeWarningType::Error, result.error);
114 Array<int> vert_offsets(mesh_data.size());
115 Array<int> face_offsets(mesh_data.size());
116 Array<int> loop_offsets(mesh_data.size());
117 for (
const int i : grids.index_range()) {
118 const bke::OpenVDBMeshData &data = mesh_data[i].data;
119 vert_offsets[i] = vert_offset;
120 face_offsets[i] = face_offset;
121 loop_offsets[i] = loop_offset;
122 vert_offset += data.verts.size();
123 face_offset += (data.tris.size() + data.quads.size());
124 loop_offset += (3 * data.tris.size() + 4 * data.quads.size());
129 MutableSpan<float3> positions = mesh->vert_positions_for_write();
130 MutableSpan<int> dst_face_offsets = mesh->face_offsets_for_write();
131 MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
133 for (
const int i : grids.index_range()) {
134 const bke::OpenVDBMeshData &data = mesh_data[i].data;
135 bke::fill_mesh_from_openvdb_data(data.verts,
149 mesh->tag_overlapping_none();
156static Mesh *create_mesh_from_volume(GeometrySet &geometry_set, GeoNodeExecParams &
params)
158 const Volume *volume = geometry_set.get_volume();
159 if (volume ==
nullptr) {
163 const bke::VolumeToMeshResolution resolution = get_resolution_param(
params);
166 resolution.settings.voxel_size <= 0.0f)
171 resolution.settings.voxel_amount <= 0)
178 Vector<bke::VolumeTreeAccessToken> tree_tokens;
179 Vector<const openvdb::GridBase *> grids;
182 tree_tokens.append_as();
183 grids.append(&volume_grid->grid(tree_tokens.last()));
186 if (grids.is_empty()) {
190 return create_mesh_from_volume_grids(grids,
192 params.get_input<
float>(
"Threshold"),
193 params.get_input<
float>(
"Adaptivity"),
204 Mesh *mesh = create_mesh_from_volume(geometry_set,
params);
208 params.set_output(
"Mesh", std::move(geometry_set));
221 "Use resolution of the volume grid"},
226 "Desired number of voxels along one axis"},
231 "Desired voxel side length"},
232 {0,
nullptr, 0,
nullptr,
nullptr},
238 "How the voxel size is specified",
239 resolution_mode_items,
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(struct 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
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 BLT_I18NCONTEXT_ID_ID
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)
#define NOD_storage_enum_accessors(member)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void make_available(bNode &node) const
std::string translation_context
local_group_size(16, 16) .push_constant(Type b
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_size(bNodeType *ntype, int width, int minwidth, int maxwidth)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
void debug_randomize_mesh_order(Mesh *mesh)
static void node_register()
static void node_declare(NodeDeclarationBuilder &b)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_rna(StructRNA *srna)
static void node_geo_exec(GeoNodeExecParams params)
static void node_init(bNodeTree *, bNode *node)
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 ¶ms)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
void keep_only_during_modify(Span< GeometryComponent::Type > component_types)
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
VolumeToMeshResolutionMode mode
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare