File size: 4,638 Bytes
94b4398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""pytorch3d.renderer stub with catch-all for missing attributes."""
import torch
import math
import warnings


def __getattr__(name):
    """Catch-all: return a dummy class/function for any missing attribute."""
    if name.startswith("__") and name.endswith("__"):
        raise AttributeError(name)
    warnings.warn(f"pytorch3d.renderer stub: {name} not implemented, returning dummy", stacklevel=2)
    class _Dummy:
        def __init__(self, *a, **kw): pass
        def __call__(self, *a, **kw): return None
        def to(self, *a, **kw): return self
        def forward(self, *a, **kw): return None
    _Dummy.__name__ = _Dummy.__qualname__ = name
    return _Dummy


def look_at_view_transform(dist=1.0, elev=0.0, azim=0.0, degrees=True, eye=None,
                            at=((0, 0, 0),), up=((0, 1, 0),), device="cpu"):
    if eye is not None:
        if not isinstance(eye, torch.Tensor):
            eye = torch.tensor(eye, dtype=torch.float32, device=device)
        if eye.dim() == 1:
            eye = eye.unsqueeze(0)
    else:
        elev_r = math.radians(float(elev)) if degrees else float(elev)
        azim_r = math.radians(float(azim)) if degrees else float(azim)
        x = dist * math.cos(elev_r) * math.sin(azim_r)
        y = dist * math.sin(elev_r)
        z = dist * math.cos(elev_r) * math.cos(azim_r)
        eye = torch.tensor([[x, y, z]], dtype=torch.float32, device=device)
    if not isinstance(at, torch.Tensor):
        at = torch.tensor(at, dtype=torch.float32, device=device)
    if at.dim() == 1: at = at.unsqueeze(0)
    if not isinstance(up, torch.Tensor):
        up = torch.tensor(up, dtype=torch.float32, device=device)
    if up.dim() == 1: up = up.unsqueeze(0)
    z_axis = eye - at
    z_axis = z_axis / z_axis.norm(dim=-1, keepdim=True).clamp(min=1e-8)
    x_axis = torch.cross(up.expand_as(z_axis), z_axis, dim=-1)
    x_axis = x_axis / x_axis.norm(dim=-1, keepdim=True).clamp(min=1e-8)
    y_axis = torch.cross(z_axis, x_axis, dim=-1)
    R = torch.stack([x_axis, y_axis, z_axis], dim=-1)
    T = -torch.bmm(R.transpose(1, 2), eye.unsqueeze(-1)).squeeze(-1)
    return R, T


def ray_bundle_to_ray_points(ray_bundle):
    return None


class CamerasBase:
    pass


class PerspectiveCameras(CamerasBase):
    def __init__(self, focal_length=None, principal_point=None, R=None, T=None,
                 image_size=None, device="cpu", in_ndc=True, **kwargs):
        self.device = device
        self.focal_length = focal_length
        self.principal_point = principal_point
        self.R = R if R is not None else torch.eye(3, device=device).unsqueeze(0)
        self.T = T if T is not None else torch.zeros(1, 3, device=device)
        self.image_size = image_size
        self.in_ndc = in_ndc
    def to(self, device):
        self.device = device; return self


class RasterizationSettings:
    def __init__(self, image_size=256, blur_radius=0.0, faces_per_pixel=1, **kwargs):
        self.image_size = image_size; self.blur_radius = blur_radius; self.faces_per_pixel = faces_per_pixel


class BlendParams:
    def __init__(self, sigma=1e-4, gamma=1e-4, background_color=(0.0, 0.0, 0.0)):
        self.sigma = sigma; self.gamma = gamma; self.background_color = background_color


class SoftSilhouetteShader:
    def __init__(self, blend_params=None):
        self.blend_params = blend_params or BlendParams()


class MeshRasterizer(torch.nn.Module):
    def __init__(self, cameras=None, raster_settings=None):
        super().__init__()
        self.cameras = cameras; self.raster_settings = raster_settings
    def forward(self, meshes, **kw):
        raise NotImplementedError("MeshRasterizer stub")


class MeshRenderer(torch.nn.Module):
    def __init__(self, rasterizer=None, shader=None):
        super().__init__()
        self.rasterizer = rasterizer; self.shader = shader
    def forward(self, meshes, **kw):
        raise NotImplementedError("MeshRenderer stub")


class TexturesVertex:
    def __init__(self, verts_features=None):
        self.verts_features_list = verts_features if isinstance(verts_features, list) else [verts_features]
    def to(self, device): return self


class TexturesAtlas:
    def __init__(self, atlas=None, **kw): self.atlas = atlas
    def to(self, device): return self


class TexturesUV:
    def __init__(self, **kw): pass
    def to(self, device): return self


class HeterogeneousRayBundle:
    def __init__(self, *a, **kw): pass


class RayBundle:
    def __init__(self, origins=None, directions=None, lengths=None, xys=None, **kw):
        self.origins = origins; self.directions = directions; self.lengths = lengths; self.xys = xys