-
Notifications
You must be signed in to change notification settings - Fork 477
Add color support for robot meshes in Viser #2793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: devel
Are you sure you want to change the base?
Changes from all commits
be2587c
f760906
2347877
ea797d4
68c539c
ac14f5f
9decb6c
7e2e7a9
16c3bed
e0bfdf1
bcf1681
e98d328
446c658
b8e5274
ea7a881
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| import time | ||
| import os | ||
|
|
||
| try: | ||
| import hppfcl | ||
|
|
@@ -7,12 +8,16 @@ | |
|
|
||
| import numpy as np | ||
|
|
||
| from pathlib import Path | ||
| from trimesh.exchange import dae | ||
| from .. import pinocchio_pywrap_default as pin | ||
| from . import BaseVisualizer | ||
|
|
||
| try: | ||
| import trimesh # Required by viser | ||
| import viser | ||
| import collada | ||
|
|
||
| except ImportError: | ||
| import_viser_succeed = False | ||
| else: | ||
|
|
@@ -214,20 +219,90 @@ def loadViewerGeometryObject(self, geometry_object, prefix="", color=None): | |
|
|
||
| self.frames[name] = frame | ||
|
|
||
| def _add_mesh_from_path(self, name, mesh_path, color): | ||
| def _add_mesh_from_path(self, name, mesh_path, color=None): | ||
| """ | ||
| Load a mesh from a file. | ||
| """ | ||
| ext = os.path.splitext(mesh_path)[1].lower() | ||
|
|
||
| if ext == ".dae": | ||
| return self._load_collada_mesh(name, mesh_path, color) | ||
| else: | ||
| return self._load_standard_mesh(name, mesh_path, color) | ||
|
|
||
| def _load_collada_mesh(self, name, mesh_path, color): | ||
| """ | ||
| Load a COLLADA mesh with color support. | ||
| """ | ||
| try: | ||
| mesh_collada = collada.Collada(mesh_path) | ||
|
|
||
| if len(mesh_collada.effects) < len(mesh_collada.geometries): | ||
| return self._load_standard_mesh(name, mesh_path, color) | ||
|
|
||
| frames = [] | ||
| for i, (geometry, effect) in enumerate(zip(mesh_collada.geometries, mesh_collada.effects)): | ||
| frame = self._process_collada_geometry(name, i, geometry, effect, color, mesh_path) | ||
| if frame: | ||
| frames.append(frame) | ||
|
|
||
| return frames[0] if frames else None | ||
| except Exception: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is really too general. Do we know which kind of exception can be raised by |
||
| return self._load_standard_mesh(name, mesh_path, color) | ||
|
|
||
| def _process_collada_geometry(self, name, index, geometry, effect, fallback_color, mesh_path): | ||
| """ | ||
| Process a single COLLADA geometry with its material. | ||
| """ | ||
| try: | ||
| vertices, faces = self._extract_geometry_data(geometry) | ||
| mesh_color = getattr(effect, "diffuse", None) | ||
|
|
||
| if mesh_color is not None: | ||
| return self.viewer.scene.add_mesh_simple( | ||
| f"{name}_{index}", vertices, faces, | ||
| color=mesh_color[:3], opacity=mesh_color[3] | ||
| ) | ||
| elif fallback_color is not None: | ||
| return self.viewer.scene.add_mesh_simple( | ||
| f"{name}_{index}", vertices, faces, | ||
| color=fallback_color[:3], opacity=fallback_color[3] | ||
| ) | ||
| else: | ||
| mesh = trimesh.load_mesh(mesh_path) | ||
| return self.viewer.scene.add_mesh_trimesh(f"{name}_{index}", mesh) | ||
| except Exception: | ||
| try: | ||
| mesh = trimesh.load_mesh(mesh_path) | ||
| return self.viewer.scene.add_mesh_trimesh(f"{name}_{index}", mesh) | ||
| except Exception: | ||
|
Comment on lines
+274
to
+278
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is really too general. You should target a more specialized exception. |
||
| return None | ||
|
|
||
| def _extract_geometry_data(self, geometry): | ||
| """ | ||
| Extract vertices and faces from a COLLADA geometry. | ||
| """ | ||
| vertices = geometry.primitives[0].sources["VERTEX"][0][4].data | ||
| indices = geometry.primitives[0].indices | ||
|
|
||
| if indices.ndim == 3: | ||
| faces = indices[:, :, 0] | ||
| else: | ||
| faces = indices.reshape(-1, 3) | ||
|
|
||
| return vertices, faces | ||
|
|
||
| def _load_standard_mesh(self, name, mesh_path, color): | ||
| """ | ||
| Load a mesh using trimesh (STL and other formats). | ||
| """ | ||
| mesh = trimesh.load_mesh(mesh_path) | ||
| if color is None: | ||
| return self.viewer.scene.add_mesh_trimesh(name, mesh) | ||
| else: | ||
| return self.viewer.scene.add_mesh_simple( | ||
| name, | ||
| mesh.vertices, | ||
| mesh.faces, | ||
| color=color[:3], | ||
| opacity=color[3], | ||
| name, mesh.vertices, mesh.faces, | ||
| color=color[:3], opacity=color[3] | ||
| ) | ||
|
|
||
| def _add_mesh_from_convex(self, name, geom, color): | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should delete this file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if there is more effects than geometrie, do the next loop work ?