Skip to content

Commit

Permalink
Use object interface
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderFabisch committed Jul 27, 2023
1 parent 6bdbe76 commit 445cb5c
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 41 deletions.
168 changes: 132 additions & 36 deletions pytransform3d/mesh_loader.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,145 @@
import abc

import numpy as np


def load_mesh(filename, convex_hull=False, return_as_open3d_mesh=False):
vertices = np.empty((0, 3), dtype=float)
triangles = np.empty((0, 3), dtype=int)
done = False
def load_mesh(filename, convex_hull=False):
"""Load mesh from file.
try:
import trimesh
geometry = trimesh.load(filename)
done = True
Parameters
----------
filename : str
File in which the mesh is stored.
if isinstance(geometry, trimesh.Scene):
geometry = geometry.dump().sum()
if convex_hull:
geometry = geometry.convex_hull
convex_hull : bool, optional (default: False)
Compute convex hull of mesh.
vertices = geometry.vertices
triangles = geometry.faces
Returns
-------
mesh : MeshBase
Mesh instance.
"""
mesh = _Trimesh(filename)
success = mesh.load()

if return_as_open3d_mesh:
import open3d
return open3d.geometry.TriangleMesh(
open3d.utility.Vector3dVector(vertices),
open3d.utility.Vector3iVector(triangles))
except ImportError:
pass
if not success:
mesh = _Open3DMesh(filename)
success = mesh.load()

if not success:
raise IOError("Could not load mesh from '%s'" % filename)

if convex_hull:
mesh.convex_hull()

return mesh


class MeshBase(abc.ABC):
"""Abstract base class of meshes.
Parameters
----------
filename : str
File in which the mesh is stored.
"""
def __init__(self, filename):
self.filename = filename

@abc.abstractmethod
def load(self):
"""Load mesh from file.
Returns
-------
success : bool
Has the mesh been loaded?
"""

@abc.abstractmethod
def convex_hull(self):
"""Compute convex hull of mesh."""

@abc.abstractmethod
def get_open3d_mesh(self):
"""Return Open3D mesh.
Returns
-------
mesh : open3d.geometry.TriangleMesh
Open3D mesh.
"""

try:
@property
@abc.abstractmethod
def vertices(self):
"""Vertices."""

@property
@abc.abstractmethod
def triangles(self):
"""Triangles."""


class _Trimesh(MeshBase):
def __init__(self, filename):
super(_Trimesh, self).__init__(filename)
self.mesh = None

def load(self):
try:
import trimesh
except ImportError:
return False

obj = trimesh.load(self.filename)
if isinstance(obj, trimesh.Scene):
obj = obj.dump().sum()
self.mesh = obj
return True

def convex_hull(self):
self.mesh = self.mesh.convex_hull

def get_open3d_mesh(self):
import open3d
mesh = open3d.io.read_triangle_mesh(filename)
done = True
return open3d.geometry.TriangleMesh(
open3d.utility.Vector3dVector(self.vertices),
open3d.utility.Vector3iVector(self.triangles))

if convex_hull:
mesh = mesh.compute_convex_hull()[0]
@property
def vertices(self):
return self.mesh.vertices

if return_as_open3d_mesh:
return mesh
else:
vertices = np.asarray(mesh.vertices)
triangles = np.asarray(mesh.triangles)
except ImportError:
pass
@property
def triangles(self):
return self.mesh.faces

if not done:
raise IOError("Could not load mesh from '%s'" % filename)

return vertices, triangles
class _Open3DMesh(MeshBase):
def __init__(self, filename):
super(_Open3DMesh, self).__init__(filename)
self.mesh = None

def load(self):
try:
import open3d
except ImportError:
return False
self.mesh = open3d.io.read_triangle_mesh(self.filename)
return True

def convex_hull(self):
assert self.mesh is not None
self.mesh = self.mesh.compute_convex_hull()[0]

def get_open3d_mesh(self):
return self.mesh

@property
def vertices(self):
return np.asarray(self.mesh.vertices)

@property
def triangles(self):
return np.asarray(self.mesh.triangles)
6 changes: 3 additions & 3 deletions pytransform3d/plot_utils/_plot_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,11 @@ def plot_mesh(ax=None, filename=None, A2B=np.eye(4),
"package directory.")
return ax

vertices, triangles = load_mesh(filename, convex_hull=convex_hull)
vertices = vertices * s
mesh = load_mesh(filename, convex_hull=convex_hull)
vertices = mesh.vertices * s
vertices = np.hstack((vertices, np.ones((len(vertices), 1))))
vertices = transform(A2B, vertices)[:, :3]
vectors = np.array([vertices[[i, j, k]] for i, j, k in triangles])
vectors = np.array([vertices[[i, j, k]] for i, j, k in mesh.triangles])
if wireframe:
surface = Line3DCollection(vectors)
surface.set_color(color)
Expand Down
4 changes: 2 additions & 2 deletions pytransform3d/visualizer/_artists.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,8 @@ class Mesh(Artist):
"""
def __init__(self, filename, A2B=np.eye(4), s=np.ones(3), c=None,
convex_hull=False):
self.mesh = mesh_loader.load_mesh(
filename, convex_hull=convex_hull, return_as_open3d_mesh=True)
mesh = mesh_loader.load_mesh(filename, convex_hull=convex_hull)
self.mesh = mesh.get_open3d_mesh()
self.mesh.vertices = o3d.utility.Vector3dVector(
np.asarray(self.mesh.vertices) * s)
self.mesh.compute_vertex_normals()
Expand Down

0 comments on commit 445cb5c

Please sign in to comment.