Skip to content

Commit

Permalink
Work through some geometry for set_up_direction(), bump ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Dec 26, 2023
1 parent 575b349 commit d73fede
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 34 deletions.
14 changes: 10 additions & 4 deletions docs/source/examples/03_gui_callbacks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ we get updates.
gui_plane.on_update(lambda _: update_plane())
with server.add_gui_folder("Control", expand_by_default=False):
gui_show = server.add_gui_checkbox("Show Frame", initial_value=True)
gui_show_frame = server.add_gui_checkbox("Show Frame", initial_value=True)
gui_show_everything = server.add_gui_checkbox(
"Show Everything", initial_value=True
)
gui_axis = server.add_gui_dropdown("Axis", ("x", "y", "z"))
gui_include_z = server.add_gui_checkbox("Z in dropdown", initial_value=True)
Expand Down Expand Up @@ -75,7 +78,7 @@ we get updates.
"/frame",
wxyz=(1.0, 0.0, 0.0, 0.0),
position=pos,
show_axes=gui_show.value,
show_axes=gui_show_frame.value,
axes_length=5.0,
)
Expand All @@ -89,15 +92,18 @@ we get updates.
# We can (optionally) also attach callbacks!
# Here, we update the point clouds + frames whenever any of the GUI items are updated.
gui_show.on_update(lambda _: draw_frame())
gui_show_frame.on_update(lambda _: draw_frame())
gui_show_everything.on_update(
lambda _: server.set_global_scene_node_visibility(gui_show_everything.value)
)
gui_axis.on_update(lambda _: draw_frame())
gui_location.on_update(lambda _: draw_frame())
gui_num_points.on_update(lambda _: draw_points())
@gui_reset_scene.on_click
def _(_) -> None:
"""Reset the scene when the reset button is clicked."""
gui_show.value = True
gui_show_frame.value = True
gui_location.value = 0.0
gui_axis.value = "x"
gui_num_points.value = 10_000
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/06_mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Visualize a mesh. To get the demo data, see ``./assets/download_dragon_mesh.sh``
import viser
import viser.transforms as tf
mesh = trimesh.load_mesh(Path(__file__).parent / "assets/dragon.obj")
mesh = trimesh.load_mesh(str(Path(__file__).parent / "assets/dragon.obj"))
assert isinstance(mesh, trimesh.Trimesh)
mesh.apply_scale(0.05)
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/20_scene_click.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ To get the demo data, see ``./assets/download_dragon_mesh.sh``.
server = viser.ViserServer()
mesh = trimesh.load_mesh(Path(__file__).parent / "assets/dragon.obj")
mesh = trimesh.load_mesh(str(Path(__file__).parent / "assets/dragon.obj"))
assert isinstance(mesh, trimesh.Trimesh)
mesh.apply_scale(0.05)
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependencies = [
dev = [
"pyright>=1.1.308",
"mypy>=1.4.1",
"ruff==0.0.267",
"ruff==0.1.9",
"black==23.11.0",
"pre-commit==3.3.2",
]
Expand Down Expand Up @@ -87,6 +87,7 @@ select = [
ignore = [
"E741", # Ambiguous variable name. (l, O, or I)
"E501", # Line too long.
"E721", # Do not compare types, use `isinstance()`.
"F722", # Forward annotation false positive from jaxtyping. Should be caught by pyright.
"F821", # Forward annotation false positive from jaxtyping. Should be caught by pyright.
"PLR2004", # Magic value used in comparison.
Expand Down
6 changes: 5 additions & 1 deletion src/viser/_client_autobuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def ensure_client_is_built() -> None:
),
cwd=client_dir,
shell=True,
check=False,
)


Expand All @@ -79,10 +80,13 @@ def _install_sandboxed_node() -> Path:
rich.print("[bold](viser)[/bold] nodejs is set up!")
return env_dir

subprocess.run([sys.executable, "-m", "nodeenv", "--node=20.4.0", env_dir])
subprocess.run(
[sys.executable, "-m", "nodeenv", "--node=20.4.0", env_dir], check=False
)
subprocess.run(
args=[env_dir / "bin" / "npm", "install", "yarn"],
input="y\n".encode(),
check=False,
)
assert (env_dir / "bin" / "npx").exists()
return env_dir
Expand Down
47 changes: 22 additions & 25 deletions src/viser/_message_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,37 +280,34 @@ def rotate_between(before: onp.ndarray, after: onp.ndarray) -> tf.SO3:
before = before / onp.linalg.norm(before)
after = after / onp.linalg.norm(after)

angle = onp.arccos(onp.dot(before, after))
angle = onp.arccos(onp.clip(onp.dot(before, after), -1, 1))
axis = onp.cross(before, after)
if onp.allclose(axis, onp.zeros(3)):
axis = onp.cross(
before,
(1.0, 0.0, 0.0)
if onp.abs(before[0]) < onp.abs(before[1])
else (0.0, 1.0, 0.0),
)
if onp.allclose(axis, onp.zeros(3), rtol=1e-3, atol=1e-5):
unit_vector = onp.arange(3) == onp.argmin(onp.abs(before))
axis = onp.cross(before, unit_vector)
axis = axis / onp.linalg.norm(axis)
return tf.SO3.exp(angle * axis)

return tf.SO3.exp(-angle * axis)

R_threeworld_world = rotate_between(default_three_up, direction)
R_threeworld_world = rotate_between(direction, default_three_up)

# Rotate the world frame such that:
# If we set +Y to up, +X and +Z should face the camera.
# If we set +Z to up, +X and +Y should face the camera.
#
# This could be made more efficient...
thetas = onp.arange(360)
sums = [
onp.sum(
(tf.SO3.from_y_radians(theta) @ R_threeworld_world)
@ onp.array([-1.0, -1.0, -1.0])
# In App.tsx, the camera is initialized at [-3, 3, -3] in the threejs
# coordinate frame.
desired_fwd = onp.array([-1.0, 0.0, -1.0]) / onp.sqrt(2.0)
current_fwd = R_threeworld_world @ (onp.ones(3) / onp.sqrt(3.0))
current_fwd = current_fwd * onp.array([1.0, 0.0, 1.0])
current_fwd = current_fwd / onp.linalg.norm(current_fwd)
R_threeworld_world = (
tf.SO3.from_y_radians( # Rotate around the null space / up direction.
onp.arctan2(
onp.cross(current_fwd, desired_fwd)[1],
onp.dot(current_fwd, desired_fwd),
),
)
for theta in thetas
]
best_theta = thetas[onp.argmax(sums)]

R_threeworld_world = tf.SO3.from_y_radians(best_theta) @ R_threeworld_world
@ R_threeworld_world
)

if not onp.any(onp.isnan(R_threeworld_world.wxyz)):
# Set the orientation of the root node.
Expand Down Expand Up @@ -685,8 +682,8 @@ def add_point_cloud(
assert (
len(points.shape) == 2 and points.shape[-1] == 3
), "Shape of points should be (N, 3)."
assert colors_cast.shape == points.shape or colors_cast.shape == (
3,
assert (
colors_cast.shape == points.shape == (3,)
), "Shape of colors should be (N, 3) or (3,)."

if colors_cast.shape == (3,):
Expand Down
2 changes: 1 addition & 1 deletion sync_message_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
print(f"Wrote to {target_path}")

# Run prettier.
subprocess.run(args=["npx", "prettier", "-w", str(target_path)])
subprocess.run(args=["npx", "prettier", "-w", str(target_path)], check=False)

0 comments on commit d73fede

Please sign in to comment.