LIA-DiTella / DiffUDF

Repo for the CVPR 2024 paper: "DUDF: Differentiable Unsigned Distance Fields with Hyperbolic Scaling"
https://lia-ditella.github.io/DUDF/
MIT License
16 stars 1 forks source link

Questions about non-zero isosurface extraction #2

Closed LCJ18051316 closed 4 months ago

LCJ18051316 commented 4 months ago

Hello and thank you for your outstanding contribution. I'm having some issues reproducing your code. I passed in a mesh model, and based on the example you gave, and I successfully got the reconstruction of the surface. It's exciting! Now I'm wondering if there's any way to extract non-zero isosurfaces based on the trained model. Because I want to generate a thickened model based on an open surface. The reconstruction methods from CAP-UDF and MeshUDF seem to work for 0 isosurfaces. Is there any ready-made method or place that can be directly modified to solve the non-zero isosurface extraction?

miguef98 commented 4 months ago

Hi! Yes, actually extracting thickened models is easier because you can use the original Marching Cubes. You can simply utilize the function 'extract_fields' in the file 'generate_mc.py', then substract from the grid the isovalue you want (disregarding the grid of gradients), and proceed to generate a mesh by utilizing the method 'convert_sdf_samples_to_ply' located in the file 'src/render_mc.py'. Hope that helps!

LCJ18051316 commented 4 months ago

Thank you for your prompt answer, I found that convert_sdf_samples_to_ply() in the render_mc.py file called marching_cubes() and I noticed that there is a 'level' argument here. So I create 'get_my_mesh_sdf()' and finally it works! Thank you very much for your suggestions. code in render_mc.py

def get_my_mesh_sdf(sdf_values, N=256, level=0.01):

    # NOTE: the voxel_origin is actually the (bottom, left, down) corner, not
    # the middle
    voxel_origin = [-1, -1, -1]
    voxel_size = 2.0 / (N - 1)

    # set level to 0.0 to extract the surface, or a positive value to extract
    verts, faces, normals, values = convert_sdf_samples_to_ply(
        sdf_values.data.cpu(),
        voxel_origin,
        voxel_size,
        level=level
    )

    return trimesh.Trimesh(vertices=verts, faces=faces, vertex_normals=normals)

code in generate_mc.py

u,g = extract_fields(model, torch.Tensor([[]]).to(device), N, gt_mode, device, alpha )
MeshMy = get_my_mesh_sdf(u, N=512, level=0.01)