Community图像github.com

Joinery – 家具照片转可制作3D模型

将家具照片转化为木工可制作的3D模型,包含真实木料尺寸、接合方式、交互式离线HTML页面(分解视图、X光透视、分步组装)以及全套制作包(下料清单、带标注的工程图、木材采购清单、五金件和组装说明书)。

Joinery – 家具照片转可制作3D模型 是什么?

Joinery 是一个面向AI Agent的技术技能,用于将一张家具照片(如桌子、椅子、长凳、架子、边柜、床、书桌)转化为一个可实际制作的3D模型。它并非摄影测量工具,而是设计解析工具:通过人为解读照片并添加尺寸锚点,生成包含所有部件名称、接合方式、材料假设的 `spec.json` 文件。然后编写 `model.js`,将每个部件定义为带有真实木纹方向和接合特征的边界框,并生成交互式HTML页面(Three.js 实现,离线可用)以及完整的制作包。 该技能支持多个平台(Claude Code、Cursor、Codex 等),要求 Node 20.10+,并可选择安装 Chromium 用于生成静态渲染图和PDF手册。其核心价值在于确保屏幕上的3D模型与纸质图纸、下料清单完全一致:所有尺寸、接合点、五金件都由同一个模型驱动。工作流程包括:解读照片 → 构建模型 → 验证碰撞和浮动部件 → 生成页面和制作包。验证规则严格:所有接合必须声明,实木厚度必须是可用规格,宽板必须拼板,厚板必须层压。此外,页面具有自动巡视功能(20秒无操作后自动展示分解、分步和X光视图),并支持通过URL参数控制静态捕捉。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/JoseChipanaTica/joinery/tree/HEAD

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Joinery – 家具照片转可制作3D模型 是做什么的?

一张照片,一个页面,一个制作包。访客可以看到组装好的家具,拖动滑块让它分解开来,一步步了解组装顺序,点击部件即可查看其规格尺寸。驱动部件运动的同一个模型也生成了下料清单、工程图和说明书,因此纸面上的任何内容都与屏幕上的完全一致。

SKILL_DIR 是本文件所在的文件夹。构建结果和制作包将输出到运行命令所在文件夹下的 ./joinery-out 目录。

首次运行

cd "$SKILL_DIR" && npm install

需要 Node 20.10+。如需生成静态渲染图和说明书图片,还需要 Chromium:npx playwright install chromium,或者将 CHROMIUM 环境变量指向任意 Chrome/Chromium 可执行文件(CHROMIUM=/usr/bin/google-chrome)。

工作流程

照片 + 锚点 ─► spec.json ─► model.js ─► 验证 ─► 页面 ─► 静态图片 ─► 制作包
步骤命令输出结果
1. 解读你,阅读照片spec.json:类型、锚点、材料、每个部件命名、每种接合方式选择、每条假设记录
2. 建模你,编写 model.js作为参数函数描述的家具:盒子、接合、步骤
3. 验证 + 打包node "$SKILL_DIR/pack.mjs" ./my-piece如有任何碰撞或悬空则拒绝打包;生成下料清单、工程图、板材切割图、木材与五金清单、说明书(有 Chromium 时还会生成 manual.pdf)
4. 构建页面node "$SKILL_DIR/build.mjs" ./my-piecejoinery-out/dist/my-piece.html,离线可用,约 570 KB
5. 审查node "$SKILL_DIR/capture.mjs" my-piece --stills steps包含所有视图和步骤的联系表——阅读、修复、重复
6. 再次打包node "$SKILL_DIR/pack.mjs" ./my-piece说明书和 PDF 现在包含步骤图片

从最接近待制作家具的示例开始复制。每个示例都包含家具所需的所有文件:spec.json、model.js、main.js。家具文件通常放在用户自己的文件夹中,而不是 SKILL_DIR 中:复制后,将 model.js 和 main.js 中的两个 ../../kit/ 导入路径改为绝对路径 $SKILL_DIR/kit/。

示例复制用于展示内容
parsons-table简单的桌子、书桌、长凳最小配置:桌腿、横撑、桌面、榫卯、纽扣件。64 行
walnut-racetrack-table圆形、椭圆形或锥形部件roundedRect / circle 轮廓、锥形圆腿、榫头足够短以避免在桌腿内互相干涉
walnut-display-cabinet带曲线或玻璃的箱体家具弯曲层压角(quarterRing、stock.layers)、夹钳铰链玻璃门、层板销、嵌槽背板、底座
walnut-entry-unit嵌入式家具、衣柜、厨房风格单元多个箱体、框架与嵌板门、滑轨抽屉、浮动层板、贴皮 MDF 与 veneer 搭配、LED 和挂钩五金
walnut-hallway-unit钢木混合家具焊接钢框架内嵌木盒、藤编面板门、绕过电箱的开放式凹槽

步骤 1:忠实解读照片

一张照片只能提供 无尺寸和隐藏结构。本技能是设计解读,而非摄影测量。在编写任何几何之前:

  1. 获取锚点。 询问一至三个实际尺寸(整体长 × 宽 × 高,或一个已知尺寸如“桌面 180 cm”)。如果对方无法提供,则使用 kit/validate.js 中的人体工学标准(餐桌 750 H,座椅 450 H)并注明。其他所有尺寸均为照片中读取的比例乘以锚点。
  2. 命名类型。 dining-table、chair、bookshelf……这将决定人体工学检查和典型构造。
  3. 列出可见和不可见部分。 桌腿、桌面、可见层板标记为 visible。厚桌面下的横撑、背板、拉档、抽屉滑轨、角块标记为 inferred —— 在部件上设置 inferred: true,以便在每个输出中标记。制作者可以覆盖它们;他们必须知道哪些是你推断的。
  4. 从库中选择接合方式(templates/joinery-library.md),根据类型 × 材料 × 车间选择。如果车间类型不明显,询问制作者有什么车间(shop:hand、cabinet、cnc);这也会影响工具列表。默认为木工车间:桌腿/横撑用榫卯、层板用槽接、面板用木榫或 Dominos、仅隐藏处用 pocket screws。将选择及其理由写入 spec.source.assumptions。
  5. 读取材料和涂装。 根据颜色和纹理判断树种,根据边缘比例判断厚度,根据高光判断边缘处理(圆角/斜角/直角)。厚度必须落在标准规格上(kit/validate.js 中的 STOCK_T)—— 40,而不是 38.7。根据光泽度设置 finish:开放式哑光表面为 hardwax-oil(默认)或 oil,均匀的半光薄膜为 lacquer。涂漆和金属部件遵循各自的材料。

将所有内容写入 spec.json,使用 templates/spec.schema.json。规格是给人看的:制作者在阅读其他任何内容之前先阅读 source.assumptions。

步骤 2:构建模型

model.js 导出 piece = definePiece({name, type, shop, finish, params, source, materials, build})。build(P) 返回 {parts, joints, steps, hardware}。示例约为 70 行;一把椅子约为 120 行。

部件 是在组装姿态下的轴对齐边界框:box(id, name, [sx, sy, sz], [x, y, z], {grain, material, edge, explode, inferred, note})。x 为长度,y 为高度(地板在 0 处),z 为深度。grain 是木材纹理方向——决定下料清单中的木料长度和渲染中的年轮图案。相同下料的部件使用相同的 name,合并为下料清单的一行;id 保持唯一。

曲线和圆角部件 保留 size/at 的边界框,并添加 profile: {axis, path, note}:沿 axis 的真实轮廓,以盒子为中心(用于弯曲角的 quarterRing(R, t, [su, sv])、圆角玻璃或跑道形桌面的 roundedRect(w, h, radii)、圆腿的 circle(d);profile.taper: {to, end} 向一端渐缩)。它渲染为挤出形状,按轮廓验证,并按轮廓绘制。当盒子不是实际木料时(如弯曲层压板),添加 stock: {L, W, T, layers, layerT},下料清单和采购清单将使用该信息。在两个方向弯曲的部件(如雕刻椅背、复合形状的靠背板)尚无实体类型:告知用户,建模为最接近的直线挤出件,并在其 note 中说明。

五金件 是绘制在部件上的成品硬件,而非切割件:fittings: [{kind, size, at, material, axis, dir, holes: {n, d, cc, axis}}],其中 at 相对于部件中心。拉手、挂钩和 LED 轮廓会渲染;其螺丝孔会出现在部件的工程图上。同时也在 hardware 中列出它们。

每件颜色: materials 映射中的条目可以携带 base、dark、ring、streak、rough、clearcoat、env 来调整套件材料以匹配照片,而不影响其他部件。大平面上的深色油性木材需要 rough ≈ 0.9,否则主光的光泽会使其变灰;请对比照片和渲染的数值,而非凭感觉。

接合 连接两个部件 id:{a, b, type},其中 a 携带榫头/螺丝,b 接收。类型:mortise-tenon(榫长、榫厚、肩宽、斜接)、dowel(数量、直径、长度)、dado(深度)、rebate(面、深度:背板嵌在 b 边缘的槽中)、shelf-pin(数量、直径、长度、缩进:层板通过销子放在 b 上)、hinge(面、at:[世界 y…]、cup:35 在 a 上钻孔:+z 方向的门挂在 b 上)、groove(宽度、深度:面板或抽屉底板浮在 b 的边缘或面内)、runner(抽屉盒在 b 上的侧装滑轨)、weld(钢连接)、pocket-screw、button、figure-8、screw、glue。shelf-pin 和 hinge 允许硬件桥接所需的几毫米间隙;每个部件必须连接到其余部件,否则验证会拒绝。applyJoinery 将匹配的特征写入两个构件:榫头会延长下料清单中的木料长度,榫眼会出现在桌腿工程图上,并带有其面和位置,两者都会渲染。接合还告诉 validate 这两个实体允许接触。

步骤 是说明书:{title, parts: [ids], note, check, view}。每个部件必须恰好出现在一个步骤中。按制作者的方式排列:先子组件(端架、抽屉盒),然后连接它们的东西,最后是放在上面的东西,如果操作方式是倒置则家具倒置。view 设置该步骤在页面和说明书中的摄像机位置。

参数。 所有内容都是 P 中的数字。更改 L,横撑、榫头、纽扣间距和下料清单都会随之变化。这就是关键:同一个 model.js 可以生成 1600 版本和 2200 版本。

决定可建造性的规则

  1. 从照片出发,而非想象。 对照照片构建并并排比较渲染图:轮廓、腿与桌面比例、悬挑、横撑阴影线位置。从“一张漂亮的橡木桌子”想象出来的家具会显得通用;当有参照物时,同一段代码可以紧密重建真实家具。
  2. 真实木料。 厚度为标准规格。宽度超过 200 mm 的部件不能是一块整板——pack.mjs 会将其转化为拼板并注明。厚度超过 50 mm 的部件不能是一块整板——会变成层压板。纹理沿每根木料长度方向,否则验证会警告短纹理。
  3. 每个接合都是真实接合。 两个部件只能通过声明的接合共享体积。在桌腿内部相遇的榫头必须 mitred: true 或缩短;验证会检查碰撞。宽实心桌面必须用纽扣件、figure-8 或长条孔固定——绝不能刚性胶合——验证会警告。
  4. 用数字修复碰撞。 当验证报告一个部件穿过另一个部件时,更改 P 或 build 中的值。绝不能用摄像机隐藏它。
  5. 写下假设,而不仅仅是部件。 照片中未显示的横撑应标记为 inferred: true 并添加 note。说明书的第一个框中列出所有假设。
  6. 一个数字,一个来源。 下料清单、工程图、页面上的 HUD 和说明书都读取 stockOf(part)。如果某个数字看起来不对,修复模型,而不是输出。

实时页面规则

  • 页面是一个离线 HTML 文件,小于 1 MB(内联 Three.js)。包含许多部件的大型家具也能保持快速,因为每个部件是一个圆角盒子,木材通过着色器实现,而非纹理。
  • 灯光工作室:暖色主光、冷色补光、柔和地面阴影。木材着色器沿 grain 自动绘制弦切纹理,并在端面显示端面纹理。保持 roughness ≥ 0.45;浅色地面上的光泽木材看起来像塑料。
  • 无操作 20 秒后,页面自动巡视:分解、分步、底部 X 光。任何输入都会交还控制权。
  • URL 状态驱动静态捕捉:?step=2、?explode=1、?iso=leg-fl、?view=under&xray=1、?panel=0。设置这些参数后,页面会直接跳转到状态而非动画,因此静态图片在 5 fps 和 60 fps 下相同。

审查循环

你无法查看页面,但可以查看静态图片。未经阅读当前构建的联系表,切勿报告家具已完成。

  1. node "$SKILL_DIR/capture.mjs" <name> --stills steps → joinery-out/<name>-sheet.png:组装图、分解图、正视图、底部 X 光图、每个步骤一张图。
  2. 对照检查清单阅读每张图。将参考照片放在 front 和 assembled 图旁边。
  3. 对于单个部件,--stills parts 可隔离每个部件;对于单个状态,--still "step=3&view=under"。
  4. 修复、重建、返回步骤 1。当一遍检查未发现问题时停止。
  5. 同样打开 joinery-out/<name>/manual.html,像制作者那样阅读。

检查清单:

  • 比例。 对照照片:腿粗与长度、顶部厚度与长度、悬挑、横撑线高度。误差在 5% 以内,否则修改参数。
  • 接合。 榫眼出现在横撑接触的面上;榫头在分解视图和 X 光中可见;分解视图中没有部件悬空(无接合的部件没有合理的分解矢量)。
  • 步骤。 每个步骤添加可见的内容;摄像机显示正在添加的部件;已放置的部件在下面可见。步骤 1 绝不能是桌面。
  • 工程图。 工程图上的每个榫眼、槽孔和孔洞都命名了其面和距端部的距离。包含榫头的下料清单长度需注明。
  • 木料。 木料清单中没有宽度超过 200 或厚度超过 50 的板材;拼板和层压板被列出。每个部件在切割图中位于一块板材或板料上。
  • 工具和涂装。 tools.md 列出制作者车间会用的工具,夹钳长度适用于最大的拼板。涂漆、贴皮和金属部件各有其涂装。
  • 渲染。 距离边缘不超过 60 像素,面板从不遮挡家具,近白色木材(枫木、白蜡木)在浅色背景下有可见的边缘。

材料

kit/stage.js → MATERIALS:白橡木、红橡木、胡桃木、枫木、白蜡木、山毛榉、松木、樱桃木、桦木胶合板、MDF、钢、黄铜。通过基础/深色颜色加上年轮和纹理强度来添加树种。还包括:胡桃木-MDF、胡桃木-弯曲胶合板(贴皮板材)、MDF 黑色、玻璃(透明,由边缘绘制,在制作包中按尺寸订购而非从板材上切割)。definePiece 中的 materials 映射为下料清单命名(例如“白橡木,实木”)。

相关技能