Mesh to BoolGrid? Is that possible?

147 views
Skip to first unread message

Víctor M. Feliz

unread,
Jun 19, 2023, 1:41:42 PM6/19/23
to OpenVDB Forum
Is known that you can get a LevelSet or a SDF from mesh with the tools you can get at openvdb::tools but is there anything similar to create a binary tree?

Thank you in advance.

andre pradhana

unread,
Jun 23, 2023, 2:17:15 AM6/23/23
to OpenVDB Forum
Hello,

One way to do this is to create the Bool Grid as a post-process step after you obtain a level-set (openvdb::FloatGrid) from converting your mesh to an SDF. For example, you can do the following to get a Bool Grid where voxel values near the zero iso-contour are true:
    openvdb::FloatGrid::Ptr sdf = ... ;
    auto voxelSize = sdf->voxelSize();

    // Create a boolgrid that is true near the zero iso-contour of the level-set
    openvdb::BoolGrid::Ptr bGrid = openvdb::BoolGrid::create(false);
    bGrid->tree().topologyUnion(sdf->tree());
    openvdb::tree::NodeManager<openvdb::BoolTree> nodeManager(bGrid->tree());
    TrueNearZeroKernel op(voxelSize.length(), sdf);
    nodeManager.foreachTopDown(op, true /* = threaded*/, 1 /* = grainSize*/);
    bGrid->setTransform(sdf->transform().copy());

    // Write boolgrid to a file
    openvdb::io::File file("boolgrid.vdb");
    openvdb::GridPtrVec grids;
    grids.push_back(bGrid);
    file.write(grids);
    file.close();

Here's the definition of the kernel used in the example:
struct TrueNearZeroKernel {
    TrueNearZeroKernel(float epsilon, openvdb::FloatGrid::Ptr sdf) : mEpsilon(epsilon), mSdf(sdf) {}

    // Root node, internal nodes, and leaf nodes
    template<typename NodeT>
    void operator()(NodeT& node, size_t = 1) const
    {
        openvdb::FloatGrid::Accessor acc = mSdf->getAccessor();
        for (auto iter = node.beginValueAll(); iter; ++iter) {
            auto const ijk = iter.getCoord();
            if (std::abs(acc.getValue(ijk)) < mEpsilon) {
                iter.setValue(true);
            } else {
                iter.setValue(false);
            }
        }
    }

  float mEpsilon;
  openvdb::FloatGrid::Ptr mSdf;
};// TrueNearZeroKernel

Note that you need to include #include <openvdb/tree/NodeManager.h>.
Reply all
Reply to author
Forward
0 new messages