trimesh.util module¶
“Grab bag” of utility functions.
- class trimesh.util.FunctionRegistry(**kwargs)¶
Bases:
Mapping
Non-overwritable mapping of string keys to functions.
This allows external packages to register additional implementations of common functionality without risk of breaking implementations provided by trimesh.
See trimesh.voxel.morphology for example usage.
- __init__(**kwargs)¶
- trimesh.util.allclose(a, b, atol: float = 1e-08)¶
A replacement for np.allclose that does few checks and validation and as a result is faster.
- Parameters:
a (np.ndarray) – To be compared
b (np.ndarray) – To be compared
atol (float) – Acceptable distance between a and b to be “close”
- Return type:
bool indicating if all elements are within atol.
- trimesh.util.append_faces(vertices_seq, faces_seq)¶
Given a sequence of zero-indexed faces and vertices combine them into a single array of faces and a single array of vertices.
- Parameters:
vertices_seq ((n, ) sequence of (m, d) float) – Multiple arrays of verticesvertex arrays
faces_seq ((n, ) sequence of (p, j) int) – Zero indexed faces for matching vertices
- Returns:
vertices ((i, d) float) – Points in space
faces ((j, 3) int) – Reference vertex indices
- trimesh.util.array_to_encoded(array, dtype=None, encoding='base64')¶
Export a numpy array to a compact serializable dictionary.
- Parameters:
array (array) – Any numpy array
dtype (str or None) – Optional dtype to encode array
encoding (str) – ‘base64’ or ‘binary’
- Returns:
encoded – Has keys: ‘dtype’: str, of dtype ‘shape’: tuple of shape ‘base64’: str, base64 encoded string
- Return type:
dict
- trimesh.util.array_to_string(array, col_delim=' ', row_delim='\n', digits=8, value_format='{}')¶
Convert a 1 or 2D array into a string with a specified number of digits and delimiter. The reason this exists is that the basic numpy array to string conversions are surprisingly bad.
- Parameters:
array ((n,) or (n, d) float or int) – Data to be converted If shape is (n,) only column delimiter will be used
col_delim (str) – What string should separate values in a column
row_delim (str) – What string should separate values in a row
digits (int) – How many digits should floating point numbers include
value_format (str) – Format string for each value or sequence of values If multiple values per value_format it must divide into array evenly.
- Returns:
formatted – String representation of original array
- Return type:
str
- trimesh.util.attach_to_log(level=10, handler=None, loggers=None, colors=True, capture_warnings=True, blacklist=None)¶
Attach a stream handler to all loggers.
- Parameters:
level (enum) – Logging level, like logging.INFO
handler (None or logging.Handler) – Handler to attach
loggers (None or (n,) logging.Logger) – If None, will try to attach to all available
colors (bool) – If True try to use colorlog formatter
blacklist ((n,) str) – Names of loggers NOT to attach to
- trimesh.util.bounds_tree(bounds)¶
Given a set of axis aligned bounds create an r-tree for broad-phase collision detection.
- Parameters:
bounds ((n, 2D) or (n, 2, D) float) – Non-interleaved bounds where D=dimension E.G a 2D bounds tree: [(minx, miny, maxx, maxy), …]
- Returns:
tree – Tree containing bounds by index
- Return type:
Rtree
- trimesh.util.comment_strip(text, starts_with='#', new_line='\n')¶
Strip comments from a text block.
- Parameters:
text (str) – Text to remove comments from
starts_with (str) – Character or substring that starts a comment
new_line (str) – Character or substring that ends a comment
- Returns:
stripped – Text with comments stripped
- Return type:
str
- trimesh.util.compress(info, **kwargs)¶
Compress data stored in a dict.
- Parameters:
info (dict) – Data to compress in form: {file name in archive: bytes or file-like object}
kwargs (dict) – Passed to zipfile.ZipFile
- Returns:
compressed – Compressed file data
- Return type:
bytes
- trimesh.util.concatenate(a, b=None) trimesh.Trimesh | trimesh.path.Path2D | trimesh.path.Path3D ¶
Concatenate two or more meshes.
- Parameters:
a (trimesh.Trimesh) – Mesh or list of meshes to be concatenated object, or list of such
b (trimesh.Trimesh) – Mesh or list of meshes to be concatenated
- Returns:
Concatenated mesh
- Return type:
result
- trimesh.util.convert_like(item, like)¶
Convert an item to have the dtype of another item
- Parameters:
item (any) – Item to be converted
like (any) – Object with target dtype If None, item is returned unmodified
- Returns:
result
- Return type:
item, but in dtype of like
- trimesh.util.decimal_to_digits(decimal, min_digits=None) int ¶
Return the number of digits to the first nonzero decimal.
- Parameters:
decimal (float)
min_digits (int, minimum number of digits to return)
- Returns:
digits
- Return type:
int, number of digits to the first nonzero decimal
- trimesh.util.decode_keys(store, encoding='utf-8')¶
If a dictionary has keys that are bytes decode them to a str.
- Parameters:
store (dict) – Dictionary with data
- Returns:
result – Values are untouched but keys that were bytes are converted to ASCII strings.
- Return type:
dict
Example
In [1]: d Out[1]: {1020: ‘nah’, b’hi’: ‘stuff’}
In [2]: trimesh.util.decode_keys(d) Out[2]: {1020: ‘nah’, ‘hi’: ‘stuff’}
- trimesh.util.decode_text(text, initial='utf-8')¶
Try to decode byte input as a string.
Tries initial guess (UTF-8) then if that fails it uses chardet to try another guess before failing.
- Parameters:
text (bytes) – Data that might be a string
initial (str) – Initial guess for text encoding.
- Returns:
decoded – Data as a string
- Return type:
str
- trimesh.util.decompress(file_obj, file_type)¶
Given an open file object and a file type, return all components of the archive as open file objects in a dict.
- Parameters:
file_obj (file-like) – Containing compressed data
file_type (str) – File extension, ‘zip’, ‘tar.gz’, etc
- Returns:
decompressed – Data from archive in format {file name : file-like}
- Return type:
dict
- trimesh.util.diagonal_dot(a, b)¶
Dot product by row of a and b.
There are a lot of ways to do this though performance varies very widely. This method uses a dot product to sum the row and avoids function calls if at all possible.
Comparing performance of some equivalent versions: ``` In [1]: import numpy as np; import trimesh
In [2]: a = np.random.random((10000, 3))
In [3]: b = np.random.random((10000, 3))
In [4]: %timeit (a * b).sum(axis=1) 1000 loops, best of 3: 181 us per loop
In [5]: %timeit np.einsum(‘ij,ij->i’, a, b) 10000 loops, best of 3: 62.7 us per loop
In [6]: %timeit np.diag(np.dot(a, b.T)) 1 loop, best of 3: 429 ms per loop
In [7]: %timeit np.dot(a * b, np.ones(a.shape[1])) 10000 loops, best of 3: 61.3 us per loop
In [8]: %timeit trimesh.util.diagonal_dot(a, b) 10000 loops, best of 3: 55.2 us per loop ```
- Parameters:
a ((m, d) float) – First array
b ((m, d) float) – Second array
- Returns:
result – Dot product of each row
- Return type:
(m,) float
- trimesh.util.distance_to_end(file_obj)¶
For an open file object how far is it to the end
- Parameters:
file_obj (open file-like object)
- Returns:
distance
- Return type:
int, bytes to end of file
- trimesh.util.encoded_to_array(encoded)¶
Turn a dictionary with base64 encoded strings back into a numpy array.
- Parameters:
encoded (dict) –
- Has keys:
dtype: string of dtype shape: int tuple of shape base64: base64 encoded string of flat array binary: decode result coming from numpy.tobytes
- Returns:
array
- Return type:
numpy array
- trimesh.util.euclidean(a, b) float ¶
DEPRECATED: use np.linalg.norm(a - b) instead of this.
- trimesh.util.generate_basis(z, epsilon=1e-12)¶
Generate an arbitrary basis (also known as a coordinate frame) from a given z-axis vector.
- Parameters:
z ((3,) float) – A vector along the positive z-axis.
epsilon (float) – Numbers smaller than this considered zero.
- Returns:
x ((3,) float) – Vector along x axis.
y ((3,) float) – Vector along y axis.
z ((3,) float) – Vector along z axis.
- trimesh.util.grid_arange(bounds, step)¶
Return a grid from an (2,dimension) bounds with samples step distance apart.
- Parameters:
bounds ((2,dimension) list of [[min x, min y, etc], [max x, max y, etc]])
step (float, or (dimension) floats, separation between points)
- Returns:
grid
- Return type:
(n, dimension), points inside the specified bounds
- trimesh.util.grid_linspace(bounds, count)¶
Return a grid spaced inside a bounding box with edges spaced using np.linspace.
- Parameters:
bounds ((2,dimension) list of [[min x, min y, etc], [max x, max y, etc]])
count (int, or (dimension,) int, number of samples per side)
- Returns:
grid
- Return type:
(n, dimension) float, points in the specified bounds
- trimesh.util.has_module(name: str) bool ¶
Check to see if a module is installed by name without actually importing the module.
- Parameters:
name (str) – The name of the module to check
- Returns:
installed – True if module is installed
- Return type:
bool
- trimesh.util.is_binary_file(file_obj)¶
Returns True if file has non-ASCII characters (> 0x7F, or 127) Should work in both Python 2 and 3
- trimesh.util.is_ccw(points, return_all=False)¶
Check if connected 2D points are counterclockwise.
- Parameters:
points ((n, 2) float) – Connected points on a plane
return_all (bool) – Return polygon area and centroid or just counter-clockwise.
- Returns:
ccw (bool) – True if points are counter-clockwise
area (float) – Only returned if return_centroid
centroid ((2,) float) – Centroid of the polygon.
- trimesh.util.is_file(obj)¶
Check if an object is file-like
- Parameters:
obj (object) – Any object type to be checked
- Returns:
is_file – True if object is a file
- Return type:
bool
- trimesh.util.is_instance_named(obj, name)¶
Given an object, if it is a member of the class ‘name’, or a subclass of ‘name’, return True.
- Parameters:
obj (instance) – Some object of some class
name (str) – The name of the class we want to check for
- Returns:
is_instance – Whether the object is a member of the named class
- Return type:
bool
- trimesh.util.is_pathlib(obj)¶
Check if the object is a pathlib.Path or subclass.
- Parameters:
obj (object) – Object to be checked
- Returns:
is_pathlib – Is the input object a pathlib path
- Return type:
bool
- trimesh.util.is_sequence(obj) bool ¶
Check if an object is a sequence or not.
- Parameters:
obj (object) – Any object type to be checked
- Returns:
is_sequence – True if object is sequence
- Return type:
bool
- trimesh.util.is_shape(obj, shape, allow_zeros: bool = False) bool ¶
Compare the shape of a numpy.ndarray to a target shape, with any value less than zero being considered a wildcard
Note that if a list-like object is passed that is not a numpy array, this function will not convert it and will return False.
- Parameters:
obj (np.ndarray) – Array to check the shape on
shape (list or tuple) – Any negative term will be considered a wildcard Any tuple term will be evaluated as an OR
allow_zeros (bool) – if False, zeros do not match negatives in shape
- Returns:
shape_ok – True if shape of obj matches query shape
- Return type:
bool
Examples
In [1]: a = np.random.random((100, 3))
In [2]: a.shape Out[2]: (100, 3)
In [3]: trimesh.util.is_shape(a, (-1, 3)) Out[3]: True
In [4]: trimesh.util.is_shape(a, (-1, 3, 5)) Out[4]: False
In [5]: trimesh.util.is_shape(a, (100, -1)) Out[5]: True
In [6]: trimesh.util.is_shape(a, (-1, (3, 4))) Out[6]: True
In [7]: trimesh.util.is_shape(a, (-1, (4, 5))) Out[7]: False
- trimesh.util.is_string(obj) bool ¶
DEPRECATED : this is not necessary since we dropped Python 2.
Replace with isinstance(obj, str)
- trimesh.util.isclose(a, b, atol: float = 1e-08)¶
A replacement for np.isclose that does fewer checks and validation and as a result is roughly 4x faster.
Note that this is used in tight loops, and as such a and b MUST be np.ndarray, not list or “array-like”
- Parameters:
a (np.ndarray) – To be compared
b (np.ndarray) – To be compared
atol (float) – Acceptable distance between a and b to be “close”
- Returns:
close – Per-element closeness
- Return type:
np.ndarray, bool
- trimesh.util.jsonify(obj, **kwargs)¶
A version of json.dumps that can handle numpy arrays by creating a custom encoder for numpy dtypes.
- Parameters:
obj (list, dict) – A JSON-serializable blob
kwargs (dict) – Passed to json.dumps
- Returns:
dumped – JSON dump of obj
- Return type:
str
- trimesh.util.make_sequence(obj)¶
Given an object, if it is a sequence return, otherwise add it to a length 1 sequence and return.
Useful for wrapping functions which sometimes return single objects and other times return lists of objects.
- Parameters:
obj (object) – An object to be made a sequence
- Returns:
as_sequence – Contains input value
- Return type:
(n,) sequence
- trimesh.util.multi_dict(pairs)¶
Given a set of key value pairs, create a dictionary. If a key occurs multiple times, stack the values into an array.
Can be called like the regular dict(pairs) constructor
- Parameters:
pairs ((n, 2) array of key, value pairs)
- Returns:
result
- Return type:
dict, with all values stored (rather than last with regular dict)
- trimesh.util.pairwise(iterable)¶
For an iterable, group values into pairs.
- Parameters:
iterable ((m, ) list) – A sequence of values
- Returns:
pairs – Pairs of sequential values
- Return type:
(n, 2)
Example
In [1]: data Out[1]: [0, 1, 2, 3, 4, 5, 6]
In [2]: list(trimesh.util.pairwise(data)) Out[2]: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
- trimesh.util.row_norm(data)¶
Compute the norm per-row of a numpy array.
This is identical to np.linalg.norm(data, axis=1) but roughly three times faster due to being less general.
In [3]: %timeit trimesh.util.row_norm(a) 76.3 us +/- 651 ns per loop
In [4]: %timeit np.linalg.norm(a, axis=1) 220 us +/- 5.41 us per loop
- Parameters:
data ((n, d) float) – Input 2D data to calculate per-row norm of
- Returns:
norm – Norm of each row of input array
- Return type:
(n,) float
- trimesh.util.sigfig_int(values, sigfig)¶
Convert a set of floating point values into integers with a specified number of significant figures and an exponent.
- Parameters:
values ((n,) float or int) – Array of values
sigfig ((n,) int) – Number of significant figures to keep
- Returns:
as_int ((n,) int) – Every value[i] has sigfig[i] digits
multiplier ((n, int)) – Exponent, so as_int * 10 ** multiplier is the same order of magnitude as the input
- trimesh.util.sigfig_round(values, sigfig=1)¶
Round a single value to a specified number of significant figures.
- Parameters:
values (float) – Value to be rounded
sigfig (int) – Number of significant figures to reduce to
- Returns:
rounded – Value rounded to the specified number of significant figures
- Return type:
float
Examples
In [1]: trimesh.util.round_sigfig(-232453.00014045456, 1) Out[1]: -200000.0
In [2]: trimesh.util.round_sigfig(.00014045456, 1) Out[2]: 0.0001
In [3]: trimesh.util.round_sigfig(.00014045456, 4) Out[3]: 0.0001405
- trimesh.util.spherical_to_vector(spherical)¶
Convert an array of (n, 2) spherical angles to (n, 3) unit vectors.
- Parameters:
spherical ((n , 2) float) – Angles, in radians
- Returns:
vectors – Unit vectors
- Return type:
(n, 3) float
- trimesh.util.split_extension(file_name, special=None)¶
Find the file extension of a file name, including support for special case multipart file extensions (like .tar.gz)
- Parameters:
file_name (str) – File name
special (list of str) – Multipart extensions eg: [‘tar.bz2’, ‘tar.gz’]
- Returns:
extension – Last characters after a period, or a value from ‘special’
- Return type:
str
- trimesh.util.stack_3D(points, return_2D=False)¶
For a list of (n, 2) or (n, 3) points return them as (n, 3) 3D points, 2D points on the XY plane.
- Parameters:
points ((n, 2) or (n, 3) float) – Points in either 2D or 3D space
return_2D (bool) – Were the original points 2D?
- Returns:
points ((n, 3) float) – Points in space
is_2D (bool) – [OPTIONAL] if source points were (n, 2)
- trimesh.util.stack_lines(indices)¶
Stack a list of values that represent a polyline into individual line segments with duplicated consecutive values.
- Parameters:
indices ((m,) any) – List of items to be stacked
- Returns:
stacked – Stacked items
- Return type:
(n, 2) any
Examples
In [1]: trimesh.util.stack_lines([0, 1, 2]) Out[1]: array([[0, 1],
[1, 2]])
In [2]: trimesh.util.stack_lines([0, 1, 2, 4, 5]) Out[2]: array([[0, 1],
[1, 2], [2, 4], [4, 5]])
In [3]: trimesh.util.stack_lines([[0, 0], [1, 1], [2, 2], [3, 3]]) Out[3]: array([[0, 0],
[1, 1], [1, 1], [2, 2], [2, 2], [3, 3]])
- trimesh.util.structured_array_to_string(array, col_delim=' ', row_delim='\n', digits=8, value_format='{}')¶
Convert an unstructured array into a string with a specified number of digits and delimiter. The reason thisexists is that the basic numpy array to string conversionsare surprisingly bad.
- Parameters:
array ((n,) or (n, d) float or int) – Data to be converted If shape is (n,) only column delimiter will be used
col_delim (str) – What string should separate values in a column
row_delim (str) – What string should separate values in a row
digits (int) – How many digits should floating point numbers include
value_format (str) – Format string for each value or sequence of values If multiple values per value_format it must divide into array evenly.
- Returns:
formatted – String representation of original array
- Return type:
str
- trimesh.util.submesh(mesh, faces_sequence, repair=True, only_watertight=False, min_faces=None, append=False)¶
Return a subset of a mesh.
- Parameters:
mesh (Trimesh) – Source mesh to take geometry from
faces_sequence (sequence (p,) int) – Indexes of mesh.faces
repair (bool) – Try to make submeshes watertight
only_watertight (bool) – Only return submeshes which are watertight
append (bool) – Return a single mesh which has the faces appended, if this flag is set, only_watertight is ignored
- Returns:
if append (Trimesh object)
else list of Trimesh objects
- trimesh.util.to_ascii(text)¶
Force a string or other to ASCII text ignoring errors.
- Parameters:
text (any) – Input to be converted to ASCII string
- Returns:
ascii – Input as an ASCII string
- Return type:
str
- trimesh.util.tolist(data)¶
Ensure that any arrays or dicts passed containing numpy arrays are properly converted to lists
- Parameters:
data (any) – Usually a dict with some numpy arrays as values
- Returns:
result – JSON-serializable version of data
- Return type:
any
- trimesh.util.triangle_fans_to_faces(fans)¶
Convert fans of m + 2 vertex indices in fan format to m triangles
- Parameters:
fans ((n,) list of (m + 2,) int) – Vertex indices
- Returns:
faces – Vertex indices representing triangles
- Return type:
(m, 3) int
- trimesh.util.triangle_strips_to_faces(strips)¶
Convert a sequence of triangle strips to (n, 3) faces.
Processes all strips at once using np.concatenate and is significantly faster than loop-based methods.
From the OpenGL programming guide describing a single triangle strip [v0, v1, v2, v3, v4]:
Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
- Parameters:
strips ((n,) list of (m,) int) – Vertex indices
- Returns:
faces – Vertex indices representing triangles
- Return type:
(m, 3) int
- trimesh.util.type_bases(obj, depth=4)¶
Return the bases of the object passed.
- trimesh.util.type_named(obj, name)¶
Similar to the type() builtin, but looks in class bases for named instance.
- Parameters:
obj (any) – Object to look for class of
name (str) – Nnme of class
- Returns:
class – Camed class, or None
- Return type:
Optional[Callable]
- trimesh.util.unique_id(length=12)¶
Generate a random alphaNumber unique identifier using UUID logic.
- Parameters:
length (int) – Length of desired identifier
- Returns:
unique – Unique alphaNumber identifier
- Return type:
str
- trimesh.util.unique_name(start, contains, counts=None)¶
Deterministically generate a unique name not contained in a dict, set or other grouping with __includes__ defined. Will create names of the form “start_10” and increment accordingly.
- Parameters:
start (str) – Initial guess for name.
contains (dict, set, or list) – Bundle of existing names we can not use.
counts (None or dict) – Maps name starts encountered before to increments in order to speed up finding a unique name as otherwise it potentially has to iterate through all of contains. Should map to “how many times has this start been attempted, i.e. counts[start]: int. Note that this will be mutated in-place by this function!
- Returns:
unique – A name that is not contained in contains
- Return type:
str
- trimesh.util.unitize(vectors, check_valid=False, threshold=None)¶
Unitize a vector or an array or row-vectors.
- Parameters:
vectors ((n,m) or (j) float) – Vector or vectors to be unitized
check_valid (bool) – If set, will return mask of nonzero vectors
threshold (float) – Cutoff for a value to be considered zero.
- Returns:
unit ((n,m) or (j) float) – Input vectors but unitized
valid ((n,) bool or bool) – Mask of nonzero vectors returned if check_valid
- trimesh.util.vector_hemisphere(vectors, return_sign=False)¶
For a set of 3D vectors alter the sign so they are all in the upper hemisphere.
If the vector lies on the plane all vectors with negative Y will be reversed.
If the vector has a zero Z and Y value vectors with a negative X value will be reversed.
- Parameters:
vectors ((n, 3) float) – Input vectors
return_sign (bool) – Return the sign mask or not
- Returns:
oriented ((n, 3) float) – Vectors with same magnitude as source but possibly reversed to ensure all vectors are in the same hemisphere.
sign ((n,) float) – [OPTIONAL] sign of original vectors
- trimesh.util.vector_to_spherical(cartesian)¶
Convert a set of cartesian points to (n, 2) spherical unit vectors.
- Parameters:
cartesian ((n, 3) float) – Points in space
- Returns:
spherical – Angles, in radians
- Return type:
(n, 2) float
- trimesh.util.vstack_empty(tup)¶
A thin wrapper for numpy.vstack that ignores empty lists.
- Parameters:
tup (tuple or list of arrays) – With the same number of columns
- Returns:
stacked – With same number of columns as constituent arrays.
- Return type:
(n, d) array
- trimesh.util.wrap_as_stream(item)¶
Wrap a string or bytes object as a file object.
- Parameters:
item (str or bytes) – Item to be wrapped
- Returns:
wrapped – Contains data from item
- Return type:
file-like object
- trimesh.util.write_encoded(file_obj, stuff, encoding='utf-8')¶
If a file is open in binary mode and a string is passed, encode and write.
If a file is open in text mode and bytes are passed decode bytes to str and write.
Assumes binary mode if file_obj does not have a ‘mode’ attribute (e.g. io.BufferedRandom).
- Parameters:
file_obj (file object) – With ‘write’ and ‘mode’
stuff (str or bytes) – Stuff to be written
encoding (str) – Encoding of text
- trimesh.util.zero_pad(data, count, right=True)¶
- Parameters:
data ((n,)) – 1D array
count (int) – Minimum length of result array
- Returns:
padded – 1D array where m >= count
- Return type:
(m,)