Skip to content

Commit

Permalink
Installer script and commented out dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
ramenguy99 committed Jul 27, 2023
1 parent ebd1807 commit 5c3f3b2
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 104 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export/
data/
.vscode/
tests/failure/
installer/

# Copied from https://github.com/github/gitignore/blob/main/Jekyll.gitignore
# Ignore metadata generated by Jekyll
Expand Down
8 changes: 8 additions & 0 deletions aitviewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
Entry point of the aitviewer binary dist.
"""

from aitviewer.viewer import Viewer

v = Viewer()
v.run()
22 changes: 11 additions & 11 deletions aitviewer/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"""
import os

import torch
# import torch
from omegaconf import OmegaConf
from omegaconf.dictconfig import DictConfig

Expand Down Expand Up @@ -47,7 +47,7 @@ def __init__(self):
self._conf.merge_with(conf)

self._gui_counter = 0
self._gpu_available = torch.cuda.is_available()
# self._gpu_available = torch.cuda.is_available()

def update_conf(self, conf_obj):
"""Update the configuration with another configuration file or another OmegaConf configuration object."""
Expand All @@ -59,15 +59,15 @@ def update_conf(self, conf_obj):

def __getattr__(self, item):
if hasattr(self._conf, item):
# Some attributes of the config are converted to torch objects automatically.
if item == "device":
return torch.device(self._conf.get("device", "cuda:0") if self._gpu_available else "cpu")
elif item == "f_precision":
return getattr(torch, "float{}".format(self._conf.get("f_precision", 32)))
elif item == "i_precision":
return getattr(torch, "int{}".format(self._conf.get("i_precision", 64)))
else:
return getattr(self._conf, item)
# # Some attributes of the config are converted to torch objects automatically.
# if item == "device":
# return torch.device(self._conf.get("device", "cuda:0") if self._gpu_available else "cpu")
# elif item == "f_precision":
# return getattr(torch, "float{}".format(self._conf.get("f_precision", 32)))
# elif item == "i_precision":
# return getattr(torch, "int{}".format(self._conf.get("i_precision", 64)))
# else:
return getattr(self._conf, item)
else:
# Default behavior.
return self.__getattribute__(item)
Expand Down
4 changes: 2 additions & 2 deletions aitviewer/renderables/billboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import pickle
from typing import List, Union

import cv2
# import cv2
import moderngl
import numpy as np
from moderngl_window.opengl.vao import VAO
from pxr import Gf, Sdf, UsdGeom
# from pxr import Gf, Sdf, UsdGeom
from trimesh.triangles import points_to_barycentric

from aitviewer.scene.camera import Camera, OpenCVCamera
Expand Down
2 changes: 1 addition & 1 deletion aitviewer/renderables/meshes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import trimesh.geometry
from moderngl_window.opengl.vao import VAO
from PIL import Image
from pxr import Gf, Sdf, UsdGeom
# from pxr import Gf, Sdf, UsdGeom
from trimesh.triangles import points_to_barycentric

from aitviewer.scene.node import Node
Expand Down
2 changes: 1 addition & 1 deletion aitviewer/renderables/plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"""
import moderngl
import numpy as np
from pxr import Gf, UsdGeom
# from pxr import Gf, UsdGeom

from aitviewer.renderables.meshes import Meshes
from aitviewer.scene.node import Node
Expand Down
2 changes: 1 addition & 1 deletion aitviewer/scene/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ def export_usd(self, stage, usd_path: str, directory: str = None, verbose=False)
:param stage: an object of type Usd.Stage into which to export the node
:param usd_path: the path of the parent object in the USD file scene hierarchy.
"""
from pxr import Gf, UsdGeom
# from pxr import Gf, UsdGeom

usd_path = f"{usd_path}/{self.name.replace(' ', '_')}_{self.uid:03}"

Expand Down
2 changes: 1 addition & 1 deletion aitviewer/streamables/webcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import cv2
# import cv2
import numpy as np
from moderngl_window import geometry

Expand Down
41 changes: 20 additions & 21 deletions aitviewer/utils/so3.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,29 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import numpy as np
import roma
import torch
# import roma
# import torch
from scipy.spatial.transform import Rotation as R
from scipy.spatial.transform import RotationSpline


def rot2aa_torch(rotation_matrices):
"""
Convert rotation matrices to rotation vectors (angle-axis representation).
:param rotation_matrices: A torch tensor of shape (..., 3, 3).
:return: A torch tensor of shape (..., 3).
"""
assert isinstance(rotation_matrices, torch.Tensor)
return roma.rotmat_to_rotvec(rotation_matrices)


def aa2rot_torch(rotation_vectors):
"""
Convert rotation vectors (angle-axis representation) to rotation matrices.
:param rotation_vectors: A torch tensor of shape (..., 3).
:return: A torch tensor of shape (..., 3, 3).
"""
assert isinstance(rotation_vectors, torch.Tensor)
return roma.rotvec_to_rotmat(rotation_vectors)
# def rot2aa_torch(rotation_matrices):
# """
# Convert rotation matrices to rotation vectors (angle-axis representation).
# :param rotation_matrices: A torch tensor of shape (..., 3, 3).
# :return: A torch tensor of shape (..., 3).
# """
# assert isinstance(rotation_matrices, torch.Tensor)
# return roma.rotmat_to_rotvec(rotation_matrices)


# def aa2rot_torch(rotation_vectors):
# """
# Convert rotation vectors (angle-axis representation) to rotation matrices.
# :param rotation_vectors: A torch tensor of shape (..., 3).
# :return: A torch tensor of shape (..., 3, 3).
# """
# assert isinstance(rotation_vectors, torch.Tensor)
# return roma.rotvec_to_rotmat(rotation_vectors)


def rot2aa_numpy(rotation_matrices):
Expand Down
2 changes: 1 addition & 1 deletion aitviewer/utils/usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import numpy as np
from PIL import Image
from pxr import Sdf, UsdShade
# from pxr import Sdf, UsdShade


def _get_texture_paths(path, name, directory):
Expand Down
126 changes: 63 additions & 63 deletions aitviewer/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
import subprocess

import numpy as np
import torch
# import torch
from scipy.interpolate import CubicSpline

from aitviewer.utils.so3 import aa2rot_torch as aa2rot
from aitviewer.utils.so3 import rot2aa_torch as rot2aa
# from aitviewer.utils.so3 import aa2rot_torch as aa2rot
# from aitviewer.utils.so3 import rot2aa_torch as rot2aa


def to_torch(x, dtype, device):
if x is None:
return None
if isinstance(x, np.ndarray):
return torch.from_numpy(x).to(dtype=dtype, device=device)
return x.to(dtype=dtype, device=device)
# def to_torch(x, dtype, device):
# if x is None:
# return None
# if isinstance(x, np.ndarray):
# return torch.from_numpy(x).to(dtype=dtype, device=device)
# return x.to(dtype=dtype, device=device)


def to_numpy(x):
Expand Down Expand Up @@ -166,28 +166,28 @@ def resample_positions(positions, fps_in, fps_out):
return interpolate_positions(positions, ts_in, ts_out)


def compute_vertex_and_face_normals_torch(vertices, faces, vertex_faces, normalize=False):
"""
Compute (unnormalized) vertex normals for the given vertices.
:param vertices: A tensor of shape (N, V, 3).
:param faces: A tensor of shape (F, 3) indexing into `vertices`.
:param vertex_faces: A tensor of shape (V, MAX_VERTEX_DEGREE) that lists the face IDs each vertex is a part of.
:param normalize: Whether to make the normals unit length or not.
:return: The vertex and face normals as tensors of shape (N, V, 3) and (N, F, 3) respectively.
"""
vs = vertices[:, faces.to(dtype=torch.long)]
face_normals = torch.cross(vs[:, :, 1] - vs[:, :, 0], vs[:, :, 2] - vs[:, :, 0], dim=-1) # (N, F, 3)
# def compute_vertex_and_face_normals_torch(vertices, faces, vertex_faces, normalize=False):
# """
# Compute (unnormalized) vertex normals for the given vertices.
# :param vertices: A tensor of shape (N, V, 3).
# :param faces: A tensor of shape (F, 3) indexing into `vertices`.
# :param vertex_faces: A tensor of shape (V, MAX_VERTEX_DEGREE) that lists the face IDs each vertex is a part of.
# :param normalize: Whether to make the normals unit length or not.
# :return: The vertex and face normals as tensors of shape (N, V, 3) and (N, F, 3) respectively.
# """
# vs = vertices[:, faces.to(dtype=torch.long)]
# face_normals = torch.cross(vs[:, :, 1] - vs[:, :, 0], vs[:, :, 2] - vs[:, :, 0], dim=-1) # (N, F, 3)

ns_all_faces = face_normals[:, vertex_faces] # (N, V, MAX_VERTEX_DEGREE, 3)
ns_all_faces[:, vertex_faces == -1] = 0.0
vertex_degrees = (vertex_faces > -1).sum(dim=-1).to(dtype=ns_all_faces.dtype)
vertex_normals = ns_all_faces.sum(dim=-2) / vertex_degrees[None, :, None] # (N, V, 3)
# ns_all_faces = face_normals[:, vertex_faces] # (N, V, MAX_VERTEX_DEGREE, 3)
# ns_all_faces[:, vertex_faces == -1] = 0.0
# vertex_degrees = (vertex_faces > -1).sum(dim=-1).to(dtype=ns_all_faces.dtype)
# vertex_normals = ns_all_faces.sum(dim=-2) / vertex_degrees[None, :, None] # (N, V, 3)

if normalize:
face_normals = face_normals / torch.norm(face_normals, dim=-1).unsqueeze(-1)
vertex_normals = vertex_normals / torch.norm(vertex_normals, dim=-1).unsqueeze(-1)
# if normalize:
# face_normals = face_normals / torch.norm(face_normals, dim=-1).unsqueeze(-1)
# vertex_normals = vertex_normals / torch.norm(vertex_normals, dim=-1).unsqueeze(-1)

return vertex_normals, face_normals
# return vertex_normals, face_normals


def compute_vertex_and_face_normals(vertices, faces, vertex_faces, normalize=False):
Expand Down Expand Up @@ -329,38 +329,38 @@ def compute_union_of_current_bounds(nodes):
return bounds


def local_to_global(poses, parents, output_format="aa", input_format="aa"):
"""
Convert relative joint angles to global ones by unrolling the kinematic chain.
:param poses: A tensor of shape (N, N_JOINTS*3) defining the relative poses in angle-axis format.
:param parents: A list of parents for each joint j, i.e. parent[j] is the parent of joint j.
:param output_format: 'aa' or 'rotmat'.
:param input_format: 'aa' or 'rotmat'
:return: The global joint angles as a tensor of shape (N, N_JOINTS*DOF).
"""
assert output_format in ["aa", "rotmat"]
assert input_format in ["aa", "rotmat"]
dof = 3 if input_format == "aa" else 9
n_joints = poses.shape[-1] // dof
if input_format == "aa":
local_oris = aa2rot(poses.reshape((-1, 3)))
else:
local_oris = poses
local_oris = local_oris.reshape((-1, n_joints, 3, 3))
global_oris = torch.zeros_like(local_oris)

for j in range(n_joints):
if parents[j] < 0:
# root rotation
global_oris[..., j, :, :] = local_oris[..., j, :, :]
else:
parent_rot = global_oris[..., parents[j], :, :]
local_rot = local_oris[..., j, :, :]
global_oris[..., j, :, :] = torch.matmul(parent_rot, local_rot)

if output_format == "aa":
global_oris = rot2aa(global_oris.reshape((-1, 3, 3)))
res = global_oris.reshape((-1, n_joints * 3))
else:
res = global_oris.reshape((-1, n_joints * 3 * 3))
return res
# def local_to_global(poses, parents, output_format="aa", input_format="aa"):
# """
# Convert relative joint angles to global ones by unrolling the kinematic chain.
# :param poses: A tensor of shape (N, N_JOINTS*3) defining the relative poses in angle-axis format.
# :param parents: A list of parents for each joint j, i.e. parent[j] is the parent of joint j.
# :param output_format: 'aa' or 'rotmat'.
# :param input_format: 'aa' or 'rotmat'
# :return: The global joint angles as a tensor of shape (N, N_JOINTS*DOF).
# """
# assert output_format in ["aa", "rotmat"]
# assert input_format in ["aa", "rotmat"]
# dof = 3 if input_format == "aa" else 9
# n_joints = poses.shape[-1] // dof
# if input_format == "aa":
# local_oris = aa2rot(poses.reshape((-1, 3)))
# else:
# local_oris = poses
# local_oris = local_oris.reshape((-1, n_joints, 3, 3))
# global_oris = torch.zeros_like(local_oris)

# for j in range(n_joints):
# if parents[j] < 0:
# # root rotation
# global_oris[..., j, :, :] = local_oris[..., j, :, :]
# else:
# parent_rot = global_oris[..., parents[j], :, :]
# local_rot = local_oris[..., j, :, :]
# global_oris[..., j, :, :] = torch.matmul(parent_rot, local_rot)

# if output_format == "aa":
# global_oris = rot2aa(global_oris.reshape((-1, 3, 3)))
# res = global_oris.reshape((-1, n_joints * 3))
# else:
# res = global_oris.reshape((-1, n_joints * 3 * 3))
# return res
4 changes: 2 additions & 2 deletions aitviewer/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from aitviewer.scene.camera import PinholeCamera, ViewerCamera
from aitviewer.scene.node import Node
from aitviewer.scene.scene import Scene
from aitviewer.server import ViewerServer
# from aitviewer.server import ViewerServer
from aitviewer.shaders import clear_shader_cache
from aitviewer.streamables.streamable import Streamable
from aitviewer.utils import path
Expand Down Expand Up @@ -1753,7 +1753,7 @@ def export_frame(self, file_path, scale_factor: float = None, transparent_backgr
self._last_frame_rendered_at = self.timer.time

def export_usd(self, path: str, export_as_directory=False, verbose=False):
from pxr import Usd, UsdGeom
# from pxr import Usd, UsdGeom

if export_as_directory:
if path.endswith(".usd"):
Expand Down
39 changes: 39 additions & 0 deletions installer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import PyInstaller.__main__

Check failure on line 1 in installer.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import os
import shutil

OUTPUT_DIR = "installer"
BUILD_PATH = os.path.join(OUTPUT_DIR, "build")
DIST_PATH = os.path.join(OUTPUT_DIR, "dist")

os.makedirs(OUTPUT_DIR, exist_ok=True)

PyInstaller.__main__.run([
"aitviewer.py",
"--noconfirm",
"--windowed",
# "--exclude", "PyQt5",
"--exclude", "matplotlib",
"--exclude", "pandas",
"--exclude", "cv2",
"--exclude", "open3d",
"--hidden-import", "moderngl_window.loaders.program.separate",
"--hidden-import", "moderngl_window.loaders.program.single",
"--hidden-import", "moderngl_window.loaders.program",
"--hidden-import", "moderngl_window.context.pyglet",
"--hidden-import", "glcontext",
"--workpath", BUILD_PATH,
"--distpath", DIST_PATH,
"--specpath", OUTPUT_DIR,
"--add-data", os.path.join("..", "aitviewer", "resources", "*") + os.pathsep + os.path.join("aitviewer", "resources"),
"--add-data", os.path.join("..", "aitviewer", "shaders", "**", "*") + os.pathsep + os.path.join("aitviewer", "shaders"),
"--add-data", os.path.join("..", "aitviewer", "aitvconfig.yaml") + os.pathsep + os.path.join("aitviewer"),
])

root = os.path.join(DIST_PATH, "aitviewer")
shutil.copytree(os.path.join("aitviewer", "resources"), os.path.join(root, "aitviewer", "resources"), dirs_exist_ok=True)
shutil.copytree(os.path.join("aitviewer", "shaders"), os.path.join(root, "aitviewer", "shaders"), dirs_exist_ok=True)
shutil.copy(os.path.join("aitviewer", "aitvconfig.yaml"), os.path.join(root, "aitviewer"))

# moderngl.window requires a scene folder to exist.
os.makedirs(os.path.join(OUTPUT_DIR, "dist", "aitviewer", "moderngl_window", "scene", "programs"))

0 comments on commit 5c3f3b2

Please sign in to comment.