Skip to content

Latest commit

 

History

207 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GeoJitter

Max/Jitter externals that mirror Blender Geometry Nodes, so that a Blender geometry-node tutorial can be rebuilt in Max without inventing a different graph.

254 externals, one Max object per Blender node, plus the bridges Jitter needs that Blender does not have (matrix in/out, OBJ/PLY/STL import, jit.gl.mesh export).

What is in it

Family Count Examples
Volume & grid (SDF, OpenVDB-style) 50 sdf_sphere, grid_advect, volume_to_mesh
Attributes, fields & control flow 45 store_named_attribute, capture_attribute, switch
Utility, math & colour 28 math, vector_math, map_range, color_ramp
Mesh & curve primitives 32 primitive_cube, curve_primitive_spiral
Procedural textures 10 noise_texture, voronoi_texture, gabor_texture
Instances, topology, sampling, I/O, material bridge rest instance_on_points, sample_curve, to_gl_mesh

Every object ships a help patch — 254 of them, generated rather than hand-maintained — plus 11 runnable example patches under examples/.

Scope decisions live in adrs/ (12 ADRs). What is deliberately not ported, and why, is written down there rather than left to guesswork: render-context nodes (Fresnel, Light Path), Blender datablock nodes, simulation zones, and the legacy texture-node tree.

Requirements

  • Max 8.0 or later (this is what package-info.json declares; development and all verification happen on Max 9)
  • macOS: Xcode command line tools. Accept the licence first: sudo xcodebuild -license
  • CMake 3.19+

Build

git submodule update --init --recursive   # max-sdk-base
cmake -S . -B build -DBUILD_TESTING=ON
cmake --build build
ctest --test-dir build

The build writes one .mxo bundle per object into externals/. Together with package-info.json at the repository root, that folder is a Max package.

For the sanitizer build used during development, add -DGEOJITTER_SANITIZE=ON.

Install

Max loads packages from its search path (Cycling '74 docs). Put the whole repository folder — it already has externals/ and package-info.json — into a package location:

  • macOS: ~/Documents/Max 9/Packages/
  • Windows: %USERPROFILE%\Documents\Max 9\Packages\

so you end up with Packages/GeoJitter/externals/jit.geo.primitive_cube.mxo and so on. Then restart Max, or use File → Rescan.

For development, symlink instead of copying — a rebuild is then picked up on the next rescan.

Externals are not re-read from disk once Max has loaded them. A rebuilt object needs a Max restart, not a rescan. This surprises everyone once.

Getting started

Create an object box and type jit.geo. — autocomplete lists everything. Then:

  • tutorials/ — eight narrated, runnable patches rebuilding the canonical Blender Geometry-Nodes workflows, from displacement to repeat zones. Start here (index)
  • extras/GeoJitter Node Overview.maxpat — every object in one browsable patch
  • examples/DISPLACEMENT_TUTORIAL.md — grid → noise → set position, the canonical first geometry-nodes exercise
  • examples/SHADER_TUTORIAL.md — noise → colour ramp → set position
  • examples/FLUID_TUTORIAL.md — the grid/volume side
  • help/jit.geo.<name>.maxhelp — one per object, reachable with right-click → Open Help

Geometry travels between objects as a pointer inside a Max message. The sender releases it, the receiver retains it (ADR-010) — so a geometry outlet can feed several inlets without copying, and nothing has to be freed by hand in a patch.

How it is tested

The maths lives in pure C with no Max or Jitter API, which is what makes it testable at all: 78 test binaries run under AddressSanitizer in CI on every push.

Each of the 254 nodes is classified by what can honestly be asserted about it — tests/golden/COVERAGE.md names the class and the oracle for every one:

Class Nodes Oracle
GOLDEN 57 compared against Blender ground truth, generated headless
ANALYTIC 96 closed-form output; the formula is the specification
INVARIANT 78 deterministic but Blender's exact output is not canonical (tessellation, element order), or randomized — structural invariants asserted instead
BRIDGE 8 no Blender equivalent (I/O, render, matrix); round-trip and format tests

The point of the split is not to flatter the coverage number. A node whose tessellation legitimately differs from Blender's cannot be golden-tested, and saying so is more useful than a green tick that means nothing.

Known limitations

Setting an attribute and banging in the same message chain uses the previous value. [rotation_y 45, bang( sends the bang before the attribute arrives. Drive the two from separate events instead — a [t b b] with the bang on the left outlet, or two message boxes. This is a regression from the attribute rewrite in GJ-152…155 and is not yet solved; the measurements and the candidate fixes are in plans/BUG-getattr-crash.md.

Windows is untested. The build declares it and the code avoids platform specifics, but nobody has compiled it there.

The material bridge is a bridge, not a renderer. jit.mat.* maps shader parameters onto jit.gl.material and OB3D attributes. Jitter has no closure renderer, so the same graph gives a plausible image, not Blender's image. ADR-012 says this in more detail; no golden parity is claimed for those objects.

Repository layout

Path Contents
source/projects/geojitter/ main_<node>.c (Max wrapper) + jit_geo_<node>.c (Jitter object) + shared pure-C cores
tests/ unit/ pure-core tests, mock/ ownership and protocol tests, golden/ Blender comparison
tutorials/ eight narrated workflow patches + their write-ups (generated by build_tutorials.py)
help/, examples/, extras/, patchers/ generated help patches, demo patches, the overview patch, UI abstractions
adrs/ scope and architecture decisions
plans/ per-node plans, trackers, open investigations
doc/license/ the licence audit and the third-party licence texts
scripts/ plan and help generators, the licence audit
max_mcp/ an MCP server for generating .maxpat files from an editor — a development aid, not part of the package (setup)

Help patches and examples are generated (examples/build_*.py). Edit the generator, not the .maxhelp.

Licence

GPL-3.0-or-later, and the version matters.

Most of the ported maths comes from GPL-2.0-or-later files of Blender. Six files come from the Cycles kernel and the shared radial-tiling maths, which Blender licenses Apache-2.0. Apache-2.0 is compatible with GPL-3.0 but not with GPL-2.0, so the combination can only be distributed under GPL-3.0-or-later — which is why LICENSE carries the v3 text. The v2 text is kept at doc/license/GPL-2.0-license.txt, because that is the licence the individual ported files name.

Every source file carries an SPDX header, so the licence of any one of them can be read off the file rather than inferred. doc/license/LICENSE-AUDIT.md lists all 747 and where each obligation comes from; regenerate with python3 scripts/license_audit.py, and --check fails on a file that has no header or that transcribes Blender code without naming a licence.

The counts are worth knowing: 41 files carry a Blender GPL obligation and 6 are Apache-2.0 — those cannot be relicensed by anyone here. The remaining 700 are GeoJitter's own code with no inbound obligation at all; they are GPL-3.0-or-later because the project chose that, not because anyone upstream requires it.

One question is open, and this repository cannot settle it. The externals link against MaxAudioAPI and JitterAPI, closed-source frameworks inside Max.app. The Max SDK headers are plain MIT and pose no problem — that was checked, not assumed — but GPL code linking a proprietary library is the classic plugin-in-a-proprietary-host case, and GPLv2 §3's "major components of the operating system" exemption does not obviously cover an application. Anyone redistributing this as a binary package should get that answered first. The audit sets out the facts so the question can be asked precisely.

About

Blender Geometry Nodes as Max/Jitter externals — 254 objects, one per Blender node, so a geometry-node tutorial can be rebuilt in Max

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages