6# include <openvdb/tools/GridTransformer.h>
7# include <openvdb/tools/VolumeToMesh.h>
32 .supported_type(GeometryComponent::Type::Volume)
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")
45 .make_available([](
bNode &node) {
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());
104 bke::VolumeToMeshDataResult &
result = mesh_data[
i];
105 result = bke::volume_to_mesh_data(*grids[
i], resolution, threshold, adaptivity);
106 if (!
result.error.empty()) {
114 Array<int> vert_offsets(mesh_data.size());
115 Array<int> face_offsets(mesh_data.size());
116 Array<int> loop_offsets(mesh_data.size());
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();
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)
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)
183 grids.
append(&volume_grid->grid(tree_tokens.
last()));
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,
248 ntype.
ui_name =
"Volume to Mesh";
249 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 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)
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)
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 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, 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_during_modify(Span< GeometryComponent::Type > component_types)
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
VolumeToMeshResolutionMode mode
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
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)