コンテンツにスキップ

linkcad.db

データベースモジュールは、LinkCAD のインメモリ図面データベースへのアクセスを提供します。すべてのデータベースオブジェクトは、性能のためネイティブ実装に支えられています。

スクリプトとプラグインでは、安定した linkcad.v1.db 名前空間を使用してください。これは linkcad.db の公開名前空間全体をミラーしたもので、オブジェクトは同一です。

from linkcad.v1 import db
with db.Drawing("scratch") as dwg:
cell = dwg.add_cell("TOP")

または、使う名前をインポートします。

from linkcad.v1.db import (
Drawing, Cell, Layer, Object, DrawingObject, CellObject, Shape,
Polygon, Polyline, Arc, Ellipse, Donut, Nurbs, Text, Ref,
Color, Property, ReadLock, WriteLock, Transaction,
Unit, ObjectType, CellContext, EndCap, FillRule,
BooleanOperation, MergeLayerPolarityResult, TextStyle, TextStyleMask,
)

最初に押さえておく規則

この API は全体を通じて同じ規約に従っています。このモジュールでも、他のどのモジュールでも同じです。これを知っていれば調べ物はほとんど不要です。

  1. 名詞はプロパティ、動詞はメソッド。 shape.areacell.shapespolygon.verticesarc.radiusobj.boundsobj.selected——括弧は付きません。destroy()clone()rotate()reverse()toggle_selection() は括弧を保ちます。
  2. ゲッター/セッターの対は 1 つの読み書き可能プロパティであり、2 つの名前にはならない。 セッターを呼ぶのではなく代入してください: arc.center = Point(0, 0)layer.enabled = Falseobj.selected = True。ジオメトリに set_* メソッドはありません。
  3. ジオメトリは、それを所有することになるオブジェクトが作成する。 図面はセルとレイヤーを作り(drawing.add_celldrawing.add_layer)、セルは形状を作ります(cell.add_polygoncell.add_arccell.add_ref など)。独立したコンストラクターも静的ファクトリーもありません。
  4. アクセサーにパラメーターが必要な場合、プロパティが一般的なケースを担当し、filtered_* メソッドが残りを担当します——cell.shapes はすべての形状、cell.filtered_shapes(selected_only=True) は絞り込みです。

さらに 2 つの規約が、呼び出しのたびの変換を不要にします。

  • 座標は Point または (x, y) の対であり、linkcad.db が座標を受け取るあらゆる場所——頂点の並び、add_arc(center=…)add_text(position=…)text.position = …——で相互に使えます。
  • レイヤーは Layer、レイヤー名、または None obj.layer = "METAL1" はオブジェクトをそのレイヤーへ移し、存在しなければ作成します。obj.layer = None は既定のレイヤーへ移します。

クラス

Drawing

すべてのレイアウトデータを収める最上位のコンテナです。

図面はデータベース全体をメモリに保持しており、確実に解放する必要があります——インタープリター終了時まで残るとプロセスがクラッシュします。コンテキストマネージャーとして使えば忘れようがありません。

from linkcad.v1.db import Drawing
with Drawing("scratch") as dwg:
cell = dwg.add_cell("TOP")
dwg.main_cell = cell
metal = dwg.add_layer("METAL1")
cell.add_polygon(metal, [(0, 0), (10_000, 0), (10_000, 10_000), (0, 10_000)])

ツールプラグインの中では、図面は run() に渡され、アプリケーションが所有しています。そこで破棄してはいけません。

プロパティ / メソッド説明
Drawing(name="")図面を作成します。name を省略すると LinkCAD が一意な名前を割り当てます
with Drawing(...) as dwg:推奨される形式。ブロックを抜けるときにデータベースを解放します
drawing.name図面名
drawing.units1 メートルあたりのデータベース単位数(float)。例えばナノメートルデータベースなら 1e90.0 は図面が単位を宣言していないことを意味します。データベースに何か入った後で代入すると RuntimeError になるため、最初に設定してください
drawing.main_cellメイン(トップ)セルの取得または設定
drawing.cellsすべてのセル(リスト)
drawing.layersすべてのレイヤー(リスト)
drawing.cell(name)名前でセルを検索。見つからなければ None
drawing.layer(name)名前でレイヤーを検索。見つからなければ None
drawing.add_cell(name)セルを追加、または同名の既存セルを返します
drawing.add_layer(name)レイヤーを追加、または同名の既存レイヤーを返します
drawing.modif_time / drawing.access_timeUnix 秒によるタイムスタンプ
drawing.undo_enabled取り消し記録の有効/無効
drawing.begin_undo_marker(tag=0) / drawing.end_undo_marker()取り消し可能なトランザクションを手動で囲みます
drawing.undo() / drawing.redo()直前のトランザクションを取り消す/やり直す
drawing.can_undo / drawing.can_redo(可否, tag) のタプル
drawing.destroy_layer_by_name(name)名前でレイヤーを削除。存在した場合 True
drawing.rename_layer(from_name, to_name)レイヤー名を変更。成功時 True
drawing.boolean_layers_by_name(op, result_layer, operand_layer, maximum_error=100, minimum_facets=16)名前で指定した 2 つのレイヤーにブール演算を適用。result_layer がオペランド A であり、結果を受け取ります
drawing.merge_layer_polarity_group(group_name, maximum_error=100, minimum_facets=16, progress_from=0, progress_to=100)遅延極性レイヤーグループを 1 つマージします
drawing.merge_all_polarity_groups(maximum_error=100, minimum_facets=16, progress_from=0, progress_to=100)すべての遅延極性レイヤーグループをマージします
drawing.destroy()図面とその内容を破棄します
drawing.memory_usageネイティブデータベースのメモリ使用量(バイト)
drawing.lockedいずれかのスレッドがデータベースのロックを保持していれば True
drawing.locked_by_this_thread呼び出し元スレッドが書き込みロックを保持していれば True

後半の 3 つはプロセス全体の状態を読むため、インスタンスからでもクラスからでも参照できます。Drawing.memory_usagedwg.memory_usage は同じ数値を返します。

図面を変更するレイヤー用ヘルパーメソッドは、それぞれ独自の取り消し可能なトランザクションを作成します。

from linkcad.v1.db import BooleanOperation, Drawing, MergeLayerPolarityResult
with Drawing("example") as dwg:
ok = dwg.boolean_layers_by_name(
BooleanOperation.Or,
result_layer="metal",
operand_layer="vias",
)
result = dwg.merge_all_polarity_groups()
if result != MergeLayerPolarityResult.Success:
raise RuntimeError("Polarity merge failed")

列挙型の値は is ではなく == で比較してください。バインディングは読み取りのたびに新しい Python オブジェクトを返すため、マージが成功していても result is MergeLayerPolarityResult.SuccessFalse になります。

drawing.units は 1 メートルが何データベース単位に相当するかを示します。物理的な寸法を、データベースが格納する整数へ変換するために必要な値です。

units_per_meter = drawing.units
if units_per_meter <= 0.0:
raise ValueError("This drawing does not declare its database units")
seven_microns = 7.0 * 1e-6 * units_per_meter

プラグインならもっと簡単です。DrawingContext または WriterContext に作業単位を指定すれば、LinkCAD が変換を行います。linkcad.plugin を参照してください。

Cell

形状とセル参照を収める名前付きのコンテナです。セルは、それを所有する図面から取得します。

cell = drawing.add_cell("TOP") # creates, or returns the existing "TOP"
cell = drawing.cell("TOP") # looks up; None if not found

ジオメトリを作成する

どの形状型も同じ形をしています: add_<なにか>(layer, …) が新しいオブジェクトを返します。

座標は Point オブジェクトでも単純な (x, y) タプルでもよく、相互に使えます。これは頂点の並びでも、円弧・円・ドーナツの center やテキストの position のような単一の座標でも同じです。対はちょうど 2 つの座標であり、それ以外は切り詰めずに拒否されます。

メソッド説明
cell.add_polygon(layer, vertices)閉じたポリゴンを追加します
cell.add_polyline(layer, vertices, width=0, closed=False, end_cap=EndCap.Round)ポリラインを追加します
cell.add_arc(layer, center, radius, width=0, start_angle=None, end_angle=None)円弧を追加します。start_angle <= end_angle のとき反時計回りに描かれます。角度を省略すると完全な円の輪郭になります
cell.add_circle(layer, center, diameter)塗りつぶした円を追加します
cell.add_donut(layer, center, mean_diameter, width)リングを追加します。mean_diameter(外径 + 内径) / 2 です
cell.add_text(layer, content, position, height=1.0, font="")テキスト形状を追加します
cell.add_nurbs(layer, control_points, degree, knots, width=0, weights=None, periodic=False)NURBS 曲線を追加します。次数は 1、2、3、5 のいずれかです
cell.add_ref(cell, transformation=None, columns=1, rows=1, column_spacing=0, row_spacing=0, layer=None)別のセルをここに配置します。配列にするには columns/rows を 1 より大きくします
from linkcad.v1.db import Drawing, EndCap
from linkcad.v1.geom import Angle, Point, Transformation
with Drawing("shapes") as dwg:
top = dwg.add_cell("TOP")
dwg.main_cell = top
metal = dwg.add_layer("METAL1")
top.add_polygon(metal, [(0, 0), (1000, 0), (1000, 1000), (0, 1000)])
top.add_polyline(metal, [(0, 0), (2000, 2000)], width=100, end_cap=EndCap.SquareFlat)
top.add_arc(metal, Point(5000, 0), radius=1000, width=50,
start_angle=Angle.from_degrees(0), end_angle=Angle.from_degrees(90))
top.add_circle(metal, Point(0, 5000), diameter=800)
top.add_donut(metal, Point(3000, 5000), mean_diameter=800, width=100)
top.add_text(metal, "TOP", Point(0, 8000), height=500)
stamp = dwg.add_cell("STAMP")
stamp.add_circle(metal, Point(0, 0), diameter=200)
top.add_ref(stamp, Transformation().translate(10_000, 0), columns=4, rows=2,
column_spacing=1000, row_spacing=1000)

セルを調べる

プロパティ / メソッド説明
cell.nameセル名
cell.shapesセルが所有するすべての形状。それぞれ実際の型(PolygonPolyline など)で返されます
cell.filtered_shapes(selected_only=False)絞り込んだ形状。shapes は既定値でのこれと同じです
cell.cell_objectsRef オブジェクトを含む、セルが保持するすべて。それぞれ実際の型で返されます
cell.filtered_cell_objects(selected_only=False)絞り込んだセルオブジェクト
cell.boundsこのセルとサブセルに含まれるすべてのバウンディングボックス
cell.filtered_bounds(layer=None)1 つのレイヤーに絞ったバウンディングボックス
cell.nesting_level最大のネストレベル(トップセルは 0)
cell.child_levelsこのセルの下にある子レベルの数
cell.enabledいずれかのコンテキストでセルが有効なら True
cell.enabled_in_context(context_cell)別のセルの中でこのセルが有効かどうか
cell.enable(enabled=True, context_cell=None, context=CellContext.Descend)セルを有効/無効にします
cell.uses_layer(layer, context=CellContext.Descend, enabled_only=False)セルがそのレイヤー上に何かを持つかどうか
cell.first_shape_layer含まれる形状が使用する最初のレイヤー
cell.selected_count選択されているセルオブジェクトの数
cell.first_selected最初に選択されているセルオブジェクト、または None
cell.modif_time / cell.access_timeUnix 秒によるタイムスタンプ
cell.clone(name)新しい名前でセルを複製します

cell_objects は実際の型を返すため、isinstance は期待どおりに動作します。

from linkcad.v1 import db
for obj in cell.cell_objects:
if isinstance(obj, db.Ref):
print(f"reference to {obj.ref_cell.name}")
elif isinstance(obj, db.Polygon):
print(f"polygon with {obj.vertex_count} vertices")

Layer

表示プロパティを持つ名前付きレイヤーです。レイヤーは図面から取得します。

metal = drawing.add_layer("METAL1") # creates, or returns the existing layer
metal = drawing.layer("METAL1") # looks up; None if not found
プロパティ / メソッド説明
layer.nameレイヤー名
layer.colorパックされた RGBA 整数としてのレイヤー色
layer.enabledレイヤーが有効かどうか。代入可能
layer.hiddenレイヤーが非表示かどうか。代入可能
layer.used有効なセルがそのレイヤーに何かを置いていれば True
layer.move_before(other_layer=None)レイヤー一覧内で並び替えます
layer.clone(drawing, name)レイヤーを複製します。別の図面へも可能です。両方の引数をキーワードで渡すこともでき、その場合 drawing=None はこの図面を意味します
layer.destroy()レイヤーを破棄します

静的ファクトリーはありません。drawing.add_layer() がレイヤーを作成し、drawing.layer() が検索します。

Object

すべてのデータベースオブジェクトの基底クラスです。

プロパティ / メソッド説明
obj.idオブジェクト ID
obj.validオブジェクトが破棄されると False
obj.dynamic_typeオブジェクトの実際の型(ObjectType
obj.drawingこのオブジェクトが属する Drawing
obj.destroy()オブジェクトを削除して破棄します。以後は無効になります

DrawingObjectLayerCell の基底)は Object に何も追加しません。

CellObject

セル内に存在するすべて——あらゆる形状と Ref——の基底クラスです。

プロパティ / メソッド説明
obj.owning_cellこのオブジェクトを含む Cell
obj.boundsバウンディングボックス(Bounds
obj.layerオブジェクトの Layer。代入可能
obj.layer_nameレイヤー名
obj.selected選択状態。代入可能
obj.toggle_selection()選択状態を反転します

layerRef を含むすべてのセルオブジェクトで読み書き可能で、Layer、レイヤー名、None のいずれかを受け付けます。

obj.layer = drawing.layer("METAL1") # a Layer
obj.layer = "METAL2" # by name; created if it does not exist
obj.layer = None # the default layer

toggle_selection() がゲッター/セッター規則の例外として残るのは、これが selected = not selected ではないからです。それは 2 つの別々のロックのもとでの読み取りと書き込みになりますが、データベースは反転を 1 つの操作として提供しています。

Shape

幾何形状の基底クラスです: ポリゴン、ポリライン、円弧、楕円、ドーナツ、NURBS、テキスト。CellObject を継承します。

プロパティ / メソッド説明
shape.closed形状が閉じていれば True
shape.widthデータベース単位でのトレース幅(塗りつぶし形状では 0)
shape.area囲まれた面積(データベース単位の平方)
shape.equivalent_to(other, ignore_sense=True)2 つの形状の同等性を比較します
shape.layer / shape.boundsCellObject から継承。layer はそちらで読み書き可能です
shape.destroy()この形状を削除して破棄します

verticesShape の一部ではありません。持っているのは PolygonPolylineNurbs だけです。曲線——円弧、円、ドーナツ——は中心と半径で記述され、必要に応じてホストがテセレーションします。

total = sum(shape.area for shape in cell.shapes if shape.closed)
print(f"filled area: {total}")

Polygon

閉じた塗りつぶし形状です。Shape を継承し、cell.add_polygon(layer, vertices) で作成します。

プロパティ / メソッド説明
polygon.verticesPoint のリストとしての頂点。Point オブジェクトまたは (x, y) タプルを代入できます
polygon.vertex_count頂点数
polygon.head / polygon.tail最初と最後の頂点
polygon.is_boxポリゴンが軸平行の矩形なら True
polygon.is_self_intersecting輪郭が自己交差していれば True
polygon.has_bulgesいずれかの辺が 0 以外のふくらみを持てば True
polygon.add_vertex(point)頂点を 1 つ追加します
polygon.add_vertices(points)複数の頂点を追加します
poly = cell.add_polygon(layer, [(0, 0), (1000, 0), (1000, 1000)])
poly.add_vertex((0, 1000))
poly.vertices = [(p.x * 2, p.y * 2) for p in poly.vertices]

Polyline

幅を任意に持てる開いた/閉じたパスです。Shape を継承し、cell.add_polyline(...) で作成します。

プロパティ / メソッド説明
polyline.verticesPoint のリストとしての頂点。代入可能
polyline.vertex_count頂点数
polyline.head / polyline.tail最初と最後の頂点
polyline.widthデータベース単位でのパス幅
polyline.closedパスが閉じているかどうか
polyline.end_cap_styleEndCap の値
polyline.add_vertex(point) / polyline.add_vertices(points)頂点を追加します
polyline.reverse()頂点の順序を反転します

Arc

円弧です。Shape を継承し、cell.add_arc(...) で作成します。

from linkcad.v1.geom import Angle, Point
arc = cell.add_arc(
layer,
center=Point(0, 0),
radius=10_000,
width=500,
start_angle=Angle.from_degrees(0),
end_angle=Angle.from_degrees(90),
)
arc.center = Point(1000, 1000)
arc.radius = 12_000
プロパティ説明
arc.center中心点。代入可能
arc.radiusデータベース単位での半径。代入可能
arc.widthデータベース単位での線幅。代入可能
arc.start_angle開始角(Angle)。x 軸から反時計回りに測ります
arc.end_angle終了角(Angle

Ellipse

円のプリミティブです。Shape を継承し、cell.add_circle(layer, center, diameter) で作成します。

プロパティ説明
ellipse.center中心点。代入可能
ellipse.diameterデータベース単位での直径。代入可能
ellipse.radius半径(直径の半分、読み取り専用)

Donut

リング(円環)のプリミティブです。Shape を継承し、cell.add_donut(layer, center, mean_diameter, width) で作成します。

プロパティ説明
donut.center中心点。代入可能
donut.mean_diameter平均直径 (外径 + 内径) / 2。代入可能
donut.widthリング幅。代入可能
donut.outer_diameter / donut.inner_diameter導出される直径(読み取り専用)
donut.mean_radius / donut.outer_radius / donut.inner_radius導出される半径(読み取り専用)

Nurbs

非一様 B スプライン曲線です。Shape を継承し、cell.add_nurbs(...) で作成します。

from linkcad.v1.geom import Point
nurbs = cell.add_nurbs(
layer,
control_points=[Point(0, 0), Point(10, 20), Point(20, 20), Point(30, 0)],
degree=3,
knots=[0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0],
width=5,
)
プロパティ / メソッド説明
nurbs.width線幅。代入可能
nurbs.degree曲線の次数
nurbs.knots / nurbs.knot_countノットベクトルとその個数
nurbs.vertices / nurbs.control_pointsPoint オブジェクトとしての制御点(両者は同じもの)
nurbs.control_point_count制御点の数
nurbs.weights重みベクトル
nurbs.rational重みがあれば True
nurbs.periodic曲線が周期的/閉じていれば True。代入可能

Text

書式付きテキストのジオメトリです。Shape を継承し、cell.add_text(...) で作成します。

from linkcad.v1.geom import Angle, Point
label = cell.add_text(
layer,
content="Hello LinkCAD",
position=Point(100, 200),
height=12.5,
font="simplex.shx",
)
label.content = "Goodbye"
label.rotate(Angle.from_degrees(90))
プロパティ / メソッド説明
text.content書式付きテキスト内容。代入可能。text.text は別名です
text.fontフォント名。代入可能
text.position基準点。代入可能
text.heightテキスト高さ。代入可能
text.line_spacing行間。代入可能
text.box_width折り返し幅。代入可能
text.rotation回転角(Angle)。代入すると、外側の参照に対する相対的な回転になります
text.rotate(angle, absolute=False)回転します。absolute=True では外側の参照による回転を無視します
text.width_factor横方向の倍率。代入可能
text.stroke_width線幅。代入可能
Text.escape(content)平文を書式付きテキスト保存用にエスケープします

Ref

変換を伴って配置された別セルのインスタンスです。CellObject を継承し、cell.add_ref(...) で作成します。

from linkcad.v1.geom import Transformation
xform = Transformation()
xform.rotate(45.0)
xform.translate(1000, 2000)
ref = parent_cell.add_ref(child_cell, xform)
ref.columns = 4
ref.column_spacing = 5000
プロパティ / メソッド説明
ref.ref_cell参照先の Cell。代入可能
ref.transformation配置の Transformation(配列全体に適用)。代入可能
ref.columns / ref.rows配列サイズ。1 は単一インスタンスを意味します
ref.column_spacing / ref.row_spacingデータベース単位での配列ピッチ
ref.apply_transformation(transformation)追加の変換を適用します
ref.clone(cell=None, transformation=None)参照を複製します。別のセルへも可能です
ref.destroy()この参照を削除して破棄します

cell.add_ref() は、使いものにならない値を返す代わりに ValueError を送出します。循環階層——セルを自身の子孫の中に置くこと——のときと、対象セルが存在しないとき(以前は行き先のない参照ができていました)です。セルがユーザー入力由来の場合は例外を捕捉してください。

try:
ref = parent_cell.add_ref(child_cell, xform)
except ValueError as exc:
print(f"cannot place '{child_cell.name}': {exc}")

Color

RGB のカラー値です。

プロパティ / メソッド説明
Color() / Color(red, green, blue)色を構築します
color.red / color.green / color.blue各チャンネル(0-255)。代入可能

layer.colorColor ではなくパックされた RGBA 整数です。API が Color を求める場所では Color を使ってください。

Property

データベースオブジェクトに付随する名前付きプロパティです。

プロパティ / メソッド説明
prop.owner_typeプロパティが付いているオブジェクトの型(ObjectType
prop.destroy()プロパティを破棄します
Property.properties(drawing, holding_type)あるオブジェクト型のプロパティ名を列挙します
Property.lookup_type(drawing, name, holding_type)名前からプロパティの型を調べます
from linkcad.v1.db import ObjectType, Property
for name in Property.properties(drawing, ObjectType.Cell):
print(name, Property.lookup_type(drawing, name, ObjectType.Cell))

列挙型

ObjectType

データベースオブジェクトの具体的な型です。obj.dynamic_typeprop.owner_type が返し、Property のクラスメソッドが受け取ります。

グループ
コンテナDrawingLayerCell
セルオブジェクトRefArcPolygonPolylineDonutTextEllipseNurbs
基底クラスObjectDrawingObjectCellObjectShapeProperty
プロパティBooleanPropertyIntegerPropertyRealPropertyStringProperty。それぞれ Drawing… / Cell… / CellObject… / Layer… 形もあります
番兵Invalid

CellContext

操作がサブセルまで降りるかどうかを制御します。

説明
CellContext.Descendサブセルを含めます
CellContext.DontDescendこのセルのみ

Unit

単位を意識する API やオプションダイアログで使われる、名前付きの測定単位です。

説明
Unit.PicometerUnit.NanometerUnit.MicronUnit.MillimeterUnit.CentimeterUnit.Meterメートル法の単位
Unit.MilUnit.InchUnit.Feetヤード・ポンド法の単位
Unit.Point活字のポイント(1/72 インチ)
Unit.Databaseデータベース単位(ピコメートル)
Unit.DotsPerInchUnit.Facetsオプションダイアログで使われる解像度・個数の「単位」

「単位なし」を表すメンバーもありますが、None は Python の予約語であるため getattr(Unit, "None") としてのみ参照できます。

drawing.unitsUnit を返しません。1 メートルあたりのデータベース単位数を表す float です——Drawing を参照してください。

EndCap

ポリラインのエンドキャップスタイルです。linkcad.v1.plugin からも再エクスポートされます。

説明
EndCap.Round丸いキャップ
EndCap.SquareExtended端点を越えて延びる角形キャップ
EndCap.SquareFlat端点で終わる角形キャップ

FillRule

ポリゴンの塗りつぶし規則です。ライター API 向けに linkcad.v1.plugin からも再エクスポートされます。

説明
FillRule.NonZero非ゼロ回転数規則
FillRule.EvenOdd偶奇規則

BooleanOperation

drawing.boolean_layers_by_name() 用の、レイヤー単位のブール演算です。

説明
BooleanOperation.Orオペランドレイヤーを結果レイヤーに合成します
BooleanOperation.AMinusB結果レイヤーからオペランドレイヤーを引きます

MergeLayerPolarityResult

遅延極性マージ用ヘルパーの結果です。

説明
MergeLayerPolarityResult.Successマージに成功しました
MergeLayerPolarityResult.Failureマージに失敗しました

TextStyle と TextStyleMask

TextStyle はテキストの配置、方向、行間を表すビットフラグを含みます。TextStyleMaskDrawingBuilder.set_text_style() がどのスタイルビット群を変更するかを選択します。

列挙型主な値
TextStyleDefaultAlignHLeftAlignHCenterAlignHRightAlignVBaselineAlignVBottomAlignVMiddleAlignVMiddleAscentAlignVTopOrientHOrientVLineSpacingExactLineSpacingCompact
TextStyleMaskNone_AlignHAlignVOrientLineSpacing

ロック

必要なロックは実行コンテキストによって異なります。

プラグインコンテキスト(@tool@format_reader@format_writer

フレームワークは run()read()write() を呼び出す前に適切なロックを取得します。読み取り操作に明示的なロックは不要です。取り消し可能にすべき書き込み操作には Transaction が必要です。

from linkcad.v1.db import Transaction
def run(self, drawing):
for cell in drawing.cells:
print(cell.name)
with Transaction(drawing, "My Operation"):
result = drawing.add_cell("RESULT")
layer = drawing.add_layer("OUTPUT")
result.add_polygon(layer, [(0, 0), (100, 0), (100, 100), (0, 100)])
return {"summary": "Created RESULT"}

スタンドアロンスクリプト(linkcad --python-script

プラグインフレームワークの外で動くスクリプトは、明示的にロックを取得しなければなりません。

from linkcad.v1.db import Drawing, ReadLock, WriteLock
with Drawing("scratch") as dwg:
with ReadLock():
for cell in dwg.cells:
print(cell.name)
with WriteLock():
for layer in list(dwg.layers):
if layer.name.startswith("TEMP_"):
dwg.destroy_layer_by_name(layer.name)

ReadLock

スタンドアロンスクリプトでの読み取り専用アクセス用コンテキストマネージャーです。

from linkcad.v1.db import ReadLock
with ReadLock():
main = dwg.main_cell
for shape in main.shapes:
print(shape.bounds)

WriteLock

スタンドアロンスクリプトでの書き込みアクセス用コンテキストマネージャーです。取り消しエントリは作成しません。

from linkcad.v1.db import WriteLock
with WriteLock():
for cell in dwg.cells:
for obj in list(cell.cell_objects):
if obj.layer_name == "SCRATCH":
obj.destroy()

Transaction

書き込みアクセス用のコンテキストマネージャーで、取り消し履歴に 1 つのエントリを作成します。ツールプラグインで使用してください。「Edit」メニューに表示される説明文字列、または数値タグのいずれかを受け取ります。

from linkcad.v1.db import Transaction
with Transaction(drawing, "Create Panel"):
panel = drawing.add_cell("PANEL")
panel.add_ref(drawing.cell("UNIT"))

トランザクションはブロックが正常に終了するとコミットされ、例外が抜けるとロールバックされます。transaction.commit() は早期にコミットします。