"""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