text-to-cad G-code 技能:以 dry-run 优先的切片器 CLI 编排实现网格到 G-code 的生成与静态校验
【免费下载链接】text-to-cadA library of agent skills for CAD, CAE and CAM项目地址: https://gitcode.com/GitHub_Trending/tex/text-to-cad
gcode是 text-to-cad 仓库中面向 Agent 的 CAM 技能,它通过编排本机真实切片器 CLI(OrcaSlicer、PrusaSlicer、CuraEngine),把.stl、.obj、未切片.3mf、.ply、.glb、.gltf等网格文件转换为带打印机画像的纯 FDM.gcode。全文覆盖技能声明的完整工作流、wrapper profile 契约、后端发现机制、输入修复(remediation)策略与 G-code 静态校验规则,并结合 gcode_tool.py 的源码实现讲清每个命令背后的调用链与容错边界,帮助读者在本地搭建可复现的“网格 → G-code → 校验”流水线。
技能定位:只产纯 G-code,不碰打印机
技能定义见 SKILL.md,其 frontmatter 明确声明了适用范围:为 Codex 等 Agent 提供.stl、.obj、未切片.3mf、.ply、.glb、.gltf的切片能力,支持本机切片后端发现、切片就绪检查、以及打印前 G-code 校验。两条核心边界贯穿整个技能:
- 打印机无关(printer-agnostic):技能只生成纯
.gcode,从不上传、启动或打包打印任务; - dry-run 优先:任何真实切片执行前,必须先输出并审阅将要执行的切片器命令。
Agent 侧的技能元数据(展示名 "G-code"、默认提示 "Use $gcode to generate printer-profiled G-code from a mesh file.")定义在 openai.yaml。运行时以本地安装的技能文件为准,仓库只用于溯源与发布审查。
标准工作流:从发现后端到校验 G-code
SKILL.md 定义了七步工作流,全部通过单一入口脚本 gcode_tool.py 的四个子命令完成:discover、inspect、slice、validate。
1. 确认输入并发现切片后端
第一步是确认输入属于支持网格(.stl、.obj、未切片.3mf、.ply、.glb、.gltf)。当未知本机有哪些切片器时,运行:
python scripts/gcode_tool.py discover从源码结构看,discover输出的是一个 JSON 报告,其核心逻辑在 discover_backends() 与 discovery_report():按orcaslicer→prusa-slicer→curaengine的偏好顺序逐一探测可执行文件,报告包含preferred_order、backends、not_preferred三个字段。每个后端的探测遵循三级策略,见 find_backend_executable():
- 后端专属环境变量:
ORCASLICER_BIN、PRUSASLICER_BIN、CURAENGINE_BIN(定义于 BACKEND_ENV_VARS); - PATH 查找:候选名包括
OrcaSlicer/orca-slicer/orcaslicer、prusa-slicer/PrusaSlicer/prusa-slicer-console、CuraEngine/curaengine(见 BACKEND_EXECUTABLES); - macOS 应用包位置:扫描
/Applications下OrcaSlicer*.app/Contents/MacOS/OrcaSlicer、PrusaSlicer*.app/...等 glob 模式(见 BACKEND_APP_GLOBS 与 find_app_executable())。
Bambu Studio 会被单独探测(BAMBU_STUDIO_BIN环境变量、PATH、/Applications),但始终标记preferred: false,原因是其 CLI 导出路径在 macOS 上出现过导出.gcode.3mf时崩溃的不稳定表现,详见 discover_bambu_studio() 中写入的reason字段。
2. 检查输入是否切片就绪
python scripts/gcode_tool.py inspect --input path/to/model.stl --jsoninspect_input() 对输入做三类判定,返回InputInspection数据类:
| 状态(status) | 条件 | 含义 |
|---|---|---|
direct_to_slicer | .stl/.obj/ 未切片.3mf | 直接交给切片器 |
requires_stl_conversion | .ply/.glb/.gltf | 执行时需经trimesh转临时 STL |
already_sliced_bambu | .3mf且内部含Metadata/plate_N.gcode | 已是切片产物,拒绝再切片 |
其中“是否已被切片”的判定很关键:is_sliced_bambu_3mf() 把.3mf当 zip 打开,用正则^Metadata/plate_(\d+)\.gcode$匹配内部条目——命中即说明这是 Bambu 已生成的打印任务包,build_slice_plan() 会直接抛出 “Refusing to re-slice it”。
3. slice:先 dry-run,后 execute
slice子命令要求显式传入 wrapper profile JSON,禁止 Agent 凭空发明真实打印机画像。dry-run 与 execute 互斥(slice_main() 会拒绝同时给出两者)。
先 dry-run,审阅输出的 JSON 计划(后端、可执行文件、完整命令、输入分类、输出路径、profile 快照):
python scripts/gcode_tool.py slice \ --input path/to/model.stl \ --output /tmp/model.gcode \ --profile path/to/profile.json \ --backend auto \ --dry-run确认命令与 profile 无误后再执行:
python scripts/gcode_tool.py slice \ --input path/to/model.stl \ --output /tmp/model.gcode \ --profile path/to/profile.json \ --backend auto \ --execute--backend取值为auto或三个受支持后端之一;auto时以 profile 中声明的backend为准(见 build_slice_plan())。执行路径 execute_slice() 有几个值得注意的工程细节:
- 需要转换的输入(
.ply/.glb/.gltf)在临时目录gcode-slice-*中转成 STL,切片器看到的是该临时文件; - 切片器退出码为 0 但目标输出不存在时,会在输出目录寻找“新生成的
.gcode”候选(优先{输入名}.gcode,否则恰好一个新文件),命中则原子性地改名到目标路径(generated_gcode_candidate()),以兼容只接受--outputdir的后端; - 无论成败,返回的 JSON 都附带
returncode、stdout_tail、stderr_tail(各截断至 80 行),便于 Agent 诊断切片器失败原因。
4. validate:切片产物必须静态校验
python scripts/gcode_tool.py validate \ --gcode /tmp/model.gcode \ --profile path/to/profile.json \ --json校验结果ok: true且无错误时进程返回 0,否则返回 1;profile 解析等预期错误统一走 main() 的错误通道,输出{"ok": false, "error": ...}JSON 并返回 2。
Profile 契约:wrapper JSON 的字段与校验规则
每次slice与validate都要求一个 wrapper profile JSON,其职责是提供校验边界与后端选择,而非复刻完整切片器画像——工艺、打印机、线材的详细行为仍由原生切片器 profile 决定。
最小示例
{ "backend": "orcaslicer", "native_config": "/absolute/path/to/native-slicer-profile", "machine": { "name": "Example Printer", "bed_size_mm": [180, 180], "z_height_mm": 180, "motion_bounds_mm": { "x": [0, 180], "y": [0, 180], "z": [0, 180] } }, "filament": { "type": "PLA", "nozzle_temp_c": 220, "bed_temp_c": 65 } }字段约束以 load_profile() 的实现为准:
| 字段 | 必填 | 约束(源码依据) |
|---|---|---|
backend | 是 | 必须为orcaslicer/prusa-slicer/curaengine之一(大小写不敏感) |
native_config | 是 | 绝对路径且文件必须存在(require_absolute_file()) |
native_settings | 否 | 字符串或字符串列表,逐项校验为存在的绝对路径;缺省时退化为只传native_config |
native_filaments | 否 | 同上;仅 OrcaSlicer 会实际使用(传给--load-filaments) |
machine.name | 是 | 非空字符串 |
machine.bed_size_mm | 是 | 二元数值数组[width, depth],两项均须 > 0 |
machine.z_height_mm | 是 | 数值且 > 0 |
machine.motion_bounds_mm | 否 | 对象,可含x/y/z,各为[min, max]且min < max(parse_axis_bounds());缺省时默认0..bed_size_mm[0]、0..bed_size_mm[1]、0..z_height_mm |
filament.type | 是 | 非空字符串 |
filament.nozzle_temp_c/filament.bed_temp_c | 是 | 数值且 > 0(require_number()) |
machine.motion_bounds_mm的存在意义:部分打印机原生画像的开头/结尾 G-code 会故意移动到打印区之外的安全擦拭/排料位置。此时应依据真实打印机画像显式放宽对应轴边界,而不是用它来掩盖未知 G-code(gcode-validation.md 明确禁止这种做法)。
OrcaSlicer 多文件画像
当真实 OrcaSlicer 画像拆分为机器、工艺、线材多份 JSON 时,用native_settings与native_filaments:
{ "backend": "orcaslicer", "native_config": "/absolute/path/to/machine-or-process.json", "native_settings": [ "/absolute/path/to/machine.json", "/absolute/path/to/process.json" ], "native_filaments": [ "/absolute/path/to/filament.json" ], "machine": { "name": "Example Printer", "bed_size_mm": [180, 180], "z_height_mm": 180 }, "filament": { "type": "PLA", "nozzle_temp_c": 220, "bed_temp_c": 65 } }native_config保留为指向主原生画像的绝对路径以维持兼容性。在命令构造侧,build_backend_command() 将多份设置以分号拼接传给 OrcaSlicer:
OrcaSlicer --load-settings machine.json\;process.json --load-filaments filament.json --outputdir /tmp/out --slice 0 input.stl三个后端的完整命令形态(详见 slicer-backends.md):
# OrcaSlicer OrcaSlicer --load-settings machine.json\;process.json --load-filaments filament.json --outputdir /tmp/out --slice 0 input.stl # PrusaSlicer prusa-slicer --load profile.ini --export-gcode --output output.gcode input.stl # CuraEngine CuraEngine slice -j profile.json -l input.stl -o output.gcode后端选择与输入处理策略
偏好顺序与安装建议
偏好顺序为orcaslicer→prusa-slicer→curaengine(PREFERRED_BACKEND_ORDER)。SKILL.md 的建议是:若本机没有任何偏好后端,优先安装 OrcaSlicer,而不是把“缺切片器”当成用户侧阻塞项——macOS 上执行brew install --cask orcaslicer后重跑discover即可,因为 helper 同时检查 PATH 与/Applications/OrcaSlicer.app的 cask 安装位置。
网格直传与 trimesh 转换
.stl、.obj、未切片.3mf直接传给切片器;.ply、.glb、.gltf在--execute时经trimesh转成临时 STL。convert_mesh_to_stl() 会处理场景容器(dump(concatenate=True)合并多节点)、拒绝空网格,且trimesh不可用时抛出明确错误,要求安装它或直接提供.stl/.obj/.3mf。dry-run 的 JSON 输出里会带conversion.note: "Requires trimesh at execution time."提前提示。
结构化 remediation:拒绝即给出下一步
.step、.stp、.dxf、.svg、.urdf、.sdf在 v1 中被显式拒绝。UNSUPPORTED_INPUT_REMEDIATION 为每种扩展名预置了结构化修复对象,inspect与slice命中时都会以GCodeToolError携带details.remediation(含extension、skill、reason、next_step)输出——Agent 应直接遵循该对象,而非自行猜测转换流程:
.step/.stp(边界表示 CAD,不是网格):用$cad导出 STL 侧车——python scripts/step --kind part <input> --stl <output>.stl,或针对生成器脚本python scripts/step <model>.step.py --stl <output>.stl,然后回本技能切片该.stl;.dxf/.svg(二维图纸,本工具链无 2D 转网格能力):若是 FDM 打印,用$cad的gen_step()建模并导出 STL 侧车再切片;若实际是平面切割件而非打印件,改走$sendcutsend技能;.urdf/.sdf(引用各连杆网格的机器人描述):逐个切片其引用的.stl/.obj网格,缺失或过期的网格先用$cad从 CAD 源重新生成;机器人描述本身则交给$urdf/$sdf技能。
静态校验:检查项、边界策略与结果解读
validate_gcode_file() 只做静态检查:不模拟挤出物理、固件状态、加速度限制或切片器特有语义(见 gcode-validation.md)。
失败条件(errors)
- 文件为空;
- 无
G0/G1/G2/G3移动指令; - 无挤出移动(
G1且带E参数); - 无喷嘴/床温度指令(
M104/M109/M140/M190); - 绝对定位模式下解析出的
X/Y/Z坐标超出 wrapper profile 的运动边界。
警告条件(warnings,不修改、不删除命令)
- 遇到未知/不受支持的 G-code 命令(白名单为 SUPPORTED_GCODE_COMMANDS:G0/G1/G2/G3/G4/G21/G28/G29/G90/G91/G92 与 M18/M73/M82/M83/M84/M104/M106/M107/M109/M117/M118/M140/M190/M201/M203/M204/M205/M220/M221/M400/M500/M501/M900,
T<n>换头命令单独豁免),最多列出前 12 个样本及行号; - 出现相对定位(
G91):相对模式激活期间跳过 XYZ 边界检查。
边界策略
校验器假设 G-code 从开始就处于绝对定位(G90语义),遇到G91进入相对模式并暂停边界检查,G90恢复后重新启用——这既避免了相对运动块造成的误报,又能抓住明显的出板绝对移动。边界默认取X=0..bed_size_mm[0]、Y=0..bed_size_mm[1]、Z=0..z_height_mm,可按 profile 中machine.motion_bounds_mm逐轴覆盖。
输出的 JSON 报告包含ok、path、profile快照、errors、warnings与stats(总行数、非注释行数、移动/挤出/温度指令计数)。ok: true只代表通过了静态检查,不代表可安全打印:交付打印机专属流程前仍需人工复核打印机/画像匹配、线材与温度设置、开头与结尾 G-code、床原点与坐标系,以及任何未知命令警告。
Bambu 边界:校验后的 G-code 如何交接
本技能与$bambu-labs的职责切分非常清晰(bambu-labs/SKILL.md):gcode只产纯.gcode,不创建 Bambu.gcode.3mf归档、不接触打印机;打印上传/启动工作流整体交接给$bambu-labs,由后者选择打印机专属的局域网交接方式,例如 A1 Mini 模板项目(template-project)或显式启用的bambox项目包。典型的跨技能链路为:
$cad建模并导出网格;$gcode切片并validate;$bambu-labs对已校验的纯.gcode执行 dry-run 上传,按需--execute --confirm-start-print启动打印。
参考文件
- 技能主文档:skills/gcode/SKILL.md
- 唯一实现脚本:skills/gcode/scripts/gcode_tool.py(
discover/inspect/slice/validate四个子命令,参数定义见 build_parser()) - 后端行为与命令形态参考:skills/gcode/references/slicer-backends.md
- 校验语义与边界策略参考:skills/gcode/references/gcode-validation.md
- 技能元数据:skills/gcode/agents/openai.yaml
- 打印交接技能:skills/bambu-labs/SKILL.md
【免费下载链接】text-to-cadA library of agent skills for CAD, CAE and CAM项目地址: https://gitcode.com/GitHub_Trending/tex/text-to-cad
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考