Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 81 additions & 6 deletions bindings/python/pinocchio/visualize/viser_visualizer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import time
import os

try:
import hppfcl
Expand All @@ -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:
Expand Down Expand Up @@ -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):
Copy link
Contributor

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 ?

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:
Copy link
Contributor

Choose a reason for hiding this comment

The 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 self._process_collada_geometry ? Then we should only except on these exceptions

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
Copy link
Contributor

Choose a reason for hiding this comment

The 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):
Expand Down
Binary file added leap.mp4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should delete this file

Binary file not shown.
Loading