跳转到内容

编写格式插件

本教程说明如何使用 Python 为 LinkCAD 添加自定义文件格式支持。

格式读取器(导入)

格式读取器会将外部文件格式转换为 LinkCAD 的图纸数据库。

示例:简单坐标文件读取器

from pathlib import Path
from 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 提供用于创建单元、图层和形状的构建器 API
  • drawing.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 Path
from 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_namestr图层名称
cell_namestr单元名称
verticeslist[tuple](x, y) 坐标列表
is_polygonbool对多边形为 True,对折线为 False
widthint折线宽度(多边形为 0)
is_closedbool形状是否闭合

错误处理

使用内置异常类提供清晰的错误报告:

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")

后续步骤