Skip to main content

GTLF Builder

This library wraps the pygltflib library to handle the low-level details of managing buffers, buffer views, and accessors.

In this document, we will generalliy refer to the pygltflib library with the gltf orefix.

You start by creating a Builder instance. There are abstract types corresponding to the major classes from the pygltflib library, with names prepended with 'B'. For example, this library supplies a BNode class that plays the same role as gltf.Node. These classe are compiled to the corresponding gltf clases with the compile(Builder) method.

The BXxxxx names are abstract; the implementation classes bear names like _Xxxxx.

Compilation and collection of the pieces is performed by the Builder.build() method.

Quaternions

Because pygltflib uses quaternions of the form (X, Y, Z, W) instead of the form (W, X, Y, Z) used by scipy, and to avoid introducing heavyweight and potentially incompatible libraries, we provided (courtesy of ChatGPT to my specifications) an implementation of various quaternion routines relating to rotations.

Basic usage

import gltf_builder.quaternion as quat

# Rotate around Z axis by pi/2 
rotation = quat.from_axis_angle((0, 0, 1), math.py / 4)
# Instantiate a geometry, rotated.
root_node.instantiate(cube, rotation=rotation)

See quaternion.md or quaternion.py for more information.

Usage

Install via your usual tool (I recommend uv as the modern upgrade from pip and others).

from gltf_builder import Builder, PrimitiveMode

CUBE = (
    (0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0),
    (1, 0, 0), (1, 0, 1), (1, 1, 1), (1, 1, 0),
)
CUBE_FACE1 = (0, 1, 2, 3)
CUBE_FACE2 = (4, 5, 6, 7)
CUBE_FACE3 = (0, 4, 5, 1)
CUBE_FACE4 = (0, 4, 7, 3)
CUBE_FACE5 = (1, 2, 6, 5)
CUBE_FACE6 = (1, 5, 6, 2)

builder = Builder()

mesh = builder.add_mesh('CUBE')
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE1])
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE2])
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE3])
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE4])
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE5])
mesh.add_primitive(PrimitiveMode.LINE_LOOP, *[CUBE[i] for i in CUBE_FACE6])
top = builder.add_node(name='TOP')
cube = builder.add_node(name='CUBE',
                        mesh=mesh,
                        translation=(-0.5, -0.5, -0.5),
                        detached=True, # Don't make it part of the scene
)
# Instantiate it at the origin
top.instantiate(cube)
# Instantiate it translated, scaled, and rotated.
top.instantiate(cube,
                translation=(2, 0, 0),
                scale=(1, 2, 2),
                rotation=(0.47415988, -0.40342268,  0.73846026,  0.25903472)
            )
gltf = builder.build()
gltf.save_binary('cube.glb')

The builder.build() method produces a regular pygltflib.GLTF2 instance.

To create hierarchy, use the add_node() method on a parent node.

Note that referencing the same tuple for a point treats it as the same vertex, while a copy will create a separate vertex.

Instancing

Simple instancing can be done by simply using the same mesh for multiple nodes.

You can also instance a node hierarchy with the instantiate method. This takes a node and copies it, optionally supplying a transformation.

The node can be an existing node in the scene, or it cn be created with the detached=True option to add_node(), which creates the a node that is not added to the scene. You can then use this as the root of an instancable tree, and add child nodes and meshes.

You can access existing nodes by name by the builder[name] syntax. If nodes with the same name appear in different places, you may need to first access a parent that holds only one of the duplicates. Alternatively, you can loop over all nodes like this:

builder = Builder()
# Add a bunch of nodes
...
# Print the names of every node in the tree
for node in builder:
    print(f'node={node.name}')

# Get a list of all nodes named 'Fred'
fred = [n for n in builder if n.name == 'Fred']

Still Needed

  • Tangents and other attributes (implemented but no tested)
  • Materials
  • Skins
  • Textures
  • …

Metadata

Release files for gltf-builder 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gltf-builder 0.1.8
File Size Uploaded
gltf_builder-0.1.8.tar.gz 41.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gltf-builder 0.1.8
File Interpreter ABI Platform
gltf_builder-0.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 67.7 kB

Release files / gltf_builder-0.1.8.tar.gz

Download URL gltf_builder-0.1.8.tar.gz
Size 41.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0f10491f8c8cff167cf3d04db78d3b0af646a666e7b186c25501a3e0e5c19718
BLAKE2b-256 checksum
How to use checksums
2526c358dc0269475ea64fcf1d009a6ae51e010e8b3b21954e86e047e7586513
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.6.6

Release files / gltf_builder-0.1.8-py3-none-any.whl

Download URL gltf_builder-0.1.8-py3-none-any.whl
Size 26.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8f771b65a835d7a814c63a9e676f618113bc96bc6002d14072dffe4bb8bb5fc
BLAKE2b-256 checksum
How to use checksums
4dfc1b14e1530358b2d85c516825feeed63955706efad9ab6db1869f0fccb6b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.6.6

Release history Release notifications | RSS feed

This release

0.1.8 This release

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page