mcpField
P
parametric-3d-printing

parametric-3d-printing

github.com/flowful-ai设计与 UI703230 次安装3 天前更新
代码仓库

关于 parametric-3d-printing

这是一个基于 CadQuery 的技能,用于创建参数化 3D 打印模型并导出 STL。它涵盖需求收集、尺寸调研、分阶段预览与反馈,以及打印建议。

主要功能

  1. 01使用 CadQuery 参数化建模
  2. 02导出 STL 并渲染预览
  3. 03分阶段设计并收集反馈
  4. 04尺寸调研与可打印性检查

适用场景

  1. 01按实测尺寸设计组件外壳
  2. 02最终导出前迭代模型
  3. 03准备 FDM 打印模型

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/flowful-ai/cad-skill --skill parametric-3d-printing

安装后在 Claude Code 中输入/parametric-3d-printing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
outline_from_scan.py
design-review.md
preview.py
LICENSE
.gitignore
mesh_io.py
gridfinity.py
stl_to_3mf.py
requirements.txt
run_cadquery_model.py
examples/
gridfinity_d110_bin.py
mx_master3_bin_3x3.py
tests/
conftest.py
test_mesh_io.py
test_run_wrapper.py
test_stl_to_3mf.py
test_gridfinity.py

详细介绍

使用 CadQuery 进行参数化 3D 打印

概述

此技能使用 CadQuery(Python)生成参数化 3D 模型,并将其导出为可直接切片的 STL 文件。CadQuery 是首选方案,因为它可通过 pip 安装,拥有符合 Python 风格的 API,并且处理复杂几何体(圆角、倒角、布尔运算、装配体)的能力优于其他方案。

设置

# CadQuery requires Python 3.10-3.12 (OCC kernel lacks 3.13+ wheels)
python3.12 -m venv .venv && source .venv/bin/activate

# Install CadQuery and preview dependencies
pip install cadquery trimesh pyrender Pillow numpy lxml

CadQuery 底层使用 OpenCASCADE 内核。trimesh、pyrender、Pillow 和 numpy 用于预览、分析和迭代流程;3MF writer(stl_to_3mf.py)依赖 lxml。无需显示服务器;所有内容都通过 pyrender 的离屏后端进行渲染。

如果 CadQuery 安装失败(OCC 内核构建错误),请尝试:

# Option 1: Use conda (CadQuery's officially recommended method)
conda install -c cadquery -c conda-forge cadquery

# Option 2: Use the pre-built wheels
pip install cadquery --find-links https://github.com/CadQuery/CadQuery/releases

现实世界尺寸调研

设计需要与真实产品(手机、充电器、PCB、连接器等)配合使用的物体时,请先通过网页搜索查找准确尺寸,再编写任何几何代码。不要猜测或使用近似值。即使相差 1-2mm,也可能导致部件无法使用。

需要调研的内容:

  • 连接器/端口尺寸(USB-C:开口尺寸为 8.4 x 2.6mm,Lightning、桶形插孔)
  • 设备尺寸(手机宽度/厚度、PCB 封装尺寸、充电器圆盘直径)
  • 安装孔位图和螺丝尺寸(M2.5、M3 等)
  • 标准组件规格(MagSafe 圆盘:直径 56mm、厚度 5.6mm)
  • 电缆弯曲半径和应力消除要求

使用方法:

  1. 搜索“[product] dimensions mm”或“[component] datasheet”
  2. 对精度要求较高的尺寸,至少交叉核对 2 个来源
  3. 将查到的尺寸作为注释添加到 PARAMETERS 部分:
    # MagSafe puck dimensions (source: Apple spec + iFixit teardown)
    puck_diameter = 56.0    # mm
    puck_thickness = 5.6    # mm
    
  4. 如有疑问,给外部尺寸增加 0.3-0.5mm 的间隙

以下情况尤其需要注意:手机壳/支架、充电器支架、PCB 外壳、电缆管理、适配器接头,以及任何需要夹在现有产品上或包裹现有产品的物件。

核心工作流程

  1. 收集需求(见下文“需求收集”)
  2. 调研涉及的任何真实产品尺寸(见上文)
  3. 阶段 1:基础形状:构建外壳、预览并征求用户反馈
  4. 阶段 2:功能特征:添加功能细节、预览并征求用户反馈
  5. 阶段 3:最终交付:添加圆角、清理模型、最终预览 + STL + 打印建议
  6. 交付后提供参数调整选项

这是一个协作式、逐步展示的流程。不要离开一段时间后直接带着完成的模型回来。请在每个阶段向用户展示进展,并在继续之前采纳他们的反馈。

需求收集

在编写任何代码之前,先与用户通过对话逐项讨论以下主题。不要一次性抛出所有问题。先问最重要的问题,再根据回答追问。用户未指定时,采用合理的默认值。

这是什么? 对象类型、用途,以及它容纳/保护什么或连接到什么。首先要对对象形成清晰的整体认识。

关键尺寸 必须匹配的尺寸,例如 PCB 的大小、手机宽度、螺丝间距、它要环绕的物体直径等。这些尺寸不可妥协,并决定了其他所有设计。

安装与连接 它如何连接到其他物体?用螺丝(多大尺寸?)、卡扣、胶带、磁铁,还是独立放在桌面上?这会影响壁厚、螺丝柱位置和整体结构。

打印机与材料 用户使用什么打印机?(Bambu、Prusa、Ender 等)喷嘴尺寸是多少?使用什么材料(PLA、PETG、TPU)?这会直接影响公差、最小特征尺寸和设计限制。默认值:0.4mm 喷嘴、PLA、0.2mm 层高。

功能需求 通风/气流、防水性、布线、检修面板、可视窗口、堆叠、重量限制。只询问与对象相关的内容。

美观偏好 边缘要圆润还是锐利,偏简约还是工业风,以及颜色方面的考虑(会影响层纹的可见度)。简单询问即可。大多数用户更看重功能而非外观。

先询问前两项(是什么 + 尺寸),然后在相关时再询问安装方式和材料。只有在用户似乎在意美观,或美观会影响结构选择时,才询问外观偏好。

渐进式预览工作流

分阶段构建模型。每个阶段都要导出 STL、渲染预览、自行检查,然后向用户展示并征求反馈,再继续下一阶段。这样可以及早发现问题,并让用户参与其中。

预览流程(每个阶段都使用)

一步完成(运行脚本 + 渲染 + 将结果解析为 JSON):

python3 run_cadquery_model.py model.py --preview --strict

此流程会执行 model.py,找到它写入的 STL,渲染多视图预览,并输出包含 success、stdout、stderr、stl、preview 和 watertight 的 JSON 结果。使用 --strict 时,非水密网格会导致硬性失败。默认使用此流程:如果 success 为 false,读取 stderr 字段以修复 CadQuery 脚本,然后重新运行。

仅渲染(STL 已存在时):

python3 preview.py model.stl preview.png --views multi

然后查看预览图像,根据 design-review.md 中的清单自行检查,并在向用户展示之前修复发现的任何问题。


第 1 阶段:基本形状

构建基本外形:整体尺寸、外壳/壁面、底板。暂不添加开孔、圆角或细节。

  1. 编写包含参数和基本几何体的脚本
  2. 导出 STL 并渲染预览
  3. 自行检查:形状和尺寸看起来是否正确?底面是否平整,适合打印?
  4. 向用户展示预览:“这是基本形状。在我添加细节之前,这样看起来合适吗?”并附上关键尺寸。
  5. 等待反馈。如果用户希望修改,先在此阶段迭代,再继续下一阶段。
第 2 阶段:特征

添加功能细节:孔、开口、安装凸台、线缆槽、通风结构、卡扣、内部结构。

  1. 在脚本中添加特征
  2. 导出 STL 并渲染预览
  3. 自行检查:所有特征是否清晰可见?布尔运算结果是否干净?孔的位置是否正确?
  4. 向用户展示预览:“我已添加[特征列表]。最终定稿前还需要修改什么吗?”
  5. 等待反馈。按需迭代。
第 3 阶段:最终交付

进行收尾处理:圆角、倒角、清理边缘。全面检查模型是否适合打印。

  1. 添加圆角/倒角(先处理最大半径,在外壳完成后应用)
  2. 导出最终 STL 并渲染预览图
  3. 使用 design-review.md 中的完整检查清单进行全面自检:目视检查、尺寸验证、可打印性分析
  4. 修复发现的任何问题,必要时重新导出
  5. 交付给用户:最终 STL + 预览图 + 打印建议(方向、支撑、填充率、材料说明)

**重要:**除非模型非常简单(例如带两个孔的平面支架),否则请勿跳过或合并阶段。对于带有封闭几何体、多个特征或严格公差的模型,请遵循全部三个阶段。

请阅读 design-review.md,了解完整的目视检查清单、尺寸验证代码和可打印性分析辅助工具。

打印建议(最终交付)

交付最终 STL 时,务必附上一行切片器配方和简短说明。Bambu Studio、PrusaSlicer 和 OrcaSlicer 已根据耗材和工艺预设设置了合理的默认值,因此无需重述每项切片器选项。只需告知用户与此模型相关的重要事项:材料、层高、壁数、填充率、支撑和摆放方向。除非模型有需要,否则请沿用以下基准设置。

基准配方(0.4mm 喷嘴,常见 FDM):

PLA,0.2mm 层高,2 层壁,15% 陀螺形填充,无支撑,摆放方向:平面朝下置于热床。

何时偏离基准设置:

  • 承重支架/挂钩/铰链:将填充率提高到 25-40%,设置 3-4 层壁;考虑使用韧性优于 PLA 的 PETG。
  • 薄装饰壁或花瓶:0 填充率,使用花瓶模式或 1 层壁。
  • 高而窄的部件:添加裙边以增强热床附着力。
  • 柔性部件(垫圈、握把):使用 TPU 95A,0.2mm 层高,降低速度,无支撑。
  • 几何形状无法避免的功能性悬垂:使用树状支撑,或明确指出,让用户知晓。
  • 户外/高温环境:使用 PETG 或 ASA,而非 PLA。
  • 食品/皮肤接触:指出 FDM 部件不适用于食品接触,并建议使用食品级涂层。

交付时的格式:

Print settings: PLA, 0.2mm layer, 2 walls, 15% gyroid infill, no supports.
Orientation: place flat back side on the bed (front face up).
Why: the case has no overhangs above 45°, and 15% infill is plenty for a
TPU-adjacent protective shell.

控制在约 3 行。切勿罗列所有切片器设置;切片器已经知道这些信息。

脚本模板

脚本始终按以下结构编写:

import cadquery as cq

# ============================================================
# PARAMETERS - Edit these to customize the model
# ============================================================
# Overall dimensions
width = 60.0        # mm - outer width
depth = 40.0        # mm - outer depth  
height = 25.0       # mm - outer height

# Wall and structural
wall = 2.0          # mm - wall thickness (min 1.2 for FDM)
corner_r = 2.0      # mm - corner fillet radius

# Tolerances
fit_clearance = 0.3 # mm - clearance for press-fit (adjust per printer)

# ============================================================
# MODEL
# ============================================================
result = (
    cq.Workplane("XY")
    .box(width, depth, height, centered=(True, True, False))
    # ... build geometry using parameters above (bottom at Z=0)
)

# ============================================================
# EXPORT
# ============================================================
# Use tolerance=0.01, angularTolerance=0.1 for consistent tessellation
# across models. Defaults give coarser, wildly variable STL sizes.
cq.exporters.export(result, "output.stl",
                    tolerance=0.01, angularTolerance=0.1)
print(f"Exported: {width}x{depth}x{height}mm")

关键规则

参数优先
  • 所有尺寸都放在顶部的 PARAMETERS 部分
  • 使用描述性名称:screw_hole_d,而不是 d1
  • 在注释中注明单位(始终使用 mm)
  • 按关联参数分组,各组之间留空行并添加分节注释
适合打印的默认值

FDM 设计的关键默认值:

属性最小值推荐值
壁厚1.2mm2.0mm
层高0.08mm0.2mm
孔隙间隙0.2mm0.3mm
压配过盈量0.1mm0.15mm
最小特征尺寸0.4mm(喷嘴)0.8mm
圆角半径(底部)0.5mm1.0mm
桥接跨度-无支撑时 < 20mm
悬垂角度-相对垂直方向 < 45 度

**材料特定调整:**TPU 柔性较大,需要更大的间隙(约 0.5mm)。PETG 更容易粘连,因此配合间隙增加 +0.1mm。ABS 收缩约 0.5-0.7%,因此应略微增大关键尺寸。不确定时,请先打印一个小型测试件。

方向意识
  • 设计时考虑打印方向
  • 平坦的底面最适合打印
  • 尽可能通过设计避开悬垂,减少支撑
  • 底部边缘使用倒角而非圆角(圆角需要支撑)
  • 在脚本中注明预期的打印方向
CadQuery 常用模式

需要了解的常用模式:

中空外壳(布尔减法,优先使用):

outer = (
    cq.Workplane("XY")
    .box(width, depth, height, centered=(True, True, False))
    .edges("|Z").fillet(corner_r)
)
inner = (
    cq.Workplane("XY")
    .workplane(offset=floor_t)
    .box(width - 2*wall, depth - 2*wall, height, centered=(True, True, False))
    .edges("|Z").fillet(max(0.1, corner_r - wall))
)
result = outer.cut(inner)

螺钉凸台:

.pushPoints([(x, y)])
.circle(boss_od / 2).extrude(boss_h)
.pushPoints([(x, y)])
.hole(screw_d + fit_clearance)

卡扣:

# Cantilever beam with overhang hook
.workplane(offset=wall)
.moveTo(x, y).rect(clip_w, clip_l).extrude(clip_h)
# Add hook at tip with a small overhang (< 45 deg)

通风栅格:

.pushPoints(vent_positions)
.slot2D(slot_l, slot_w).cutThruAll()

其他模式:安装支架、走线槽、文本/标签(.text())、带定位销的多部件装配。

常见问题
  • 挖空:优先使用布尔减法,而不是 .shell()。.shell() 很脆弱,在带锥度的实体、放样形状、多个基本体的并集,以及带有许多圆角的形状上都会失败。可靠的模式是:
    outer = cq.Workplane("XY").box(w, d, h, centered=(True, True, False)).edges("|Z").fillet(corner_r)
    inner = (
        cq.Workplane("XY")
        .workplane(offset=floor_t)
        .box(w - 2*wall, d - 2*wall, h, centered=(True, True, False))
        .edges("|Z").fillet(max(0.1, corner_r - wall))
    )
    result = outer.cut(inner)
    
    只有当实体是单个简单基本体(一个 .box() 或 .cylinder()),且所有侧面的壁厚均匀时,才考虑使用 .shell()。如有疑问,请使用布尔减法。
  • 构建顺序:先倒圆角,再切割,而不是先切割,再倒圆角。几何体仍为干净的基本体时就应用圆角。对实体切出孔、槽或凹腔后,再对产生的边倒圆角往往会失败,或产生糟糕的几何形状。倒角也遵循同样的规则。
  • 圆角失败:按半径从大到小的顺序应用圆角。不要将圆角操作包在 try/except 中,以便悄悄缩小半径。 圆角失败意味着几何形状或半径有误;请找出根本原因(半径过大、壁厚小于半径,或相邻面会因倒圆角而退化)并修复。
  • 零厚度几何体:确保布尔运算不会产生无限薄的壁。在切割刚好穿过表面的实体时,加入一个小的 epsilon(0.01mm)。
  • 坐标系:CadQuery 默认将几何体置于原点。对 .box() 使用 centered=(True, True, False),将底部放在 Z=0,这样 .faces("<Z") 始终是打印平台面。
  • 孔的方向:默认情况下,.hole() 会贯穿整个零件。若要加工沉孔或沉头孔,请使用 .cboreHole() 或 .cskHole()。
  • 锥度方向:在 .extrude(taper=angle) 中,正锥度角会使形状变窄(向内拔模),负锥度角会使形状向外扩张。这与许多人的预期相反。
  • 放样不稳定:.loft() 在许多截面组合上都会失败。如果要在某个形状与其缩放版本之间过渡,请优先使用 .extrude(taper=angle)。只有在需要在真正不同的轮廓之间过渡时(例如从圆形过渡到矩形),才使用 .loft()。
  • 导出错误/STL 不闭合:如果导出失败,或预览报告网格不闭合,则几何体无效(通常是布尔运算导致自相交,或存在零厚度面)。请修复原因,不要掩盖问题。运行 python3 preview.py model.stl --strict,以便在输出不闭合时明确报错。

导出

# STL (for slicing) - always set tolerance + angularTolerance for
# consistent tessellation. Defaults produce variable file sizes and
# over-tessellated glyphs on text features.
cq.exporters.export(result, "model.stl",
                    tolerance=0.01, angularTolerance=0.1)

# STEP (for further CAD editing)
cq.exporters.export(result, "model.step")

打印时始终导出 STL。如果用户可能想在 Fusion 360 或类似软件中编辑,也可以选择导出 STEP。

多零件模型

对于包含多个零件的模型(例如外壳 + 盖子):

# Export each part separately
cq.exporters.export(body, "enclosure_body.stl")
cq.exporters.export(lid, "enclosure_lid.stl")

文件名应描述清晰,让用户知道每个文件对应哪个零件。

Gridfinity 收纳盒

对于任何 Gridfinity 请求(适用于 42 mm 模块化网格系统的收纳盒、内衬、托架),请使用随附的 gridfinity.py 模块;切勿手动重建底座轮廓。该模块经过测试,符合规格(底座轮廓、堆叠凸缘、6×2 mm 磁铁孔、位于 26 mm 方形上的 M3 螺丝孔),并会针对参数提供有实际指导意义的错误信息。

工作流:

  1. 将此技能目录中的 gridfinity.py 复制到模型脚本旁边(这是一个随附的模块;生成的脚本必须能够独立运行)。
  2. 使用 GridfinityBin API 构建:
import cadquery as cq
from gridfinity import GridfinityBin

bin = GridfinityBin(grid_x=3, grid_y=2, height_units=3,
                    stacking_lip=True, magnets=False)
bin.add_pocket(length=88.6, width=72.6, corner_r=(12.0, 1.0))  # cradle
# or: bin.add_compartments(cols=3, rows=2, scoop_r=6, label_tab=True)
# or: bin.add_polygon_pocket(points, depth=15, clearance=0.3)
# or: bin.add_cylinder_pocket(diameter=22, center=(42, 27),  # finger well; overlapping pockets merge
#         tilt=35, tilt_dir=(-1, 0), round_bottom=True)      # smooth angled thumb scoop
# or: bin.add_finger_notch(side="+Y", width=20, offset=40)   # offset slides it along the wall
result = bin.build()
cq.exporters.export(result, "my_bin.stl", tolerance=0.01, angularTolerance=0.1)
print(bin.summary())

速查表:

  • 规格常量:网格间距为 42 mm,高度单位为 7 mm。所有派生数值(占地尺寸、凸缘高度、底面 Z 坐标、可用内腔深度)都可通过构建器获取:bin.outer_w、bin.outer_d、bin.total_h、bin.floor_z、bin.max_depth,而 bin.summary() 会打印全部数值。请读取这些值,不要重新计算。
  • 为物品设计收纳槽尺寸:每侧增加 0.3 mm 的配合间隙;如果物品需要轻松放入和取出,则每侧再增加约 1 mm。
  • 让收纳槽贴合实际物品的形状:outline_from_scan.py 可从物品的 STL 扫描模型中提取最大截面轮廓(对齐、缩放至规格尺寸、切片、合并),可直接用于 add_polygon_pocket。
  • 高度选择:只需能容纳物品;物品可以高出边缘(参见 examples/gridfinity_d110_bin.py)。
  • magnets=True 需要配合磁性底板使用;抽屉收纳盒请跳过此设置。

如果收纳槽过大、侧壁过薄或底面太浅而无法容纳螺丝,构建器会抛出带有具体错误信息的 GridfinityError(部分检查在 add_* 调用中触发,其余检查在 build() 中触发)。请修正参数;不要绕过验证。

如果用户需要模块不支持的设计(如底板、特殊凸缘),则改用自定义几何,但仍须以 gridfinity.py 中的规格常量为准。交付正式版本时,请将 gridfinity.py 与模型脚本一并提供。

提供参数调整选项

交付最终模型后,始终以汇总表的形式列出关键参数,并主动提出调整选项。这样用户无需重新说明整个设计,就能微调参数。

示例:

Here's your final model! Current parameters:

| Parameter       | Value  |
|----------------|--------|
| Width          | 90 mm  |
| Depth          | 65 mm  |
| Height         | 30 mm  |
| Wall thickness | 4 mm   |
| Cable slot     | 18 mm  |
| Corner radius  | 3 mm   |
| Fit clearance  | 0.3 mm |

Want me to adjust anything? Just say e.g. "make it 5mm taller" or "wider cable slot."

只列出用户可能希望更改的参数。跳过 eps 或 nozzle_d 等内部常量。按逻辑分组(先列尺寸,再列结构参数,最后列公差)。

输出检查清单

交付模型前,请确认:

  • 所有尺寸均已参数化(几何代码中没有魔法数字)
  • 壁厚 >= 1.2 mm
  • 设计便于打印(尽量减少悬垂和支撑)
  • 在注释中注明打印方向
  • 已导出 STL,且文件大小合理(不为 0 字节)
  • 参数名称清晰,并标明单位
  • 脚本可无错误运行
  • 已生成多视图预览并进行目视检查
  • 预览中显示的形状、特征和比例均正确
  • 边界框尺寸符合要求
  • 已向用户交付 STL 和预览 PNG

评论

支持 Markdown