openvdb icon indicating copy to clipboard operation
openvdb copied to clipboard

Value error when use csgBoolean

Open SimonNgj opened this issue 2 years ago • 4 comments

Hi, I created a simple example to try csgBoolean operation as follow:

#include <iostream>
#include <typeinfo>
#include <tuple>
#include <limits>

#include <openvdb/openvdb.h>
#include <openvdb/points/PointCount.h>
#include "openvdb/tools/GridTransformer.h"
#include "openvdb/tools/Interpolation.h"
#include "openvdb/util/Util.h"
#include <openvdb/tools/LevelSetFilter.h>
#include <openvdb/Exceptions.h>
#include <openvdb/Types.h>
#include <openvdb/tools/Filter.h>
#include <openvdb/tools/VolumeToMesh.h>
#include <openvdb/tools/LevelSetUtil.h>

using namespace std;

int main()
{
    // Initialize the OpenVDB library.  This must be called at least
    // once per program and may safely be called multiple times.
    openvdb::initialize();
    // Create an empty floating-point grid with background value 0. 
    openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create();
    grid->setGridClass(openvdb::GRID_LEVEL_SET);
    std::cout << "Testing random access:" << std::endl;
    // Get an accessor for coordinate-based access to voxels.
    openvdb::FloatGrid::Accessor accessor = grid->getAccessor();
    // Define a coordinate with large signed indices.
    openvdb::Coord xyz(30, -30, 30);

    for (int z{ 0 }; z < 8; ++z) {
        for (int y{ 0 }; y < 8; ++y) {
            for (int x{ 0 }; x < 8; ++x) {
                xyz.reset(x, y, z);
                accessor.setValue(xyz, x);
            }
        }
    }

    for (int z{ 8 }; z < 16; ++z) {
        for (int y{ 0 }; y < 8; ++y) {
            for (int x{ 0 }; x < 8; ++x) {
                xyz.reset(x, y, z);
                accessor.setValue(xyz, numeric_limits<float>::infinity());
            }
        }
    }

    openvdb::FloatGrid::Ptr grid1;
    openvdb::FloatGrid::Ptr grid2;
    if (grid != NULL) {
        grid1 = grid;
        //std::cout << "not Null1" << std::endl;
    }
    if (grid != NULL) {
        grid2 = grid;
        //std::cout << "not Null2" << std::endl;
    }
    openvdb::tools::csgDifference(*grid1, *grid2, true);
    std::cout << "Done" << std::endl;
}

but I have a problem with csgDifference function as shown below. Anyone know how to solve it? image

SimonNgj avatar Sep 28 '22 00:09 SimonNgj

Hi, without diving into this too much the csgDifference takes two grids and steals from the second. So as you are using the same grid for both, I imagine that is causing an issue as it is modifying what it is running over, you could deep copy the grid for grid2, or use csgDifferenceCopy(). Also CSG Difference expects two level set grids, so I wouldnt be surprised if the operation doesnt like inifinity() as that as that value isn't a valid distance value, but I'm not sure about this. What result are you expecting from this, I would assume an empty grid?

richhones avatar Oct 04 '22 11:10 richhones

Thanks for your comment. This is just a test. I unintendedly used csgDifference. If I use csgUnion and/or deepCopy, I have the same error.

SimonNgj avatar Oct 04 '22 12:10 SimonNgj

Try defining your grid as a true level-set. First, add the following line at the beginning: #include <openvdb/tools/LevelSetSphere.h>. Then define your grid the following way:

const float r = 5.0f;
const Vec3f c(20.0f, 0.0f, 0.0f);
const float s = 0.5f, w = 2.0f;
FloatGrid::Ptr grid = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);

As @richhones said, csgDifference will steal from the second argument. So you can define the second grid as follow:

if (grid != NULL) {
    grid2 = grid->deepCopy();
}

Then csgDifference will 'work'. However, garbage in means garbage out. So stamping over level-set values with x or infinity will destroy the fact that they are level-sets.

apradhana avatar Oct 04 '22 14:10 apradhana

Looking at this, it seems this error is probably coming from the levelset validation in validateLevelSet() as the background value is 0, which is not a valid levelset for csg operations using tools::csgUnion/Difference etc. If you get message from the error it should say 'expected grid [name] outside value > 0'. If you follow @apradhana's example to create a level set (and make sure to copy the grid/use different grids/use the const method) you may have more luck.

richhones avatar Oct 04 '22 14:10 richhones

Closing, please re-open if this is still an issue

Idclip avatar Jan 10 '23 17:01 Idclip