57 lines
2.2 KiB
Python
57 lines
2.2 KiB
Python
import torch
|
|
import o_voxel
|
|
import utils
|
|
|
|
RES = 512
|
|
|
|
asset = utils.get_helmet()
|
|
|
|
# 0. Normalize asset to unit cube
|
|
aabb = asset.bounding_box.bounds
|
|
center = (aabb[0] + aabb[1]) / 2
|
|
scale = 0.99999 / (aabb[1] - aabb[0]).max() # To avoid numerical issues
|
|
asset.apply_translation(-center)
|
|
asset.apply_scale(scale)
|
|
|
|
# 1. Geometry Voxelization (Flexible Dual Grid)
|
|
# Returns: occupied indices, dual vertices (QEF solution), and edge intersected
|
|
mesh = asset.to_mesh()
|
|
vertices = torch.from_numpy(mesh.vertices).float()
|
|
faces = torch.from_numpy(mesh.faces).long()
|
|
voxel_indices, dual_vertices, intersected = o_voxel.convert.mesh_to_flexible_dual_grid(
|
|
vertices, faces,
|
|
grid_size=RES, # Resolution
|
|
aabb=[[-0.5,-0.5,-0.5],[0.5,0.5,0.5]], # Axis-aligned bounding box
|
|
face_weight=1.0, # Face term weight in QEF
|
|
boundary_weight=0.2, # Boundary term weight in QEF
|
|
regularization_weight=1e-2, # Regularization term weight in QEF
|
|
timing=True
|
|
)
|
|
## sort to ensure align between geometry and material voxelization
|
|
vid = o_voxel.serialize.encode_seq(voxel_indices)
|
|
mapping = torch.argsort(vid)
|
|
voxel_indices = voxel_indices[mapping]
|
|
dual_vertices = dual_vertices[mapping]
|
|
intersected = intersected[mapping]
|
|
|
|
# 2. Material Voxelization (Volumetric Attributes)
|
|
# Returns: dict containing 'base_color', 'metallic', 'roughness', etc.
|
|
voxel_indices_mat, attributes = o_voxel.convert.textured_mesh_to_volumetric_attr(
|
|
asset,
|
|
grid_size=RES,
|
|
aabb=[[-0.5,-0.5,-0.5],[0.5,0.5,0.5]],
|
|
timing=True
|
|
)
|
|
## sort to ensure align between geometry and material voxelization
|
|
vid_mat = o_voxel.serialize.encode_seq(voxel_indices_mat)
|
|
mapping_mat = torch.argsort(vid_mat)
|
|
attributes = {k: v[mapping_mat] for k, v in attributes.items()}
|
|
|
|
# Save to compressed .vxz format
|
|
## packing
|
|
dual_vertices = dual_vertices * RES - voxel_indices
|
|
dual_vertices = (torch.clamp(dual_vertices, 0, 1) * 255).type(torch.uint8)
|
|
intersected = (intersected[:, 0:1] + 2 * intersected[:, 1:2] + 4 * intersected[:, 2:3]).type(torch.uint8)
|
|
attributes['dual_vertices'] = dual_vertices
|
|
attributes['intersected'] = intersected
|
|
o_voxel.io.write("ovoxel_helmet.vxz", voxel_indices, attributes) |