Add a simple node to compute the intersection, difference, or union between SDF grids. This should be the first new use case for the new volume grid nodes that wasn't possible before. For naming and multi-inputs, the node uses the same design as the mesh boolean node. We considered splitting each operation into a separate node, but though most users considered these different "modes" of the same operation. One thing to keep in mind is that it's important for the grids to have exactly the same transform. If they have different transforms, the second grid must be resampled to match the first, because the OpenVDB CSG tools have that requirement. Resampling is expensive (for SDF grids it means a grid -> mesh -> grid round trip) and should be avoided. Pull Request: https://projects.blender.org/blender/blender/pulls/118879
39 lines
1.2 KiB
C++
39 lines
1.2 KiB
C++
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#ifdef WITH_OPENVDB
|
|
|
|
# include "BKE_volume_grid.hh"
|
|
|
|
# include "GEO_volume_grid_resample.hh"
|
|
|
|
# include <openvdb/openvdb.h>
|
|
# include <openvdb/tools/GridTransformer.h>
|
|
|
|
namespace blender::geometry {
|
|
|
|
openvdb::FloatGrid &resample_sdf_grid_if_necessary(bke::VolumeGrid<float> &volume_grid,
|
|
bke::VolumeTreeAccessToken &tree_token,
|
|
const openvdb::math::Transform &transform,
|
|
std::shared_ptr<openvdb::FloatGrid> &storage)
|
|
{
|
|
const openvdb::FloatGrid &grid = volume_grid.grid(tree_token);
|
|
if (grid.transform() == transform) {
|
|
return volume_grid.grid_for_write(tree_token);
|
|
}
|
|
|
|
storage = openvdb::FloatGrid::create();
|
|
storage->setTransform(transform.copy());
|
|
|
|
/* TODO: Using #doResampleToMatch when the transform is affine and non-scaled may be faster. */
|
|
openvdb::tools::resampleToMatch<openvdb::tools::BoxSampler>(grid, *storage);
|
|
openvdb::tools::pruneLevelSet(storage->tree());
|
|
|
|
return *storage;
|
|
}
|
|
|
|
} // namespace blender::geometry
|
|
|
|
#endif
|