コンテンツにスキップ

linkcad.plugin

プラグインモジュールは、ツール、形式リーダー、形式ライターを作成するためのフレームワークを提供します。スクリプトとプラグインでは linkcad.v1.plugin を使用してください。これは linkcad.plugin の公開名前空間全体をミラーしたもので、まったく同じ API を公開します。

from linkcad.v1.plugin import (
tool, Tool, Option, TableColumn,
format_reader, FormatReader, DrawingContext, CellContext, LayerContext, DrawingBuilder,
format_writer, FormatWriter, WriterContext, ShapeInfo, WriterController,
DialogSpec, ChoiceItem,
EventLog, Phase, LayerFlags, SortOrder,
HolesMode, PolygonType, EndCap, FillRule,
PluginError, ParseError, WriteError, ValidationError,
UNIT_IN_METERS,
)

作業単位

DrawingContext(インポート)と WriterContext(エクスポート)はどちらも units プロパティを持ちます。一度設定すれば、プラグイン境界を越えるすべての座標と幅がその単位で表現されます——プラグインが独自のスケール表を持つ必要はありません。

drawing.units = "mm" # in a reader: the numbers you hand in are millimetres
drawing.units = "um" # in a writer: the numbers you get back are microns
使用できる名前別名
nmummilmmcminchmnanometer/nanometremicron/micrometer/micrometremillimeter/millimetrecentimeter/centimetreinmeter/metre

units を未設定のままにする(または None を代入する)と生のデータベース単位になり、このプロパティが存在しなかった頃のプラグインの挙動とまったく同じです。未知の名前、またはデータベース単位を宣言していない図面の場合は ValidationError が送出されます。

UNIT_IN_METERS は唯一の換算表で、どのプラグインも独自の表を抱え込まずに済むようここから公開されています。黙って食い違いうる 2 つ目の表こそ、かつて出荷済みのツールに 1000 倍の配置誤差を持ち込んだ経路でした。

from linkcad.v1.plugin import UNIT_IN_METERS
to_db_units = UNIT_IN_METERS["mm"] * drawing.units # drawing.units is per metre

デコレーター

@tool()

クラスをメニューツールとして登録します。ツールデコレーター を参照してください。

@tool(name="My Tool", menu="Tools/Custom")
class MyTool(Tool):
def run(self, drawing) -> dict:
# `drawing` is a linkcad.v1.db.Drawing owned by the application.
return {"summary": f"{len(drawing.cells)} cells"}

@format_reader()

クラスをファイルインポート形式として登録します。形式デコレーター を参照してください。

@format_reader(name="My Format", extensions=["*.myf"])
class MyReader(FormatReader):
def read(self, path: Path, drawing: DrawingContext) -> None:
...

リーダーは任意で post_process(phase, drawing, resolution) フックを定義できます。これは解析後に LinkCAD が実行する各フェーズごとに呼ばれる、組み込みネイティブリーダーと同じフックです。read() と同じインスタンス上で実行されるため、そこで記録した情報はそのまま利用できます。False を返すとインポートを中止します。

from linkcad.v1.plugin import Phase
class MyReader(FormatReader):
def post_process(self, phase, drawing, resolution) -> bool:
if phase == Phase.ResolvedRefs:
... # every reference now points at a real cell
return True

FormatReader は LinkCAD が使うネイティブブリッジ parse_file(filepath, builder, file_size, progress_callback) も提供します。ユーザープラグインでは read() を実装し、ブリッジから呼ばせてください。

@format_writer()

クラスをファイルエクスポート形式として登録します。形式デコレーター を参照してください。

@format_writer(name="My Format", extensions=["*.myf"])
class MyWriter(FormatWriter):
def write(self, path: Path, drawing: WriterContext) -> None:
...

FormatWriter は LinkCAD が使うネイティブブリッジ write_file(filepath, controller, set_entity_sink=None) も提供します。ユーザープラグインでは write() を実装し、ブリッジから呼ばせてください。

Option クラス

Option は、型付きで永続化されるオプションを定義するためのファクトリーメソッドを提供します。

ファクトリー結果の型UI コントロール
Option.integer(label, default, min, max)intスピンボックス
Option.real(label, default, min, max, decimals)float小数スピンボックス
Option.boolean(label, default)boolチェックボックス
Option.string(label, default)strテキストフィールド
Option.choice(label, choices, default)strドロップダウン
Option.path(label, default, file_filter)strファイル選択
Option.color(label, default)strカラーピッカー
Option.table(label, columns, default)list[dict]編集可能なグリッド
Option.cell_choice(label, default)strセルのドロップダウン

すべてのファクトリーは省略可能な tooltipenabled_when、さらに生成されるオプションキーを上書きするキーワード専用引数 name を受け取ります。

オプションキーはアプリケーション自身の設定と同じ名前空間を共有します。そのため、クラス属性から生成されるキーは単に接頭辞を付けるのではなく区切られます。AsciiWriterflattenPyPlugin.AsciiWriter.flatten になります。予約されたルート PyPlugin はプラグインオプションをアプリケーションの名前空間から隔離し、クラス部分は flatten という同名のオプションを持つ 2 つのプラグインを区別します。属性名はそのまま使われるため、キーとそれを読む Python 属性の綴りは一致します。

すべてのプラグインオプションは、このキーでコマンドラインからも設定できます。

linkcad --PyPlugin.AsciiWriter.precision=5 ...

コンテキストクラス

DrawingContext

形式リーダー向けの Python らしいビルダーインターフェイスです。

  • units — 座標の単位。作業単位 を参照
  • cell(name, main=False)CellContext を返すコンテキストマネージャー
  • iter_lines(path, encoding="utf-8") — 進捗表示付きの行イテレーター
  • iter_binary(path, chunk_size=8192) — 進捗表示付きのバイナリイテレーター
  • progress0.01.0 の進捗の取得/設定

CellContext

DrawingContext.cell() が返します。

  • layer(name)LayerContext を返すコンテキストマネージャー

LayerContext

CellContext.layer() が返します。座標は図面の作業単位で指定します。

  • polygon(vertices)(x, y) タプルから閉じたポリゴンを作成します
  • polyline(width, vertices, closed=False) — ポリラインを作成します
  • circle(center, diameter) — 円を作成します
def read(self, path: Path, drawing: DrawingContext) -> None:
drawing.units = "um"
with drawing.cell(path.stem, main=True) as cell:
with cell.layer("METAL1") as layer:
layer.polygon([(0, 0), (100, 0), (100, 100), (0, 100)]) # a 100 µm square
layer.polyline(2.5, [(0, 0), (200, 200)])
layer.circle((500, 500), 50)

WriterContext

形式ライター向けの Python らしい読み取りインターフェイスです。

  • units — 受け取るジオメトリの単位。作業単位 を参照
  • flatten — 階層のフラット化の取得/設定。反復前に設定します
  • shapes(cell=None, layer=None) — 進捗表示付きで形状を反復します
  • shapes_by_layer(cell=None) — レイヤーごとにグループ化した形状
  • shapes_by_cell(layer=None) — セルごとにグループ化した形状
  • cell_names / layer_names — 名前のリスト
  • cell_count / shape_count — 個数
  • main_cell_name — トップセル名
  • progress0.01.0 の進捗の取得/設定

shapes() とその 2 つのグループ化を除けば、いずれも名詞でありプロパティです。cells()layers() のジェネレーターは廃止されました。cell_nameslayer_names がすでに保持しているのとまったく同じ文字列を返しており、1 つのリストに 2 つの綴りがあるのは正解のない選択だからです。

shapes() は、フラット化の有無にかかわらずジオメトリを走査する唯一の手段です。flatten = False では各セル自身の形状を走査し、参照の処理は呼び出し側に委ねます。flatten = True ではホストコントローラーを通じて階層をレンダリングし、降下しながら変換スタックを適用して途中で曲線をテセレーションします——したがって円弧、円、ドーナツ、NURBS がポリゴンやポリラインとしてライターに届くのはフラット化が有効なときだけです。

def write(self, path: Path, drawing: WriterContext) -> None:
drawing.units = "mm"
drawing.flatten = True
with open(path, "w") as f:
for shape in drawing.shapes():
for x, y in shape.vertices: # millimetres
f.write(f"{x:.4f} {y:.4f}\n")
f.write("\n")

フラット化された走査にはホストライターが必要なため、FormatWriter.write() の中でのみ利用できます。手作業で構築した WriterContextflatten = False しか使えません。

ShapeInfo

WriterContext.shapes() が返すデータクラスです。

  • layer_name: str — レイヤー名
  • cell_name: str — セル名
  • vertices: list[tuple] — 作業単位での (x, y) 座標
  • is_polygon: bool — ポリゴンか、ポリライン的な出力か
  • width: int — 作業単位でのポリライン幅
  • is_closed: bool — 形状が閉じているかどうか

ネイティブ形式インターフェイス

ほとんどの形式プラグインは DrawingContextWriterContext で足ります。LinkCAD の低レベル形式 API と直接対応させたいプラグインのために、ネイティブの DrawingBuilderWriterController も公開されています。

DrawingBuilder

DrawingBuilder は LinkCAD ランタイムからインポートプラグインに渡されます。ユーザーコードが直接作成することはありません。

プロパティ説明
builder.resolution曲線テセレーションの設定
builder.cell現在のセル、または None
builder.layer現在のレイヤー、または None
builder.cell_object直近に作成されたセルオブジェクト、または None
builder.drawing構築中の図面
メソッド群メソッド
図面メタデータset_drawing_name(name)set_drawing_modif_time(time)set_drawing_access_time(time)set_progress(percent)
セルopen_cell(name_or_number, is_main_cell=False, reopen=False)close_cell()delete_cell()set_cell_name(name)set_cell_modif_time(time)set_cell_access_time(time)find_cell(name)
レイヤーselect_layer(name_or_number)select_layer(major, minor)set_layer_comment(comment)set_layer_color(rgba)set_layer_enabled(enabled)set_layer_z(z)set_layer_polarity_positive(positive=True)set_layer_polarity_group(group_name)set_layer_polarity_sequence(sequence)
形状create_polygon(vertices, make_simple=False)create_polygon_with_bulges(vertices, bulges)create_rectangle(corner1, corner2)create_polyline(width, vertices, closed=False, end_cap=EndCap.Round)create_circle(center, diameter, donut=False)create_arc(center, radius, width, start_angle=0.0, end_angle=360.0, end_cap=EndCap.Round)create_donut(center, mean_diameter, width)create_nurbs(width, degree, knots, control_points, periodic=False)create_nurbs_weighted(width, degree, knots, control_points, weights, periodic=False)
テキストcreate_text()set_text_position(position)set_text_height(height)set_text_stroke_width(width)set_text_style(flags, mask=TextStyleMask.None_)set_formatted_text(text)set_unformatted_text(text)set_text_font(font_name)set_text_width_factor(factor)set_text_obliquing_angle(angle_degrees)set_text_mirrored_x(mirror=True)set_text_mirrored_y(mirror=True)set_text_rotation(angle_degrees, absolute=False)set_text_box_width(width)set_text_line_spacing(spacing)
参照create_ref(cell_name_or_number)scale_ref(scale, absolute=False)mirror_ref_x(negate=True)mirror_ref_y(negate=True)rotate_ref(angle_degrees, absolute=False)translate_ref(position)set_ref_array_spacing(dx, dy)set_ref_array_size(cols, rows)
コンテキストsave_context()enter_context(handle)leave_context()
ログlog_info(message)log_warning(message)log_error(message)
プロパティとスタイルset_entity_layer_style(flags)set_current_cell_object_real_property(name, value)set_current_cell_object_bool_property(name, value)
フォントDrawingBuilder.register_odb_fonts(fonts_dir)
from linkcad.v1.db import EndCap, TextStyle, TextStyleMask
from linkcad.v1.geom import Point
builder.open_cell("TOP", is_main_cell=True)
builder.select_layer("metal1")
builder.create_arc(Point(0, 0), radius=10_000, width=500, end_cap=EndCap.Round)
builder.create_text()
builder.set_text_position(Point(0, 12_000))
builder.set_text_height(1_000)
builder.set_text_style(TextStyle.AlignHCenter, TextStyleMask.AlignH)
builder.set_unformatted_text("TOP")
builder.close_cell()

WriterController

WriterController は LinkCAD ランタイムからエクスポートプラグインに渡されます。ユーザーコードが直接作成することはありません。

プロパティ説明
controller.file_name出力ファイルのパス
controller.resolution曲線テセレーションの設定
controller.drawingエクスポート中の図面
controller.main_cellメインセル
controller.units_per_meterメートルあたりのデータベース単位。図面が宣言していなければ 0
controller.layers有効なすべてのレイヤー(通常順)
controller.layer_names有効なすべてのレイヤーの名前
controller.layer_count有効なレイヤー数
controller.cellsすべてのサブセル(子が先。メインセルは含みません)
controller.cell_namesメインセルを含むすべてのセルの名前
controller.cell_countメインセルを含むセル数
controller.fonts図面で使用されているすべてのフォント
controller.object_count処理済みオブジェクト数
controller.total_object_countエクスポート対象オブジェクトの総数
controller.fill_rule現在の FillRule
controller.transformation座標変換スタックの現在の最上位
メソッド群メソッド
ログと進捗log_info(message)log_warning(message)log_error(message)set_progress(percent)init_progress_counter(force_flattened=False)set_object_count(count)set_total_object_count(count)
エクスポート設定set_polygon_mode(holes_mode, polygon_type)
絞り込みアクセサーfiltered_layers(sort_order=SortOrder.Regular)filtered_cells(layer=None)
逐次列挙start_enum_layers(sort_order=SortOrder.Regular)next_layer()start_enum_cells()next_cell(layer=None)start_enum_fonts()next_font()
変換transform_point(point)transform_distance(distance)

layerscells が一般的なケースで、filtered_layers(sort_order)filtered_cells(layer) はそれらのプロパティが隠しているパラメーターを露出します——cell.shapes / cell.filtered_shapes と同じ組み合わせです。

from linkcad.v1.plugin import SortOrder
for layer in controller.filtered_layers(SortOrder.Reverse):
for cell in controller.filtered_cells(layer):
...

プッシュ側はフレームワークのもの

LinkCAD はジオメトリを 2 通りの方法でエクスポートします。プラグインが形状を引き出すか、コントローラーがレンダリング済みのエンティティをライターへ押し込むかです。フラット化できるのはプッシュ方向だけです。参照をたどって降下する際に構築される変換スタックを持っているのはコントローラーだけだからです——手動でプッシュ側を操作したプラグインは、配置情報のない形状を受け取り、それを知らせるエラーも出ません。

そのため _render_cell_render_cell_in_layer_order_flatten_cell_hierarchy_get_shapes にはアンダースコアが付いています。これらはフレームワークのものであり、WriterContext が代わりに駆動します。drawing.flatten = True を設定して drawing.shapes() を反復してください。配置がすでに適用された、同じ走査です。

HolesModePolygonType は安定したプラグインモジュールから利用でき、WriterController.set_polygon_mode() で使用します。

from linkcad.v1.plugin import HolesMode, PolygonType
controller.set_polygon_mode(HolesMode.Link, PolygonType.AllowComplex)

DialogSpec

DialogSpec は形式やツールのオプションダイアログを宣言的に記述します。Rust プラグインのダイアログモデルに対応しており、LinkCAD の UI が読み取る JSON 形式にシリアライズされます。

from linkcad.v1.plugin import DialogSpec, ChoiceItem
spec = (
DialogSpec("Import Options")
.group("Geometry")
.bool_field("merge", "Merge polygons", True)
.int_field("facets", "Minimum facets", 4, 256, 32)
.combo_field("units", "Units", ["nm", "um", "mm"], "um")
.group_in_row("Layers", row=1)
.single_select_list(
"layer",
"Layer",
[ChoiceItem.with_display("metal1", "Metal 1")],
)
)
json_payload = spec.to_json()
目的
DialogSpec(title)最上位のダイアログ記述子
DialogGroup(label, row=None)関連するフィールドのグループ。同じ row を持つグループは横並びに配置できます
UiWidget(option_name, label, kind)グループ内の単一の UI 要素
WidgetKind(kind_type, **kwargs)ウィジェットの種類と設定
ChoiceItem(value, display, description=None)リスト/コンボボックスの選択肢
ビルダーメソッド説明
group(label)グループを開始します
group_in_row(label, row)指定行にグループを開始します
bool_field(option_name, label, default)チェックボックス
int_field(option_name, label, min, max, default)整数スピンボックス
real_field(option_name, label, min, max, default)小数スピンボックス
string_field(option_name, label, default)テキスト行
combo_field(option_name, label, choices, default)文字列からのコンボボックス
single_select_list(option_name, label, static_choices=None, inspection_key=None)単一選択リスト
multi_select_list(option_name, label, static_choices=None, inspection_key=None, value_separator=",")複数選択リスト
note(text)表示専用の注記
separator()水平の区切り線
to_json()JSON にシリアライズします

ChoiceItem には simple(value)with_display(value, display)full(value, display, description) のファクトリーメソッドがあります。

形式メタデータ

リーダーとライターのデコレーターは、プラグインクラスに FormatInfo オブジェクトを付与します。より低レベルの形式制約には linkcad.v1.conv.FormatFormatAttributes を使用してください。linkcad.conv を参照してください。

from linkcad.v1.conv import Format, FormatAttributes
fmt = Format()
fmt.attributes = FormatAttributes.LAYER_NAMES | FormatAttributes.CELL_NAMES
fmt.layer_max_length = 32

例外

例外用途
PluginErrorすべてのプラグインエラーの基底クラス
ParseErrorファイル解析エラー。キーワード引数 linepath を受け取ります
WriteErrorファイル書き込みエラー
ValidationErrorオプションの検証エラー

TableColumn

テーブルオプションの列を定義するデータクラスです。

  • key: str — 辞書キー
  • label: str — 列見出し
  • col_type: strstringintegerrealchoicecell_choice
  • default: Any — 既定値
  • choices: list[str]choice 列向け
  • decimals: intreal 列向け
  • min_value / max_value — 数値列向け

列挙型

列挙型用途
PhaseParsedFileParsedAllClosedOpenCellsResolvedRefsSelectedMainCellResolvedLayersByBlockAutoNumberedZリーダー後処理のフェーズフック
LayerFlagsNormalByLayerByBlockDrawingBuilder.set_entity_layer_style() におけるレイヤー属性の継承
SortOrderRegularReverseWriterController のレイヤー列挙順
EndCapRoundSquareExtendedSquareFlatビルダーでの形状作成用に linkcad.v1.db.EndCap を再エクスポート
FillRuleNonZeroEvenOddライターの塗りつぶし規則用に linkcad.v1.db.FillRule を再エクスポート

ライターのポリゴンモード列挙型は linkcad.v1.plugin から利用できます。

列挙型用途
HolesModeLinkSplitExtractKeepポリゴンエクスポート時の穴の表現方法
PolygonTypeAllowComplexForceSimpleレンダリングされるポリゴンが複雑であってよいか