How to Save 3D Scenes in Python

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-foss

Supported 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 Scene

For 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, ColladaSaveOptions

Step 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() and FbxExporter.save_to_stream() raise NotImplementedError in 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")   # STL

Step 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() raises NotImplementedError. 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.

See Also

 English