VEHICLE LAB / DOCUMENTATION
Bring your own geometry
The studio uses millimetres for design display. Geometry is a visual artifact with a source identity, not automatically a collision mesh or a fabrication model.
Import an OBJ
Export triangles or convex polygon faces in millimetres from your CAD or modeling tool. Supply a new model ID:
python3 tools/project.py add-model projects/my-rover/project.json my-bracket.obj --id bracket --units mm
python3 tools/project.py validate projects/my-rover/project.jsonThe command writes packed display geometry, records the source hash, and adds an inspection stage. It does not overwrite an existing model. OBJ material files are not loaded; the initial importer assigns one neutral material. Concave polygons should be triangulated in the authoring tool before export.
Keep assembly groups
OBJ object and group boundaries become named parts. Map those authored names to inspection subsystems with a JSON file:
{"base": "frame", "guide": "hardware", "carriage": "drive"}python3 tools/project.py add-model projects/my-rover/project.json assembly.obj --id assembly --units mm --groups subsystems.jsonUnmapped parts belong to the frame subsystem. A mapping with an unknown part name is rejected. Groups with the same subsystem and material may share a draw batch; their source identities remain in the metadata. Use the original linear-stage OBJ and its subsystem map as a working example.
Packed mesh interface
Metadata lists parts with stable IDs, subsystem groups, colors and typed-array byte ranges. A little-endian binary file stores Float32 XYZ coordinates followed by Uint32 triangle indices for each part. Each byte offset is aligned to four bytes. The metadata includes the binary SHA-256, part and triangle counts, units and display-only flags.
| Part field | Meaning |
|---|---|
| positionOffset / positionCount | Byte offset and scalar count for Float32 XYZ positions. |
| indexOffset / indexCount | Byte offset and scalar count for Uint32 triangle indices. |
| group | frame, body, wheels, suspension, drive, electrical or hardware. |
| color | Three sRGB components in the 0–1 range. |
| id | Unique component identity retained from your source model. |
Write a CAD adapter
The standard-library pack() function in tools/project.py accepts a list of parts containing positions, indices, identity, group and color. Use it with tessellation exported by FreeCAD, your CAD API or another mesh source. Preserve the native file separately and record its units, revision and hash.
Geometry fidelity
The vehicle example preserves source tessellation without triangle decimation. Float32 conversion and public omissions are recorded in the provenance register. The viewer batches geometry for rendering and normalizes the camera scale. Inspection offsets never feed a solver.
Safe imports and concurrent work
Imports create new assets exclusively and reject symlinked output paths. One import can update a project at a time; a competing command exits with a retry message. Manual manifest edits detected during import also stop the update. A terminated process may leave .project.lock in its project directory; inspect its recorded process ID and remove the lock only after confirming that writer has stopped.
Both CLI and browser validate renderer metadata, finite vertices, triangle bounds, colors, counts, hashes and nonzero spatial extent. Geometry needs nonempty id, revision and title strings, a source SHA-256, a binary SHA-256, an omission list, and explicit false values for physicsGeometry and physicalValidation. Use pack() to write the complete metadata contract.
Asset ownership
Only import geometry that you have rights to distribute. Supplier STEP solids, reconstructed brand lettering and personal fitting proxies were withheld from the bundled public view. Their omission counts remain visible in the asset manifest. The full private working tree and native vehicle fabrication files are outside this release.