编写格式插件
本教程说明如何使用 Python 为 LinkCAD 添加自定义文件格式支持。
格式读取器(导入)
格式读取器会将外部文件格式转换为 LinkCAD 的图纸数据库。
示例:简单坐标文件读取器
from pathlib import Pathfrom linkcad.plugin import format_reader, FormatReader, Option, DrawingContext
@format_reader( name="Coordinate File", extensions=["*.xyz", "*.coord"], description="Simple X Y coordinate files",)class CoordReader(FormatReader): scale = Option.integer("Scale factor", default=1000, min=1, max=1000000) layer_name = Option.string("Layer name", default="imported")
def read(self, path: Path, drawing: DrawingContext) -> None: with drawing.cell(path.stem, main=True) as cell: with cell.layer(self.layer_name) as layer: vertices = [] for line in drawing.iter_lines(path): line = line.strip() if not line or line.startswith("#"): # Blank line = end of polygon if vertices: layer.polygon(vertices) vertices = [] continue parts = line.split() x = float(parts[0]) * self.scale y = float(parts[1]) * self.scale vertices.append((x, y))
# Don't forget the last polygon if vertices: layer.polygon(vertices)关键概念
@format_reader()将类注册为导入格式extensions决定读取器处理哪些文件DrawingContext提供用于创建单元、图层和形状的构建器 APIdrawing.iter_lines()使用自动进度跟踪读取文本行drawing.iter_binary()使用进度跟踪读取二进制数据
DrawingContext API
| 方法 | 说明 |
|---|---|
cell(name, main=False) | 上下文管理器——创建/打开单元 |
iter_lines(path) | 带进度迭代文本文件行 |
iter_binary(path, chunk_size) | 带进度迭代二进制块 |
progress | 获取/设置进度(0.0 到 1.0) |
CellContext API
| 方法 | 说明 |
|---|---|
layer(name) | 上下文管理器——选择图层 |
LayerContext API
| 方法 | 说明 |
|---|---|
polygon(vertices) | 从 (x, y) 元组创建多边形 |
polyline(width, vertices, closed) | 创建折线 |
circle(center, diameter) | 创建圆 |
格式写入器(导出)
格式写入器会将 LinkCAD 几何图形导出到文件。
示例:简单文本写入器
from pathlib import Pathfrom linkcad.plugin import format_writer, FormatWriter, Option, WriterContext
@format_writer( name="Simple Text", extensions=["*.stxt"],)class SimpleWriter(FormatWriter): separator = Option.choice( "Separator", choices=["Space", "Comma", "Tab"], default="Space", ) precision = Option.integer("Decimal places", default=3, min=0, max=10)
def write(self, path: Path, drawing: WriterContext) -> None: sep = {"Space": " ", "Comma": ", ", "Tab": "\t"}[self.separator]
with open(path, "w") as f: for layer_name, shapes in drawing.shapes_by_layer(): f.write(f"# Layer: {layer_name}\n") for shape in shapes: for x, y in shape.vertices: f.write(f"{x:.{self.precision}f}{sep}" f"{y:.{self.precision}f}\n") f.write("\n")WriterContext API
| 方法 | 说明 |
|---|---|
shapes(cell, layer) | 迭代所有形状(可选单元/图层过滤器) |
shapes_by_layer(cell) | 迭代按图层分组的形状 |
shapes_by_cell(layer) | 迭代按单元分组的形状 |
cells() | 迭代单元名称 |
layers() | 迭代图层名称 |
cell_count() | 单元数量 |
shape_count() | 形状总数 |
main_cell_name() | 顶层单元名称 |
layer_names() | 所有图层名称列表 |
flatten | 获取/设置层次结构展平 |
progress | 获取/设置进度(0.0 到 1.0) |
ShapeInfo 属性
| 属性 | 类型 | 说明 |
|---|---|---|
layer_name | str | 图层名称 |
cell_name | str | 单元名称 |
vertices | list[tuple] | (x, y) 坐标列表 |
is_polygon | bool | 对多边形为 True,对折线为 False |
width | int | 折线宽度(多边形为 0) |
is_closed | bool | 形状是否闭合 |
错误处理
使用内置异常类提供清晰的错误报告:
from linkcad.plugin import ParseError, WriteError, ValidationError
# In a reader:raise ParseError("Invalid coordinate", line=42, path=path)
# In a writer:raise WriteError("Cannot write to locked file")
# In option validation:raise ValidationError("Scale must be positive")