This patch implements basic support for evaluating function nodes on volume grids. Conceptually, a function node always creates a new grid for the output, though the output is often a modified version of the input. The topology of the output grid is a union of all the input grids. All input grids have to have the same transform. Otherwise one has to use resampling to make grids compatible. Non-grid inputs are allowed to be single values or fields. The fields are evaluated in a voxel/tile context, so they compute a value per voxel or per tile. One optimization is missing that will probably be key in the future: the ability to merge multiple function nodes and execute them at the same time. Currently the entire function evaluation is started and finished for every function node that outputs a grid. This will add significant overhead in some situations. Implementing this optimization requires some more changes outside of the scope of this patch though. It's good to have something that works first. Note: Not all function nodes are supported yet, because we don't have grid types for all of them yet. Most notably, there are no color/float4 grids yet. Implementing those properly is not super straight forward and may require some more changes, because there isn't a 1-to-1 mapping between grid types and socket types (a float4 grid may correspond to a color or vector socket later on). Using grids with function nodes and fields can result in false positive warnings in the UI currently. That's a limitation of our current socket type inferencing and can be improved once we have better socket shape inferencing. Pull Request: https://projects.blender.org/blender/blender/pulls/125110
117 lines
4.1 KiB
C++
117 lines
4.1 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#ifdef WITH_OPENVDB
|
|
|
|
# include <openvdb/openvdb.h> /* IWYU pragma: export */
|
|
# include <openvdb/points/PointDataGrid.h> /* IWYU pragma: export */
|
|
# include <optional>
|
|
|
|
# include "BLI_bounds_types.hh"
|
|
# include "BLI_math_matrix_types.hh"
|
|
# include "BLI_math_vector_types.hh"
|
|
# include "BLI_parameter_pack_utils.hh"
|
|
# include "BLI_string_ref.hh"
|
|
|
|
# include "BKE_volume_enums.hh"
|
|
# include "BKE_volume_grid_fwd.hh"
|
|
|
|
# include "openvdb_fwd.hh"
|
|
|
|
struct Volume;
|
|
|
|
blender::bke::VolumeGridData *BKE_volume_grid_add_vdb(Volume &volume,
|
|
blender::StringRef name,
|
|
openvdb::GridBase::Ptr vdb_grid);
|
|
|
|
void BKE_volume_metadata_set(Volume &volume, openvdb::MetaMap::Ptr metadata);
|
|
|
|
std::optional<blender::Bounds<blender::float3>> BKE_volume_grid_bounds(
|
|
openvdb::GridBase::ConstPtr grid);
|
|
|
|
/**
|
|
* Return a new grid pointer with only the metadata and transform changed.
|
|
* This is useful for instances, where there is a separate transform on top of the original
|
|
* grid transform that must be applied for some operations that only take a grid argument.
|
|
*/
|
|
openvdb::GridBase::ConstPtr BKE_volume_grid_shallow_transform(openvdb::GridBase::ConstPtr grid,
|
|
const blender::float4x4 &transform);
|
|
|
|
blender::float4x4 BKE_volume_transform_to_blender(const openvdb::math::Transform &transform);
|
|
openvdb::math::Transform BKE_volume_transform_to_openvdb(const blender::float4x4 &transform);
|
|
|
|
template<typename OpType>
|
|
auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
|
|
{
|
|
switch (grid_type) {
|
|
case VOLUME_GRID_FLOAT:
|
|
return op.template operator()<openvdb::FloatGrid>();
|
|
case VOLUME_GRID_VECTOR_FLOAT:
|
|
return op.template operator()<openvdb::Vec3fGrid>();
|
|
case VOLUME_GRID_BOOLEAN:
|
|
return op.template operator()<openvdb::BoolGrid>();
|
|
case VOLUME_GRID_DOUBLE:
|
|
return op.template operator()<openvdb::DoubleGrid>();
|
|
case VOLUME_GRID_INT:
|
|
return op.template operator()<openvdb::Int32Grid>();
|
|
case VOLUME_GRID_INT64:
|
|
return op.template operator()<openvdb::Int64Grid>();
|
|
case VOLUME_GRID_VECTOR_INT:
|
|
return op.template operator()<openvdb::Vec3IGrid>();
|
|
case VOLUME_GRID_VECTOR_DOUBLE:
|
|
return op.template operator()<openvdb::Vec3dGrid>();
|
|
case VOLUME_GRID_MASK:
|
|
return op.template operator()<openvdb::MaskGrid>();
|
|
case VOLUME_GRID_POINTS:
|
|
return op.template operator()<openvdb::points::PointDataGrid>();
|
|
case VOLUME_GRID_UNKNOWN:
|
|
break;
|
|
}
|
|
|
|
/* Should never be called. */
|
|
BLI_assert_msg(0, "should never be reached");
|
|
return op.template operator()<openvdb::FloatGrid>();
|
|
}
|
|
|
|
template<typename Fn>
|
|
void BKE_volume_grid_type_to_static_type(const VolumeGridType grid_type, Fn &&fn)
|
|
{
|
|
switch (grid_type) {
|
|
case VOLUME_GRID_FLOAT:
|
|
return fn(blender::TypeTag<openvdb::FloatGrid>());
|
|
case VOLUME_GRID_VECTOR_FLOAT:
|
|
return fn(blender::TypeTag<openvdb::Vec3fGrid>());
|
|
case VOLUME_GRID_BOOLEAN:
|
|
return fn(blender::TypeTag<openvdb::BoolGrid>());
|
|
case VOLUME_GRID_DOUBLE:
|
|
return fn(blender::TypeTag<openvdb::DoubleGrid>());
|
|
case VOLUME_GRID_INT:
|
|
return fn(blender::TypeTag<openvdb::Int32Grid>());
|
|
case VOLUME_GRID_INT64:
|
|
return fn(blender::TypeTag<openvdb::Int64Grid>());
|
|
case VOLUME_GRID_VECTOR_INT:
|
|
return fn(blender::TypeTag<openvdb::Vec3IGrid>());
|
|
case VOLUME_GRID_VECTOR_DOUBLE:
|
|
return fn(blender::TypeTag<openvdb::Vec3dGrid>());
|
|
case VOLUME_GRID_MASK:
|
|
return fn(blender::TypeTag<openvdb::MaskGrid>());
|
|
case VOLUME_GRID_POINTS:
|
|
return fn(blender::TypeTag<openvdb::points::PointDataGrid>());
|
|
case VOLUME_GRID_UNKNOWN:
|
|
break;
|
|
}
|
|
BLI_assert_unreachable();
|
|
}
|
|
|
|
openvdb::GridBase::Ptr BKE_volume_grid_create_with_changed_resolution(
|
|
const VolumeGridType grid_type, const openvdb::GridBase &old_grid, float resolution_factor);
|
|
|
|
#endif
|