AcademySoftwareFoundation / openvdb

OpenVDB - Sparse volume data structure and tools
http://www.openvdb.org/
Apache License 2.0
2.71k stars 660 forks source link

Fillet filter in LevelSetFilter.h #1793

Closed ghurstunither closed 3 weeks ago

ghurstunither commented 7 months ago

Adds a fillet filter, which rounds off concave edges to create a smoother transition between surfaces.

Fillets a level set by


Example

Union 2 spheres:

FloatGrid::Ptr grid1 = openvdb::tools::createLevelSetSphere<FloatGrid>(1.0, Vec3f(0, 0, 0), 0.1, 3.0);
FloatGrid::Ptr grid2 = openvdb::tools::createLevelSetSphere<FloatGrid>(1.0, Vec3f(1.4, 0, 0), 0.1, 3.0);
openvdb::tools::csgUnion(*grid1, *grid2);

std::cout << grid1->evalActiveVoxelBoundingBox() << std::endl
[-12, -12, -12][26, 12, 12]

Visualization:

Screenshot 2024-04-16 at 11 51 10 AM

7 iterations of filleting:

openvdb::tools::LevelSetFilter filter(*grid1);
for(int i = 0; i < 7; ++i)
  filter.fillet();

// non-shrinking filter!
std::cout << grid1->evalActiveVoxelBoundingBox() << std::endl
[-12, -12, -12][26, 12, 12]

Visualization:

Screenshot 2024-04-16 at 11 51 28 AM

Tube radius stays the same after filleting:

Screenshot 2024-04-16 at 2 01 25 PM

Note, only concave corners are filleted:

Screenshot 2024-04-16 at 12 07 11 PM

A level set with a single connected component will transform into its convex hull after indefinite iterations of this filter. Unfortunately it's not practical in most cases, but it's still a neat fact. For example it took 16000 iterations to reasonably approximate the convex hull here:

fillet

richhones commented 6 months ago

LGTM @apradhana feel like this covers some similar ground as the smooth union (e.g. https://iquilezles.org/articles/smin/) but imagine there is still place for both of these operations?

ghurstunither commented 6 months ago

LGTM @apradhana feel like this covers some similar ground as the smooth union (e.g. https://iquilezles.org/articles/smin/) but imagine there is still place for both of these operations?

That's a good point! I think we should include both features.

  1. The fillet filter operates on a single object, and so is not a blending operator.

  2. These type of blending operations can sometimes cause undesired 'bulges' where regions have significant overlap near their boundaries. Here's a comparison combining two tubes, where the smooth/blended union shows the bulge:

    Screenshot 2024-05-17 at 9 14 40 PM
  3. The smooth union functionality has advantages, like finer control with extra blending parameters, as well as running much faster for large fillets since it isn't bound by a CFL-like condition.

danrbailey commented 3 weeks ago

@apradhana @ghurstunither - I think this was merged prematurely, it doesn't appear to have a unit test or a changelog message? At the very least, it would need a couple lines in the unit tests that evaluates this method, but better still of course would be something that validates the results.

apradhana commented 3 weeks ago

Thanks for pointing this out @danrbailey. I will add a unit test for the new feature and submit a PR. We are lacking unit tests for all the level set filters methods in the LevelSetFilter class in LevelSetFilter.h. It's a good time to start adding tests for those methods.