trimesh.exchange.gltf.extensions

gltf_extensions.py

Extension registry for glTF import/export with scope-based handlers. Each scope has a TypedDict defining the context passed to handlers.

class trimesh.exchange.gltf.extensions.MaterialContext

Bases: TypedDict

Context for material scope handlers.

data: dict[str, Any]
images: list
parse_textures: Callable[[...], dict[str, Any]]
class trimesh.exchange.gltf.extensions.PrimitiveContext

Bases: TypedDict

Context for primitive scope handlers (post-load).

accessors: list
data: dict[str, Any]
mesh_kwargs: dict
primitive: dict
class trimesh.exchange.gltf.extensions.PrimitiveExportContext

Bases: TypedDict

Context for primitive_export scope handlers (during export).

arrays: dict[int, NDArray]
buffer_items: IndexedDict
mesh: Any
name: str
primitive: dict
tree: dict
class trimesh.exchange.gltf.extensions.PrimitivePreprocessContext

Bases: TypedDict

Context for primitive_preprocess scope handlers (pre-load).

accessors: list
data: dict[str, Any]
primitive: dict
views: list
class trimesh.exchange.gltf.extensions.TextureSourceContext

Bases: TypedDict

Context for texture_source scope handlers.

data: dict[str, Any]
trimesh.exchange.gltf.extensions.draco_decode(context: PrimitivePreprocessContext) None

Replace a primitive’s placeholder accessors with decompressed draco data.

The accessors of a draco-compressed primitive have no bufferView, so the loader filled them with zeros before calling us. All of the geometry is in a single opaque blob, and the extension carries the indirection we need to unpack it: a mapping of glTF attribute name to draco attribute id.

Parameters:

context – PrimitivePreprocessContext, whose accessors we mutate in-place.

trimesh.exchange.gltf.extensions.draco_encode(context: PrimitiveExportContext) bool | None

Compress a primitive’s geometry into a single draco buffer.

Every array in arrays is absorbed, so the exporter left their accessors with no bufferView rather than storing the same data twice. Returning None makes it store them after all, so a failure here exports the primitive uncompressed rather than pointing at accessors full of zeros.

Parameters:

context – PrimitiveExportContext, whose primitive and buffer_items we mutate.

Returns:

True if the geometry is now inside a draco buffer, None if not.

Return type:

compressed

trimesh.exchange.gltf.extensions.handle_extensions(*, extensions: dict[str, Any] | None, scope: Literal['material', 'texture_source', 'primitive', 'primitive_preprocess', 'primitive_export'], failed: set | None = None, **kwargs) Any

Process extensions dict for a given scope, calling registered handlers.

Parameters:
  • extensions – The “extensions” dict from a glTF element, or None.

  • scope – Handler scope to invoke.

  • failed – If passed the name of any extension whose handler raised is added here.

  • **kwargs

    Scope-specific arguments that will be combined with extension data into a typed context dict. Required kwargs by scope:

    • material: parse_textures, images

    • texture_source: (none)

    • primitive: primitive, mesh_kwargs, accessors

    • primitive_preprocess: primitive, accessors, views

    • primitive_export: mesh, name, tree, buffer_items, primitive, arrays

Returns:

Dict of {extension_name: result} for most scopes. For scopes ending in “_source”, returns first non-None result. For “primitive” scope, automatically merges results into mesh_kwargs.

Return type:

results

trimesh.exchange.gltf.extensions.register_handler(name: str, scope: Literal['material', 'texture_source', 'primitive', 'primitive_preprocess', 'primitive_export']) Callable[[Callable[[Any], Any]], Callable[[Any], Any]]

Decorator to register a handler for a glTF extension.

Parameters:
  • name – Extension name, e.g. “KHR_materials_pbrSpecularGlossiness”.

  • scope – Handler scope, e.g. “material”, “texture_source”, “primitive”.

Returns:

Function that registers the handler and returns it unchanged.

Return type:

decorator

Example

>>> @register_handler("MY_extension", scope="material")
... def my_handler(context: MaterialContext) -> dict | None:
...     data = context["data"]
...     images = context["images"]
...     return {"baseColorFactor": [1, 0, 0, 1]}
trimesh.exchange.gltf.extensions.unregistered(extensions: Iterable[str], scope: Literal['material', 'texture_source', 'primitive', 'primitive_preprocess', 'primitive_export']) set

Find extension names with no registered handler for a scope.

Parameters:
  • extensions – Extension names, i.e. the keys of a glTF “extensions” dict.

  • scope – Handler scope to check against.

Returns:

Extension names with no handler registered for the scope.

Return type:

missing