Zig library for loading, generating, processing and optimising triangle meshes.
  • C++ 49.3%
  • C 41.4%
  • Zig 9.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Chris Heyes 11d6e048f4
Update to 0.17.0 (#30)
* Update to Zig 0.17.0

* zig fmt
2026-10-23 17:13:38 +01:00
.github/workflows Update to 0.17.0 (#30) 2026-10-23 17:13:38 +01:00
libs - Fixup usage of deprecated std.Build APIs\ 2026-10-23 16:22:32 +01:00
src Update to 0.17.0 (#30) 2026-10-23 17:13:38 +01:00
.gitignore files from monorepo @ 14e6258901c6fb47ae598705682837ef6c298e60 2024-11-03 23:17:36 +00:00
build.zig Update to 0.17.0 (#30) 2026-10-23 17:13:38 +01:00
build.zig.zon Update to 0.17.0 (#30) 2026-10-23 17:13:38 +01:00
LICENSE files from monorepo @ 14e6258901c6fb47ae598705682837ef6c298e60 2024-11-03 23:17:36 +00:00
logo.jpg files from monorepo @ 14e6258901c6fb47ae598705682837ef6c298e60 2024-11-03 23:17:36 +00:00
README.md Remove usingnamespace usage, build script fixups, and support linking memory allocation functions from a shared library (#6) 2025-08-29 00:36:26 +01:00

image

zmesh

Zig library for loading, generating, processing and optimising triangle meshes.

Under the hood this library uses below C/C++ libraries:

All memory allocations go through user-supplied, Zig allocator.

As an example program please see procedural mesh (wgpu).

Getting started

Example build.zig:

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{ ... });

    const zmesh = b.dependency("zmesh", .{});
    exe.root_module.addImport("zmesh", zmesh.module("root"));
    exe.linkLibrary(zmesh.artifact("zmesh"));
}

Now in your code you may import and use zmesh:

const zmesh = @import("zmesh");

pub fn main() !void {
    ...
    zmesh.init(allocator);
    defer zmesh.deinit();

    var custom = zmesh.Shape.init(indices, positions, normals, texcoords);
    defer custom.deinit();

    var disk = zmesh.Shape.initParametricDisk(10, 2);
    defer disk.deinit();
    disk.invert(0, 0);

    var cylinder = zmesh.Shape.initCylinder(10, 4);
    defer cylinder.deinit();

    cylinder.merge(disk);
    cylinder.translate(0, 0, -1);
    disk.invert(0, 0);
    cylinder.merge(disk);

    cylinder.scale(0.5, 0.5, 2);
    cylinder.rotate(math.pi * 0.5, 1.0, 0.0, 0.0);

    cylinder.unweld();
    cylinder.computeNormals();
    ...
}
const zmesh = @import("zmesh");

pub fn main() !void {
    zmesh.init(allocator);
    defer zmesh.deinit();

    //
    // Load mesh
    //
    const data = try zmesh.io.zcgltf.parseAndLoadFile(content_dir ++ "cube.gltf");
    defer zmesh.io.zcgltf.freeData(data);

    var mesh_indices = std.ArrayListUnmanaged(u32){};
    var mesh_positions = std.ArrayListUnmanaged([3]f32){};
    var mesh_normals = std.ArrayListUnmanaged([3]f32){};

    try zmesh.io.zcgltf.appendMeshPrimitive(
        allocator,
        data,
        0, // mesh index
        0, // gltf primitive index (submesh index)
        &mesh_indices,
        &mesh_positions,
        &mesh_normals, // normals (optional)
        null, // texcoords (optional)
        null, // tangents (optional)
    );
    ...

    //
    // Optimize mesh
    //
    const Vertex = struct {
        position: [3]f32,
        normal: [3]f32,
    };

    var remap = std.ArrayListUnmanaged(u32){};
    try remap.resize(allocator, src_indices.items.len);

    const num_unique_vertices = zmesh.opt.generateVertexRemap(
        remap.items, // 'vertex remap' (destination)
        src_indices.items, // non-optimized indices
        Vertex, // Zig type describing your vertex
        src_vertices.items, // non-optimized vertices
    );

    var optimized_vertices = std.ArrayListUnmanaged(Vertex){};
    try optimized_vertices.resize(allocator, num_unique_vertices);

    zmesh.opt.remapVertexBuffer(
        Vertex, // Zig type describing your vertex
        optimized_vertices.items, // optimized vertices (destination)
        src_vertices.items, // non-optimized vertices (source)
        remap.items, // 'vertex remap' generated by generateVertexRemap()
    );

    // More optimization steps are available - see `zmeshoptimizer.zig` file.
}