コンテンツにスキップ

形式プラグインの作成

このチュートリアルでは、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")

次のステップ