Closed ParikaGoel closed 4 years ago
How do you "generate a ply file for the occupancy"?
The result of np.where
will be integer indices of the input array, in this case they will be numbers from 0 to 32 (or whatever your resolution will be).
I have written below code to generate ply file from voxel positions:
def generate_ply(grid_positions, ply_filename, grid_size=None): cube_verts = np.array([[-1.0, -1.0, 1.0], [1.0, -1.0, 1.0], [1.0, 1.0, 1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, -1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, -1.0]]) # 8 points
cube_faces = np.array([[0, 1, 2], [2, 3, 0], [1, 5, 6], [6, 2, 1], [7, 6, 5], [5, 4, 7],
[4, 0, 3], [3, 7, 4], [4, 5, 1], [1, 0, 4], [3, 2, 6], [6, 7, 3]]) # 6 faces (12 triangles)
verts = []
faces = []
curr_vertex = 0
if grid_size is None:
grid_size = 1
min_bound = np.array([-grid_size / 2, -grid_size / 2, -grid_size / 2])
voxel_scale = grid_size / 32
color = np.array([169, 0, 255])
for i, j, k in zip(*grid_positions):
for cube_vert in cube_verts:
vertex = (cube_vert * 0.45 + np.array([i, j, k])).astype(float)
vertex *= voxel_scale
vertex += min_bound
vertex = np.append(vertex, color)
vertex = list(vertex)
verts.append(vertex)
for cube_face in cube_faces:
face = curr_vertex + cube_face
faces.append(list(face))
curr_vertex += len(cube_verts)
file = open(ply_filename, "w")
file.write('''ply
format ascii 1.0
element vertex %d
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face %d
property list uchar int vertex_index
end_header
''' % (len(verts), len(faces)))
for vert in verts:
file.write('%f %f %f %d %d %d\n' % tuple(vert))
for face in faces:
file.write('3 %d %d %d\n' % tuple(face))
file.close()
I call above function as generate_ply(positions, "table.ply", grid_size=2)
What happens if you change your voxel_scale = grid_size / 32
line to
voxel_scale = grid_size / 32 / 2
?
I got confused whether you meant dividing by 16 or 64, so I tried both
voxel_scale = grid_size / 16 produces below output
voxel_scale = grid_size / 64 produces below output
It looks like on your second image the scale is pretty good, but the translation is off. So you should try to adjust your min_bound
parameter.
Hey Marian,
I am working on generating sdf voxelizations of shapenet dataset. I came across your library which is by far the best for my task. I used the mesh_to_voxels API to generate the sdfs which are quite good. But I am facing one problem and would be grateful if you could help me out.
The voxelizations produced right now give me a voxel grid ranging from (-1,-1,-1) to (1,1,1). I am trying to transform it into a cube ranging from (-0.5,-0.5,-0.5) to (0.5,0.5,0.5) since the shapenet dataset is also normalized into this range.
Below is the code of what I am doing:
mesh = trimesh.load("table.obj") sdf_grid = mesh_to_voxels(mesh, 32, pad=False) <- Generates sdf
Then I use the truncation distance to get the occupancy grid trunc_dist = 1/32 sdf_grid = torch.from_numpy(sdf_grid) mask = torch.gt(sdf_grid, -trunc_dist) & torch.lt(sdf_grid, trunc_dist) positions = np.where(mask.cpu().numpy()) <- This gives me the grid coordinates for occupancy grid
Then I am visualizing it by generating a ply file for the occupancy
This is the visualization of the occupancy grid generated from sdf and obj file of the model in meshlab. Looks like there is the scaling difference between shapenet model is normalized in the range of (-0.5,-0.5,-0.5) to (0.5,0.5,0.5), whereas the generated sdf is in the range of (-1,-1,-1) to (1,1,1).
Is there a way by which I can make the transformation ?
Thank you for your time.