1. tuned arrow mesh drawing
2. centralixzed arrow config in layout.py 3. seperate mesh render and display resolution to speed up (~40 fps)
This commit is contained in:
@@ -97,7 +97,7 @@ def apply_view_from_world_to_cam(vis, world_to_cam: np.ndarray, *, lookat: np.nd
|
||||
|
||||
|
||||
def apply_mesh_lighting(vis) -> None:
|
||||
"""Enable shaded lighting so the tactile mesh reads as a 3D surface."""
|
||||
"""Enable shaded lighting on the legacy Open3D Visualizer."""
|
||||
import open3d as o3d
|
||||
|
||||
render_option = vis.get_render_option()
|
||||
@@ -108,3 +108,74 @@ def apply_mesh_lighting(vis) -> None:
|
||||
if hasattr(render_option, "mesh_shade_option"):
|
||||
render_option.mesh_shade_option = o3d.visualization.MeshShadeOption.Color
|
||||
vis.update_renderer()
|
||||
|
||||
|
||||
def normalize_light_direction(direction) -> np.ndarray:
|
||||
d = np.asarray(direction, dtype=np.float64).reshape(3)
|
||||
norm = float(np.linalg.norm(d))
|
||||
if norm <= 0:
|
||||
return np.array([0.0, 0.0, -1.0], dtype=np.float64)
|
||||
return d / norm
|
||||
|
||||
|
||||
def apply_filament_sun_light(renderer, *, direction, intensity: float) -> None:
|
||||
"""Configure Filament sun light on an OffscreenRenderer."""
|
||||
scene = renderer.scene
|
||||
if not hasattr(scene, "scene"):
|
||||
return
|
||||
filament = scene.scene
|
||||
sun_dir = normalize_light_direction(direction).tolist()
|
||||
if hasattr(filament, "set_sun_light"):
|
||||
filament.set_sun_light(sun_dir, [1.0, 1.0, 1.0], float(intensity))
|
||||
if hasattr(filament, "enable_sun_light"):
|
||||
filament.enable_sun_light(True)
|
||||
|
||||
|
||||
def compute_vertex_normals(vertices: np.ndarray, triangles: np.ndarray) -> np.ndarray:
|
||||
"""Per-vertex normals for a triangle mesh (vectorized)."""
|
||||
vertices = np.asarray(vertices, dtype=np.float64)
|
||||
triangles = np.asarray(triangles, dtype=np.int32)
|
||||
v0 = vertices[triangles[:, 0]]
|
||||
v1 = vertices[triangles[:, 1]]
|
||||
v2 = vertices[triangles[:, 2]]
|
||||
face_normals = np.cross(v1 - v0, v2 - v0)
|
||||
normals = np.zeros_like(vertices)
|
||||
np.add.at(normals, triangles[:, 0], face_normals)
|
||||
np.add.at(normals, triangles[:, 1], face_normals)
|
||||
np.add.at(normals, triangles[:, 2], face_normals)
|
||||
lengths = np.linalg.norm(normals, axis=1)
|
||||
valid = lengths > 1e-12
|
||||
normals[valid] /= lengths[valid, np.newaxis]
|
||||
normals[~valid] = np.array([0.0, 0.0, 1.0], dtype=np.float64)
|
||||
return normals
|
||||
|
||||
|
||||
def precompute_shade_factors(vertices: np.ndarray, triangles: np.ndarray, lighting) -> np.ndarray:
|
||||
"""Per-vertex shade multipliers from static mesh geometry and layout lighting."""
|
||||
normals = compute_vertex_normals(vertices, triangles)
|
||||
d = normalize_light_direction(lighting.direction)
|
||||
ndotl = np.clip(normals @ d, 0.0, 1.0)
|
||||
return float(lighting.ambient) + float(lighting.diffuse) * ndotl
|
||||
|
||||
|
||||
def apply_shade_factors(colors: np.ndarray, shade_factors: np.ndarray | None) -> np.ndarray:
|
||||
if shade_factors is None:
|
||||
return colors
|
||||
return np.clip(np.asarray(colors, dtype=np.float64) * shade_factors[:, np.newaxis], 0.0, 1.0)
|
||||
|
||||
|
||||
def shade_vertex_colors(
|
||||
colors: np.ndarray,
|
||||
normals: np.ndarray,
|
||||
*,
|
||||
direction,
|
||||
ambient: float,
|
||||
diffuse: float,
|
||||
) -> np.ndarray:
|
||||
"""Apply directional shading to vertex colors (legacy viewer path)."""
|
||||
colors = np.asarray(colors, dtype=np.float64)
|
||||
normals = np.asarray(normals, dtype=np.float64)
|
||||
d = normalize_light_direction(direction)
|
||||
ndotl = np.clip(normals @ d, 0.0, 1.0)
|
||||
shade = float(ambient) + float(diffuse) * ndotl
|
||||
return np.clip(colors * shade[:, np.newaxis], 0.0, 1.0)
|
||||
|
||||
Reference in New Issue
Block a user