MeshToVolume problem

838 views
Skip to first unread message

Stephen

unread,
Apr 1, 2013, 10:59:34 PM4/1/13
to openvd...@googlegroups.com
Hello,

As a simple test, I'm using MeshToVolume to convert a triangle mesh to a FloatGrid, then using VolumeToMesh to convert the grid back to a mesh.

For the most part it seems to work as I expect but on some models I get some strange behaviour. The attached image demonstrates the problem. The mesh on the left is the original model, and the mesh on the right is the mesh output of VolumeToMesh. It seems like in areas with long cylindrical regions, the voxels get "smeared".

My code looks like this:

openvdb::FloatGrid::Ptr CreateGrid( )
{
    openvdb
::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform();
    openvdb
::tools::MeshToVolume<openvdb::FloatGrid> meshToVol(transform);
   
    std
::vector<openvdb::Vec3s> pointList;
    std
::vector<openvdb::Vec4I> polyList;

   
// copy mesh data into lists...

    meshToVol
.convertToLevelSet(
        pointList
,
        polyList
);

   
return meshToVol.distGridPtr();
}



openvdb::FloatGrid::Ptr grid = CreateGrid();


// Convert the level set sphere to a narrow-band fog volume, in which
// interior voxels have value 1, exterior voxels have value 0, and
// narrow-band voxels have values varying linearly from 0 to 1.
//
// Code taken from cookbook
for( openvdb::FloatGrid::ValueOffIter iter = grid->beginValueOff(); iter; iter++ )
{
    if( iter.getValue() < 0.0f )
    {
        iter.setValue(1.0f);
        iter.setValueOff();
    }
}

const float outside = grid->background();
const float width = 2.0 * outside;

for( openvdb::FloatGrid::ValueOnIter iter = grid->beginValueOn(); iter; iter++ )
{
    float value = iter.getValue();
    iter.setValue( (outside - value) / width );
}
   
grid->setBackground(0.0f);

openvdb::v1_0_0::tools::VolumeToMesh volToMesh;
volToMesh.operator()< openvdb::v1_0_0::FloatGrid >( grid.operator*() );

// convert back into mesh using the point and poly lists from volToMesh...



I've attached the mesh I used as an obj file. Any ideas what I'm doing wrong?


badConversion.jpg
testCube.zip

OpenVDB Support

unread,
Apr 2, 2013, 12:58:30 PM4/2/13
to openvd...@googlegroups.com
Hi,

I tried converting your model using our Houdini SOPs (that use the MeshToVolume and VolumeToMesh converters) and it seems to work just fine. The attached image shows the surface obtained from the converted level set and fog volume.

Please note that the MeshToVolume converter expects a list of points in grid index space. Verify that you can surface the level set before converting it into a fog volume.

Also note that we have a threaded tool for level set to fog volume conversion in LevelSetUtils.h

/// @brief Threaded method to convert a sparse level set/SDF into a sparse fog volume
///
/// @details For a level set, the active and negative-valued interior half of the
/// narrow band becomes a linear ramp from 0 to 1; the inactive interior becomes
/// active with a constant value of 1; and the exterior, including the background
/// and the active exterior half of the narrow band, becomes inactive with a constant
/// value of 0.  The interior, though active, remains sparse.
/// @details For a generic SDF, a specified cutoff distance determines the width
/// of the ramp, but otherwise the result is the same as for a level set.
///
/// @param grid            level set/SDF grid to transform
/// @param cutoffDistance  optional world space cutoff distance for the ramp
///                        (automatically clamped if greater than the interior
///                        narrow band width)
template<class GridType>
inline void
sdfToFogVolume
(
   
GridType& grid,
   
typename GridType::ValueType cutoffDistance = lsutilGridMax<GridType>());




/Mihai

 
test.png

Stephen

unread,
Apr 2, 2013, 11:23:54 PM4/2/13
to openvd...@googlegroups.com
Ah thanks for the info. After looking at the Houdini SOP code I realized I was creating my polygon list incorrectly. I was copying data from triangle meshes, but not setting the fourth component of my poly list elements to openvdb::util::INVALID_IDX. After fixing that, I'm getting the correct result.

Reply all
Reply to author
Forward
0 new messages