Skip to content

Commit

Permalink
Nits
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Nov 28, 2023
1 parent e82a6c2 commit d29308b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 47 deletions.
37 changes: 12 additions & 25 deletions examples/12_click_meshes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
"""

import time
from typing import Literal

import matplotlib
import numpy as onp
import trimesh.creation

import viser

Expand Down Expand Up @@ -41,47 +40,35 @@ def add_swappable_mesh(i: int, j: int) -> None:

colormap = matplotlib.colormaps["tab20"]

def create_mesh(counter: int) -> None:
adding_mesh = "unknown"

if counter == 0 or counter == 1:
adding_mesh = "box"
def create_mesh(counter: Literal[0, 1, 2]) -> None:
if counter == 0:
color = (0.8, 0.8, 0.8)
else:
adding_mesh = "icosphere"

colors = (0.5, 0.5, 0.5)

if counter != 0:
index = (i * grid_shape[1] + j) / (grid_shape[0] * grid_shape[1])
colors = colormap(index)

handle = None
color = colormap(index)[:3]

if adding_mesh == "box":
if counter in (0, 1):
handle = server.add_box(
name=f"/sphere_{i}_{j}",
position=(i, j, 0.0),
colors=colors,
color=color,
dimensions=(0.5, 0.5, 0.5),
)
elif adding_mesh == "icosphere":
else:
handle = server.add_icosphere(
name=f"/sphere_{i}_{j}",
position=(i, j, 0.0),
colors=colors,
radius=0.4,
subdivisions=2,
color=color,
position=(i, j, 0.0),
)

assert handle is not None

@handle.on_click
def _(_) -> None:
x_value.value = i
y_value.value = j

# The new mesh will replace the old one because the names (/sphere_{i}_{j}) are
# the same.
# The new mesh will replace the old one because the names
# /sphere_{i}_{j} are the same.
create_mesh((counter + 1) % 3)

create_mesh(0)
Expand Down
70 changes: 49 additions & 21 deletions src/viser/_message_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import numpy as onp
import numpy.typing as onpt
import trimesh
import trimesh.creation
import trimesh.exchange
import trimesh.visual
from typing_extensions import Literal, ParamSpec, TypeAlias, assert_never
Expand Down Expand Up @@ -632,6 +633,7 @@ def add_mesh_simple(
wireframe: bool = False,
opacity: Optional[float] = None,
material: Literal["standard", "toon3", "toon5"] = "standard",
flat_shading: bool = True,
side: Literal["front", "back", "double"] = "front",
wxyz: Tuple[float, float, float, float] | onp.ndarray = (1.0, 0.0, 0.0, 0.0),
position: Tuple[float, float, float] | onp.ndarray = (0.0, 0.0, 0.0),
Expand All @@ -649,6 +651,8 @@ def add_mesh_simple(
wireframe: Boolean indicating if the mesh should be rendered as a wireframe.
opacity: Opacity of the mesh. None means opaque.
material: Material type of the mesh ('standard', 'toon3', 'toon5').
flat_shading: Whether to do flat shading. Set to False to apply smooth
shading.
side: Side of the surface to render ('front', 'back', 'double').
wxyz: Quaternion rotation to parent frame from local frame (R_pl).
position: Translation from parent frame to local frame (t_pl).
Expand All @@ -668,6 +672,7 @@ def add_mesh_simple(
vertex_colors=None,
wireframe=wireframe,
opacity=opacity,
flat_shading=flat_shading,
side=side,
material=material,
)
Expand Down Expand Up @@ -714,25 +719,35 @@ def add_mesh_trimesh(
def add_box(
self,
name: str,
color: RgbTupleOrArray,
dimensions: Tuple[float, float, float] | onp.ndarray = (1.0, 1.0, 1.0),
colors: Tuple[float, float, float] | onp.ndarray = (-1.0, -1.0, -1.0),
scale: float = 1.0,
wxyz: Tuple[float, float, float, float] | onp.ndarray = (1.0, 0.0, 0.0, 0.0),
position: Tuple[float, float, float] | onp.ndarray = (0.0, 0.0, 0.0),
visible: bool = True,
) -> GlbHandle:
"""Add a box to the scene."""
) -> MeshHandle:
"""Add a box to the scene.
mesh = trimesh.creation.box(dimensions)
Args:
name: A scene tree name. Names in the format of /parent/child can be used to
define a kinematic tree.
color: Color of the box as an RGB tuple.
dimensions: Dimensions of the box (x, y, z).
wxyz: Quaternion rotation to parent frame from local frame (R_pl).
position: Translation from parent frame to local frame (t_pl).
visible: Whether or not this box is initially visible.
if colors != (-1.0, -1.0, -1.0):
mesh.visual.vertex_colors = colors
Returns:
Handle for manipulating scene node.
"""
mesh = trimesh.creation.box(dimensions)

return self.add_mesh_trimesh(
return self.add_mesh_simple(
name=name,
mesh=mesh,
vertices=mesh.vertices,
faces=mesh.faces,
color=color,
flat_shading=True,
position=position,
scale=scale,
wxyz=wxyz,
visible=visible,
)
Expand All @@ -741,25 +756,38 @@ def add_icosphere(
self,
name: str,
radius: float,
subdivisions: int,
colors: Tuple[float, float, float] | onp.ndarray = (-1.0, -1.0, -1.0),
scale: float = 1.0,
color: RgbTupleOrArray,
subdivisions: int = 3,
wxyz: Tuple[float, float, float, float] | onp.ndarray = (1.0, 0.0, 0.0, 0.0),
position: Tuple[float, float, float] | onp.ndarray = (0.0, 0.0, 0.0),
visible: bool = True,
) -> GlbHandle:
"""Add an icosphere to the scene."""
) -> MeshHandle:
"""Add an icosphere to the scene.
mesh = trimesh.creation.icosphere(subdivisions=2, radius=0.4)
Args:
name: A scene tree name. Names in the format of /parent/child can be used to
define a kinematic tree.
radius: Radius of the icosphere.
color: Color of the icosphere as an RGB tuple.
subdivisions: Number of subdivisions to use when creating the icosphere.
wxyz: Quaternion rotation to parent frame from local frame (R_pl).
position: Translation from parent frame to local frame (t_pl).
visible: Whether or not this icosphere is initially visible.
if colors != (-1.0, -1.0, -1.0):
mesh.visual.vertex_colors = colors
Returns:
Handle for manipulating scene node.
"""
mesh = trimesh.creation.icosphere(subdivisions=subdivisions, radius=radius)

return self.add_mesh_trimesh(
# We use add_mesh_simple() because it lets us do smooth shading;
# add_mesh_trimesh() currently does not.
return self.add_mesh_simple(
name=name,
mesh=mesh,
vertices=mesh.vertices,
faces=mesh.faces,
color=color,
flat_shading=False,
position=position,
scale=scale,
wxyz=wxyz,
visible=visible,
)
Expand Down
1 change: 1 addition & 0 deletions src/viser/_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class MeshMessage(Message):

wireframe: bool
opacity: Optional[float]
flat_shading: bool
side: Literal["front", "back", "double"]
material: Literal["standard", "toon3", "toon5"]

Expand Down
1 change: 1 addition & 0 deletions src/viser/client/src/WebsocketInterface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ function useMessageHandler() {
wireframe: message.wireframe,
transparent: message.opacity !== null,
opacity: message.opacity ?? 1.0,
flatShading: message.flat_shading,
side: {
front: THREE.FrontSide,
back: THREE.BackSide,
Expand Down
3 changes: 2 additions & 1 deletion src/viser/client/src/WebsocketMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export interface MeshMessage {
vertex_colors: Uint8Array | null;
wireframe: boolean;
opacity: number | null;
flat_shading: boolean;
side: "front" | "back" | "double";
material: "standard" | "toon3" | "toon5";
}
Expand Down Expand Up @@ -346,7 +347,7 @@ export interface _GuiAddInputBase {
hint: string | null;
initial_value: any;
}
/** GuiAddButtonMessage(order: 'float', id: 'str', label: 'str', container_id: 'str', hint: 'Optional[str]', initial_value: 'bool', color: "Optional[Literal[('dark', 'gray', 'red', 'pink', 'grape', 'violet', 'indigo', 'blue', 'cyan', 'green', 'lime', 'yellow', 'orange', 'teal')]]", icon_base64: 'Optional[str]')
/** GuiAddButtonMessage(order: 'float', id: 'str', label: 'str', container_id: 'str', hint: 'Optional[str]', initial_value: 'bool', color: "Optional[Literal['dark', 'gray', 'red', 'pink', 'grape', 'violet', 'indigo', 'blue', 'cyan', 'green', 'lime', 'yellow', 'orange', 'teal']]", icon_base64: 'Optional[str]')
*
* (automatically generated)
*/
Expand Down

0 comments on commit d29308b

Please sign in to comment.