mcpField
D
dxf

dxf

github.com/earthtojake设计与 UI23.9k9.4k 次安装今天更新
代码仓库

关于 dxf

用于按需求或 CAD 几何创建并校验 2D DXF 图纸,适用于 CAD 与制造流程。技能以 build123d 几何为基础,可从零绘制,也可从生成或导入的 STEP 零件提取展开图。

主要功能

  1. 01根据 2D 几何创建 DXF 图纸
  2. 02从 CAD 零件提取展开图
  3. 03将几何分配到命名图层
  4. 04校验图纸几何与输出
  5. 05渲染 DXF 快照

适用场景

  1. 01准备激光或水刀切割轮廓
  2. 02从 STEP 零件制作展开图
  3. 03创建模板、面板或垫片

安装

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

$npx skills add https://github.com/earthtojake/text-to-cad --skill dxf

安装后在 Claude Code 中输入/dxf确认已加载。

包含的文件

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

LICENSE
agents/
openai.yaml
references/
generator-templates.md

详细介绍

DXF 生成与验证

来源:由 earthtojake/text-to-cad 维护。 以已安装的本地技能文件作为运行时事实来源;仓库链接仅用于追溯来源和审查发布版本。

设置

通过 uv 运行 cadgen,让此技能的命令与 CAD 应用的服务共用 同一套安装,以及它的预热构建守护进程:

  • 下文中的 cadgen 指 uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 cadgen
  • 下文中的 python 指 uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 python

首次运行时会下载该安装包,首次生成快照时会下载其无头浏览器;之后的运行会复用二者。

cadgen doctor <skill-dir> 会报告正在使用的安装,并检查它是否为此技能指定的版本,以及 CAD 内核是否能够加载;遇到安装或内核加载错误时,请使用它。

图纸由 build123d 几何构成,因此构建图纸时会像构建 STEP 一样加载 CAD 内核(冷启动约需 2.5 秒;后续运行由预热守护进程处理)。 cadgen dxf snapshot 完全不需要 Node:它使用 ezdxf(随 cadgen 安装)展平图纸,并在捆绑的无头浏览器中绘制图纸。

用途

根据自然语言需求或 CAD 几何创建或修改 2D DXF 图纸,生成经过验证的图纸构件,并返回已检查的输出。DXF 图纸的事实来源是名为 <name>.py 的 Python 文件,其中定义了一个无参数的 @dxf 模型函数。

图纸也是模型。 它与 @step 零件拥有相同的包装器、记录、时效性检查和构建任务;其唯一输出是 .dxf 文件;它没有几何树(没有任何内容会链接到图纸)。每次运行都会写入同级目录下的 <name>.dxf(或装饰器指定的 out=);源文件未变更时不会执行任何操作;如果图纸调用零件模型(在函数体内调用 bracket()),那么只要该零件的几何发生变化,图纸就会过期;如果几何未变,则图纸保持最新;cadgen store why <drawing>.py 会解释判定结果;--force 则会强制重新构建。CAD Viewer 和 dxf snapshot 都会读取 .dxf 文件本身,因此交给切割服务的文件、查看器绘制的文件和快照渲染的文件完全相同。

约定

@dxf 函数不接受任何参数,并返回 build123d 2D 几何。引擎负责写入 DXF。 你无需创建文档、命名文件或放置实体——分工方式与 @step 相同。

from cadgen import build123d as bd
from cadgen import dxf


HOLE_D = 4.5


@dxf
def gasket():
    with bd.BuildSketch() as cut:
        bd.Rectangle(60, 40)
        bd.Circle(HOLE_D / 2, mode=bd.Mode.SUBTRACT)
    return cut.sketch          # bare shape -> the CUT layer


if __name__ == "__main__":
    gasket()
  • 裸形状 → 一个 CUT 图层。这就是大多数图纸所需的全部约定。
  • {layer: shape} → 命名图层;仅当图纸确实包含多种 CAM 操作(CUT / ENGRAVE / SCORE)时使用。子项全部带标签的 Compound 也表示相同的含义。
  • 无参数。 尺寸使用模块常量(HOLE_D = 4.5),或从图纸所依据的零件中导入的常量;不同的图纸应使用不同的文件。
  • 文本使用 bd.Text(...),作为标记图层上的雕刻轮廓,而不是 DXF TEXT 实体:切割和标记工具链处理的是几何,而 CAM 内部的字体渲染并不可靠。
  • 几何必须位于 XY 平面。 从实体中取得的面位于该实体的高度;应将其移位(flatten.flatten_face(face),或 bd.Location((0, 0, -z)) * face)。引擎会拒绝不在平面上的几何,而不会悄悄写入其 XY 投影。
  • 输出字节由几何决定。 图层按名称排序,实体按几何内容排序,因此无论冷启动还是预热状态,在任何机器上,未变更的图纸重建后都会生成完全相同的文件。

三种 DXF 工作流

新建图纸时,从 references/generator-templates.md 中复制适用于相应工作流的完整模板。

  1. 从头绘制(垫片、面板、模板、没有 3D 模型作为基础的切割布局):编写一个构建草图并返回草图的 <name>.py 文件。

  2. 生成的 STEP 零件的平面展开图:在模型旁边编写绘图脚本,并使用其自己的文件名主干(每个文件对应一个模型——bracket_drawing.py 放在 bracket.py 旁边)。导入模型并调用它,就像装配体组合子零件一样:导入不会触发构建;在绘图的构建函数中调用时会返回零件的几何体(如果零件已过期,则先构建零件)。

    from cadgen import dxf, flatten
    from bracket import bracket        # a child: tracked by its RESULT
    
    KERF = 0.15
    
    
    @dxf
    def bracket_drawing():
        return flatten.flat_pattern(bracket(), coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        bracket_drawing()
    

    绘图的记录会固定零件的依赖树,因此,若零件编辑改变了其几何体,绘图就会过期;若未改变(例如注释、重构或颜色),绘图则仍为最新。从零件导入的常量(from bracket import THICKNESS)也会以相同方式按值跟踪。

  3. 导入的 STEP 的平面展开图(没有 Python 源代码的 .step/.stp):使用 cadgen.read_step 读取(从存储中热加载,几何体与 build123d.import_step 相同)。与构建读取的任何文件一样,它是一个输入:替换供应商提供的 STEP 文件会使绘图自行过期,无需 --force。

    from pathlib import Path
    
    from cadgen import dxf, flatten, read_step
    
    _HERE = Path(__file__).resolve().parent
    
    KERF = 0.15
    
    
    @dxf
    def panel_flat():
        panel = read_step(_HERE / "imported" / "vendor_panel.step")   # recorded input
        return flatten.flat_pattern(panel, coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        panel_flat()
    

    切勿读取本项目生成的 STEP 文件。 读取 @step 模型写入的 .step 文件并非循环依赖,而是让绘图的输入在模型每次运行时都发生变化:新鲜度检查永远无法判定其“最新”,每次构建都会完整重建,而且平面展开图依赖于磁盘上上次运行留下的文件。将源 STEP 文件放在绘图旁边的 imported/ 目录中,并像其他输入一样提交——输入路径和输出路径必须是不同文件,这就是整条规则。对于本项目生成的 STEP 文件,应改用工作流 2:导入模型脚本并调用它,这种方式会跟踪结果,且从不触碰构建产物。

建议每个文件只放一个模型,并为绘图单独编写脚本:一个文件 MAY 声明多个模型——两个 @dxf 绘图,或一个 @dxf 与一个 @step 并列——每个模型都有自己的记录、输出和任务(单个模型会写入 <file>.dxf;同一文件中的多个模型会写入 <function>.dxf),但它们共用该文件的闭包,因此编辑其中一个会触发全部模型重建。绘图会组合模型,反之则不成立:在 @step 函数体中调用 @dxf 函数,只会得到其 2D 几何体,不会建立任何关联。查看器目录中只有构建产物:脚本不会列出;运行生成的 .dxf 才是查看器渲染的条目。

何时使用此技能

当用户需要用于激光、等离子、水刀或 CNC 铣切的 DXF 文件、2D 图纸、轮廓、外形、模板、垫片、面板、平面展开图或切割布局时,请使用此技能。

对于 DXF 衍生出的 3D 零件或装配体,请使用 $cad。对于 SendCutSend 专用的上传预检,请使用 $sendcutsend。

默认设置

除非用户另有指定,否则使用以下默认设置:

  • 单位:毫米。由引擎设置,图纸不会声明单位。
  • 几何图形以 1:1 比例位于 XY 平面。
  • 切割轮廓必须闭合。开放轮廓应放在弯折/雕刻/参考图层上 — 生成验证会强制执行此规则(参见 Validation)。
  • 对于由 CAD 驱动的零件,应使用 cadgen.flatten 从实际拓扑派生轮廓,而不是重新绘制:planar_faces 用于选择, flatten_face 会将面精确铺展到 XY 平面,union_faces 用于融合,而 flat_pattern 一次调用即可完成所有操作。仅当不存在可靠的 3D 拓扑时, 才手绘参数化轮廓。
  • 切缝/刀具半径补偿使用 flatten.offset_profile(shape, amount) 或 flat_pattern(..., kerf=...);切勿手动偏移坐标。
  • 曲线必须保持为曲线。 联合和偏移都是精确的 OCC 操作,因此圆角会导出为 ARC,孔会导出为 CIRCLE,包括切缝补偿后的结果。如果轮廓最终变成数百条短 LINE,说明某处回退到了采样路径 — 请调查原因,而不要接受这种结果。
  • 图层承载设计意图:将切割几何图形与弯折/折线放在不同图层上,并在弯折图层名称中 包含“bend”,以便下游工具将其归类为弯折而非切割。
  • DXF 图层属于图纸结构,不属于 STEP 零件/装配体结构。

工具

python <drawing>.py [flags]                    # its __main__ calls the @dxf model, which writes the .dxf
cadgen dxf snapshot <drawing.dxf> <file.png>   # render it
cadgen store why <drawing>.py                  # why the drawing is stale or current

运行脚本(其 __main__ 调用)是唯一入口。 没有 cadgen dxf build:.dxf 没有需要命令生成的派生状态 — 文件本身就是产品,CAD Viewer 和 dxf snapshot 都会直接从文件自身的字节绘制。 图纸的关卡让重建成本很低:如果源文件未更改、.dxf 仍通过验证,且零件子项也未更改, 则不会执行任何操作;而 --force 会无条件重建。文件字节由图纸的 几何图形决定,因此冷启动和热运行的守护进程工作器会写出相同的 文件。构建之间不会互相等待或取消;调用零件的图纸会像任何父项一样并行构建这些零件。

导入的 .dxf 完全不需要任何处理 — 直接交给 snapshot 或 Viewer 即可。

使用当前激活的项目 Python 解释器;将 python 视为解释器占位符,并使用 --help 查看完整接口。目标路径相对于命令的当前工作目录解析;请从拥有这些构件的工作区运行, 并使用相对于 cwd 的目标路径。将图纸脚本放在它所派生的几何图形所在目录中, 命名为 <name>.py。

标志(模型脚本会自行运行;没有生成 CLI):

  • --force — 即使记录的输出已是最新,也重新生成。
  • --verbose、--json。

运行结果会像 STEP 模型一样准确地输出到 stdout — built DXF/plate_drawing.dxf 或 current DXF/plate_drawing.dxf — 进度信息则输出到 stderr;使用 --json 时, 结果会作为一行 JSON 输出(包含 outcome、document 和 tree;对于 图纸,tree 为 null),每次状态转换的进度也各输出一行 JSON。

一个脚本对应一张图纸:对每个要构建的脚本分别运行。不要将输出路径放入 @dxf 函数的返回值中;图纸唯一指定目标位置的地方是装饰器上的 out=(相对于脚本)。

cadgen dxf snapshot 会将图纸平面绘制为 PNG 静态图 — 与 CAD Viewer 显示的画面相同, 使用相同的展平方式,并通过相同的图纸代码绘制:

cadgen dxf snapshot path/to/imported.dxf review.png
cadgen dxf snapshot path/to/drawing.dxf review.png --appearance dark

它只接受 .dxf 文档 — 会根据名称拒绝模型脚本(请运行 python <drawing>.py,然后对其写出的图纸执行 snapshot)。整张图纸会适配到图像中, 并从正面绘制,使用文件声明的画笔;没有自带画笔的实体(ACI 7)会使用外观在其 背景上的前景色。该命令使用 ezdxf 展平图纸,并通过共享的 snapshot CLI (cadgen.snapshot_cli)以及所有渲染技能共用的无头浏览器运行时进行渲染。 OUT(第二个位置参数)会按给定内容原样写入,相对路径会相对于当前工作目录解析。渲染开始前会先删除目标文件,并以原子方式写入完成的图像,因此:迭代时重复使用同一个名称(可确保每次读取的都是刚刚生成的渲染结果);只有确实需要比较两个版本时,才为不同迭代命名。无效的请求组合会在触碰 OUT 之前失败;请求被接受后,会先清空 OUT,因此之后若发生故障,留下的是缺失文件,而不是过时图像。目录(例如作为 OUT 的 tmp/)属于不在意文件名的情况,系统会在其中生成带时间戳的名称,并打印在 saved snapshot: 行中。

语法:cadgen dxf snapshot TARGET [OUT] [flags]。标志:--appearance light|dark、--size-profile、--width/--height、--job、--debug、 --json。绘图没有 3D 场景设置:--camera、--display、--mode 和 --view-labels 不是 CLI 标志。作业可以用平面视图 camera 为绘图中的一个窗口设置取景范围 ({"target": [x, y, 0], "position": [x, y, d], "up": [0, 1, 0], "orthographicHalfHeight": h}),并在其上按绘图坐标绘制 annotation; Quick Edit 提示词中的视图文件就是这种作业,使用 cadgen dxf snapshot --job <it> 可重新渲染用户看到的视图。 其他相机姿态、每个输出单独设置的相机、场景显示设置、scale、列表模式、输出 label/viewLabel,以及 output.padding/viewLabels/tightFrame 都会被拒绝。 作业中的 output.renderScale 和 output.transparent 仍然有效。 Quick Edit 会以内嵌 JSON 或 .snapshot.json 路径的形式提供此数据包;使用 --job 之前,请先将内嵌 JSON 保存到临时文件。 编辑前请检查提供的注释。没有注释时,所捕获的视图只是可选的上下文信息。

没有 CLI 可以检查现有的 .dxf。要检查实体和图层,请直接用 ezdxf 读取(它随 build123d 一起提供);要检查绘图,请使用 validate_dxf_file。

请通过目视检查几何图形(参见显示模型)。

工作流

  1. 将请求整理成简短的需求说明:轮廓尺寸、孔和槽、图层、单位、输出路径以及验证目标。
  2. 选择工作流:从头绘制、生成模型的平面展开图(先使用 $cad 创建并验证 3D 几何图形),或导入 STEP 的平面展开图。
  3. 编写或编辑 <name>.py 源文件,将有意义的尺寸设为命名常量,并复用模型的几何辅助函数,而不是重复公式。
  4. 直接运行每个绘图脚本(python <drawing>.py);不要遍历目录。
python path/to/source.py
python path/to/source.py --force
  1. 确定性地验证生成的 DXF,然后交付并报告。

显示模型

向用户展示你创建或修改的每个文件,以及用户要求查看的文件。快照和验证不能替代此步骤。

  • 如果你的工具中包含 cad_show(宿主可能会为其添加前缀),请使用文件的绝对路径调用它,并按照工具说明决定何时再次调用。cad_view 读取用户选中的内容;cad_screenshot 显示用户看到的内容。两者都不能用于审查你自己的工作。

  • 否则,请从任意文件夹运行 CAD Viewer:

    cadgen viewer --host 127.0.0.1 --json --detach
    

    --detach 会在查看器能够响应请求后返回,并让它在后台继续运行:务必传入此参数,因为前台运行的查看器永远不会退出(而将其输出通过管道传给 tail 可能会彻底隐藏 URL)。它会启动本机的唯一查看器,或复用已有查看器。从唯一一行 JSON 中读取 url(绝不要猜测端口),并为每个文件返回 url?file=<该文件经过 URL 编码的绝对路径>。如果启动失败,请说明。

查看器会将已保存的 DXF 文件渲染为只读的 2D 图纸;它不会运行生成脚本。拖动以平移,滚轮/捏合以缩放,双击以适应窗口。它的 Select、Pencil、Shapes 和 Measure 会将内容传入 Quick Edit;其中的提示词会通过实体 HANDLE,将用户选取的对象作为图纸中的参考:panel.dxf#h2F 表示其句柄为 2F 的模型空间实体(在 ezdxf 中为 doc.entitydb["2F"]);块引用绘制的所有内容均以其 INSERT 命名,尺寸标注则是单个实体。提示词的标签会显示该实体的类型和图层(“Circle on CUT”)。测量值采用 $INSUNITS 声明的单位(未声明单位时显示为“units”)。

验证

验证在生成过程中进行,而非生成后进行:每次 @dxf 构建都会在写入任何内容之前,对引擎刚刚序列化的文档运行图纸检查;若检查发现错误,构建就会失败。检查内容包括:切割图层上的轮廓必须闭合(多段线、圆或由线段/圆弧串联成的环);拒绝零长度/退化实体;拒绝完全重复的几何图形(存在重复切割风险);拒绝明确声明为无单位的文档;拒绝空模型空间。仅当图层名称匹配时,才允许弯折/雕刻/参考意图图层上的开放几何图形。

同一组检查也会对任何现有的 .dxf 文件进行事后检查,包括从未由生成器生成的文件;调用 cadgen.drawing_checks 即可:

from cadgen.drawing_checks import validate_dxf_file

for finding in validate_dxf_file("path/to/file.dxf"):
    print(finding.render())

除内置检查外,还要针对生成的同目录 .dxf 文件(或声明了 out= 时所指定的路径),使用 ezdxf 有针对性地读取并验证用户要求的尺寸(按图层统计实体数量、图纸范围以及用户指定的每一项尺寸),并在 CAD Viewer 中目视检查几何图形:

import ezdxf

doc = ezdxf.readfile("path/to/source.dxf")
msp = doc.modelspace()
cut = msp.query('*[layer=="CUT"]')
holes = msp.query('CIRCLE[layer=="CUT"]')

只报告实际运行过的检查。

交付

展示你创建或修改的每张图纸(显示模型)。 明确报告任何失败。

最终回复应包含生成的文件、返回的查看器链接、实际运行的验证,以及所作的假设。

评论

支持 Markdown