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.
1 changed files with 45 additions and 25 deletions
Showing only changes of commit 027f902488 - Show all commits

View File

@ -148,35 +148,43 @@ class VMutableArrayImpl_For_GridLeaf final
};
/* Wrapper holding an accessor for an input field. */
template<typename LeafNodeType> struct AccessorWrapper {
virtual ~AccessorWrapper() {}
template<typename GridType> struct VGridReader {
using TreeType = typename GridType::TreeType;
using LeafNodeType = typename TreeType::LeafNodeType;
virtual ~VGridReader() {}
/* VArray for a specific leaf node using the accessor. */
virtual GVArray make_varray_for_leaf(const LeafNodeType &leaf) const = 0;
///* VMutableArray for a specific leaf node using the accessor. */
// virtual GVMutableArray make_vmutablearray_for_leaf(const LeafNodeType &leaf) const = 0;
};
template<typename LeafNodeType, typename AccessorType>
struct TypedAccessorWrapper : public AccessorWrapper<LeafNodeType> {
using ValueType = typename AccessorType::ValueType;
/* Wrapper holding an accessor for an input field. */
template<typename GridType> struct VGridWriter {
using TreeType = typename GridType::TreeType;
using LeafNodeType = typename TreeType::LeafNodeType;
virtual ~VGridWriter() {}
/* VMutableArray for a specific leaf node using the accessor. */
virtual GVMutableArray make_varray_for_leaf(const LeafNodeType &leaf) const = 0;
};
template<typename GridType, typename AccessorType>
struct VGridReader_For_Accessor : public VGridReader<GridType> {
using TreeType = typename GridType::TreeType;
using LeafNodeType = typename TreeType::LeafNodeType;
AccessorType accessor_;
TypedAccessorWrapper(const AccessorType &accessor) : accessor_(accessor) {}
virtual ~TypedAccessorWrapper() {}
VGridReader_For_Accessor(const AccessorType &accessor) : accessor_(accessor) {}
virtual ~VGridReader_For_Accessor() {}
virtual GVArray make_varray_for_leaf(const LeafNodeType &leaf) const override
GVArray make_varray_for_leaf(const LeafNodeType &leaf) const override
{
using VArrayImplType = VArrayImpl_For_GridLeaf<AccessorType, LeafNodeType>;
using ValueType = typename AccessorType::ValueType;
return VArray<ValueType>::template For<VArrayImplType>(accessor_, leaf);
}
// virtual GVMutableArray make_vmutablearray_for_leaf(const LeafNodeType &leaf) const override
//{
// using VMutableArrayImplType = VMutableArrayImpl_For_GridLeaf<AccessorType, LeafNodeType>;
// return VMutableArray<ValueType>::For<VMutableArrayImplType>(accessor_, leaf);
// }
};
template<typename GridType, typename MaskGridType> struct EvalPerLeafOp {
@ -187,7 +195,8 @@ template<typename GridType, typename MaskGridType> struct EvalPerLeafOp {
using ValueType = typename GridType::ValueType;
using LeafNode = typename TreeType::LeafNodeType;
using AccessorWrapperType = AccessorWrapper<LeafNode>;
using GridReaderType = VGridReader<GridType>;
using GridReaderPtr = std::shared_ptr<GridReaderType>;
using Coord = openvdb::Coord;
const int32_t leaf_size = LeafNode::size();
@ -204,21 +213,21 @@ template<typename GridType, typename MaskGridType> struct EvalPerLeafOp {
/* XXX have to use shared_ptr instead of unique_ptr because some parts
* of BLI_memory_utils try to copy the values and that's forbidden for unique_ptr.
*/
Array<std::shared_ptr<AccessorWrapperType>> input_accessors_;
Array<GridReaderPtr> input_readers_;
void make_input_accessors(Span<GGrid> field_context_inputs)
{
input_accessors_.reinitialize(field_context_inputs.size());
input_readers_.reinitialize(field_context_inputs.size());
for (const int i : field_context_inputs.index_range()) {
volume::grid_to_static_type(field_context_inputs[i].grid_, [&](auto &input_grid) {
using InputGridType = typename std::decay<decltype(input_grid)>::type;
using AccessorType = typename InputGridType::ConstAccessor;
std::shared_ptr<AccessorWrapperType> accessor_ptr =
std::make_shared<TypedAccessorWrapper<LeafNode, AccessorType>>(
GridReaderPtr reader_ptr =
std::make_shared<VGridReader_For_Accessor<GridType, AccessorType>>(
input_grid.getConstAccessor());
input_accessors_[i] = std::move(accessor_ptr);
input_readers_[i] = std::move(reader_ptr);
});
}
}
@ -233,7 +242,7 @@ template<typename GridType, typename MaskGridType> struct EvalPerLeafOp {
EvalPerLeafOp(const EvalPerLeafOp &other)
: procedure_executor_(other.procedure_executor_),
mask_accessor_(other.mask_accessor_),
input_accessors_(other.input_accessors_)
input_readers_(other.input_readers_)
{
}
@ -255,8 +264,8 @@ template<typename GridType, typename MaskGridType> struct EvalPerLeafOp {
mf::ParamsBuilder mf_params{procedure_executor_, &index_mask};
/* Provide inputs to the procedure executor. */
for (const std::shared_ptr<AccessorWrapperType> &accessor_wrapper : input_accessors_) {
mf_params.add_readonly_single_input(accessor_wrapper->make_varray_for_leaf(leaf));
for (const GridReaderPtr &input_reader : input_readers_) {
mf_params.add_readonly_single_input(input_reader->make_varray_for_leaf(leaf));
}
/* Pass output buffer to the procedure executor. */
@ -334,6 +343,17 @@ void evaluate_procedure_on_varying_volume_fields(ResourceScope &scope,
volume::grid_to_static_type(dst_grid_ptr->grid_, [&](auto &dst_grid) {
using GridType = typename std::decay<decltype(dst_grid)>::type;
/* Make sure every active tile has leaf node buffers to write into.
* A tree can have active (non-leaf) tiles with only the background value.
* We need to "densify" these tiles so that the leaf iterator actually
* yields buffers on which we can evaluate the multifunction.
* XXX Ideally we'd be able to determine in advance if all values
* in a leaf node would be constant, and only evaluate the background value!
*/
dst_grid.tree().voxelizeActiveTiles();
//std::cout << "Grid: ";
//dst_grid.print(std::cout, 2);
volume::grid_to_static_type(mask.grid_, [&](auto &mask_grid) {
using MaskGridType = typename std::decay<decltype(mask_grid)>::type;