Spaces:
Running
on
Zero
Running
on
Zero
File size: 4,471 Bytes
37aeb5b 6ade74b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# modified from https://github.com/Profactor/continuous-remeshing
import torch
import numpy as np
import trimesh
from typing import Tuple
def to_numpy(*args):
def convert(a):
if isinstance(a,torch.Tensor):
return a.detach().cpu().numpy()
assert a is None or isinstance(a,np.ndarray)
return a
return convert(args[0]) if len(args)==1 else tuple(convert(a) for a in args)
def laplacian(
num_verts:int,
edges: torch.Tensor #E,2
) -> torch.Tensor: #sparse V,V
"""create sparse Laplacian matrix"""
V = num_verts
E = edges.shape[0]
#adjacency matrix,
idx = torch.cat([edges, edges.fliplr()], dim=0).type(torch.long).T # (2, 2*E)
ones = torch.ones(2*E, dtype=torch.float32, device=edges.device)
A = torch.sparse.FloatTensor(idx, ones, (V, V))
#degree matrix
deg = torch.sparse.sum(A, dim=1).to_dense()
idx = torch.arange(V, device=edges.device)
idx = torch.stack([idx, idx], dim=0)
D = torch.sparse.FloatTensor(idx, deg, (V, V))
return D - A
def _translation(x, y, z, device):
return torch.tensor([[1., 0, 0, x],
[0, 1, 0, y],
[0, 0, 1, z],
[0, 0, 0, 1]],device=device) #4,4
def _projection(r, device, l=None, t=None, b=None, n=1.0, f=50.0, flip_y=True):
"""
see https://blog.csdn.net/wodownload2/article/details/85069240/
"""
if l is None:
l = -r
if t is None:
t = r
if b is None:
b = -t
p = torch.zeros([4,4],device=device)
p[0,0] = 2*n/(r-l)
p[0,2] = (r+l)/(r-l)
p[1,1] = 2*n/(t-b) * (-1 if flip_y else 1)
p[1,2] = (t+b)/(t-b)
p[2,2] = -(f+n)/(f-n)
p[2,3] = -(2*f*n)/(f-n)
p[3,2] = -1
return p #4,4
def _orthographic(r, device, l=None, t=None, b=None, n=1.0, f=50.0, flip_y=True):
if l is None:
l = -r
if t is None:
t = r
if b is None:
b = -t
o = torch.zeros([4,4],device=device)
o[0,0] = 2/(r-l)
o[0,3] = -(r+l)/(r-l)
o[1,1] = 2/(t-b) * (-1 if flip_y else 1)
o[1,3] = -(t+b)/(t-b)
o[2,2] = -2/(f-n)
o[2,3] = -(f+n)/(f-n)
o[3,3] = 1
return o #4,4
def make_star_cameras(az_count,pol_count,distance:float=10.,r=None,image_size=[512,512],device='cuda'):
if r is None:
r = 1/distance
A = az_count
P = pol_count
C = A * P
phi = torch.arange(0,A) * (2*torch.pi/A)
phi_rot = torch.eye(3,device=device)[None,None].expand(A,1,3,3).clone()
phi_rot[:,0,2,2] = phi.cos()
phi_rot[:,0,2,0] = -phi.sin()
phi_rot[:,0,0,2] = phi.sin()
phi_rot[:,0,0,0] = phi.cos()
theta = torch.arange(1,P+1) * (torch.pi/(P+1)) - torch.pi/2
theta_rot = torch.eye(3,device=device)[None,None].expand(1,P,3,3).clone()
theta_rot[0,:,1,1] = theta.cos()
theta_rot[0,:,1,2] = -theta.sin()
theta_rot[0,:,2,1] = theta.sin()
theta_rot[0,:,2,2] = theta.cos()
mv = torch.empty((C,4,4), device=device)
mv[:] = torch.eye(4, device=device)
mv[:,:3,:3] = (theta_rot @ phi_rot).reshape(C,3,3)
mv = _translation(0, 0, -distance, device) @ mv
return mv, _projection(r,device)
def make_star_cameras_orthographic(az_count,pol_count,distance:float=10.,r=None,image_size=[512,512],device='cuda'):
mv, _ = make_star_cameras(az_count,pol_count,distance,r,image_size,device)
if r is None:
r = 1
return mv, _orthographic(r,device)
def make_sphere(level:int=2,radius=1.,device='cuda') -> Tuple[torch.Tensor,torch.Tensor]:
sphere = trimesh.creation.icosphere(subdivisions=level, radius=1.0, color=None)
vertices = torch.tensor(sphere.vertices, device=device, dtype=torch.float32) * radius
faces = torch.tensor(sphere.faces, device=device, dtype=torch.long)
return vertices,faces
from pytorch3d.renderer import (
FoVOrthographicCameras,
look_at_view_transform,
)
def get_camera(R, T, focal_length=1 / (2**0.5)):
focal_length = 1 / focal_length
camera = FoVOrthographicCameras(device=R.device, R=R, T=T, min_x=-focal_length, max_x=focal_length, min_y=-focal_length, max_y=focal_length)
return camera
def make_star_cameras_orthographic_py3d(azim_list, device, focal=2/1.35, dist=1.1):
R, T = look_at_view_transform(dist, 0, azim_list)
focal_length = 1 / focal
return FoVOrthographicCameras(device=R.device, R=R, T=T, min_x=-focal_length, max_x=focal_length, min_y=-focal_length, max_y=focal_length).to(device)
|