vcad.
Back to IR & Format
IR & Format

Compact IR Format

Compact IR format designed for ML training pipelines

The compact IR format (v0.2) is a token-efficient text representation of vcad documents. It encodes the same parametric DAG as the JSON IR format but uses single-letter opcodes and positional arguments, making it roughly 5x smaller. This matters for ML training where context window budgets are tight, and for URL embedding where size limits are strict.

Header

Every compact IR document begins with a version header:

# vcad 0.2

Lines starting with # are comments and are ignored by the parser. Empty lines are also ignored.

Materials

Materials are declared before geometry with the M opcode.

M <name> <r> <g> <b> <metallic> <roughness> [density] [friction]
namestringrequired

Material identifier. Used in ROOT lines and assembly references. Quote with double quotes if the name contains spaces.

r, g, bnumber (0-1)required

RGB color components.

metallicnumber (0-1)required

Metallic factor. 0 for dielectric, 1 for metal.

roughnessnumber (0-1)required

Surface roughness. 0 for mirror, 1 for matte.

densitynumber (kg/m^3)optional

Material density for mass calculations. Optional.

frictionnumberoptional

Friction coefficient for physics simulation. Optional, requires density.

M aluminum 0.9 0.9 0.92 0.95 0.3 2700
M abs-black 0.08 0.08 0.08 0 0.6 1050

Geometry Opcodes

Each geometry line creates a node. Nodes are numbered sequentially starting from 0 in the order they appear. When a node references another node (e.g., a boolean referencing its operands), it uses the integer index of that node.

Primitives

OpcodeSyntaxIR TypeDescription
CC <sx> <sy> <sz>CubeBox from origin to (sx, sy, sz)
YY <radius> <height>CylinderCylinder along Z, base at origin
SS <radius>SphereSphere at origin
KK <r_bottom> <r_top> <height>ConeCone/frustum along Z
C 50 30 5
Y 10 25
S 15
K 10 0 20

Booleans

OpcodeSyntaxIR TypeDescription
UU <left> <right>UnionCombine volumes
DD <left> <right>DifferenceSubtract right from left
II <left> <right>IntersectionKeep overlap

The left and right arguments are node indices.

C 50 30 5
Y 3 10
T 1 25 15 0
D 0 2

This creates a plate (node 0), a cylinder (node 1), translates the cylinder (node 2), and subtracts it from the plate (node 3).

Transforms

OpcodeSyntaxIR TypeDescription
TT <child> <x> <y> <z>TranslateMove by offset
RR <child> <rx> <ry> <rz>RotateRotate by degrees
XX <child> <sx> <sy> <sz>ScaleScale by factors
C 10 10 10
T 0 50 0 0
R 0 0 0 45
X 0 2 2 2

Patterns

OpcodeSyntaxIR Type
LPLP <child> <dx> <dy> <dz> <count> <spacing>LinearPattern
CPCP <child> <ox> <oy> <oz> <ax> <ay> <az> <count> <angle>CircularPattern

LP creates count copies along the direction vector with the given spacing. CP creates copies around an axis defined by origin (ox, oy, oz) and direction (ax, ay, az) over the total angle in degrees.

Y 3 10
CP 0 0 0 0 0 0 1 6 360

This creates 6 cylinders equally spaced around the Z axis.

Features

OpcodeSyntaxIR TypeDescription
SHSH <child> <thickness>ShellHollow the solid
FIFI <child> <radius>FilletRound all edges
CHCH <child> <distance>ChamferBevel all edges
C 50 50 50
SH 0 2

Sketches

Sketches use a multi-line block starting with SK and ending with END. Within the block, L defines line segments and A defines arc segments.

SK <ox> <oy> <oz>  <xx> <xy> <xz>  <yx> <yy> <yz>
L <x1> <y1> <x2> <y2>
A <x1> <y1> <x2> <y2> <cx> <cy> <ccw>
...
END

The SK line specifies the sketch plane with an origin point and two direction vectors (X-axis and Y-axis of the sketch coordinate system). Segment coordinates are 2D within this local frame.

For arcs, cx/cy is the arc center and ccw is 1 for counter-clockwise, 0 for clockwise.

SK 0 0 0  1 0 0  0 1 0
L 0 0 10 0
L 10 0 10 5
L 10 5 0 5
L 0 5 0 0
END

Extrude and Revolve

OpcodeSyntaxIR TypeDescription
EE <sketch> <dx> <dy> <dz>ExtrudePush profile along direction
VV <sketch> <ox> <oy> <oz> <ax> <ay> <az> <angle>RevolveSpin profile around axis

The sketch argument is the node index of a SK block.

SK 0 0 0  1 0 0  0 1 0
L 0 0 10 0
L 10 0 10 5
L 10 5 0 5
L 0 5 0 0
END
E 0 0 0 20

This sketches a rectangle and extrudes it 20mm along Z.

Node Names

Any geometry opcode can include an optional quoted name as the last argument:

C 50 30 5 "Base Plate"
Y 3 10 "Hole"
D 0 2 "Drilled Plate"

Names are preserved through serialization and appear in the feature tree.

Scene Section

ROOT

The ROOT directive specifies which nodes to render and their materials.

ROOT <node_id> <material> [hidden]
node_idintegerrequired

Index of the geometry node to render.

materialstringrequired

Material name (must match an M declaration).

hiddenflagoptional

If present, the node is hidden (not rendered but still part of the document).

ROOT 3 aluminum
ROOT 5 abs-black hidden

If no ROOT lines are present, the parser automatically selects the highest-numbered unreferenced node as the root with a default gray material.

Assembly Section

Assembly opcodes define part definitions, instances, joints, and the ground instance.

PDEF

PDEF <part_id> <root_node_id> <material>

Declares a reusable part definition. The root_node_id references a geometry node, and material sets the default material.

INST

INST <instance_id> <part_id> <tx> <ty> <tz> <rx> <ry> <rz>

Places an instance of a part definition at the given position (translation) and orientation (Euler angles in degrees).

Joint Opcodes

OpcodeSyntax
JFIXJFIX <id> <parent> <child> <px> <py> <pz> <cx> <cy> <cz>
JREVJREV <id> <parent> <child> <px> <py> <pz> <cx> <cy> <cz> <ax> <ay> <az> [min max]
JSLDJSLD <id> <parent> <child> <px> <py> <pz> <cx> <cy> <cz> <ax> <ay> <az> [min max]
JCYLJCYL <id> <parent> <child> <px> <py> <pz> <cx> <cy> <cz> <ax> <ay> <az>
JBALJBAL <id> <parent> <child> <px> <py> <pz> <cx> <cy> <cz>

Each joint specifies parent and child instance IDs, anchor points on each (px/py/pz for parent, cx/cy/cz for child), and axis information where applicable. Use _ for the parent to ground the child to the world frame.

GROUND

GROUND <instance_id>

Designates which instance is fixed in world space (the root of the kinematic chain).

Scene Settings

Scene settings control the rendering environment, lighting, and post-processing effects.

OpcodeSyntaxDescription
ENVENV none or ENV preset <name>Environment map
BGBG <r> <g> <b>Background color
LDIRLDIR <dx> <dy> <dz> <r> <g> <b> <intensity>Directional light
LPNTLPNT <x> <y> <z> <r> <g> <b> <intensity>Point light
LSPTLSPT <x> <y> <z> <dx> <dy> <dz> <r> <g> <b> <intensity> <angle>Spot light
LAREALAREA <x> <y> <z> <dx> <dy> <dz> <r> <g> <b> <intensity> <w> <h>Area light
AOAO <radius> <intensity>Ambient occlusion
BLOOMBLOOM <threshold> <intensity>Bloom effect
VIGVIG <intensity>Vignette
TONETONE <mode>Tone mapping (aces, reinhard, linear)
EXPEXP <value>Exposure adjustment
CAMCAM <x> <y> <z> <tx> <ty> <tz> <fov>Camera position, target, FOV

Complete Example

# vcad 0.2

# Materials
M aluminum 0.9 0.9 0.92 0.95 0.3 2700
M default 0.8 0.8 0.8 0 0.5

# Geometry
C 100 60 5 "Base Plate"
Y 3 10 "Hole Tool"
T 1 25 15 0
D 0 2 "Left Hole"
Y 3 10
T 4 75 15 0
D 3 5 "Both Holes"
FI 6 1 "Filleted"

# Scene
ROOT 7 aluminum

This document creates a 100x60x5mm aluminum plate with two 3mm-radius holes and a 1mm fillet on all edges.

Parsing and Serialization

TypeScript

import { fromCompact, toCompact } from "@vcad/ir";

// Parse
const doc = fromCompact(compactText);

// Serialize
const compact = toCompact(doc);

Error Handling

The parser throws CompactParseError with the line number and a descriptive message when it encounters invalid syntax, wrong argument counts, or unknown opcodes.

import { CompactParseError } from "@vcad/ir";

try {
  const doc = fromCompact(text);
} catch (e) {
  if (e instanceof CompactParseError) {
    console.error(`Line ${e.line}: ${e.message}`);
  }
}