Functions for grouping values and rows.

trimesh.grouping.blocks(data, min_len=2, max_len=inf, wrap=False, digits=None, only_nonzero=False)

Find the indices in an array of contiguous blocks of equal values.

  • data ((n,) array) – Data to find blocks on

  • min_len (int) – The minimum length group to be returned

  • max_len (int) – The maximum length group to be retuurned

  • wrap (bool) – Combine blocks on both ends of 1D array

  • digits (None or int) – If dealing with floats how many digits to consider

  • only_nonzero (bool) – Only return blocks of non- zero values


blocks – Indices referencing data

Return type:

  1. sequence of (*,) int

trimesh.grouping.boolean_rows(a, b, operation=<function intersect1d>)

Find the rows in two arrays which occur in both rows.

  • a ((n, d) int) – Array with row vectors

  • b ((m, d) int) – Array with row vectors

  • operation (function) –

    Numpy boolean set operation function:

    -np.intersect1d -np.setdiff1d



Return type:

(p, d) array containing rows in both a and b

trimesh.grouping.clusters(points, radius)

Find clusters of points which have neighbours closer than radius

  • points ((n, d) float) – Points of dimension d

  • radius (float) – Max distance between points in a cluster


groups – Indices of points in a cluster

Return type:

(m,) sequence of int

trimesh.grouping.float_to_int(data, digits: int | integer | unsignedinteger | None = None)

Given a numpy array of float/bool/int, return as integers.

  • data ((n, d) float, int, or bool) – Input data

  • digits (float or int) – Precision for float conversion


as_int – Data as integers

Return type:

(n, d) int, min_len=0, max_len=inf)

Return the indices of values that are identical

  • values ((n,) int) – Values to group

  • min_len (int) – The shortest group allowed All groups will have len >= min_length

  • max_len (int) – The longest group allowed All groups will have len <= max_length


groups – Contains indices to form groups IE [0,1,0,1] returns [[0,2], [1,3]]

Return type:


trimesh.grouping.group_distance(values, distance)

Find groups of points which have neighbours closer than radius, where no two points in a group are farther than distance apart.

  • points ((n, d) float) – Points of dimension d

  • distance (float) – Max distance between points in a cluster


  • unique ((m, d) float) – Median value of each group

  • groups ((m) sequence of int) – Indexes of points that make up a group

trimesh.grouping.group_min(groups, data)

Given a list of groups find the minimum element of data within each group

  • groups ((n,) sequence of (q,) int) – Indexes of each group corresponding to each element in data

  • data ((m,)) – The data that groups indexes reference


minimums – Minimum value of data per group

Return type:


trimesh.grouping.group_rows(data, require_count=None, digits=None)

Returns index groups of duplicate rows, for example: [[1,2], [3,4], [1,2]] will return [[0,2], [1]]

Note that using require_count allows numpy advanced indexing to be used in place of looping and checking hashes and is ~10x faster.

  • data ((n, m) array) – Data to group

  • require_count (None or int) – Only return groups of a specified length, eg: require_count = 2 [[1,2], [3,4], [1,2]] will return [[0,2]]

  • digits (None or int)

  • decimals (If data is floating point how many)

  • consider (to)

  • tol.merge (or calculated from)


groups – Indices from in indicating identical rows.

Return type:

sequence (*,) int

trimesh.grouping.group_vectors(vectors, angle=0.0001, include_negative=False)

Group vectors based on an angle tolerance, with the option to include negative vectors.

  • vectors ((n,3) float) – Direction vector

  • angle (float) – Group vectors closer than this angle in radians

  • include_negative (bool) – If True consider the same: [0,0,1] and [0,0,-1]


  • new_vectors ((m,3) float) – Direction vector

  • groups ((m,) sequence of int) – Indices of source vectors

trimesh.grouping.hashable_rows(data: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], digits=None) ndarray[Any, dtype[_ScalarType_co]]

We turn our array into integers based on the precision given by digits and then put them in a hashable format.

  • data ((n, m) array) – Input data

  • digits (int or None) – How many digits to add to hash if data is floating point If None, tol.merge will be used


hashable – May return as a np.void or a np.uint64

Return type:


trimesh.grouping.merge_runs(data, digits=None)

Merge duplicate sequential values. This differs from unique_ordered in that values can occur in multiple places in the sequence, but only consecutive repeats are removed


data ((n,) float or int)



Return type:

(m,) float or int


In [1]: a Out[1]: array([-1, -1, -1, 0, 0, 1, 1, 2, 0,

3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9])

In [2]: trimesh.grouping.merge_runs(a) Out[2]: array([-1, 0, 1, 2, 0, 3, 4, 5, 6, 7, 8, 9])

trimesh.grouping.merge_vertices(mesh, merge_tex=None, merge_norm=None, digits_vertex=None, digits_norm=None, digits_uv=None)

Removes duplicate vertices, grouped by position and optionally texture coordinate and normal.

  • mesh (Trimesh object) – Mesh to merge vertices on

  • merge_tex (bool) – If True textured meshes with UV coordinates will have vertices merged regardless of UV coordinates

  • merge_norm (bool) – If True, meshes with vertex normals will have vertices merged ignoring different normals

  • digits_vertex (None or int) – Number of digits to consider for vertex position

  • digits_norm (int) – Number of digits to consider for unit normals

  • digits_uv (int) – Number of digits to consider for UV coordinates

trimesh.grouping.unique_bincount(values, minlength=0, return_inverse=False, return_counts=False)

For arrays of integers find unique values using bin counting. Roughly 10x faster for correct input than np.unique

  • values ((n,) int) – Values to find unique members of

  • minlength (int) – Maximum value that will occur in values (values.max())

  • return_inverse (bool) – If True, return an inverse such that unique[inverse] == values

  • return_counts (bool) – If True, also return the number of times each unique item appears in values


  • unique ((m,) int) – Unique values in original array

  • inverse ((n,) int, optional) – An array such that unique[inverse] == values Only returned if return_inverse is True

  • counts ((m,) int, optional) – An array holding the counts of each unique item in values Only returned if return_counts is True

trimesh.grouping.unique_float(data, return_index=False, return_inverse=False, digits=None)

Identical to the numpy.unique command, except evaluates floating point numbers, using a specified number of digits.

If digits isn’t specified, the library default TOL_MERGE will be used.

trimesh.grouping.unique_ordered(data, return_index=False, return_inverse=False)

Returns the same as np.unique, but ordered as per the first occurrence of the unique value in data.


In [1]: a = [0, 3, 3, 4, 1, 3, 0, 3, 2, 1]

In [2]: np.unique(a) Out[2]: array([0, 1, 2, 3, 4])

In [3]: trimesh.grouping.unique_ordered(a) Out[3]: array([0, 3, 4, 1, 2])

trimesh.grouping.unique_rows(data, digits=None, keep_order=False)

Returns indices of unique rows. It will return the first occurrence of a row that is duplicated: [[1,2], [3,4], [1,2]] will return [0,1]

  • data ((n, m) array) – Floating point data

  • digits (int or None) – How many digits to consider


  • unique ((j,) int) – Index in data which is a unique row

  • inverse ((n,) int) – Array to reconstruct original Example: data[unique][inverse] == data

trimesh.grouping.unique_value_in_row(data, unique=None)

For a 2D array of integers find the position of a value in each row which only occurs once.

If there are more than one value per row which occur once, the last one is returned.

  • data ((n, d) int) – Data to check values

  • unique ((m,) int) – List of unique values contained in data. Generated from np.unique if not passed


result – With one or zero True values per row.

Return type:

(n, d) bool


In [0]: r = np.array([[-1, 1, 1],

[-1, 1, -1], [-1, 1, 1], [-1, 1, -1], [-1, 1, -1]], dtype=np.int8)

In [1]: unique_value_in_row(r) Out[1]:

array([[ True, False, False],

[False, True, False], [ True, False, False], [False, True, False], [False, True, False]], dtype=bool)

In [2]: unique_value_in_row(r).sum(axis=1) Out[2]: array([1, 1, 1, 1, 1])

In [3]: r[unique_value_in_row(r)] Out[3]: array([-1, 1, -1, 1, 1], dtype=int8)