Skip to main content
A 3D pin has a target.model anchor. It uses the same Pinbox store, events, CLI, MCP tools, replies, resolution, and agent delivery as other pins. kind still expresses intent (note, comment, or move); the target expresses where. Existing DOM and source pins keep their current format.

Create a 3D pin with the CLI

data.target.model contains the anchor. Read it back with pinbox show <id> --json. Use --comment for an annotation that should not wake an agent. Coordinates must be finite. The CLI and core schema reject malformed anchors. Pinbox stores anchor data; it does not load or validate CAD/mesh files.

Use Pinbox’s toolbar and cards in a 3D viewer

The ordinary PIN button and keyboard shortcut now place a 3D draft when clicked on this surface. The original Pinbox draft card, conversation card, inbox, and needle markers are reused. The card identifies the 3D part. Empty-space clicks do not create canvas pins, and orbit drags do not place pins. DOM pinning outside the model surface continues to work. pick returns a ModelAnchor or null; project returns viewport CSS pixels {x,y} or null for hidden, stale, or occluded points. For a host-owned backend that calls the CLI, mount the exported PinboxToolbarElement without hub attributes and wire its public store and actions to the backend. The backend must authenticate requests and stamp their authors. Standard hub users should prefer Pinbox.init above.

Optional interaction hooks

  • onHover(anchor | null) runs on each update() while pointing at the surface in pin mode. Use it to color the picked part; restore its material on null. Leaving the surface, exiting pin mode, window blur, and disposal clear the hover.
  • onActivate(anchor, pin, { signal }) handles marker/inbox selection. Use await modelUi.openPin(pinId) for host sidebar links, including reopening the same pin. The previous signal is aborted on another selection, dismissal or disposal; honor it when loading geometry or moving the camera. acceptsAnchor routes pins to the right viewer on pages with multiple models. Omit it for a single viewer.
  • onCapture() replaces the camera action for this toolbar, including its button, puck and S shortcut. It does not request screen-sharing permission or switch the saved DOM/tab preference. With multiple viewers the first registered capture hook is the default; entering or pressing another surface makes it the capture owner. Destroying that viewer restores another registered owner, or the normal 2D toggle. Repeated capture actions are ignored until its returned promise settles.
  • onError(error) receives activation/capture failures and hover picking failures. Without it failures are logged to the console.
Hooks are optional and renderer-independent. The host supplies the actual image capture, preview, download and chat/storage behavior; Pinbox does not upload an image or launch an agent merely because the camera was pressed. They do not change automatic pin attachment capture configured through Pinbox.init.

Implement picking and projection

The @autono/pinbox-toolbar/model export works with Three.js, Babylon.js, CAD viewers, or a custom renderer. It has no renderer runtime dependency.
  1. Raycast a pointer click against the model.
  2. Convert the hit from world coordinates to the picked part’s local coordinates.
  3. Create a Pinbox pin with target.model, through your authenticated backend.
  4. Resolve the anchor against the part’s current transform each animation frame.
  5. Project the resulting world point to screen coordinates and apply your viewer’s visibility/occlusion checks.
For example, with Three.js:
The sample raycast and projection callbacks are supplied by your renderer. The matrix is column-major, object-to-world, using the anchor’s units. Updating that matrix during an exploded-view animation makes the pin follow its part. visible means the anchor resolved; the host must still check camera clipping, hidden parts, and occlusion before drawing a marker. Pinbox’s default DOM toolbar does not raycast a canvas automatically; the host supplies the 3D interaction. A different model or revision returns stale; a missing part or unusable matrix returns missing. Show the original revision or explicitly migrate the pin after checking the new geometry. Do not silently reuse triangle indices across revisions.

Attribute requests from a signed-in app

A trusted local backend may use --author-json:
The flag is an identity assertion, not authentication. Your backend must verify the login and construct this value itself, never forward a browser-supplied author. An authenticated remote hub can override the asserted identity. Omit this flag for normal CLI use, which continues to use git identity. The toolbar’s accept/reopen actions also have CLI equivalents for backend bridges: pinbox verify <id> --outcome accepted --json and pinbox verify <id> --outcome reopened --json. Replies and resolutions continue through pinbox reply and pinbox resolve.