WIP: Volume grid attribute support in geometry nodes #110044

Closed
Lukas Tönne wants to merge 130 commits from LukasTonne/blender:geometry-nodes-flip into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 114 additions and 138 deletions
Showing only changes of commit db75107fff - Show all commits

View File

@ -278,4 +278,6 @@ VolumeGrid *BKE_volume_grid_attribute_add_vdb(Volume &volume,
openvdb::GridBase::Ptr vdb_grid);
# endif // WITH_OPENVDB
void BKE_volume_grid_free(VolumeGrid *grid);
#endif

View File

@ -84,8 +84,20 @@ class VolumeGeometry : public ::VolumeGeometry {
* File Read/Write.
*/
void blend_read(BlendDataReader &reader);
void blend_read_data(BlendDataReader &reader);
void blend_write(BlendWriter &writer, ID &id);
protected:
void free_grid(Volume);
};
} // namespace blender::bke
inline blender::bke::VolumeGeometry &VolumeGeometry::wrap()
{
return *reinterpret_cast<blender::bke::VolumeGeometry *>(this);
}
inline const blender::bke::VolumeGeometry &VolumeGeometry::wrap() const
{
return *reinterpret_cast<const blender::bke::VolumeGeometry *>(this);
}

View File

@ -311,6 +311,7 @@ set(SRC
intern/vfontdata_freetype.c
intern/viewer_path.cc
intern/volume.cc
intern/volume_geometry.cc
intern/volume_render.cc
intern/volume_to_mesh.cc
intern/workspace.cc
@ -503,7 +504,7 @@ set(SRC
BKE_vfontdata.h
BKE_viewer_path.h
BKE_volume.h
BKE_volume.hh
BKE_volume_geometry.hh
BKE_volume_render.h
BKE_volume_to_mesh.hh
BKE_workspace.h

View File

@ -15,7 +15,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_volume.h"
#include "BKE_volume.hh"
#include "BKE_volume_geometry.hh"
#include "attribute_access_intern.hh"
#include "volume_openvdb.hh"
@ -229,7 +229,7 @@ struct MakeGridVArrayOp {
using ValueType = typename GridType::ValueType;
using AttributeType = typename volume_openvdb::GridValueConverter<ValueType>::AttributeType;
using VArrayImplType = VArrayImpl_For_VolumeGrid<GridType>;
result = VArray<AttributeType>::For<VArrayImplType, const GridType>(std::move(grid));
result = VArray<AttributeType>::template For<VArrayImplType, const GridType>(std::move(grid));
}
};
@ -241,7 +241,7 @@ struct MakeGridVMutableArrayOp {
using ValueType = typename GridType::ValueType;
using AttributeType = typename volume_openvdb::GridValueConverter<ValueType>::AttributeType;
using VArrayImplType = VArrayImpl_For_VolumeGrid<GridType>;
result = VMutableArray<AttributeType>::For<VArrayImplType, GridType>(std::move(grid));
result = VMutableArray<AttributeType>::template For<VArrayImplType, GridType>(std::move(grid));
}
};
@ -252,8 +252,8 @@ struct CreateGridTypeOp {
template<typename CPPType> void operator()() const
{
using TreeType = openvdb::tree::Tree4<CPPType, 5, 4, 3>::Type;
using GridType = openvdb::Grid<TreeType>;
using TreeType = typename openvdb::tree::Tree4<CPPType, 5, 4, 3>::Type;
using GridType = typename openvdb::Grid<TreeType>;
result = GridType::create();
}

View File

@ -43,7 +43,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_volume.h"
#include "BKE_volume.hh"
#include "BKE_volume_geometry.hh"
#include "BLT_translation.h"
@ -500,29 +500,6 @@ struct VolumeGridVector : public std::list<VolumeGrid> {
std::string error_msg;
/* File Metadata. */
openvdb::MetaMap::Ptr metadata;
/* --------------------------------------------------------------------
* Attributes.
*/
blender::GVArray adapt_domain(const blender::GVArray &varray,
eAttrDomain from,
eAttrDomain to) const
{
if (from == to) {
return varray;
}
else {
return {};
}
}
template<typename T>
blender::VArray<T> adapt_domain(const blender::VArray<T> &varray,
eAttrDomain from,
eAttrDomain to) const
{
return this->adapt_domain(GVArray(varray), from, to).typed<T>();
}
};
#endif
@ -567,6 +544,8 @@ static void volume_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, con
#endif
volume_dst->batch_cache = nullptr;
new (&volume_dst->geometry) blender::bke::VolumeGeometry(volume_src->geometry.wrap());
}
static void volume_free_data(ID *id)
@ -579,6 +558,8 @@ static void volume_free_data(ID *id)
MEM_delete(volume->runtime.grids);
volume->runtime.grids = nullptr;
#endif
volume->geometry.wrap().~VolumeGeometry();
}
static void volume_foreach_id(ID *id, LibraryForeachIDData *data)
@ -607,8 +588,7 @@ static void volume_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Volume *volume = reinterpret_cast<Volume *>(id);
if (volume->packedfile != nullptr &&
(bpath_data->flag & BKE_BPATH_FOREACH_PATH_SKIP_PACKED) != 0)
{
(bpath_data->flag & BKE_BPATH_FOREACH_PATH_SKIP_PACKED) != 0) {
return;
}
@ -639,6 +619,8 @@ static void volume_blend_write(BlendWriter *writer, ID *id, const void *id_addre
}
BKE_packedfile_blend_write(writer, volume->packedfile);
volume->geometry.wrap().blend_write(*writer, *id);
}
static void volume_blend_read_data(BlendDataReader *reader, ID *id)
@ -652,6 +634,8 @@ static void volume_blend_read_data(BlendDataReader *reader, ID *id)
/* materials */
BLO_read_pointer_array(reader, (void **)&volume->mat);
volume->geometry.wrap().blend_read_data(*reader);
}
static void volume_blend_read_lib(BlendLibReader *reader, ID *id)
@ -1789,7 +1773,7 @@ struct CPPTypeForGridTypeOp {
template<typename GridType> void operator()(const GridType &grid)
{
using ValueType = typename GridType::ValueType;
using AttributeType = volume_openvdb::GridValueConverter<ValueType>::AttributeType;
using AttributeType = typename volume_openvdb::GridValueConverter<ValueType>::AttributeType;
result = &CPPType::get<AttributeType>();
}
};
@ -1825,101 +1809,3 @@ VolumeGrid *BKE_volume_grid_attribute_add_vdb(Volume &volume,
}
#endif
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Constructors/Destructor
* \{ */
VolumeGeometry::VolumeGeometry() {}
/**
* \note Expects `dst` to be initialized, since the original attributes must be freed.
*/
static void copy_volume_geometry(VolumeGeometry &dst, const VolumeGeometry &src)
{
dst.tree
CustomData_free(&dst.point_data, dst.point_num);
CustomData_free(&dst.curve_data, dst.curve_num);
dst.point_num = src.point_num;
dst.curve_num = src.curve_num;
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, dst.point_num);
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, dst.curve_num);
implicit_sharing::copy_shared_pointer(src.curve_offsets,
src.runtime->curve_offsets_sharing_info,
&dst.curve_offsets,
&dst.runtime->curve_offsets_sharing_info);
dst.tag_topology_changed();
/* Though type counts are a cache, they must be copied because they are calculated eagerly. */
dst.runtime->type_counts = src.runtime->type_counts;
dst.runtime->evaluated_offsets_cache = src.runtime->evaluated_offsets_cache;
dst.runtime->nurbs_basis_cache = src.runtime->nurbs_basis_cache;
dst.runtime->evaluated_position_cache = src.runtime->evaluated_position_cache;
dst.runtime->bounds_cache = src.runtime->bounds_cache;
dst.runtime->evaluated_length_cache = src.runtime->evaluated_length_cache;
dst.runtime->evaluated_tangent_cache = src.runtime->evaluated_tangent_cache;
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
}
VolumeGeometry::VolumeGeometry(const VolumeGeometry &other) : VolumeGeometry()
{
copy_volume_geometry(*this, other);
}
VolumeGeometry &VolumeGeometry::operator=(const VolumeGeometry &other)
{
if (this != &other) {
copy_volume_geometry(*this, other);
}
return *this;
}
/* The source should be empty, but in a valid state so that using it further will work. */
static void move_volume_geometry(VolumeGeometry &dst, VolumeGeometry &src)
{
dst.point_num = src.point_num;
std::swap(dst.point_data, src.point_data);
CustomData_free(&src.point_data, src.point_num);
src.point_num = 0;
dst.curve_num = src.curve_num;
std::swap(dst.curve_data, src.curve_data);
CustomData_free(&src.curve_data, src.curve_num);
src.curve_num = 0;
std::swap(dst.curve_offsets, src.curve_offsets);
std::swap(dst.runtime, src.runtime);
}
VolumeGeometry::VolumeGeometry(VolumeGeometry &&other) : VolumeGeometry()
{
move_volume_geometry(*this, other);
}
VolumeGeometry &VolumeGeometry::operator=(VolumeGeometry &&other)
{
if (this != &other) {
move_volume_geometry(*this, other);
}
return *this;
}
VolumeGeometry::~VolumeGeometry()
{
CustomData_free(&this->point_data, this->point_num);
CustomData_free(&this->curve_data, this->curve_num);
implicit_sharing::free_shared_data(&this->curve_offsets,
&this->runtime->curve_offsets_sharing_info);
MEM_delete(this->runtime);
this->runtime = nullptr;
}
/** \} */
} // namespace blender::bke

View File

@ -0,0 +1,70 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#include "DNA_volume_types.h"
#include "BKE_volume.h"
#include "BKE_volume_geometry.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Constructors/Destructor
* \{ */
VolumeGeometry::VolumeGeometry() {}
/**
* \note Expects `dst` to be initialized, since the original attributes must be freed.
*/
static void copy_volume_geometry(VolumeGeometry &dst, const VolumeGeometry &src)
{
dst.grid = src.grid;
}
VolumeGeometry::VolumeGeometry(const VolumeGeometry &other) : VolumeGeometry()
{
copy_volume_geometry(*this, other);
}
VolumeGeometry &VolumeGeometry::operator=(const VolumeGeometry &other)
{
if (this != &other) {
copy_volume_geometry(*this, other);
}
return *this;
}
/* The source should be empty, but in a valid state so that using it further will work. */
static void move_volume_geometry(VolumeGeometry &dst, VolumeGeometry &src)
{
dst.grid = src.grid;
src.grid = nullptr;
}
VolumeGeometry::VolumeGeometry(VolumeGeometry &&other) : VolumeGeometry()
{
move_volume_geometry(*this, other);
}
VolumeGeometry &VolumeGeometry::operator=(VolumeGeometry &&other)
{
if (this != &other) {
move_volume_geometry(*this, other);
}
return *this;
}
VolumeGeometry::~VolumeGeometry()
{
BKE_volume_grid_free(grid);
}
/** \} */
} // namespace blender::bke

View File

@ -16,11 +16,11 @@ extern "C" {
struct PackedFile;
struct VolumeGridVector;
// struct VolumeGrids;
#ifdef _cplusplus
using GridHandle = openvdb::GridBase::Ptr;
#else
struct GridHandle;
struct VolumeGrid;
#ifdef __cplusplus
namespace blender::bke {
class VolumeGeometry;
} // namespace blender::bke
#endif
typedef struct Volume_Runtime {
@ -58,7 +58,12 @@ typedef struct VolumeRender {
} VolumeRender;
typedef struct VolumeGeometry {
GridHandle grid;
struct VolumeGrid *grid;
#ifdef __cplusplus
blender::bke::VolumeGeometry &wrap();
const blender::bke::VolumeGeometry &wrap() const;
#endif
} VolumeGeometry;
typedef struct Volume {