WIP: Volume grid attribute support in geometry nodes #110044
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue