8# include "util/nanovdb.h"
12# include <openvdb/tools/Activate.h>
14# include <nanovdb/util/ForEach.h>
16# if NANOVDB_MAJOR_VERSION_NUMBER > 32 || \
17 (NANOVDB_MAJOR_VERSION_NUMBER == 32 && NANOVDB_MINOR_VERSION_NUMBER >= 7)
18# include <nanovdb/tools/CreateNanoGrid.h>
20# include <nanovdb/util/OpenToNanoVDB.h>
30template<
typename NanoBuildT>
class NanoToOpenVDBMask {
31 using NanoNode0 = nanovdb::LeafNode<NanoBuildT, openvdb::Coord, openvdb::util::NodeMask>;
32 using NanoNode1 = nanovdb::InternalNode<NanoNode0>;
33 using NanoNode2 = nanovdb::InternalNode<NanoNode1>;
34 using NanoRootT = nanovdb::RootNode<NanoNode2>;
35 using NanoTreeT = nanovdb::Tree<NanoRootT>;
36 using NanoGridT = nanovdb::Grid<NanoTreeT>;
37 using NanoValueT =
typename NanoGridT::ValueType;
39 using OpenBuildT = openvdb::ValueMask;
40 using OpenNode0 = openvdb::tree::LeafNode<OpenBuildT, NanoNode0::LOG2DIM>;
41 using OpenNode1 = openvdb::tree::InternalNode<OpenNode0, NanoNode1::LOG2DIM>;
42 using OpenNode2 = openvdb::tree::InternalNode<OpenNode1, NanoNode2::LOG2DIM>;
43 using OpenRootT = openvdb::tree::RootNode<OpenNode2>;
44 using OpenTreeT = openvdb::tree::Tree<OpenRootT>;
45 using OpenGridT = openvdb::Grid<OpenTreeT>;
46 using OpenValueT =
typename OpenGridT::ValueType;
49 NanoToOpenVDBMask() =
default;
53 template<
typename NanoNodeT,
typename OpenNodeT>
54 OpenNodeT *processNode(
const NanoNodeT * );
56 OpenNode2 *
process(
const NanoNode2 *node)
58 return this->
template processNode<NanoNode2, OpenNode2>(node);
60 OpenNode1 *
process(
const NanoNode1 *node)
62 return this->
template processNode<NanoNode1, OpenNode1>(node);
65 template<
typename NanoLeafT> OpenNode0 *
process(
const NanoLeafT *node);
68template<
typename NanoBuildT>
69typename NanoToOpenVDBMask<NanoBuildT>::OpenGridT::Ptr NanoToOpenVDBMask<NanoBuildT>::operator()(
74 const NanoGridT *srcGrid =
reinterpret_cast<const NanoGridT *
>(&grid);
75 auto dstGrid = openvdb::createGrid<OpenGridT>(OpenValueT());
78 const nanovdb::Map &nanoMap =
reinterpret_cast<const nanovdb::GridData *
>(srcGrid)->mMap;
79 auto mat = openvdb::math::Mat4<double>::identity();
80 mat.setMat3(openvdb::math::Mat3<double>(nanoMap.mMatD));
81 mat = mat.transpose();
82 mat.setTranslation(openvdb::math::Vec3<double>(nanoMap.mVecD));
83 dstGrid->setTransform(openvdb::math::Transform::createLinearTransform(mat));
86 auto &root = dstGrid->tree().root();
87 auto *
data = srcGrid->tree().root().data();
88 for (uint32_t
i = 0;
i <
data->mTableSize; ++
i) {
90 if (
tile->isChild()) {
94 root.addTile(
tile->origin(), OpenValueT(),
tile->state);
102template<
typename SrcNodeT,
typename DstNodeT>
103DstNodeT *NanoToOpenVDBMask<T>::processNode(
const SrcNodeT *srcNode)
105 DstNodeT *dstNode =
new DstNodeT();
106 dstNode->setOrigin(srcNode->origin());
107 const auto &childMask = srcNode->childMask();
108 const_cast<typename DstNodeT::NodeMaskType &
>(dstNode->getValueMask()) = srcNode->valueMask();
109 const_cast<typename DstNodeT::NodeMaskType &
>(dstNode->getChildMask()) = childMask;
110 auto *dstTable =
const_cast<typename DstNodeT::UnionType *
>(dstNode->getTable());
111 auto *srcData = srcNode->data();
112 std::vector<std::pair<uint32_t, const typename SrcNodeT::ChildNodeType *>> childNodes;
113 const auto childCount = childMask.countOn();
114 childNodes.reserve(childCount);
115 for (uint32_t n = 0; n < DstNodeT::NUM_VALUES; ++n) {
116 if (childMask.isOn(n)) {
117 childNodes.emplace_back(n, srcData->getChild(n));
120 auto kernel = [&](
const auto &r) {
121 for (
auto i = r.begin();
i != r.end(); ++
i) {
122 auto &p = childNodes[
i];
123 dstTable[p.first].setChild(this->
process(p.second));
127# if NANOVDB_MAJOR_VERSION_NUMBER > 32 || \
128 (NANOVDB_MAJOR_VERSION_NUMBER == 32 && NANOVDB_MINOR_VERSION_NUMBER >= 7)
129 nanovdb::util::forEach(0, childCount, 1, kernel);
131 nanovdb::forEach(0, childCount, 1, kernel);
138template<
typename NanoLeafT>
139inline typename NanoToOpenVDBMask<T>::OpenNode0 *NanoToOpenVDBMask<T>::process(
140 const NanoLeafT *srcNode)
142 static_assert(std::is_same_v<NanoLeafT, NanoNode0>,
"NanoToOpenVDBMask wrong leaf type");
143 OpenNode0 *dstNode =
new OpenNode0();
144 dstNode->setOrigin(srcNode->origin());
145 dstNode->setValueMask(srcNode->valueMask());
150struct NanoToOpenVDBMaskOp {
151 openvdb::MaskGrid::Ptr mask_grid;
155 NanoToOpenVDBMask<NanoBuildT> tmp;
156 mask_grid = tmp(grid);
161template<
typename OpType>
162bool nanovdb_grid_type_operation(
const nanovdb::GridHandle<> &handle, OpType &&op)
166 if (
const auto *grid = handle.template grid<float>(n)) {
169 if (
const auto *grid = handle.template grid<nanovdb::Fp16>(n)) {
172 if (
const auto *grid = handle.template grid<nanovdb::FpN>(n)) {
175 if (
const auto *grid = handle.template grid<nanovdb::Vec3f>(n)) {
178 if (
const auto *grid = handle.template grid<nanovdb::Vec4f>(n)) {
182 assert(!
"Unknown NanoVDB grid type");
186openvdb::MaskGrid::Ptr nanovdb_to_openvdb_mask(
const nanovdb::GridHandle<> &handle)
188 NanoToOpenVDBMaskOp op;
189 nanovdb_grid_type_operation(handle, op);
196 nanovdb::GridHandle<> nanogrid;
198 float clipping = 0.0f;
200 template<
typename Gr
idType,
typename FloatDataType, const
int channels>
201 bool operator()(
const typename GridType::ConstPtr &grid)
203 if constexpr (std::is_same_v<GridType, openvdb::MaskGrid>) {
208# if NANOVDB_MAJOR_VERSION_NUMBER > 32 || \
209 (NANOVDB_MAJOR_VERSION_NUMBER == 32 && NANOVDB_MINOR_VERSION_NUMBER >= 6)
210# if NANOVDB_MAJOR_VERSION_NUMBER > 32 || \
211 (NANOVDB_MAJOR_VERSION_NUMBER == 32 && NANOVDB_MINOR_VERSION_NUMBER >= 7)
213 using nanovdb::tools::createNanoGrid;
214 using nanovdb::tools::StatsMode;
217 using nanovdb::createNanoGrid;
218 using nanovdb::StatsMode;
221 if constexpr (std::is_same_v<GridType, openvdb::FloatGrid>) {
222 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
223 if (precision == 0) {
224 nanogrid = createNanoGrid<openvdb::FloatGrid, nanovdb::FpN>(*floatgrid,
227 else if (precision == 16) {
228 nanogrid = createNanoGrid<openvdb::FloatGrid, nanovdb::Fp16>(*floatgrid,
232 nanogrid = createNanoGrid<openvdb::FloatGrid, float>(*floatgrid, StatsMode::Disable);
235 else if constexpr (std::is_same_v<GridType, openvdb::Vec3fGrid>) {
238 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
239 nanogrid = createNanoGrid<openvdb::Vec3fGrid, nanovdb::Vec3f>(*floatgrid,
242 else if constexpr (std::is_same_v<GridType, openvdb::Vec4fGrid>) {
243 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
244 nanogrid = createNanoGrid<openvdb::Vec4fGrid, nanovdb::Vec4f>(*floatgrid,
249 if constexpr (std::is_same_v<GridType, openvdb::FloatGrid>) {
250 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
251 if (precision == 0) {
252 nanogrid = nanovdb::openToNanoVDB<nanovdb::HostBuffer, openvdb::FloatTree, nanovdb::FpN>(
255 else if (precision == 16) {
257 nanovdb::openToNanoVDB<nanovdb::HostBuffer, openvdb::FloatTree, nanovdb::Fp16>(
261 nanogrid = nanovdb::openToNanoVDB(*floatgrid);
264 else if constexpr (std::is_same_v<FloatGridType, openvdb::Vec3fGrid>) {
265 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
266 nanogrid = nanovdb::openToNanoVDB(*floatgrid);
268 else if constexpr (std::is_same_v<FloatGridType, openvdb::Vec4fGrid>) {
269 typename GridType::ConstPtr floatgrid = apply_clipping<GridType>(grid);
270 nanogrid = nanovdb::openToNanoVDB(*floatgrid);
274 catch (
const std::exception &
e) {
275 LOG_ERROR <<
"Error converting OpenVDB to NanoVDB grid: " <<
e.what();
278 LOG_ERROR <<
"Error converting OpenVDB to NanoVDB grid: Unknown error";
283 template<
typename Gr
idT>
284 typename GridT::ConstPtr apply_clipping(
const typename GridT::ConstPtr &grid)
const
286 if (clipping == 0.0f) {
291 typename GridT::Ptr newgrid = grid->deepCopy();
292 openvdb::tools::deactivate(
293 *newgrid,
typename GridT::ValueType(0.0f),
typename GridT::ValueType(clipping));
298nanovdb::GridHandle<> openvdb_to_nanovdb(
const openvdb::GridBase::ConstPtr &grid,
300 const float clipping)
303 op.precision = precision;
304 op.clipping = clipping;
305 openvdb_grid_type_operation(grid, op);
306 return std::move(op.nanogrid);
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void process(btMatrix3x3 &B, btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V)
Helper function of 3X3 SVD for processing 2X2 SVD.
#define CCL_NAMESPACE_END
#define assert(assertion)
const ccl_global KernelWorkTile * tile
Grid< NanoTree< BuildT > > NanoGrid