Schemas / Geometry / paint

rig.geometry.mesh

v0.31.0 · draft 9 fields 2 required

Fields

FieldTypeMeaning
positions array<number> required xyz tightly packed (x0,y0,z0,x1,...)
normals array<number> optional Optional per-vertex normals, same packing, parallel to positions
indices array<uint32> optional Triangle (or line) tessellation; empty = sequential. Hosts may rebuild this from loops.
loops array<uint32> optional Optional concatenated n-gon vertex indices (authored faces). Empty = faces are implicit triangles from indices.
loopSizes array<uint32> optional Optional vertex count per authored face; sum equals loops.length. A cube is six 4-gons, not twelve triangles.
texcoords array<number> optional Optional per-vertex uv, tightly packed (u0,v0,u1,...); empty = none
mode enumtriangles · lines · line-strip required triangles, lines, line-strip
faceColors array<rgba> optional Optional per-face colour
facePalette array<uint8> optional Optional per-face palette index

Indexed mesh. Format when present.

One packing only - packed float[], not vec3[] / vec2[] beside it. Hosts may expand for editors; the wire form stays flat. Mesh corners are these arrays, not rig.spatial.vertex entities.

faceColors and facePalette are alternatives. Carrying both on one mesh is a document error (same rule as inline vs referenced paint). When loops is present they are one entry per authored face (per loopSizes row), not per tessellated triangle.

normals is authored shading data - mixed hard/soft edges need it. When absent, a presenter computes face normals (flat shading); it must not smooth-average shared vertices, which fakes roundness the document never asked for.

Edges

Do not store a parallel edge table. An authored edge is a consecutive pair in a loops face, plus the close from last to first. Name an edge for crease / rig.cad.fillet / rig.cad.chamfer as an undirected vertex pair {a, b} into positions (store min(a,b), max(a,b) on the wire).

N-gons are the authored face grammar - a cube is six 4-gons. indices are the triangle tessellation a presenter or CSG kernel may rebuild.

Solids

When any rig.cad.* component is present on the same entity, that CAD tree is the solid source of truth and this mesh is an optional bake. Hosts that can CSG should rebuild the mesh rather than treat the bake as authored.

Appearance: compose rig.render.material on the same entity for shaded 3D. 2D / unlit presenters may use rig.paint.fill_stroke instead. Do not add a material field on this schema.

No GPU buffer handles.

JSON Schema

Resolves at https://rig.works/schemas/rig.geometry.mesh.schema.jsonraw file.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://rig.works/schemas/rig.geometry.mesh.schema.json",
  "title": "rig.geometry.mesh",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "positions": {
      "type": "array",
      "items": {
        "type": "number"
      }
    },
    "normals": {
      "type": "array",
      "items": {
        "type": "number"
      }
    },
    "indices": {
      "type": "array",
      "items": {
        "$ref": "./_defs.schema.json#/$defs/uint32"
      }
    },
    "loops": {
      "type": "array",
      "items": {
        "$ref": "./_defs.schema.json#/$defs/uint32"
      }
    },
    "loopSizes": {
      "type": "array",
      "items": {
        "$ref": "./_defs.schema.json#/$defs/uint32"
      }
    },
    "texcoords": {
      "type": "array",
      "items": {
        "type": "number"
      }
    },
    "mode": {
      "type": "string",
      "enum": [
        "triangles",
        "lines",
        "line-strip"
      ]
    },
    "faceColors": {
      "type": "array",
      "items": {
        "$ref": "./_defs.schema.json#/$defs/rgba"
      }
    },
    "facePalette": {
      "type": "array",
      "items": {
        "$ref": "./_defs.schema.json#/$defs/uint8"
      }
    }
  },
  "required": [
    "positions",
    "mode"
  ]
}

Seen in

cad-boolean.json · minimal-scene.json