Introduction
Aspose.3D FOSS for Python is a zero-dependency, MIT-licensed library, published on PyPI as aspose-3d-foss, for reading, writing, and converting 3D file formats. Beyond scene loading and saving, it includes a set of smaller utility classes for working with geometry and formats directly: vector types for positions and colors, a per-node transform object for placing geometry in a scene, and format classes that resolve the correct save options without hardcoding a file extension string.
This post covers those utility classes: Vector3 and Vector4 for numeric data, Transform for positioning scene nodes, and FileFormat together with the format-specific load/save option classes. These are the building blocks used across loading, saving, and geometry-construction code, independent of any single file format.
The library has no C extensions and no third-party runtime dependencies, so every example below runs with nothing installed beyond the package itself.
What’s Included
Vector3 for Color and Position Data
Vector3 is a lightweight x/y/z value type used throughout the API wherever a direction, position, or color needs three components — for example, a material’s diffuse color:
from aspose.threed import Scene
from aspose.threed.entities import Box
from aspose.threed.shading import LambertMaterial
from aspose.threed.utilities import Vector3
scene = Scene()
box = Box(length=2.0, width=1.0, height=1.0)
material = LambertMaterial()
material.diffuse_color = Vector3(0.2, 0.6, 0.9)
scene.root_node.create_child_node("Crate", entity=box.to_mesh(), material=material)
scene.save("crate.gltf")
Node.transform for Placing Geometry
Every Node carries a Transform object with translation and scaling properties (both Vector3), used to position and size an entity without altering its underlying mesh data:
from aspose.threed import Scene
from aspose.threed.entities import Cylinder
from aspose.threed.utilities import Vector3
scene = Scene()
cylinder = Cylinder()
node = scene.root_node.create_child_node("Post", entity=cylinder.to_mesh())
node.transform.translation = Vector3(0.0, 1.0, 0.0)
node.transform.scaling = Vector3(0.5, 2.0, 0.5)
scene.save("post.obj")
FileFormat for Resolving Save Options
FileFormat.get_format_by_extension() looks up a format by its file extension and returns a FileFormat instance. Pass it into a format-specific save-options constructor, such as GltfSaveOptions, to get a correctly-configured options object without hardcoding a filename. This is the pattern to use whenever you are saving to a stream rather than a named file, since scene.save() can only infer the format from a filename’s extension — a bare stream gives it nothing to detect from:
import io
import json
from aspose.threed import Scene, FileFormat
from aspose.threed.entities import Mesh
from aspose.threed.formats.gltf import GltfSaveOptions
from aspose.threed.utilities import Vector4
scene = Scene()
mesh = Mesh("TestMesh")
mesh.control_points.add(Vector4(0.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(1.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(0.0, 1.0, 0.0, 1.0))
mesh.create_polygon(0, 1, 2)
node = scene.root_node.create_child_node("TestNode")
node.entity = mesh
stream = io.BytesIO()
options = GltfSaveOptions(FileFormat.get_format_by_extension(".gltf"))
options.binary_mode = False
scene.save(stream, options)
stream.seek(0)
gltf_data = json.loads(stream.read().decode("utf-8"))
print(len(gltf_data["meshes"]))
Load Options for Format-Specific Parsing
Import formats that carry extra, format-specific settings expose a dedicated load-options class. ObjLoadOptions, for example, controls whether companion .mtl material files are parsed during import:
from aspose.threed import Scene
from aspose.threed.formats.obj import ObjLoadOptions
scene = Scene()
options = ObjLoadOptions()
options.enable_materials = True
scene.open("model.obj", options)
for node in scene.root_node.child_nodes:
if node.entity is not None:
mesh = node.entity
print(f"{node.name}: {len(mesh.control_points)} vertices, {mesh.polygon_count} polygons")
Quick Start
pip install aspose-3d-fossBuild a triangle from Vector4 control points, move and scale it with node.transform, then resolve glTF save options from the target extension via FileFormat instead of a filename:
import io
from aspose.threed import Scene, FileFormat
from aspose.threed.entities import Mesh
from aspose.threed.formats.gltf import GltfSaveOptions
from aspose.threed.utilities import Vector3, Vector4
scene = Scene()
mesh = Mesh("Triangle")
mesh.control_points.add(Vector4(0.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(1.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(0.0, 1.0, 0.0, 1.0))
mesh.create_polygon(0, 1, 2)
node = scene.root_node.create_child_node("Triangle", entity=mesh)
node.transform.translation = Vector3(0.0, 0.0, 2.0)
node.transform.scaling = Vector3(2.0, 2.0, 2.0)
stream = io.BytesIO()
options = GltfSaveOptions(FileFormat.get_format_by_extension(".gltf"))
options.binary_mode = False
scene.save(stream, options)
Supported Formats
| Format | Extension | Read | Write |
|---|---|---|---|
| OBJ | .obj | ✓ | ✓ |
| STL | .stl | ✓ | ✓ |
| glTF / GLB | .gltf / .glb | ✓ | ✓ |
| COLLADA | .dae | ✓ | ✓ |
| 3MF | .3mf | ✓ | ✓ |
| FBX | .fbx | ✓ | — |
FBX import uses a dedicated tokenizer and parser; FBX export (FbxExporter) is not implemented in this FOSS edition. Use FileFormat.get_format_by_extension() to resolve the matching load or save options class for any of the formats above instead of hardcoding option-class names.
Open Source & Licensing
Aspose.3D FOSS for Python is released under the MIT license. You can use, modify, and redistribute it in both open-source and commercial projects without restriction. The source is available on GitHub under the Aspose organization, alongside the published package on PyPI.