Functions and classes that help with tracking changes in numpy.ndarray and clearing cached values based on those changes.

You should really pip install xxhash:

``` In [23]: %timeit int(blake2b(d).hexdigest(), 16) 102 us +/- 684 ns per loop

In [24]: %timeit int(sha256(d).hexdigest(), 16) 142 us +/- 3.73 us

In [25]: %timeit xxh3_64_intdigest(d) 3.37 us +/- 116 ns per loop ```

class trimesh.caching.Cache(id_function, force_immutable=False)

Bases: object

Class to cache values which will be stored until the result of an ID function changes.

__init__(id_function, force_immutable=False)

Create a cache object.

  • id_function (function) – Returns hashable value

  • force_immutable (bool) – If set will make all numpy arrays read-only


Remove elements in the cache.


exclude (list) – List of keys in cache to not clear.


Remove a key from the cache.


Set the current ID to the value of the ID function.


Update the cache with a set of key, value pairs without checking id_function.


Verify that the cached values are still for the same value of id_function and delete all stored items if the value of id_function has changed.

class trimesh.caching.DataStore

Bases: Mapping

A class to store multiple numpy arrays and track them all for changes.

Operates like a dict that only stores numpy.ndarray


Remove all data from the DataStore.


Is the current DataStore empty or not.


empty – False if there are items in the DataStore

Return type:


property mutable

Is data allowed to be altered or not.


is_mutable – Can data be altered in the DataStore

Return type:


class trimesh.caching.DiskCache(path, expire_days=30)

Bases: object

Store results of expensive operations on disk with an option to expire the results. This is used to cache the multi-gigabyte test corpuses in tests/

__init__(path, expire_days=30)

Create a cache on disk for storing expensive results.

  • path (str) – A writeable location on the current file path.

  • expire_days (int or float) – How old should results be considered expired.

get(key, fetch)

Get a key from the cache or run a calculation.

  • key (str) – Key to reference item with

  • fetch (function) – If key isn’t stored and recent run this function and store its result on disk.

class trimesh.caching.TrackedArray

Bases: ndarray

Subclass of numpy.ndarray that provides hash methods to track changes.

General method is to aggressively set ‘modified’ flags on operations which might (but don’t necessarily) alter the array, ideally we sometimes compute hashes when we don’t need to, but we don’t return wrong hashes ever.

We store boolean modified flag for each hash type to make checks fast even for queries of different hashes.

__hash__ : int
Runs the fastest available hash in this order:

xxh3_64, xxh_64, blake2b, sha256


Swap the bytes of the array elements

Toggle between low-endian and big-endian data representation by returning a byteswapped array, optionally swapped in-place. Arrays of byte-strings are not swapped. The real and imaginary parts of a complex number are swapped individually.


inplace (bool, optional) – If True, swap bytes in-place, default is False.


out – The byteswapped array. If inplace is True, this is a view to self.

Return type:



>>> A = np.array([1, 256, 8755], dtype=np.int16)
>>> list(map(hex, A))
['0x1', '0x100', '0x2233']
>>> A.byteswap(inplace=True)
array([  256,     1, 13090], dtype=int16)
>>> list(map(hex, A))
['0x100', '0x1', '0x3322']

Arrays of byte-strings are not swapped

>>> A = np.array([b'ceg', b'fac'])
>>> A.byteswap()
array([b'ceg', b'fac'], dtype='|S3')
A.newbyteorder().byteswap() produces an array with the same values

but different representation in memory

>>> A = np.array([1, 2, 3])
>>> A.view(np.uint8)
array([1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
       0, 0], dtype=uint8)
>>> A.newbyteorder().byteswap(inplace=True)
array([1, 2, 3])
>>> A.view(np.uint8)
array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
       0, 3], dtype=uint8)

Fill the array with a scalar value.


value (scalar) – All elements of a will be assigned this value.


>>> a = np.array([1, 2])
>>> a.fill(0)
>>> a
array([0, 0])
>>> a = np.empty(2)
>>> a.fill(1)
>>> a
array([1.,  1.])

Fill expects a scalar value and always behaves the same as assigning to a single array element. The following is a rare example where this distinction is important:

>>> a = np.array([None, None], dtype=object)
>>> a[0] = np.array(3)
>>> a
array([array(3), None], dtype=object)
>>> a.fill(np.array(3))
>>> a
array([array(3), array(3)], dtype=object)

Where other forms of assignments will unpack the array being assigned:

>>> a[...] = np.array(3)
>>> a
array([3, 3], dtype=object)

Insert scalar into an array (scalar is cast to array’s dtype, if possible)

There must be at least 1 argument, and define the last argument as item. Then, a.itemset(*args) is equivalent to but faster than a[args] = item. The item should be a scalar value and args must select a single item in the array a.


*args (Arguments) – If one argument: a scalar, only used in case a is of size 1. If two arguments: the last argument is the value to be set and must be a scalar, the first argument specifies a single array element location. It is either an int or a tuple.


Compared to indexing syntax, itemset provides some speed increase for placing a scalar into a particular location in an ndarray, if you must do this. However, generally this is discouraged: among other problems, it complicates the appearance of the code. Also, when using itemset (and item) inside a loop, be sure to assign the methods to a local variable to avoid the attribute look-up at each loop iteration.


>>> np.random.seed(123)
>>> x = np.random.randint(9, size=(3, 3))
>>> x
array([[2, 2, 6],
       [1, 3, 6],
       [1, 0, 1]])
>>> x.itemset(4, 0)
>>> x.itemset((2, 2), 9)
>>> x
array([[2, 2, 6],
       [1, 0, 6],
       [1, 0, 9]])
property mutable
partition(kth, axis=-1, kind='introselect', order=None)

Rearranges the elements in the array in such a way that the value of the element in kth position is in the position it would be in a sorted array. All elements smaller than the kth element are moved before this element and all equal or greater are moved behind it. The ordering of the elements in the two partitions is undefined.

Added in version 1.8.0.

  • kth (int or sequence of ints) –

    Element index to partition by. The kth element value will be in its final sorted position and all smaller elements will be moved before it and all equal or greater elements behind it. The order of all elements in the partitions is undefined. If provided with a sequence of kth it will partition all elements indexed by kth of them into their sorted position at once.

    Deprecated since version 1.22.0: Passing booleans as index is deprecated.

  • axis (int, optional) – Axis along which to sort. Default is -1, which means sort along the last axis.

  • kind ({'introselect'}, optional) – Selection algorithm. Default is ‘introselect’.

  • order (str or list of str, optional) – When a is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can be specified as a string, and not all fields need to be specified, but unspecified fields will still be used, in the order in which they come up in the dtype, to break ties.

See also


Return a partitioned copy of an array.


Indirect partition.


Full sort.


See np.partition for notes on the different algorithms.


>>> a = np.array([3, 4, 2, 1])
>>> a.partition(3)
>>> a
array([2, 1, 3, 4])
>>> a.partition((1, 3))
>>> a
array([1, 2, 3, 4])
put(indices, values, mode='raise')

Set a.flat[n] = values[n] for all n in indices.

Refer to numpy.put for full documentation.

See also


equivalent function

setflags(write=None, align=None, uic=None)

Set array flags WRITEABLE, ALIGNED, WRITEBACKIFCOPY, respectively.

These Boolean-valued flags affect how numpy interprets the memory area used by a (see Notes below). The ALIGNED flag can only be set to True if the data is actually aligned according to the type. The WRITEBACKIFCOPY and flag can never be set to True. The flag WRITEABLE can only be set to True if the array owns its own memory, or the ultimate owner of the memory exposes a writeable buffer interface, or is a string. (The exception for string is made so that unpickling can be done without copying memory.)

  • write (bool, optional) – Describes whether or not a can be written to.

  • align (bool, optional) – Describes whether or not a is aligned properly for its type.

  • uic (bool, optional) – Describes whether or not a is a copy of another “base” array.


Array flags provide information about how the memory area used for the array is to be interpreted. There are 7 Boolean flags in use, only four of which can be changed by the user: WRITEBACKIFCOPY, WRITEABLE, and ALIGNED.

WRITEABLE (W) the data area can be written to;

ALIGNED (A) the data and strides are aligned appropriately for the hardware (as determined by the compiler);

WRITEBACKIFCOPY (X) this array is a copy of some other array (referenced by .base). When the C-API function PyArray_ResolveWritebackIfCopy is called, the base array will be updated with the contents of this array.

All flags can be accessed using the single (upper case) letter as well as the full name.


>>> y = np.array([[3, 1, 7],
...               [2, 0, 0],
...               [8, 5, 9]])
>>> y
array([[3, 1, 7],
       [2, 0, 0],
       [8, 5, 9]])
>>> y.flags
  OWNDATA : True
  ALIGNED : True
>>> y.setflags(write=0, align=0)
>>> y.flags
  OWNDATA : True
  ALIGNED : False
>>> y.setflags(uic=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot set WRITEBACKIFCOPY flag to True
sort(axis=-1, kind=None, order=None)

Sort an array in-place. Refer to numpy.sort for full documentation.

  • axis (int, optional) – Axis along which to sort. Default is -1, which means sort along the last axis.

  • kind ({'quicksort', 'mergesort', 'heapsort', 'stable'}, optional) –

    Sorting algorithm. The default is ‘quicksort’. Note that both ‘stable’ and ‘mergesort’ use timsort under the covers and, in general, the actual implementation will vary with datatype. The ‘mergesort’ option is retained for backwards compatibility.

    Changed in version 1.15.0: The ‘stable’ option was added.

  • order (str or list of str, optional) – When a is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can be specified as a string, and not all fields need be specified, but unspecified fields will still be used, in the order in which they come up in the dtype, to break ties.

See also


Return a sorted copy of an array.


Indirect sort.


Indirect stable sort on multiple keys.


Find elements in sorted array.


Partial sort.


See numpy.sort for notes on the different sorting algorithms.


>>> a = np.array([[1,4], [3,1]])
>>> a.sort(axis=1)
>>> a
array([[1, 4],
       [1, 3]])
>>> a.sort(axis=0)
>>> a
array([[1, 3],
       [1, 4]])

Use the order keyword to specify a field to use when sorting a structured array:

>>> a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)])
>>> a.sort(order='y')
>>> a
array([(b'c', 1), (b'a', 2)],
      dtype=[('x', 'S1'), ('y', '<i8')])

A decorator for class methods, replaces @property but will store and retrieve function return values in object cache.


function (method) –

This is used as a decorator: ``` @cache_decorator def foo(self, things):

return ‘happy days’


trimesh.caching.sha256(item) int
trimesh.caching.tracked_array(array, dtype=None)

Properly subclass a numpy ndarray to track changes.

Avoids some pitfalls of subclassing by forcing contiguous arrays and does a view into a TrackedArray.

  • array (array- like object) – To be turned into a TrackedArray

  • dtype (np.dtype) – Which dtype to use for the array


tracked – Contains input array data.

Return type: