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.
3 changed files with 149 additions and 144 deletions
Showing only changes of commit 54cc5d17e1 - Show all commits

View File

@ -34,58 +34,58 @@ namespace blender::bke {
* directly from the struct rather than storing a pointer to avoid more complicated ownership
* handling.
*/
// class VolumeGeometry : public ::VolumeGeometry {
// public:
// VolumeGeometry();
// VolumeGeometry(const VolumeGeometry &other);
// VolumeGeometry(VolumeGeometry &&other);
// VolumeGeometry &operator=(const VolumeGeometry &other);
// VolumeGeometry &operator=(VolumeGeometry &&other);
// ~VolumeGeometry();
//
// /* --------------------------------------------------------------------
// * Accessors.
// */
//
// /**
// * The total number of control points in all curves.
// */
// int cells_num() const;
// IndexRange cells_range() const;
//
// /**
// * The largest and smallest position values of evaluated points.
// */
// std::optional<Bounds<float3>> bounds_min_max() const;
//
// /* --------------------------------------------------------------------
// * Operations.
// */
//
// public:
// /** Call after operations changing the grid tree topology. */
// void tag_tree_changed();
//
// AttributeAccessor attributes() const;
// MutableAttributeAccessor attributes_for_write();
//
// /* --------------------------------------------------------------------
// * Attributes.
// */
//
// GVArray adapt_domain(const GVArray &varray, eAttrDomain from, eAttrDomain to) const;
// template<typename T>
// VArray<T> adapt_domain(const VArray<T> &varray, eAttrDomain from, eAttrDomain to) const
// {
// return this->adapt_domain(GVArray(varray), from, to).typed<T>();
// }
//
// /* --------------------------------------------------------------------
// * File Read/Write.
// */
//
// void blend_read(BlendDataReader &reader);
// void blend_write(BlendWriter &writer, ID &id);
// };
class VolumeGeometry : public ::VolumeGeometry {
public:
VolumeGeometry();
VolumeGeometry(const VolumeGeometry &other);
VolumeGeometry(VolumeGeometry &&other);
VolumeGeometry &operator=(const VolumeGeometry &other);
VolumeGeometry &operator=(VolumeGeometry &&other);
~VolumeGeometry();
/* --------------------------------------------------------------------
* Accessors.
*/
/**
* The total number of control points in all curves.
*/
int cells_num() const;
IndexRange cells_range() const;
/**
* The largest and smallest position values of evaluated points.
*/
std::optional<Bounds<float3>> bounds_min_max() const;
/* --------------------------------------------------------------------
* Operations.
*/
public:
/** Call after operations changing the grid tree topology. */
void tag_tree_changed();
AttributeAccessor attributes() const;
MutableAttributeAccessor attributes_for_write();
/* --------------------------------------------------------------------
* Attributes.
*/
GVArray adapt_domain(const GVArray &varray, eAttrDomain from, eAttrDomain to) const;
template<typename T>
VArray<T> adapt_domain(const VArray<T> &varray, eAttrDomain from, eAttrDomain to) const
{
return this->adapt_domain(GVArray(varray), from, to).typed<T>();
}
/* --------------------------------------------------------------------
* File Read/Write.
*/
void blend_read(BlendDataReader &reader);
void blend_write(BlendWriter &writer, ID &id);
};
} // namespace blender::bke

View File

@ -1832,93 +1832,93 @@ 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;
// }
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;
}
/** \} */

View File

@ -17,6 +17,11 @@ extern "C" {
struct PackedFile;
struct VolumeGridVector;
// struct VolumeGrids;
#ifdef _cplusplus
using GridHandle = openvdb::GridBase::Ptr;
#else
struct GridHandle;
#endif
typedef struct Volume_Runtime {
/** OpenVDB Grids. */
@ -52,9 +57,9 @@ typedef struct VolumeRender {
float clipping;
} VolumeRender;
// typedef struct VolumeGeometry {
// struct VolumeGrids *grids;
// } VolumeGeometry;
typedef struct VolumeGeometry {
GridHandle grid;
} VolumeGeometry;
typedef struct Volume {
ID id;
@ -100,7 +105,7 @@ typedef struct Volume {
float velocity_scale;
/* Grid geometry */
// VolumeGeometry geometry;
VolumeGeometry geometry;
/* Draw Cache */
void *batch_cache;