How to Save 3D Scenes in Python
Aspose.3D FOSS for Python lets you save a Scene to any supported output format using a single Scene.save() call. Format detection is automatic when you pass a file path; for advanced options such as binary output or texture embedding, you supply a format-specific save-options object.
Step-by-Step Guide
Step 1: Install the Package
Install Aspose.3D FOSS from PyPI. No native libraries are required.
pip install aspose-3d-fossSupported Python versions: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Step 2: Import Required Classes
At minimum you need Scene. Import the format-specific exporter or save-options class only when you need non-default behaviour.
from aspose.threed import SceneFor format-specific options:
from aspose.threed.formats.gltf import GltfSaveOptions, GltfExporter
from aspose.threed.formats.stl import StlFormat, StlSaveOptions
from aspose.threed.formats.fbx import FbxExporter, FbxSaveOptions
from aspose.threed.formats.collada import ColladaExporter, ColladaSaveOptionsStep 3: Load a Scene
Load an existing scene from disk using Scene.from_file(). The library detects the source format automatically from the file extension. To build a scene from scratch instead, see How to Build a Mesh in Python.
# Load from an existing file — format auto-detected from extension
scene = Scene.from_file("input.obj")Alternatively, open a scene with explicit options via Scene.open():
from aspose.threed import Scene
scene = Scene()
scene.open("input.fbx")Step 4: Save to STL
Call Scene.save() with a .stl path. By default the output is ASCII STL. To write a binary STL (smaller file, no human-readable header) use StlSaveOptions.
# ASCII STL — format detected from the .stl extension
scene.save("output.stl")
# Binary STL — smaller file size
from aspose.threed.formats.stl import StlFormat, StlSaveOptions
stl_format = StlFormat()
options = stl_format.create_save_options()
options.binary_mode = True
scene.save("output_binary.stl", options)Step 5: Save to glTF or GLB
GLTF 2.0 files can be exported using GltfExporter and GltfSaveOptions. Set binary_mode = True to produce a self-contained .glb binary bundle; set binary_mode = False for the JSON-based .gltf format.
import io
from aspose.threed.formats.gltf import GltfExporter, GltfSaveOptions
# Text glTF
options = GltfSaveOptions()
options.binary_mode = False
options.file_name = "output.gltf"
exporter = GltfExporter()
with open("output.gltf", "wb") as f:
stream = io.BytesIO()
exporter.export(scene, stream, options)
f.write(stream.getvalue())
# Binary GLB
options_glb = GltfSaveOptions()
options_glb.binary_mode = True
options_glb.file_name = "output.glb"
stream_glb = io.BytesIO()
exporter.export(scene, stream_glb, options_glb)
with open("output.glb", "wb") as f:
f.write(stream_glb.getvalue())Step 6: Save to FBX
Not implemented:
FbxExporter.save()andFbxExporter.save_to_stream()raiseNotImplementedErrorin the current release. FBX export is not available in Aspose.3D FOSS for Python at this time.Use GLB, OBJ, STL, or Collada (DAE) formats instead. See Steps 4, 5, and 7 for working export options.
# The following code raises NotImplementedError in the current release:
# from aspose.threed.formats.fbx import FbxExporter, FbxSaveOptions
# exporter = FbxExporter()
# exporter.save(scene, "output.fbx", options) # raises NotImplementedError
# Use a supported format instead:
scene.save("output.glb") # binary GLB — recommended
scene.save("output.obj") # Wavefront OBJ
scene.save("output.stl") # STLStep 7: Save to OBJ or Collada (DAE)
For OBJ and Collada, pass the file path directly to Scene.save(). The library detects the format from the extension.
# OBJ — format auto-detected from .obj extension
scene.save("output.obj")
# Collada DAE — with material and coordinate-system options
from aspose.threed.formats.collada import ColladaExporter, ColladaSaveOptions
options = ColladaSaveOptions()
options.enable_materials = True
options.flip_coordinate_system = False
options.indented = True
exporter = ColladaExporter()
exporter.export(scene, open("output.dae", "wb"), options)Common Issues and Fixes
Empty output file after scene.save()
This usually means the scene’s root node has no child nodes with geometry. Verify that each mesh node was attached to scene.root_node before calling save. Check len(scene.root_node.child_nodes) after building the scene.
AttributeError when building mesh geometry
The Mesh class stores vertices as an internal control-points list. For detailed mesh construction patterns, refer to the How to Build a Mesh in Python article which covers polygon creation, vertex elements, and UV data.
GLB output is larger than expected
Binary GLB inlines all geometry and texture data. If GltfSaveOptions.flip_tex_coord_v is set to True, an extra coordinate-flip pass is included. Set it to False if you do not need V-axis texture flipping.
FBX export is not available in the current release
FbxExporter.save() raises NotImplementedError. FBX import (loading .fbx files) works normally, but export to FBX is not implemented. Convert to GLB, OBJ, STL, or Collada instead.
Collada DAE does not include materials
Set ColladaSaveOptions.enable_materials = True (it is False by default) before exporting.
Frequently Asked Questions
Which formats can Aspose.3D FOSS for Python export?
The library supports exporting to: STL, glTF 2.0 (text and binary GLB), OBJ, and Collada (DAE). Format detection is automatic when you pass a file-path string to Scene.save(); the library reads the extension to select the correct exporter.
Note: FBX export is not implemented in the current release —
FbxExporter.save()raisesNotImplementedError. Use GLB, OBJ, STL, or Collada instead.
Is there a streaming export API that avoids writing to disk?
Yes. GltfExporter.export(scene, stream, options) writes to any io.BytesIO or file-like object. You can pass the in-memory buffer directly to a web response or further processing without touching the filesystem.
How do I convert a scene from one format to another?
Load the scene with Scene.from_file("input.fbx") and save with scene.save("output.gltf"). The library handles the in-memory conversion; no intermediate files are needed.
Can I save multiple sub-scenes to separate files?
Access scene.sub_scenes to iterate over each sub-scene, create a new Scene object, attach the relevant nodes, and call save() on each.
Does Scene.save() overwrite existing files silently?
Yes. The library does not raise an error if the target file already exists; it overwrites it. Add a file-existence check in your code if you need to guard against accidental overwrites.