occt

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: MIT Imports: 5 Imported by: 0

README

occt-import-go

Convert STEP and IGES CAD files to GLB (binary glTF) in pure Go.

This package embeds Open CASCADE Technology (OCCT) — the same CAD kernel behind occt-import-js — compiled to WebAssembly, and runs it in-process under wazero, a zero-dependency pure-Go WebAssembly runtime.

  • No cgo, no system dependencies. go get and it works: Linux (glibc and musl/Alpine), macOS, amd64/arm64 — anywhere Go runs.
  • Names, colors, and assembly hierarchy from the STEP file are preserved in the GLB output (via OCCT's XCAF document + RWGltf_CafWriter pipeline).
  • Goroutine-safe. The wasm module is compiled once; each conversion runs in an isolated, short-lived instance whose memory is reclaimed immediately.

Usage

import occt "github.com/avgjerry/occt-import-go"

// One-shot:
glb, err := occt.StepToGLB(ctx, stepBytes)

// Server-style (compile the wasm once, convert many times, concurrently):
conv, err := occt.NewConverter(ctx)
defer conv.Close(ctx)

glb, err = conv.StepToGLB(ctx, stepBytes,
    occt.WithLinearDeflection(0.001),  // mesh quality: chordal deflection
    occt.WithAngularDeflection(0.5),   // mesh quality: radians
)

// IGES works the same way:
glb, err = conv.IgesToGLB(ctx, igesBytes)

Mesh quality defaults to a bounding-box-relative linear deflection of 0.001 and an angular deflection of 0.5 rad (the same defaults as occt-import-js), so results are scale-independent. Use WithRelativeDeflection(false) to switch the linear deflection to absolute model units (millimeters for most STEP files).

Errors are matchable with errors.Is: ErrInvalidInput, ErrParse, ErrEmptyModel, ErrConversion. Conversions honor context cancellation and deadlines.

How it works

STEP bytes ─▶ STEPCAFControl_Reader ─▶ XCAF document ─▶ BRepMesh_IncrementalMesh
                                                             │
GLB bytes  ◀─ in-memory mem:// filesystem ◀─ RWGltf_CafWriter┘
        (all inside a WebAssembly sandbox hosted by wazero — no file I/O)

The C++ side is a ~400-line shim (wasm/shim.cpp) over unmodified OCCT 7.9.1, built as a standalone wasm module with Emscripten using the standardized WebAssembly exception-handling (exnref) encoding, which wazero supports as an experimental feature. The build is reproducible: pinned, checksummed sources (wasm/build_occt.sh) and a pinned Emscripten version.

Because execution is single-threaded wasm, one conversion uses one core and runs a few times slower than native OCCT — a fine trade for a dependency-free go get on a server that can run conversions concurrently. Ballpark: the 88KB screw.step test fixture converts in ~7s on an Apple M1 Pro at default mesh quality (plus a one-time ~13s wasm compilation at startup). If you need maximum single-conversion throughput, a cgo backend is a possible future addition.

Rebuilding the wasm module

./wasm/build_occt.sh   # fetch + build OCCT 7.9.1 static wasm libs (once, ~30 min)
./wasm/build_shim.sh   # build shim, link, compress into internal/wasm/occt.wasm.zst

Requires cmake, ninja, zstd, and emsdk. CI (.github/workflows/build-wasm.yml) rebuilds the artifact and checks it against the committed one.

Scope & roadmap

Converts STEP and IGES to GLB. Candidates for later: Draco compression, a mesh-data API (geometry access without GLB), OCCT 8.x.

License

MIT for this package. The embedded wasm module contains OCCT, licensed LGPL-2.1 with the Open CASCADE Exception (which permits this form of distribution), and RapidJSON (MIT) — see THIRD_PARTY_NOTICES.md.

Documentation

Overview

Package occt converts STEP CAD files to GLB (binary glTF) in pure Go.

It embeds OpenCascade (OCCT) compiled to WebAssembly and runs it under wazero, so `go get` works on any platform Go supports — no cgo, no system dependencies. Names, colors, and assembly hierarchy from the STEP file are preserved in the produced GLB.

glb, err := occt.StepToGLB(ctx, stepBytes)

For servers, create one Converter and reuse it: the wasm module is compiled once, and each conversion runs in its own short-lived instance (goroutine-safe, memory returned to the OS per call).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidInput reports empty or malformed arguments.
	ErrInvalidInput = errors.New("occt: invalid input")
	// ErrParse reports an input file that could not be parsed.
	ErrParse = errors.New("occt: file parse failed")
	// ErrEmptyModel reports an input file with no convertible shapes.
	ErrEmptyModel = errors.New("occt: no shapes in file")
	// ErrConversion reports a failure while meshing or writing glTF.
	ErrConversion = errors.New("occt: conversion failed")
)

Sentinel errors, matchable with errors.Is. The returned error also carries the shim's detailed message.

Functions

func IgesToGLB

func IgesToGLB(ctx context.Context, iges []byte, opts ...Option) ([]byte, error)

IgesToGLB converts an IGES file to GLB using a lazily-initialized package-level Converter (wasm compiled on first call).

func StepToGLB

func StepToGLB(ctx context.Context, step []byte, opts ...Option) ([]byte, error)

StepToGLB converts a STEP file to GLB using a lazily-initialized package-level Converter (wasm compiled on first call).

Types

type Converter

type Converter struct {
	// contains filtered or unexported fields
}

Converter holds the compiled OCCT wasm module. It is safe for concurrent use: every conversion runs in a fresh, short-lived module instance.

func NewConverter

func NewConverter(ctx context.Context, opts ...ConverterOption) (*Converter, error)

NewConverter compiles the embedded OCCT wasm module (the expensive step, done once) and returns a reusable, goroutine-safe Converter.

func (*Converter) Close

func (c *Converter) Close(ctx context.Context) error

Close releases the compiled module and runtime.

func (*Converter) IgesToGLB

func (c *Converter) IgesToGLB(ctx context.Context, iges []byte, opts ...Option) ([]byte, error)

IgesToGLB converts one IGES file to GLB.

func (*Converter) StepToGLB

func (c *Converter) StepToGLB(ctx context.Context, step []byte, opts ...Option) ([]byte, error)

StepToGLB converts one STEP file to GLB.

type ConverterOption

type ConverterOption func(*converterConfig)

ConverterOption configures a Converter.

func WithDefaultOptions

func WithDefaultOptions(opts ...Option) ConverterOption

WithDefaultOptions sets conversion options applied to every StepToGLB call on this Converter (still overridable per call).

func WithInterpreter

func WithInterpreter() ConverterOption

WithInterpreter selects wazero's interpreter engine instead of its optimizing compiler. Much slower; intended for tests and debugging.

type Option

type Option func(*options)

Option configures a single conversion.

func WithAngularDeflection

func WithAngularDeflection(d float64) Option

WithAngularDeflection sets the angular deflection for meshing, in radians. Smaller values produce finer meshes on curved surfaces.

func WithLinearDeflection

func WithLinearDeflection(d float64) Option

WithLinearDeflection sets the chordal deflection for meshing. With WithRelativeDeflection(true) (the default) it is a fraction of the shape's bounding box; otherwise it is an absolute distance in model units (millimeters for most STEP files). Smaller values produce finer meshes.

func WithRelativeDeflection

func WithRelativeDeflection(relative bool) Option

WithRelativeDeflection chooses whether linear deflection is relative to each shape's bounding box (true, default) or absolute in model units.

Directories

Path Synopsis
internal
wasm
Package wasm embeds the OCCT conversion module and hosts it under wazero.
Package wasm embeds the OCCT conversion module and hosts it under wazero.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL