mcpField
C
cadloop OpenSCAD

cadloop OpenSCAD

本地服务
github.com媒体与设计112 周前更新

关于 cadloop OpenSCAD

cadloop OpenSCAD 是用于无 GUI 编译和检查 OpenSCAD 模型的 MCP 服务,为准备 3D 打印模型的用户提供快速语法与数值检查、渲染、测量和预览。

主要功能

  1. 01检查 OpenSCAD 语法与引用
  2. 02无需渲染读取计算值
  3. 03渲染并测量模型几何
  4. 04以 MCP 图像返回 PNG 预览
  5. 05访问工作区文件

适用场景

  1. 01渲染前发现源文件错误
  2. 02检查模型尺寸与体积
  3. 03切片前目视检查模型

MCP 相关

它向 MCP 客户端提供 OpenSCAD 检查、计算值读取、渲染、测量、预览及工作区文件访问。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"richardofortune-cadloop-openscad": {
"command": "uvx",
"args": [
"cadloop"
],
"env": {
"OPENSCAD_WORKSPACE": "<OPENSCAD_WORKSPACE>",
"OPENSCAD_BIN": "<OPENSCAD_BIN>",
"OPENSCAD_TIMEOUT": "<OPENSCAD_TIMEOUT>"
}
}
}
}
启动命令uvx cadloop
需要配置的环境变量
OPENSCAD_WORKSPACEThe only directory this server reads and writes. Defaults to ~/cad.
OPENSCAD_BINPath to the openscad binary. Auto-detected from PATH and the usual install locations if unset.
OPENSCAD_TIMEOUTSeconds before a run is killed. Defaults to 300.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypicadloop0.1.0

工具

9

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

cadloop

从参数化源文件到 G-code 的闭环,中间加入验证步骤,这是 CAD 工具和切片器都无法完成的。

两个 MCP 服务。模型编写 OpenSCAD、编译、读回计算值、查看渲染结果、检查是否适合打印床、切片并提取 G-code,同时证明每个打印板都在可打印区域内。全程无需 GUI。

中间的验证步骤由你编写。cadloop 让周边的一切都足够廉价,因此你可以经常运行;但它无法判断零件是否可用。

闭环演示,最后由验证器发现一个会卡住的轮子

演示中的每个数字都是真实输出。故障轮子是实际测量结果,并非示意图。其构建方式以及每个数字的来源见 docs/walkthrough。

 setup_printer   once, no arguments: which printer is this for
      |
  write .scad
      |
   check          syntax and references, about a second
      |
   echo           read computed values without rendering
      |
   preview        look at it
      |
   verify         does it actually work  <- yours; nothing here does it for you
      |
   measure        bounding box and volume
      |
 check_bed_fit    against the printer you set up
      |
  slice_model     -> .gcode.3mf
      |
 extract_gcode    -> .gcode

顺序是关键。check 和 echo 完全跳过几何求值,因此对于完整渲染需要几分钟的模型,它们只需一秒。只有通过廉价步骤后,才为昂贵步骤付出成本。

从打印床检查开始的所有步骤,也可以通过一次调用 make_printable 完成:渲染、排版、切片,并验证结果是否在打印床上,然后以一屏文字报告执行结果。参见完整示例。

安装

pip install cadloop

唯一的依赖项是 mcp。也可以从代码检出目录安装;如果你打算运行完整示例或测试,就应该使用这种方式——verify 扩展依赖 shapely,这是示例自身的检查器所需的,而不是 cadloop 所需的:

git clone https://github.com/richardofortune/cadloop
cd cadloop
pip install -e ".[verify]"

需要在 PATH 中或 OPENSCAD_BIN 指定的位置安装 OpenSCAD;切片则需要 OrcaSlicer、Bambu Studio、ElegooSlicer 或 Creality Print。它们共用一个 CLI,因此任选其一均可,并且会自动检测这四种软件及其附带的配置文件。

这里不偏好任何一种切片器。setup_printer 会探测找到的每一种,然后使用你的配置文件切片一个 20mm 的立方体,以此验证最终选择。因此,实际使用哪一种取决于哪一种能在你的机器上正常工作,而不是取决于本仓库中的列表顺序。Creality Print 的 CLI 目前在 macOS 上无法以无头模式正常工作;程序会发现这一点,而不是直接断言,因此上游发布修复后,它也会自动恢复正常;见下文的测试状态。SLICER_BIN 可覆盖此选择。

配置

将 mcp.json 复制到客户端配置中,并修正路径。两个服务都应指向同一个工作区目录,这是它们唯一会读取或写入的位置。

变量默认值含义
OPENSCAD_BIN、SLICER_BIN自动检测二进制文件路径
OPENSCAD_WORKSPACE、SLICER_WORKSPACE~/cad沙盒
SLICER_PROFILE_DIRS自动检测额外的配置文件根目录
CADLOOP_MACHINE$XDG_CONFIG_HOME/cadloop/machine.json机器记录的存放位置
OPENSCAD_TIMEOUT、SLICER_TIMEOUT300、600终止进程前的秒数

服务

openscad 提供 check、echo、render、measure、preview 和工作区文件访问功能。preview 会将 PNG 作为 MCP 图像返回,让模型直接查看构建结果,而不是根据数字推测。render 会连同边界框和体积一起返回 OpenSCAD 的流形报告;其中 simple: yes 且体积数值合理,表明网格可用于打印。

两者的区别在于如何处理图像。preview 会返回图像但不保留;render 则会在输出路径以 .png 结尾时将图像写入工作区,并接受相同的 camera、imgsize、projection 和 full_render 选项。如果图像本身是产物而非答案,就使用 render。由于 render 也接受文本形式的 source,对比中的前一版本可以直接通过 git show <rev>:model.scad 管道传入——无需检出代码,也无需临时文件。 slicer 提供 setup_printer、machine_info、make_printable、 slicer_info、list_profiles、check_bed_fit、slice_model、 slice_summary 和 extract_gcode。

make_printable 一次调用即可完成整个流程。给它一个 .scad 文件和 你想要的部件,它会逐个渲染并测量,尽可能将可放入的部件排到尽量少的打印板上, 然后进行切片,最后读取生成的 G-code,验证每个挤出动作都落在打印板上。如果某个 部件无法按设计打印,它不会修改模型,而是报告问题,不会悄悄缩小或拆分部件。它 唯一会更改的是部件所在的打印板;如果部件无法正向放入,也会将其旋转九十度,并在 报告中说明。它会返回所有已确认的信息,并在 summary 中汇总成一屏文字,最后 说明接下来该怎么做。

无参数调用一次 setup_printer()。它会读取切片器当前的配置,将其解析为同一安装中的 机器、流程和耗材配置,通过切片一个 20mm 立方体验证这组配置,然后将其保存。它会报告 最终采用的打印机、质量和耗材;如果测试切片失败,则完全不会保存任何内容。只有在 需要覆盖某个字段时才传入 printer、filament 或 process;其余字段仍取自切片器 自身的设置。你指定的配置要么会被使用,要么会按名称拒绝,绝不会悄悄换成其他配置。

此后,check_bed_fit 和 slice_model 无需配置参数,这正是这样设计的目的:调用方 不传入配置,就无法提供三个彼此不一致的配置。你明确传入的参数仍会优先采用。

machine_info 会说明此工作区配置的是哪台打印机,以及配置是否仍然有效。此记录只是 缓存,并非事实来源。如果切片器移位、配置被编辑或切片器版本发生变化,所有原本会 使用该记录的工具都会拒绝执行并说明原因,而不是继续使用——返回 ok: null,不写入 任何内容——直到你再次运行 setup_printer。与实际情况不符的配置绝不会用于生成 G-code。

进行任何不寻常的操作前,先调用 slicer_info:Orca 系列的 CLI 没有文档说明,不同 版本之间会有变化,而 Creality 的分支也有所不同,因此从你的安装中读取的标志列表比 任何假设都更可靠。slice_model 提供 extra_args 备用入口和 dry_run 模式。

check_bed_fit 正是两者的交汇点。切片器会生成超出边界的 G-code 而不发出警告,因此 它会测量 STL,读取机器配置中的 printable_area,并进行比对。它还会检查 45 度对角线, 因为正向放不下的部件通常旋转后就能放入。

读取 printable_area 比看起来更棘手。原厂配置既会用 "XxY" 字符串列表来写,也会用 单个逗号分隔的字符串来写;而且大多数 Bambu 机器本身没有打印板尺寸,而是通过 inherits 从通用基础配置继承。因此,查找逻辑会解析这两种格式,并沿继承链逐级查找。 Creality Print 7.1.1 随附的 473 个具体机器配置中,有 469 个能解析出结果;其余四个在 继承链中的任何位置都未定义打印板尺寸,因此会返回带有原因的 ok: null,而不是猜测。

验证步骤

这是 cadloop 不会替你完成的部分,也是它只是一个实操示例而非功能的原因。models/verify_spirograph.py 与模型放在一起,而不在包内:每个项目对“它到底能不能用”的定义都不一样,而且没有一种能通用。你的版本会和这个截然不同。

它会运行两项检查。对于螺旋线绘图器,第一项会将每个齿轮的节曲线与齿圈的节圆对齐,沿整圈移动,并测量两个实体在每个位置的重叠量。在某个啮合相位下,整圈的重叠量都为零,即为通过。第二项会检查各零件在打印板上是否互相叠放。

$ python models/verify_spirograph.py
part     teeth  overlap mm2  result
24T         24     0.000000  pass
...
trefoil     23     0.000000  pass

14/14 parts mesh cleanly

group        volume mm3
ring            23939.8
outer_ring      25652.8
wheels         197113.5
shapes          10078.7
sum            256784.8
sheet          256784.8

no parts overlap on the sheet

第二项检查是同一思路在更高一层的应用。即使打印板上的两个零件叠在一起,它仍会渲染为干净的流形网格,仍能放进打印平台,也仍能顺利切片,完全不会报错;只是打印出来会变成一个融合的物体。因此,它会渲染打印板及其各个组,并将并集与各部分之和进行比较,因为只有在这里才能发现碰撞。它需要 OpenSCAD,没有安装时会跳过;--skip-layout 和 --skip-mesh 可以单独运行其中一项检查。

齿数决定什么

在一个有 R 个齿的齿圈中,一个有 r 个齿的齿轮滚动时,笔尖会画出一个有 R / gcd(R, r) 个叶瓣的图形,并在滚动 r / gcd(R, r) 圈后闭合。齿数在任何几何形状生成之前就决定了图案,因此检查器的 --patterns 模式会直接从齿数组合中读取图案:

$ python models/verify_spirograph.py --patterns

main ring, 96 teeth
      part  teeth  lobes  circuits
       32T     32      3         1  plain
       24T     24      4         1  plain
       72T     72      4         3  plain
...
   trefoil     23     96        23

96 = 2^5 x 3,因此它与偶数齿数组合中的大多数齿轮以及这里约一半的齿轮都有公因数,这些齿轮绘制的叶瓣数不超过 8 个。集合中没有 48,原因就在这里:48 恰好是 96 的一半,这是一个退化比例,笔尖只会画出椭圆,不会画出其他图形,因此没有入选。外齿圈的齿数为 105 = 3 x 5 x 7,效果好得多;而 23 齿的三叶草轮与两个齿圈的齿数都互质,这使它成为集合中图案最丰富的齿轮。

在选择齿数时就运行这项检查,胜过打印之后再运行。

从本质上说,这只适用于特定模型,这就是它揭示的实际情况。一个能放进打印平台且切片顺利的流形网格,仍可能是无法正常工作的零件。无论你的“它到底能不能滚动”对应的检查是什么,都应将其放入预览与测量之间的流程中,并且必须由你自己编写。

实际示例

models/spirograph.scad 是构建此循环所依据的模型。它包含一个带法兰主体中的 96 齿内齿圈、一个外齿圈、十一个圆形齿轮和三个非圆形齿轮(椭圆、蛋形、三叶形),全部采用模数 1.5 的渐开线齿轮,并在黄金角螺旋线上设有笔孔。

非圆形齿轮正是验证器存在的原因。第一次尝试用切线构成胶囊形和泪滴形轮廓;它们看起来没问题,渲染结果是干净的流形,也能顺利切片,但滚动检查显示它们会刨入齿圈齿牙 30 到 80 mm²。节曲线上的平直部分只在一点与齿圈接触,其他地方都凸出齿圈。CAD 之后的任何环节都发现不了这个问题。最终采用的形状是平滑凸曲线,曲率半径处处都在齿圈范围内。

从源文件到打印板,整个流程只需调用两次,第一次只需执行一次:

setup_printer()
make_printable("spirograph.scad",
               ["ring", "outer_ring", 24, 30, 32, 36, 40, 45, 52, 56, 63, 72,
                80, "ellipse", "egg", "trefoil"])

在配备 OrcaSlicer 2.4.2、使用通用 PLA 的 Ender-3 V3 SE 上,大约半分钟内即可完成 16 次渲染、5 块打印板、5 次切片,并回读和检查 5 个 G-code 文件,确认它们符合热床要求:

ok      16 parts on 5 plates, every plate proven on the bed

  machine ...... Creality Ender-3 V3 SE 0.4 nozzle, 220 x 220 mm bed, PLA
  parts ........ 16 of 16 fit this bed
  plates ....... 16 parts packed onto 5
  sliced ....... 5 of 5, every extruding move on the bed
  ready ........ ~/cad/plates/spirograph, 13h09m, 63.17 m PLA

  worth a look:
    plate_2 sits 2.2 mm from the bed edge, consider a brim

  next: print the plates in ~/cad/plates/spirograph. Nothing above stops the
        print — the notes are advisories — so read them and go.

这里的每个数字都来自那次运行。关于裙边的提示仅供参考,并非缺陷:打印板 2 能放在热床上,还剩 2.2 mm 余量;这已经很靠近边缘,翘曲的首层就会显现出来。运行无法证明的任何事项都会用明确的措辞说明——ok 表示已完成的事项,FAILED 表示尝试但未成功的事项,UNKNOWN 表示无法判定的事项——而最后一行始终会给出下一步要调用的命令。

make verify              # rolling interference and layout, all 14 parts
make render PART=ring    # one part to an .stl, no printer set up needed
make smoke               # both servers, end to end

make render 是旧版教程中值得手动保留的唯一步骤:它只需要 OpenSCAD,因此在你仍在修改模型时,这是查看单个部件最快的方法。此后的所有步骤都由 make_printable 完成。

测试状态

make smoke 会通过真实的 MCP stdio 会话驱动两个服务,并验证四十五种行为:工具接口、定义传递给脚本、捕获预期的语法错误、测量出的几何尺寸与已知尺寸一致、预览返回图像、配置分类、参数顺序、归档解析、G-code 提取、床面适配检查通过和失败、printable_area 的两种拼写形式和继承的床面,以及工作区防护机制拒绝路径遍历。

它还会使用专为本次运行构建的切片器安装端到端测试无参数路径:不带参数调用 setup_printer() 时,必须说明所选打印机、质量和耗材,并保存来自同一安装的一组三项配置;随后,不带任何配置参数的 check_bed_fit 和 slice_model 必须能够正常工作。之后编辑配置文件,两者都必须拒绝操作且不写入任何内容。

make_printable 也会以相同方式、通过同一会话进行测试:一个双部件 .scad 必须返回至少一个打印板,每个打印板都必须通过读取其 G-code 证明能放置在床面上,而非仅凭假设;同时,报告不得超过三十行,并且要说明下一步操作。这是对单次调用路径唯一的自动化端到端检查。

OpenSCAD 部分使用真实的 OpenSCAD 运行;若未安装,则跳过。切片器部分使用一个模拟二进制文件,它会输出 Orca 风格的帮助文本和有代表性的 .gcode.3mf,因此除了真实切片器本身的行为外,其他内容都已覆盖。

在真实安装环境中,OpenSCAD 部分和 check_bed_fit 已通过端到端验证:从 spirograph.scad 渲染出的 24 齿齿轮尺寸为 38.99 mm,适配 K1 的 220 mm 床面。slice_model 构建的每个标志都能在 Creality Print 7.1.1 的 --help 中找到。

已在 macOS 上使用 OrcaSlicer 2.4.2 端到端验证完整流程:96 齿环切片生成 113,808 行 G-code,共 35 层,打印耗时 51 分钟,使用 7.27 m PLA,且所有坐标都在床面范围内。

Creality Print 的 CLI 在 macOS 上无法以无头模式运行。 在 macOS 26 上使用 7.1.1.4472 时,除 --help 外的所有操作都会发生段错误,包括在完全未加载配置文件时运行 --info。它会在 Slic3r::CLI::run 调用的 Slic3r::GUI::PartPlate::set_shape 中崩溃,这是无头路径未初始化 GUI 床面设置导致的空指针解引用;无论如何组合使用 --datadir、--outputdir 或配置参数都无法避免。请将 SLICER_BIN 指向 OrcaSlicer、Bambu Studio 或 ElegooSlicer,或者在 Linux 上运行 Creality Print 的 CLI。如果传入 --datadir,该目录必须可写:不可写的目录会在 set_data_dir 中中止,而不是发生段错误,但结果同样无法使用。

工作区防护机制仅检查工具参数,不检查脚本本身。OpenSCAD 的 include、use 和 import 可以访问进程有权读取的任意文件,因此运行不可信的 .scad 就是在运行不可信代码。

许可证

MIT。请参阅 LICENSE。

与 Creality、Bambu Lab、Elegoo、OrcaSlicer 项目或 OpenSCAD 项目均无关联。此处提及这些名称仅为说明本工具所驱动的软件。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。