Skip to content
Plugins (183)

obj

stable

Parse and export Wavefront OBJ and MTL files, providing access to vertices, normals, texture coordinates, faces, and material definitions.

use plugin obj::{parse_obj, parse_obj_file, vertex_count, …}
10 functions Graphics
Runs with the native Zolo host

Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.

/ filter jk navigate Esc clear
Functions (10)
  1. parse_obj Parse OBJ text into a mesh data table
  2. parse_obj_file Parse an OBJ file from disk
  3. vertex_count Count vertices in a parsed mesh
  4. face_count Count faces in a parsed mesh
  5. parse_mtl Parse MTL material text into a table
  6. normal_count Count normals in a parsed mesh
  7. texcoord_count Count texture coordinates in a parsed mesh
  8. bounding_box Compute axis-aligned bounding box of a mesh
  9. export_obj Serialize mesh data to OBJ text
  10. export_obj_file Write mesh data to an OBJ file on disk

From import to result

  1. 01Import only what you use
  2. 02Copy the smallest example
  3. 03Run it with the Zolo CLI

Overview

obj is a self-contained reader and writer for the Wavefront OBJ geometry format and its companion MTL material format, with no external dependencies. Parsing a model returns a plain mesh table with four sections — vertices, normals, texcoords, and faces — so the geometry is ordinary Zolo data you can index, count, transform, and feed back to the exporter. Faces store index triples {v, vt, vn} exactly as written in the file, where -1 marks a component (texture or normal) that was omitted.

Reach for it whenever you need to load a .obj mesh, inspect its size or bounds, read material colors out of a .mtl file, or generate and round-trip OBJ text programmatically. The mental model is: parse with parse_obj / parse_obj_file (or parse_mtl for materials), inspect with the *_count and bounding_box queries, then serialize with export_obj / export_obj_file.

Common patterns

Load a mesh and report its size and extents:

use plugin obj::{parse_obj_file, vertex_count, face_count, bounding_box}

let mesh = parse_obj_file("models/cube.obj")
let bb = bounding_box(mesh)
print("{vertex_count(mesh)} verts, {face_count(mesh)} faces")
print("height: {bb["max_y"] - bb["min_y"]}")

Round-trip a mesh: parse OBJ text, then serialize it straight back out:

use plugin obj::{parse_obj, export_obj}

let mesh = parse_obj("v 0 0 0\nv 1 0 0\nv 0 1 0\nf 1 2 3")
print(export_obj(mesh))

Read a material's diffuse color from MTL text:

use plugin obj::{parse_mtl}

let mats = parse_mtl("newmtl red\nKd 1.0 0.0 0.0\nKs 0.5 0.5 0.5")
let red = mats["red"]
print("diffuse: {red["diffuse_r"]}, {red["diffuse_g"]}, {red["diffuse_b"]}")

Parse OBJ text into a mesh data table

Parses Wavefront OBJ text and returns a table with four sections: vertices (list of {x, y, z}), normals (list of {x, y, z}), texcoords (list of {u, v}), and faces (list of face vertex index triples {v, vt, vn}, where -1 means absent).

use plugin obj::{parse_obj}

let mesh = parse_obj("v 0 0 0\nv 1 0 0\nv 0 1 0\nf 1 2 3")
print("vertices: {mesh["vertices"][0]["x"]}")

Faces preserve the full v/vt/vn index triple; absent components read as -1:

use plugin obj::{parse_obj}

let mesh = parse_obj("v 0 0 0\nvt 0 0\nvn 0 1 0\nf 1/1/1 1/1/1 1/1/1")
let corner = mesh["faces"][0][0]
print("v={corner["v"]} vt={corner["vt"]} vn={corner["vn"]}")

Parse an OBJ file from disk

Reads an OBJ file from the given path and returns the same structure as parse_obj. Errors if the file cannot be read.

use plugin obj::{parse_obj_file, vertex_count, face_count}

let mesh = parse_obj_file("models/cube.obj")
print("verts: {vertex_count(mesh)}, faces: {face_count(mesh)}")

Count vertices in a parsed mesh

Returns the number of vertices in a parsed mesh table. Equivalent to reading the length of data["vertices"].

use plugin obj::{parse_obj_file, vertex_count}

let mesh = parse_obj_file("scene.obj")
print("{vertex_count(mesh)} vertices")

Count faces in a parsed mesh

Returns the number of polygon faces in a parsed mesh table.

use plugin obj::{parse_obj_file, face_count}

let mesh = parse_obj_file("scene.obj")
print("{face_count(mesh)} faces")

Parse MTL material text into a table

Parses Wavefront MTL material text and returns a table keyed by material name. Each entry contains name, diffuse_r/g/b, and specular_r/g/b fields from the Kd and Ks directives.

use plugin obj::{parse_mtl}

let mtl_text = "newmtl red\nKd 1.0 0.0 0.0\nKs 0.5 0.5 0.5"
let mats = parse_mtl(mtl_text)
let red = mats["red"]
print("diffuse r: {red["diffuse_r"]}")

A library can contain several materials; each is keyed by its newmtl name:

use plugin obj::{parse_mtl}

let mats = parse_mtl("newmtl gold\nKd 1.0 0.84 0.0\nnewmtl steel\nKd 0.6 0.6 0.65")
print("gold diffuse_g: {mats["gold"]["diffuse_g"]}")
print("steel diffuse_b: {mats["steel"]["diffuse_b"]}")

Count normals in a parsed mesh

Returns the number of vertex normals in a parsed mesh table.

use plugin obj::{parse_obj_file, normal_count}

let mesh = parse_obj_file("scene.obj")
print("{normal_count(mesh)} normals")

Count texture coordinates in a parsed mesh

Returns the number of texture coordinate pairs (UV) in a parsed mesh table.

use plugin obj::{parse_obj_file, texcoord_count}

let mesh = parse_obj_file("scene.obj")
print("{texcoord_count(mesh)} uvs")

Compute axis-aligned bounding box of a mesh

Computes the axis-aligned bounding box of all vertices in the mesh. Returns {min_x, min_y, min_z, max_x, max_y, max_z}. Useful for centering or scaling a model.

use plugin obj::{parse_obj_file, bounding_box}

let mesh = parse_obj_file("character.obj")
let bb = bounding_box(mesh)
let height = bb["max_y"] - bb["min_y"]
print("model height: {height}")

Use the min/max corners to find the model's center point:

use plugin obj::{parse_obj, bounding_box}

let mesh = parse_obj("v -1 -1 -1\nv 1 1 1")
let bb = bounding_box(mesh)
let cx = (bb["min_x"] + bb["max_x"]) / 2
let cy = (bb["min_y"] + bb["max_y"]) / 2
let cz = (bb["min_z"] + bb["max_z"]) / 2
print("center: {cx}, {cy}, {cz}")

Serialize mesh data to OBJ text

Serializes a mesh data table back to Wavefront OBJ text format. The output includes v, vt, vn, and f lines in the correct order. Use this to generate or modify OBJ files programmatically.

use plugin obj::{parse_obj_file, export_obj}

let mesh = parse_obj_file("input.obj")
let text = export_obj(mesh)
print(text)

Because the exporter consumes the same table shape parse_obj produces, you can build a mesh from text and serialize it back in one pass:

use plugin obj::{parse_obj, export_obj}

let triangle = parse_obj("v 0 0 0\nv 1 0 0\nv 0 1 0\nf 1 2 3")
print(export_obj(triangle))

Write mesh data to an OBJ file on disk

Serializes a mesh data table to OBJ format and writes it directly to the given file path. Errors if the file cannot be written.

use plugin obj::{parse_obj_file, export_obj_file}

let mesh = parse_obj_file("original.obj")
export_obj_file(mesh, "output/copy.obj")
print("exported")

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

en