Mesh#

class genesis.engine.mesh.Mesh(mesh, surface: Surface | None = None, uvs: NDArray | None = None, scale: NDArray | float | None = None, convexify=False, decimate=False, decimate_face_num=500, decimate_aggressiveness=0, metadata=None, is_mesh_zup: bool = True)[source]#

Bases: RBC, SerializationMixin

Genesis’s own triangle mesh object.

This is a wrapper of trimesh.Trimesh with some additional features and attributes. The internal trimesh object can be accessed via self.trimesh.

Parameters:
  • surface (genesis.Surface) – The mesh’s surface object.

  • uvs (np.ndarray) – The mesh’s uv coordinates.

  • convexify (bool) – Whether to convexify the mesh.

  • decimate (bool) – Whether to decimate the mesh.

  • decimate_face_num (int) – The target number of faces after decimation.

  • decimate_aggressiveness (int) – How hard the decimation process will try to match the target number of faces, as a integer ranging from 0 to 8. 0 is losseless. 2 preserves all features of the original geometry. 5 may significantly alters the original geometry if necessary. 8 does what needs to be done at all costs. Default to 0.

  • metadata (dict) – The metadata of the mesh.

convexify()[source]#

Convexify the mesh.

watertighten(aggressiveness=7)[source]#

Replace self._mesh with a closed manifold wrap of the current geometry.

aggressiveness is the integer 0..8 controlling the wrap’s quadric-error decimation cost cutoff; see genesis.utils.watertighten.watertighten_mesh for the full pipeline.

decimate(decimate_face_num, decimate_aggressiveness)[source]#

Decimate the mesh.

remesh(edge_len_abs=None, edge_len_ratio=0.01, fix=True)[source]#

Remesh for tetrahedralization.

tetrahedralize(tet_cfg)[source]#

Tetrahedralize the mesh.

particlize(p_size=0.01, sampler='random')[source]#

Sample particles using the mesh volume.

sample_point_cloud(n_points: int, *, n_candidates: int | None = None, seed: int | None = None, use_cache: bool = True, return_normals: bool = False) ndarray | tuple[numpy.ndarray, numpy.ndarray][source]#

Sample n_points from mesh in local coordinates using Furthest Point Sampling.

If return_normals is True, returns (positions, normals) with face normals aligned to each sample.

clear_visuals()[source]#

Clear the mesh’s visual attributes by resetting the surface to gs.surfaces.Default().

get_unique_edges()[source]#

Get the unique edges of the mesh.

property inertial#

Mass, center of mass and inertia tensor of the geometry in its own frame, at unit density.

Non-watertight geometry is closed by its convex hull first so the volume integral is well-defined; a degenerate geometry has no mass, and composes as a geom of no mass at the origin. The result is memoized and shared by reference across entities backed by the same geometry.

get_vert_adjacency()[source]#

Get the per-vertex adjacency graph as flat arrays (vert_neighbors, vert_n_neighbors, vert_neighbor_start).

vert_neighbors concatenates each vertex’s neighbor indices, vert_n_neighbors holds the neighbor count of each vertex, and vert_neighbor_start the offset of each vertex’s slice into vert_neighbors.

copy()[source]#

Copy the mesh.

classmethod from_trimesh(mesh, scale=None, convexify=False, decimate=False, decimate_face_num=500, decimate_aggressiveness=2, metadata=None, surface=None, is_mesh_zup=True)[source]#

Create a genesis.Mesh from a trimesh.Trimesh object.

classmethod from_attrs(verts, faces, normals=None, surface=None, uvs=None, scale=None, metadata=None, is_mesh_zup=True)[source]#

Create a genesis.Mesh from mesh attributes including vertices, faces, and normals.

classmethod from_morph_surface(morph, surface=None) list[genesis.engine.mesh.Mesh][source]#

Create genesis.Mesh objects from morph and surface options.

A list is always returned: a Mesh morph (morphs.Mesh) may contain multiple sub-meshes, while primitive morphs yield a single mesh.

set_color(color)[source]#

Set the mesh’s color.

update_trimesh_visual()[source]#

Update the trimesh obj’s visual attributes using its surface and uvs.

apply_transform(T)[source]#

Apply a 4x4 transformation matrix (translation on the right column) to the mesh.

property uid#

Return the mesh’s uid.

property trimesh#

Return the mesh’s trimesh object.

property is_convex: bool#

Whether the mesh is convex.

property is_watertight: bool#

Whether the mesh is a closed manifold surface.

property metadata#

Metadata of the mesh.

property verts#

Vertices of the mesh.

property faces#

Faces of the mesh.

property normals#

Normals of the mesh.

property color#

Color of the mesh, as red, green, blue and alpha.

property surface#

Surface of the mesh.

property uvs#

UVs of the mesh.

property area#

Surface area of the mesh.

property volume#

Volume of the mesh.

export(exporting: Exporting) dict[source]#

Export the geometry, uvs, surface and metadata a mesh holds.

A mesh is written this way rather than through its fields because construction convexifies, decimates and rescales it: what a file carries is the geometry as it now stands, so reading one back processes nothing.

classmethod load(raw: dict, loading: Loading) Mesh[source]#

Recreate the mesh exactly as exported, processing none of its geometry again.

Meshes written from one geometry are handed the edges, the vertex adjacency and the inertia of the first of them, exactly as ‘postprocess_collision_geoms’ hands them to the entities it builds from one asset. Each keeps its own trimesh and surface, so a mesh drawn in its own colour still costs one copy of the geometry.