or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bvh-loading.mdgltf-loading.mdindex.mdobj-loading.mdsplat-loading.mdstl-loading.md
tile.json

stl-loading.mddocs/

STL Loading

The STL loader provides support for STL (stereolithography) files commonly used in 3D printing and CAD applications. It supports both ASCII and binary STL formats with automatic format detection.

Capabilities

STLFileLoader Class

Main loader class for STL files with coordinate system options.

/**
 * STL file loader supporting both ASCII and binary STL formats
 */
class STLFileLoader implements ISceneLoaderPlugin {
  /** Don't alter file coordinates during import (default: false) */
  static DO_NOT_ALTER_FILE_COORDINATES: boolean;
  
  // Core properties  
  readonly name: string; // "stl"
  readonly extensions: { [key: string]: { isBinary: boolean } }; // { ".stl": { isBinary: true } }
  
  // Parsing regex patterns
  readonly solidPattern: RegExp;
  readonly facetsPattern: RegExp; 
  readonly normalPattern: RegExp;
  readonly vertexPattern: RegExp;
  
  /**
   * Import mesh from STL file data
   * @param meshesNames - Names of meshes to import (ignored for STL)
   * @param scene - Target scene for the mesh
   * @param data - STL file data as string or ArrayBuffer
   * @param rootUrl - Root URL for the file (used for naming)
   * @param meshes - Array to receive the imported meshes
   * @param onProgress - Progress callback
   * @param fileName - Name of the STL file
   * @returns True if import succeeded
   */
  importMesh(
    meshesNames: any,
    scene: Scene,
    data: string | ArrayBuffer,
    rootUrl: string,
    meshes: AbstractMesh[],
    onProgress?: (event: ISceneLoaderProgressEvent) => void,
    fileName?: string
  ): boolean;
  
  /**
   * Load STL file into an asset container
   * @param scene - Target scene
   * @param data - STL file data
   * @param rootUrl - Root URL for the file
   * @param onProgress - Progress callback  
   * @param fileName - Name of the STL file
   * @returns Asset container with the loaded mesh
   */
  loadAssetContainer(
    scene: Scene,
    data: string | ArrayBuffer,
    rootUrl: string,
    onProgress?: (event: ISceneLoaderProgressEvent) => void,
    fileName?: string
  ): AssetContainer;
}

Usage Examples:

import { STLFileLoader } from "@babylonjs/loaders";
import { SceneLoader } from "@babylonjs/core";

// Basic usage with automatic loader selection
const result = await SceneLoader.ImportMeshAsync("", "/models/", "part.stl", scene);
const mesh = result.meshes[0];

console.log(`Loaded STL mesh: ${mesh.name}`);
console.log(`Vertices: ${mesh.getTotalVertices()}`);

// Configure coordinate system handling
STLFileLoader.DO_NOT_ALTER_FILE_COORDINATES = true;

// Load with coordinate preservation
const result2 = await SceneLoader.ImportMeshAsync("", "/cad/", "precise_part.stl", scene);

Asset Container Loading

Load STL files into isolated containers for advanced asset management:

import { STLFileLoader } from "@babylonjs/loaders";

const loader = new STLFileLoader();

// Load STL data (from file or fetch)
const stlData = await fetch("/models/gear.stl").then(r => r.arrayBuffer());

// Load into asset container
const assetContainer = loader.loadAssetContainer(scene, stlData, "/models/", undefined, "gear.stl");

console.log(`Loaded ${assetContainer.meshes.length} meshes`);

// The mesh is loaded but not added to scene automatically
// Add when ready
assetContainer.addAllToScene();

// Or access the mesh directly
const stlMesh = assetContainer.meshes[0];
stlMesh.position.x = 5;

STL Format Support

The STL loader automatically detects and supports both STL formats:

ASCII STL Format

Text-based format with human-readable vertex and normal data:

solid name
  facet normal nx ny nz
    outer loop
      vertex x1 y1 z1
      vertex x2 y2 z2
      vertex x3 y3 z3
    endloop
  endfacet
  ...
endsolid name

Binary STL Format

Compact binary format with 80-byte header followed by triangle data:

  • 80-byte header
  • 4-byte triangle count
  • For each triangle:
    • 12 bytes: normal vector (3 floats)
    • 36 bytes: three vertices (9 floats)
    • 2 bytes: attribute byte count (unused)

Advanced Configuration

Coordinate System Handling

import { STLFileLoader } from "@babylonjs/loaders";

// Preserve original coordinate system (useful for CAD precision)
STLFileLoader.DO_NOT_ALTER_FILE_COORDINATES = true;

// Default behavior applies Babylon.js coordinate system transformations
STLFileLoader.DO_NOT_ALTER_FILE_COORDINATES = false;

Material and Appearance

STL files contain only geometry data, so meshes are created with default materials:

import { STLFileLoader, StandardMaterial, Color3 } from "@babylonjs/loaders";

// Load STL mesh
const result = await SceneLoader.ImportMeshAsync("", "/models/", "part.stl", scene);
const mesh = result.meshes[0];

// STL meshes have no material by default - create one
const material = new StandardMaterial("stlMaterial", scene);
material.diffuseColor = new Color3(0.8, 0.8, 0.8);
material.specularColor = new Color3(0.2, 0.2, 0.2);

mesh.material = material;

// Enable wireframe view (common for STL inspection)
material.wireframe = true;

Performance Considerations

STL files can contain high vertex counts. Consider these optimizations:

import { STLFileLoader } from "@babylonjs/loaders";

// For large STL files, consider mesh optimization
const result = await SceneLoader.ImportMeshAsync("", "/models/", "large_part.stl", scene);
const mesh = result.meshes[0];

// Optimize mesh for rendering
mesh.simplify([
  { quality: 0.8, distance: 0.1 }
], false, () => {
  console.log("Mesh simplified");
});

// Or freeze mesh if it won't change
mesh.freezeWorldMatrix();
mesh.material?.freeze();

Common Use Cases

3D Printing Preview

import "@babylonjs/loaders/STL";
import { SceneLoader, StandardMaterial, Color3 } from "@babylonjs/core";

// Load STL for 3D printing preview
const result = await SceneLoader.ImportMeshAsync("", "/prints/", "model.stl", scene);
const printMesh = result.meshes[0];

// Apply print material appearance
const printMaterial = new StandardMaterial("printMaterial", scene);
printMaterial.diffuseColor = new Color3(0.9, 0.9, 0.9);
printMaterial.specularColor = new Color3(0.1, 0.1, 0.1);
printMaterial.roughness = 0.8;

printMesh.material = printMaterial;

// Center the model
const boundingInfo = printMesh.getBoundingInfo();
const center = boundingInfo.boundingBox.center;
printMesh.position.subtractInPlace(center);

CAD Part Inspection

import { STLFileLoader } from "@babylonjs/loaders";

// Preserve exact coordinates for CAD precision
STLFileLoader.DO_NOT_ALTER_FILE_COORDINATES = true;

const result = await SceneLoader.ImportMeshAsync("", "/cad/", "precision_part.stl", scene);
const cadMesh = result.meshes[0];

// Inspect mesh properties
console.log(`Bounding box: ${cadMesh.getBoundingInfo().boundingBox.extendSize}`);
console.log(`Vertex count: ${cadMesh.getTotalVertices()}`);
console.log(`Face count: ${cadMesh.getTotalIndices() / 3}`);

// Enable wireframe for detailed inspection
const wireframeMaterial = new StandardMaterial("wireframe", scene);
wireframeMaterial.wireframe = true;
wireframeMaterial.diffuseColor = new Color3(0, 1, 0);
cadMesh.material = wireframeMaterial;

File Format Limitations

STL format limitations to be aware of:

  • Geometry Only: No materials, textures, or colors
  • No Hierarchy: Single mesh per file, no object grouping
  • No Animation: Static geometry only
  • No Normals: Per-facet normals only, no smooth shading information
  • File Size: ASCII format can be very large for complex meshes
  • Precision: Binary format uses 32-bit floats, may have precision limits for CAD

For more complex 3D data requirements, consider using glTF or OBJ formats instead.