CommunityImagegithub.com

Menuiserie

Transforme une photo de meuble (table, chaise, banc, étagère, buffet, lit, bureau) en un modèle 3D constructible qu'un ébéniste peut réaliser — chaque pièce en stock réel avec des assemblages réels, une page HTML interactive hors ligne avec vue éclatée, radiographie et assemblage pas à pas, ainsi que le pack de fabrication : liste de coupe, plans cotés, bois à acheter, quincaillerie et manuel d'assemblage illustré.

Qu'est-ce que Menuiserie ?

Ce skill transforme une simple photo de meuble en un plan de construction complet et prêt à l'emploi pour un ébéniste. Il ne s'agit pas de photogrammétrie, mais d'une interprétation basée sur des dimensions réelles fournies par l'utilisateur (ancres) et des proportions déduites de la photo. Le résultat est un modèle 3D paramétrique où chaque élément est défini avec des dimensions de stock réelles, des assemblages précis (tenon-mortaise, queue d'aronde, etc.) et des matériaux identifiés. Le skill génère une page HTML interactive hors ligne qui permet de visualiser le meuble assemblé, de l'exploser, de voir les assemblages en transparence, et de suivre un tutoriel pas à pas. Il produit également un pack de fabrication complet incluant une liste de coupe, des plans cotés, des schémas de débit, la quincaillerie nécessaire et un manuel d'assemblage illustré. Tout est cohérent : modifier une dimension dans le modèle met à jour automatiquement les plans, la liste de coupe et le manuel. Le skill est conçu pour fonctionner avec Node.js et peut être utilisé avec divers agents d'IA (Claude Code, Cursor, Codex) pour la conception de meubles sur mesure.

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

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Menuiserie ?

Une pièce, une page, un pack. Le visiteur voit la pièce assemblée, fait glisser un curseur et elle se désassemble, parcourt les étapes de son assemblage, clique sur une pièce et lit sa dimension de stock. Le même modèle qui déplace les pièces écrit la liste de coupe, les dessins et le manuel, de sorte qu'aucun élément papier ne peut être en contradiction avec ce qui est à l'écran.

SKILL_DIR est le dossier où se trouve ce fichier. Les constructions et le pack vont dans ./joinery-out du dossier à partir duquel vous exécutez.

Première exécution

cd "$SKILL_DIR" && npm install

Node 20.10+. Pour les aperçus et les images du manuel, vous avez besoin de Chromium : npx playwright install chromium, ou pointez CHROMIUM vers un binaire Chrome/Chromium (CHROMIUM=/usr/bin/google-chrome).

Le pipeline

photo + ancres ─► spec.json ─► model.js ─► valider ─► page ─► aperçus ─► pack
ÉtapeCommandeCe que vous obtenez
1. Interprétervous, en lisant la photospec.json : type, ancres, matériaux, chaque pièce nommée, chaque assemblage choisi, chaque hypothèse écrite
2. Modéliservous, en écrivant model.jsla pièce en fonction de ses paramètres : boîtes, assemblages, étapes
3. Valider + empaqueternode "$SKILL_DIR/pack.mjs" ./ma-piecerefuse d'empaqueter si quelque chose entre en collision ou flotte ; écrit la liste de coupe, les dessins, les schémas de débit de planches et de panneaux, le stock, les outils et la finition, le manuel (et manual.pdf quand Chromium est présent)
4. Construire la pagenode "$SKILL_DIR/build.mjs" ./ma-piecejoinery-out/dist/ma-piece.html, hors ligne, ~570 Ko
5. Révisernode "$SKILL_DIR/capture.mjs" ma-piece --stills stepsune planche-contact de chaque vue et étape — lisez-la, corrigez, répétez
6. Empaqueter à nouveaunode "$SKILL_DIR/pack.mjs" ./ma-piecele manuel et le PDF intègrent désormais les images des étapes

Commencez par copier l'exemple le plus proche de la pièce. Chacun contient tous les fichiers nécessaires à une pièce : spec.json, model.js, main.js. Une pièce se trouve généralement dans son propre dossier, pas dans SKILL_DIR : après copie, modifiez les deux imports ../../kit/ (dans model.js et main.js) pour utiliser le chemin absolu $SKILL_DIR/kit/.

ExempleCopiez-le pourMontre
parsons-tableune table simple, un bureau, un bancle minimum : pieds, ceintures, plateau, tenon-mortaise, boutons. 64 lignes
walnut-racetrack-tabledes pièces rondes, ovales ou effiléesles profils roundedRect / circle, pieds ronds effilés, tenons assez courts pour ne pas se croiser dans le pied
walnut-display-cabinetun meuble à caisson avec des courbes ou du verrecoins en lamellé-cintré (quarterRing, stock.layers), portes vitrées sur charnières à pince, taquets d'étagère, fond embrevé, plinthe
walnut-entry-unitdes rangements encastrés, des armoires, des unités de style cuisineplusieurs caissons, portes à cadre et panneau, tiroirs sur coulisses, étagères flottantes, MDF peint à côté de placage, éclairages LED et crochets
walnut-hallway-unitune pièce mixte acier et boisun cadre en acier soudé contenant des caissons en bois, portes à panneaux de canne, une niche ouverte autour d'un tableau électrique

Étape 1 : lire la photo honnêtement

Une seule photo ne donne ni échelle, ni structure cachée. Ce skill est une interprétation de design, pas de la photogrammétrie. Avant d'écrire une quelconque géométrie :

  1. Obtenez des ancres. Demandez une à trois dimensions réelles (L × P × H globales, ou une dimension connue comme « le plateau fait 180 cm »). Si la personne ne peut en donner aucune, utilisez les standards ergonomiques dans kit/validate.js (table à manger 750 H, assise 450 H) et dites-le. Chaque autre dimension est une proportion lue sur la photo multipliée par l'ancre.
  2. Nommez le type. dining-table, chair, bookshelf… cela choisit les vérifications ergonomiques et la construction typique.
  3. Listez ce que vous voyez et ce que vous ne voyez pas. Les pieds, le plateau, les étagères visibles sont visible. Les ceintures sous un plateau épais, les panneaux arrière, les traverses, les coulisses de tiroirs, les blocs d'angle sont inferred — marquez-les avec inferred: true sur la pièce afin qu'ils soient signalés dans chaque sortie. Le fabricant pourra les modifier ; il doit savoir lesquels sont les vôtres.
  4. Choisissez les assemblages dans la bibliothèque (templates/joinery-library.md), en fonction du type × matériau × atelier. Demandez quel atelier le fabricant possède si ce n'est pas évident (shop : hand, cabinet, cnc) ; cela détermine également la liste d'outils. Par défaut, un atelier d'ébénisterie : tenon-mortaise pour les pieds/ceintures, rainures pour les étagères, tourillons ou Dominos pour les panneaux, vis à bois cachées uniquement là où c'est nécessaire. Écrivez le choix et la raison dans spec.source.assumptions.
  5. Lisez le matériau et la finition. Essence à partir de la couleur et du fil, épaisseur à partir de la proportion du bord, traitement du bord (congé / chanfrein / vif) à partir des reflets. L'épaisseur doit correspondre à une dimension de stock (STOCK_T dans kit/validate.js) — 40, pas 38,7. Définissez finish à partir du brillant : une surface mate et ouverte correspond à hardwax-oil (par défaut) ou oil, un film satiné uniforme correspond à lacquer. Les parties peintes et métalliques suivent leur matériau.

Écrivez tout cela dans spec.json en utilisant templates/spec.schema.json. Le spec est destiné aux humains : le fabricant lit source.assumptions avant toute autre chose.

Étape 2 : construire le modèle

model.js exporte piece = definePiece({name, type, shop, finish, params, source, materials, build}). build(P) retourne {parts, joints, steps, hardware}. L'exemple fait 70 lignes ; une chaise en fait environ 120.

Les pièces sont des boîtes alignées sur les axes dans leur pose assemblée : box(id, name, [sx, sy, sz], [x, y, z], {grain, material, edge, explode, inferred, note}). x est la longueur, y est la hauteur avec le sol à 0, z est la profondeur. grain est l'axe le long duquel le bois est filé — il détermine la longueur de stock dans la liste de coupe et le motif des cernes dans le rendu. Les pièces qui sont identiques à la coupe reçoivent le même name et se fusionnent en une seule ligne de liste de coupe ; id reste unique.

Les pièces courbes et arrondies conservent une boîte englobante pour size/at et ajoutent profile: {axis, path, note} : le contour réel à travers axis, centré sur la boîte (quarterRing(R, t, [su, sv]) pour un coin cintré, roundedRect(w, h, radii) pour du verre arrondi, un dossier ou un plateau de forme ovale, circle(d) pour un pied rond ; profile.taper: {to, end} l'effile vers une extrémité). Il est rendu par extrusion, validé sur son contour et dessiné comme son contour. Lorsque la boîte n'est pas le stock (un lamellé-cintré), ajoutez stock: {L, W, T, layers, layerT} et la liste de coupe et la liste d'achats l'utilisent. Une pièce courbée dans deux directions (un dossier de chaise sculpté, une traverse composée) n'a pas encore de type de corps : dites-le à la personne, modélisez l'extrusion droite la plus proche et indiquez-le dans sa note.

Les accessoires sont de la quincaillerie achetée, dessinée sur une pièce, non coupée : fittings: [{kind, size, at, material, axis, dir, holes: {n, d, cc, axis}}] avec at relatif au centre de la pièce. Les poignées, crochets et profils LED sont rendus ; leurs trous de vis apparaissent sur le dessin de la pièce. Listez-les aussi dans hardware.

Couleurs par pièce : une entrée dans la map materials peut contenir base, dark, ring, streak, rough, clearcoat, env pour ajuster un matériau du kit à la photo sans modifier les autres pièces. Les bois foncés huilés sur un grand plateau plat ont besoin de rough ≈ 0,9 sinon la lumière principale les grise ; échantillonnez la photo et le rendu et comparez les chiffres, pas les impressions.

Les assemblages connectent deux identifiants de pièces : {a, b, type} où a porte le tenon/la vis et b le reçoit. Types : mortise-tenon (tenonLen, tenonT, shoulder, mitred), dowel (count, d, len), dado (depth), rebate (face, depth: un fond dans une feuillure le long du bord de b), shelf-pin (count, d, len, inset: une étagère sur des taquets dans b), hinge (face, at: [y monde…], cup: 35 pour percer l'embouti dans a: une porte faisant face à +z suspendue à b), groove (width, depth: un panneau ou un fond de tiroir flottant dans le bord ou la face de b), runner (une boîte à tiroir sur des coulisses montées sur les côtés dans b), weld (acier sur acier), pocket-screw, button, figure-8, screw, glue. shelf-pin et hinge permettent les quelques mm de jeu que la quincaillerie comble ; chaque pièce doit être assemblée au reste ou la validation refuse. applyJoinery écrit les caractéristiques correspondantes sur les deux membres : le tenon allonge le stock dans la liste de coupe, la mortaise apparaît sur le dessin du pied avec sa face et sa position, et les deux sont rendus. Un assemblage indique également à validate que ces deux corps sont autorisés à se toucher.

Les étapes sont le manuel : {title, parts: [ids], note, check, view}. Chaque pièce doit apparaître dans exactement une étape. Ordonnez-les comme le ferait un fabricant : sous-ensembles d'abord (cadres d'extrémité, boîtes de tiroir), puis ce qui les assemble, puis ce qui se pose dessus, avec la pièce à l'envers lorsque c'est ainsi qu'elle est réalisée. view définit la caméra pour cette étape sur la page et dans le manuel.

Paramètres. Tout est un nombre dans P. Modifiez L et les ceintures, les tenons, l'espacement des boutons et la liste de coupe suivent. C'est là l'intérêt : le même model.js produit la version 1600 et la version 2200.

Règles qui décident si la pièce peut être construite

  1. Partez de la photo, jamais de l'imagination. Construisez par rapport à elle et comparez les rendus côte à côte : silhouette, rapport pied/plateau, débord, où tombe la ligne d'ombre de la ceinture. Une pièce inventée à partir d'« une jolie table en chêne » devient générique ; le même code reconstruit fidèlement la vraie lorsqu'il a quelque chose à égaler.
  2. Du stock réel. L'épaisseur est une dimension de stock. Rien de plus large que 200 mm n'est une seule planche — pack.mjs la transforme en un collage de lames et le mentionne. Rien de plus épais que 50 mm n'est une seule planche — cela devient un lamellé-collé. Le fil du bois court sur la longueur de chaque pièce, ou la validation avertit d'un fil court.
  3. Chaque assemblage est un vrai assemblage. Deux pièces ne peuvent partager du volume qu'à travers un assemblage déclaré. Les tenons qui se rencontrent à l'intérieur d'un pied doivent être mitred: true ou raccourcis ; la validation vérifie la collision. Un plateau massif large doit être maintenu avec des boutons, des figure-8 ou des trous oblongs — jamais collé rigidement — et la validation avertit si c'est le cas.
  4. Résolvez les collisions avec un nombre. Lorsque la validation signale qu'une pièce en traverse une autre, modifiez une valeur dans P ou dans build. Ne la masquez jamais avec la caméra.
  5. Écrivez l'hypothèse, pas seulement la pièce. Une ceinture que la photo ne montrait pas est marquée inferred: true avec une note. La première boîte du manuel liste chaque hypothèse.
  6. Un nombre, une source. La liste de coupe, le dessin, le HUD sur la page et le manuel lisent tous stockOf(part). Si un nombre semble erroné, corrigez le modèle, pas la sortie.

Règles de la page en direct

  • La page est un fichier HTML hors ligne de moins de 1 Mo (three.js intégré). Les grandes pièces avec de nombreuses pièces restent rapides car chaque pièce est une boîte arrondie et le bois est un shader, pas une texture.
  • Studio lumineux, lumière chaude principale, lumière froide de remplissage, ombre douce au sol. Le shader bois dessine le fil plat le long de grain et le fil de bout aux extrémités automatiquement. Gardez roughness ≥ 0.45 ; un bois brillant sur un fond pâle donne l'impression de plastique.
  • Laissée seule pendant 20 s, la page fait une visite automatique : éclater, parcourir les étapes, radiographie en dessous. Toute interaction rend le contrôle à l'utilisateur.
  • L'état de l'URL pilote la capture : ?step=2, ?explode=1, ?iso=leg-fl, ?view=under&xray=1, ?panel=0. Avec l'un de ces éléments, la page prend un instantané au lieu d'animer, de sorte qu'une image fixe soit la même à 5 ips qu'à 60.

Boucle de révision

Vous ne pouvez pas regarder la page ; vous pouvez regarder les aperçus. Ne signalez jamais une pièce comme terminée sans avoir lu une planche de la construction actuelle.

  1. node "$SKILL_DIR/capture.mjs" <nom> --stills steps → joinery-out/<nom>-sheet.png : assemblé, éclaté, face, radiographie en dessous, une vignette par étape.
  2. Lisez chaque vignette par rapport à la liste de contrôle. Mettez la photo de référence à côté des vignettes face et assemblé.
  3. Pour une pièce, --stills parts l'isole ; pour un état, --still "step=3&view=under".
  4. Corrigez, reconstruisez, revenez à 1. Arrêtez-vous lorsqu'un passage ne trouve rien.
  5. Ouvrez joinery-out/<nom>/manual.html de la même manière et lisez-le comme le ferait le fabricant.

Liste de contrôle :

  • Proportion. Par rapport à la photo : épaisseur du pied vs longueur, épaisseur du plateau vs longueur, débord, hauteur de la ligne de ceinture. À moins de 5 % ou modifiez un paramètre.
  • Assemblages. Les mortaises apparaissent sur les faces que les ceintures rencontrent ; les tenons sont visibles dans la vue éclatée et à la radiographie ; rien ne flotte en l'air dans la vue éclatée (une pièce sans assemblage n'a pas de vecteur d'éclatement qui a du sens).
  • Étapes. Chaque étape ajoute quelque chose que vous pouvez voir ; la caméra montre les pièces en cours d'ajout ; les pièces déjà placées sont visibles en dessous. L'étape 1 n'est jamais le plateau.
  • Dessins. Chaque mortaise, rainure et trou sur un dessin nomme sa face et sa distance par rapport à l'extrémité. Les longueurs de la liste de coupe qui incluent des tenons le mentionnent.
  • Stock. La liste de stock n'a pas de planche plus large que 200 ou plus épaisse que 50 ; les collages et lamellés-collés sont listés. Chaque pièce repose sur une planche ou un panneau dans les schémas de débit.
  • Outils et finition. tools.md liste ce que l'atelier du fabricant utiliserait, et les longueurs de serre-joints ont du sens pour le plus grand collage. Les pièces peintes, plaquées et métalliques reçoivent chacune leur propre finition.
  • Rendu. Rien à moins de 60 px d'un bord, le panneau ne recouvre jamais la pièce, les bois clairs (érable, frêne) ont un bord visible par rapport au fond pâle.

Matériaux

kit/stage.js → MATERIALS : chêne blanc, chêne rouge, noyer, érable, frêne, hêtre, pin, cerisier, contreplaqué bouleau, MDF, acier, laiton. Ajoutez une essence sous forme de couleurs de base/foncé plus la force des cernes et des veines. Également : noyer-MDF, noyer-bendply (feuille plaquée), MDF noir, verre (transparent, dessiné par ses bords, commandé sur mesure dans le pack plutôt que découpé dans des planches). La map materials dans definePiece les nomme pour la liste de coupe (« Chêne blanc, massif »).

Skills associés