CommunityBildgithub.com

Joinery

Verwandelt ein Foto eines Möbelstücks (z.B. Tisch, Stuhl, Bank, Regal, Sideboard, Bett, Schreibtisch) in ein baubares 3D-Modell – jedes Teil aus echtem Holz mit echter Verbindungstechnik, eine interaktive offline HTML-Seite mit Explosionsansicht, Röntgenblick und Schritt-für-Schritt-Montage sowie das Maker-Paket mit Schnittliste, bemaßten Werkstattzeichnungen, Einkaufsliste für Holz und Beschläge und einer illustrierten Montageanleitung.

Was ist Joinery?

Joinery verwandelt ein einzelnes Foto eines Möbelstücks in ein vollständiges, baubares 3D-Modell und alle dazugehörigen Fertigungsunterlagen. Dabei handelt es sich um eine Designinterpretation, keine Photogrammetrie: Anhand von wenigen echten Maßen (Ankern) und sorgfältiger Beobachtung des Fotos werden Proportionen, Holzart, Verbindungstechnik und Oberfläche bestimmt. Das Ergebnis ist eine interaktive Offline-HTML-Seite (ca. 570 KB), die das Möbelstück in einer Explosionsansicht, mit Röntgenblick und in Montageschritten zeigt – jedes Teil kann angeklickt werden, um seine genauen Maße zu sehen. Parallel dazu erstellt das Tool das Maker-Paket: eine detaillierte Schnittliste, bemaßte Werkstattzeichnungen, Zuschnittpläne für Bretter und Platten, eine Liste mit benötigtem Holz, Beschlägen und Werkzeugen sowie eine bebilderte Montageanleitung (auch als PDF). Die gesamte Pipeline arbeitet mit einem konsistenten Modell, sodass Schnittliste, Zeichnungen und Anleitung nie voneinander abweichen. Das System unterstützt verschiedene Werkstatttypen (Handwerk, Tischlerei, CNC) und wählt automatisch die passenden Verbindungstechniken aus einer Bibliothek aus. Es läuft auf Node.js (Node 20.10+) und benötigt optional Chromium für die Erstellung von Standbildern und PDF-Dokumenten. Der Anwender muss zunächst ein Foto und einige Maße liefern, dann eine Spezifikationsdatei (`spec.json`) und ein JavaScript-Modell (`model.js`) erstellen, die die Geometrie, Verbindungen und Montageschritte definieren. Die Validierung prüft Kollisionen und Plausibilität, bevor das Paket erstellt wird.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/JoseChipanaTica/joinery/tree/HEAD

Installed? Explore more Bild skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Joinery?

Ein Stück, eine Seite, ein Paket. Der Besucher sieht das zusammengebaute Möbelstück, zieht einen Regler und es zerlegt sich, geht Schritt für Schritt durch den Zusammenbau, klickt auf ein Teil und sieht dessen Maße. Dasselbe Modell, das die Teile bewegt, schreibt die Schnittliste, die Zeichnungen und die Anleitung – daher kann nichts auf Papier dem widersprechen, was auf dem Bildschirm zu sehen ist.

SKILL_DIR ist der Ordner, in dem diese Datei liegt. Die Bauprojekte und das Paket werden in ./joinery-out des Ordners abgelegt, von dem aus Sie die Befehle ausführen.

Erster Start

cd "$SKILL_DIR" && npm install

Benötigt Node 20.10+. Für Standbilder und Anleitungsbilder wird Chromium benötigt: npx playwright install chromium oder setzen Sie CHROMIUM auf den Pfad zu einem beliebigen Chrome/Chromium-Binary (CHROMIUM=/usr/bin/google-chrome).

Die Pipeline

Foto + Anker ─► spec.json ─► model.js ─► validieren ─► Seite ─► Standbilder ─► Paket
SchrittBefehlErgebnis
1. InterpretierenSie, das Foto lesendspec.json: Typ, Anker, Materialien, jedes Teil benannt, jede Verbindung gewählt, jede Annahme notiert
2. ModellierenSie, model.js schreibenddas Möbelstück als Funktion seiner Parameter: Boxen, Verbindungen, Schritte
3. Validieren + Paketnode "$SKILL_DIR/pack.mjs" ./my-pieceverweigert das Paket, wenn etwas kollidiert oder in der Luft schwebt; erstellt Schnittliste, Zeichnungen, Zuschnittpläne für Bretter und Platten, Holz-, Werkzeug- und Oberflächenliste, Anleitung (und manual.pdf, wenn Chromium vorhanden ist)
4. Seite bauennode "$SKILL_DIR/build.mjs" ./my-piecejoinery-out/dist/my-piece.html, offline, ~570 KB
5. Überprüfennode "$SKILL_DIR/capture.mjs" my-piece --stills stepsein Kontaktbogen jeder Ansicht und jedes Schrittes – lesen, korrigieren, wiederholen
6. Erneut paketierennode "$SKILL_DIR/pack.mjs" ./my-pieceAnleitung und PDF enthalten jetzt die Schrittbilder

Beginnen Sie, indem Sie das dem Möbelstück am nächsten kommende Beispiel kopieren. Jedes Beispiel enthält alle Dateien, die ein Projekt benötigt: spec.json, model.js, main.js. Ein Projekt lebt normalerweise im eigenen Ordner des Benutzers, nicht in SKILL_DIR: Nach dem Kopieren ändern Sie die beiden ../../kit/-Importe (in model.js und main.js) in den absoluten Pfad $SKILL_DIR/kit/.

BeispielKopieren fürZeigt
parsons-tableeinen einfachen Tisch, Schreibtisch, Bankdas Minimum: Beine, Zargen, Platte, Zapfenverbindung, Tischplattenhalter. 64 Zeilen
walnut-racetrack-tablerunde, ovale oder konische TeileroundedRect- / circle-Profile, konische runde Beine, Zapfen kurz genug, um sich im Bein nicht zu behindern
walnut-display-cabinetein Korpusmöbel mit Rundungen oder Glasgebogene Schichtholzecken (quarterRing, stock.layers), Glastüren auf Klappscharnieren, Regalträger, eine gefalzte Rückwand, ein Sockel
walnut-entry-unitEinbaumöbel, Kleiderschränke, Küchenzeilenmehrere Korpusse, Rahmen-Türen, Schubladen auf Auszügen, schwebende Böden, lackierte MDF neben Furnier, LED- und Hakenbeschläge
walnut-hallway-unitein gemischtes Stahl-Holz-Möbelein geschweißter Stahlrahmen, der Holzkästen hält, Türen mit Rohrflechtpaneelen, eine offene Nische um einen Elektrokasten herum

Schritt 1: Das Foto ehrlich lesen

Ein einzelnes Foto gibt keinen Maßstab und keine verborgenen Strukturen. Diese Fähigkeit ist Designinterpretation, nicht Photogrammetrie. Bevor Sie Geometrie schreiben:

  1. Anker ermitteln. Fragen Sie nach ein bis drei echten Maßen (Gesamt-L×B×H oder einem bekannten Wert wie „die Platte ist 180 cm lang"). Wenn die Person keine Angaben machen kann, verwenden Sie die ergonomischen Standards aus kit/validate.js (Esstisch 750 H, Sitz 450 H) und sagen Sie dies. Jedes andere Maß ist eine Proportion, die Sie vom Foto in Verbindung mit dem Anker ablesen.
  2. Den Typ benennen. dining-table, chair, bookshelf … dies legt die ergonomischen Prüfungen und die typische Bauweise fest.
  3. Auflisten, was Sie sehen und was nicht. Beine, Platte, sichtbare Böden sind visible. Zargen unter einer dicken Platte, Rückwände, Querverstrebungen, Schubladenauszüge, Eckwinkel sind inferred – markieren Sie sie mit inferred: true am Teil, damit sie in jeder Ausgabe gekennzeichnet sind. Der Handwerker wird sie überschreiben; er muss wissen, welche Ihre Schätzungen sind.
  4. Die Verbindungstechnik aus der Bibliothek wählen (templates/joinery-library.md), abgestimmt auf Typ × Material × Werkstatt. Fragen Sie, welche Werkstatt der Handwerker hat, falls nicht offensichtlich (shop: hand, cabinet, cnc); dies wählt auch die Werkzeugliste. Standardmäßig eine Tischlerei: Zapfenverbindungen für Beine/Zargen, Nuten für Böden, Dübel oder Dominos für Paneele, Taschenlochschrauben nur, wo versteckt. Schreiben Sie die Wahl und den Grund in spec.source.assumptions.
  5. Material und Oberfläche ablesen. Holzart aus Farbe und Maserung, Dicke aus der Proportion der Kante, Kantenbehandlung (Rundung / Fase / scharf) aus Glanzlichtern. Die Dicke muss einer handelsüblichen Stärke entsprechen (STOCK_T in kit/validate.js) – 40, nicht 38,7. Setzen Sie finish nach dem Glanzgrad: eine offene, matte Oberfläche ist hardwax-oil (Standard) oder oil, ein gleichmäßiger seidenmatter Film ist lacquer. Lackierte und Metallteile folgen ihrem Material.

Schreiben Sie all dies in spec.json unter Verwendung von templates/spec.schema.json. Die Spezifikation ist für Menschen: Der Handwerker liest source.assumptions vor allem anderen.

Schritt 2: Das Modell bauen

model.js exportiert piece = definePiece({name, type, shop, finish, params, source, materials, build}). build(P) gibt {parts, joints, steps, hardware} zurück. Das Beispiel hat 70 Zeilen; ein Stuhl etwa 120.

Teile sind achsenausgerichtete Boxen in ihrer zusammengebauten Position: box(id, name, [sx, sy, sz], [x, y, z], {grain, material, edge, explode, inferred, note}). x ist die Länge, y ist oben mit dem Boden bei 0, z ist die Tiefe. grain ist die Achse, entlang der das Holz verläuft – es bestimmt die Länge des Zuschnitts in der Schnittliste und die Ringdarstellung im Render. Teile mit demselben Zuschnitt erhalten denselben name und werden in einer Zeile der Schnittliste zusammengefasst; id bleibt eindeutig.

Gebogene und abgerundete Teile behalten eine Begrenzungsbox für size/at und fügen profile: {axis, path, note} hinzu: die tatsächliche Kontur über axis, zentriert auf der Box (quarterRing(R, t, [su, sv]) für eine gebogene Ecke, roundedRect(w, h, radii) für abgerundetes Glas, eine Rückwand oder eine Racetrack-Platte, circle(d) für ein rundes Bein; profile.taper: {to, end} verjüngt es zu einem Ende hin). Es wird extrudiert dargestellt, anhand seiner Kontur validiert und als Kontur gezeichnet. Wenn die Box nicht der Rohling ist (z. B. eine gebogene Schichtholzlamelle), fügen Sie stock: {L, W, T, layers, layerT} hinzu – die Schnittliste und die Einkaufsliste verwenden dann diese Werte. Ein in zwei Richtungen gebogenes Teil (eine geschnitzte Stuhllehne, ein komplexer Rücken) hat noch keinen Körpertyp: informieren Sie die Person, modellieren Sie die nächstgelegene gerade Extrusion und vermerken Sie dies in der note.

Beschläge sind gekaufte Metallteile, die auf einem Teil eingezeichnet, aber nicht zugeschnitten werden: fittings: [{kind, size, at, material, axis, dir, holes: {n, d, cc, axis}}] mit at relativ zur Mitte des Teils. Griffe, Haken und LED-Profile werden dargestellt; ihre Schraublöcher erscheinen auf der Zeichnung des Teils. Listen Sie sie auch unter hardware auf.

Farben pro Stück: Ein Eintrag in der materials-Map kann base, dark, ring, streak, rough, clearcoat, env enthalten, um ein Material aus dem Kit an das Foto anzupassen, ohne andere Teile zu ändern. Dunkle geölte Hölzer auf einer großen flachen Platte benötigen rough ≈ 0,9, da sonst das Licht der Hauptlichtquelle bei der Berechnung des Glanzgrades ausbleicht; vergleichen Sie dazu Zahlen aus dem Foto und dem Render, keine Eindrücke.

Verbindungen verbinden zwei Teil-IDs: {a, b, type}, wobei a den Zapfen/Schraube trägt und b sie aufnimmt. Typen: mortise-tenon (ZapfenLänge, ZapfenDicke, Schulter, Gehrung), dowel (Anzahl, d, Länge), dado (Tiefe), rebate (Fläche, Tiefe: eine Rückwand in einer Falz entlang der Kante von b), shelf-pin (Anzahl, d, Länge, Einlass: ein Boden auf Stiften in b), hinge (Fläche, at: [Welt-y…], Cup: 35, um den Topf in a zu bohren: eine Tür, die +z zugewandt ist, an b angeschlagen), groove (Breite, Tiefe: eine Füllung oder ein Schubladenboden, der in der Kante oder Fläche von b schwimmt), runner (ein Schubladenkasten auf seitlich montierten Auszügen in b), weld (Stahl an Stahl), pocket-screw, button, figure-8, screw, glue. shelf-pin und hinge erlauben die wenigen mm Spielraum, die die Beschläge überbrücken; jedes Teil muss mit dem Rest verbunden sein, sonst verweigert die Validierung. applyJoinery schreibt die passenden Merkmale auf beide Bauteile: Der Zapfen verlängert das Rohmaterial in der Schnittliste, das Zapfenloch erscheint auf der Zeichnung des Beins mit Fläche und Position, und beides wird gerendert. Eine Verbindung teilt der Validierung auch mit, dass diese beiden Körper sich berühren dürfen.

Schritte sind die Anleitung: {title, parts: [ids], note, check, view}. Jedes Teil muss in genau einem Schritt vorkommen. Ordnen Sie sie so, wie ein Handwerker vorgehen würde: zuerst Unterbaugruppen (Endrahmen, Schubladenkästen), dann was sie verbindet, dann was oben aufliegt, wobei das Möbelstück auf dem Kopf steht, wenn das die übliche Arbeitsweise ist. view setzt die Kamera für diesen Schritt auf der Seite und in der Anleitung.

Parameter. Alles ist eine Zahl in P. Ändern Sie L und die Zargen, Zapfen, Tischplattenhalter-Abstände und die Schnittliste passen sich an. Das ist der Punkt: Dasselbe model.js fertigt die 1600er und die 2200er Version.

Regeln, die entscheiden, ob es gebaut werden kann

  1. Vom Foto ausgehen, niemals aus der Vorstellung. Bauen Sie das Modell gegen das Foto und vergleichen Sie die Renderings nebeneinander: Silhouette, Bein-zu-Platte-Verhältnis, Überstand, wo der Schlagschatten der Zarge fällt. Ein aus „einer schönen Eichentafel“ erfundenes Stück wirkt generisch; derselbe Code baut das reale Stück genau nach, wenn er etwas hat, das er abgleichen kann.
  2. Echtes Holz. Die Dicke ist eine handelsübliche Stärke. Nichts breiter als 200 mm ist ein Brett – pack.mjs macht daraus eine Verleimung aus Streifen und gibt dies an. Nichts dicker als 50 mm ist ein Brett – es wird zu einer Schichtholzlamelle. Die Maserung verläuft entlang der Länge jedes Stücks, sonst warnt die Validierung vor Kurzfasern.
  3. Jede Verbindung ist eine echte Verbindung. Zwei Teile dürfen nur Volumen teilen, wenn eine deklarierte Verbindung vorliegt. Zapfen, die sich in einem Bein treffen, müssen mitred: true sein oder verkürzt werden; die Validierung prüft die Kollision. Eine breite massive Platte muss mit Tischplattenhaltern, Figur-8-Beschlägen oder Langlöchern gehalten werden – niemals starr verleimt – und die Validierung warnt, wenn dies der Fall ist.
  4. Kollisionen mit einer Zahl beheben. Wenn die Validierung meldet, dass ein Teil ein anderes durchdringt, ändern Sie einen Wert in P oder in build. Verstecken Sie es niemals mit der Kamera.
  5. Die Annahme notieren, nicht nur das Teil. Eine Zarge, die das Foto nicht gezeigt hat, ist inferred: true mit einer note. Das erste Feld der Anleitung listet alle Annahmen auf.
  6. Eine Zahl, eine Quelle. Die Schnittliste, die Zeichnung, das HUD auf der Seite und die Anleitung lesen alle stockOf(part). Wenn eine Zahl falsch aussieht, korrigieren Sie das Modell, nicht die Ausgabe.

Regeln für die Live-Seite

  • Die Seite ist eine einzige offline HTML-Datei unter 1 MB (three.js eingebunden). Große Möbel mit vielen Teilen bleiben schnell, da jedes Teil eine einzelne abgerundete Box ist und das Holz ein Shader, keine Textur.
  • Lichtstudio: warmes Hauptlicht, kühles Fülllicht, weicher Bodenschatten. Der Holzshader zeichnet flachgesägtes Ringmuster entlang der grain-Achse und Hirnholz an den Enden automatisch. Halten Sie roughness ≥ 0,45; glänzendes Holz auf hellem Grund wirkt wie Plastik.
  • Nach 20 Sekunden ohne Interaktion startet die Seite eine automatische Vorführung: Explodieren, Schritt für Schritt, Unteransicht mit Röntgenblick. Jede Eingabe gibt die Steuerung zurück.
  • Der URL-Status steuert die Aufnahme: ?step=2, ?explode=1, ?iso=leg-fl, ?view=under&xray=1, ?panel=0. Mit einem dieser Parameter wird die Seite sofort auf die entsprechende Ansicht gesetzt, anstatt zu animieren, damit ein Standbild bei 5 fps identisch zu einem bei 60 fps ist.

Überprüfungs-Schleife

Sie können die Seite nicht ansehen; Sie können sich Standbilder ansehen. Melden Sie ein Projekt niemals als fertig, ohne ein Blatt des aktuellen Baus gelesen zu haben.

  1. node "$SKILL_DIR/capture.mjs" <name> --stills steps → joinery-out/<name>-sheet.png: zusammengebaut, explodiert, Vorderansicht, Unteransicht mit Röntgenblick, eine Kachel pro Schritt.
  2. Lesen Sie jede Kachel anhand der Checkliste. Legen Sie das Referenzfoto neben die Kacheln front und assembled.
  3. Für ein einzelnes Teil isoliert --stills parts jedes; für einen bestimmten Zustand: --still "step=3&view=under".
  4. Korrigieren, neu bauen, zurück zu Schritt 1. Stoppen, wenn ein Durchgang nichts findet.
  5. Öffnen Sie joinery-out/<name>/manual.html auf dieselbe Weise und lesen Sie es wie der Handwerker.

Checkliste:

  • Proportion. Gegen das Foto: Beindicke vs. Länge, Plattendicke vs. Länge, Überstand, Höhe der Zargenlinie. Innerhalb von 5 % oder Parameter ändern.
  • Verbindungen. Zapfenlöcher erscheinen auf den Flächen, an denen die Zargen anliegen; Zapfen sind in der Explosionsansicht und im Röntgenblick sichtbar; nichts schwebt in der Luft in der Explosionsansicht (ein Teil ohne Verbindung hat keinen sinnvollen Explosionsvektor).
  • Schritte. Jeder Schritt fügt etwas Sichtbares hinzu; die Kamera zeigt die Teile, die hinzugefügt werden; bereits platzierte Teile sind darunter sichtbar. Schritt 1 ist niemals die Platte.
  • Zeichnungen. Jedes Zapfenloch, jede Nut und jedes Bohrloch auf einer Zeichnung nennt seine Fläche und den Abstand vom Ende. Längen in der Schnittliste, die Zapfen enthalten, sind entsprechend gekennzeichnet.
  • Rohmaterial. Die Materialliste enthält kein Brett breiter als 200 oder dicker als 50; Verleimungen und Schichtholzlamellen werden aufgeführt. Jedes Teil liegt in den Zuschnittplänen auf einem Brett oder einer Platte.
  • Werkzeuge und Oberfläche. tools.md listet die Werkzeuge, die die Werkstatt des Handwerkers verwenden würde, und die Spannlängen sind für die größte Verleimung sinnvoll. Lackierte, furnierte und Metallteile erhalten jeweils ihre eigene Oberflächenbehandlung.
  • Render. Nichts innerhalb von 60 Pixeln vom Rand, das Bedienfeld bedeckt nie das Möbelstück, fast weiße Hölzer (Ahorn, Esche) haben eine sichtbare Kante gegen den hellen Hintergrund.

Materialien

kit/stage.js → MATERIALS: weißeiche, roteiche, walnuss, ahorn, esche, buche, kiefer, kirsche, birken-sperrholz, mdf, stahl, messing. Fügen Sie eine Holzart als Basis-/Dunkelfarben sowie Ring- und Streifenstärke hinzu. Ebenfalls enthalten: walnuss-mdf, walnuss-bendply (furnierte Platte), mdf-schwarz, glas (transparent, durch seine Kanten gezeichnet, im Paket maßgenau zugeschnitten bestellt, nicht aus Brettern geschnitten). Die materials-Map in definePiece benennt sie für die Schnittliste („Weißeiche, massiv").

Verwandte Skills