spaceflow / utils.py
multimodalart's picture
multimodalart HF Staff
SpaceFlow demo
43ca9e0 verified
Raw History Blame Contribute Delete
3.41 kB
import numpy as np
import open3d_pycg as o3d
import os
import torch
from sklearn.decomposition import PCA
def merge_meshes(mesh_list):
merged = o3d.geometry.TriangleMesh()
v_offset = 0
for mesh in mesh_list:
vertices = np.asarray(mesh.vertices)
triangles = np.asarray(mesh.triangles) + v_offset
merged.vertices.extend(o3d.utility.Vector3dVector(vertices))
merged.triangles.extend(o3d.utility.Vector3iVector(triangles))
v_offset += len(vertices)
return merged
def voxelgrid_to_open3d(voxels: np.ndarray, threshold=0.5):
if len(voxels.shape) > 3:
C, D, H, W = voxels.shape
flat_feats = voxels.reshape(C, -1).transpose(1,0)
pca = PCA(n_components=3)
reduced = pca.fit_transform(flat_feats)
# Compute feature norm and PCA color std
# Normalize for RGB
reduced -= reduced.min(0)
reduced /= reduced.max(0) + 1e-6
# Compute norms and color std
norms = np.linalg.norm(flat_feats, axis=1)
color_std = np.std(reduced, axis=1)
# Filter: active voxels with non-trivial color
mask = (norms > threshold) & (color_std > 1e-3)
# zz, yy, xx = np.meshgrid(np.arange(D), np.arange(H), np.arange(W), indexing='ij')
xx, yy, zz = np.meshgrid(np.arange(D), np.arange(H), np.arange(W), indexing='ij')
coords = np.stack([xx, yy, zz], axis=-1).reshape(-1, 3)
valid_coords = coords[mask]
valid_colors = reduced[mask]
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(valid_coords.astype(np.float32))
pcd.colors = o3d.utility.Vector3dVector(valid_colors.astype(np.float32))
else:
coords = np.argwhere(voxels > threshold)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(coords)
return pcd
def save_voxelgrid_as_ply(voxels: np.ndarray, filename: str, threshold=0.5):
pcd = voxelgrid_to_open3d(voxels, threshold)
o3d.io.write_point_cloud(filename, pcd)
def voxelize_sq_francis(file_name):
superquadric_mesh = o3d.io.read_triangle_mesh(file_name)
vertices = np.clip(np.asarray(superquadric_mesh.vertices), -0.5 + 1e-6, 0.5 - 1e-6)
superquadric_mesh.vertices = o3d.utility.Vector3dVector(vertices)
theta = np.pi / 2
#superquadric_mesh.rotate(R_x, center=(0, 0, 0))
voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh_within_bounds(
superquadric_mesh, voxel_size=1/64, min_bound=(-0.5, -0.5, -0.5), max_bound=(0.5, 0.5, 0.5))
vertices = np.array([voxel.grid_index for voxel in voxel_grid.get_voxels()])
unique_points = np.unique(vertices, axis=0)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(unique_points)
o3d.io.write_point_cloud("merged_mesh_voxelized.ply", pcd)
zeros = np.zeros((unique_points.shape[0], 1))
unique_points_4d = np.hstack((zeros, unique_points)) # shape [N, 4]
unique_points_4d_torch = torch.from_numpy(unique_points_4d).to(dtype=torch.int32, device='cpu')
my_coords_orig = unique_points_4d_torch
coords_dense = torch.ones(1, 1, 64, 64, 64).to(device='cpu', dtype=torch.float32) * 0.0
for i in range(my_coords_orig.shape[0]):
x, y, z = my_coords_orig[i, 1], my_coords_orig[i, 2], my_coords_orig[i, 3]
coords_dense[0, 0, x, y, z] = 1.0
return coords_dense