アクセスの概要
図面データベースは、図面に含まれる図形、画層、線種、保存されたビュー設定などを含んだ、データの塊です。command 系関数からAutoCADを操作する場合は、AutoCADユーザーの操作をコマンドをとおしてなぞることで図面データベースを操作していましたが、直接図面データベースにアクセスし変更することで、高速で複雑な操作が可能になります。command 系関数では実現が難しかったり、速度に問題があったりする場合に、直接アクセスを検討してください。図面データベースに直接アクセスする方法として、ent~系関数が用意されています。
図面データベースのおおまかなイメージは次のようなものです。【図形名】をインデックスとして、データが順に整然と並んでいます。
<図形名: 046>、エンティティタイプ:LINE、画層:0、色:1、線種:bylayer、始点:0,0、終点:10,10
<図形名: 047>、エンティティタイプ:CIRCLE、画層:0、色:5、線種:bylayer、中心:0,0、半径:25
<図形名: 060>、エンティティタイプ:LINE、画層:0、色:1、線種:HIDDEN、始点:10,0、終点:10,10
<図形名: 061>、エンティティタイプ:ARC、画層:0、色:5、線種:bylayer、中心:0,0、半径:25、開始角度:0、終了角度:90
なお、ActiveX の VLA オブジェクトを使用する場合は、また異なった見え方をします。
【図形名】は一つの図面データベースで一つのユニークな値です。【図形名】は図面ファイルが開かれてメモリーにロードされるたびに、その値が変わります。そのため、次回図面を開いたときは以前の【図形名】が有効とはなりません。このような「セッション」をまたいで特定のものを指したい場合は「ハンドル」を用います。ハンドルも図形に関連付けられたユニークな値で、文字列で表されます。
基本的に一つの【図形名】で一つの図形を表しますが、複合図形は、複数の【図形名】で表現され、SEQENDを終端のマークとする一連のデータとして表現されます。
<図形名: 088>、エンティティタイプ:VIRTEX、座標:0,0
<図形名: 089>、エンティティタイプ:VIRTEX、座標:25,0
<図形名: 090>、エンティティタイプ:VIRTEX、座標:25,25
<図形名: 091>、エンティティタイプ:VIRTEX、座標:0,25
<図形名: 092>、エンティティタイプ:SEQEND
【図形名】は、ユーザーによる図形選択で得られるほか entnext 関数を用いて、ある【図形名】の次に登録されている【図形名】を得るといった連続した走査で得ることができます。なお、画層などの【図形名】は、【テーブル】というものを入口として得ることができます。
ent~系関数を用いる場合は、図面データベースのデータは、DXF グループコードで装飾された LISP の連想リストの形で得られます。DXF グループコードの意味については、ヘルプを参照してください。
entget 関数は、登録されている図形データを取り出す関数です。得られた連想リストには、どの図形のデータか判別するための既存の【図形名】が必ず含まれます。図形を変更する場合は、得られた連想リストの必要な部分を書き換えて、図面データベースに書き戻します。連想リストに含まれていた【図形名】の図形データが変更されます。entmod 関数が、既存の図形のデータを書き換える関数です。
新しい図形を作成する場合は、【図形名】やハンドルの情報以外の、図形を表すのに必要な連想リストを用意します。新しい図形を表す連想リストが用意できたら、図面データベースに書き込みます。entmake 関数が新規の図形を作成する関数です。
新しい図形は、必ず図面データベースの最後に付け加えられます。entlast 関数が、図面データベースの最後の図形の【図形名】を得る関数です。図形を新規作成し、その【図形名】を得たい場合は、作成した直後に entlast 関数を使う必要があります。これは、command 系関数を使用して図形を作成した場合も有効な手法です。
図面データベースの図形を削除する場合は、entdel関数を用います。
図面データベースの座標系
図面データベースに直接アクセスして図形を作成する場合は、座標系のことを常に意識する必要が出てきます。
AutoCAD コマンドを command 系関数で使う場合は、座標系は UCS です。また、AutoLISP の入力関数も座標は UCS で返ってきます。ですから、これらのみを使っている限りは UCS のみで完結し、直感的で簡潔です。しかし、図面データベースの座標は WCS あるいは OCS です。そのため UCS と WCS や OCS との座標変換が必ず必要になってきます。UCS をあまり変更しない AutoCAD ユーザーの場合は UCS と WCS は一致していて座標変換を行わなくても問題がでないかもしれません。しかし、それはたまたまそうであっただけです。ヘルプを参照する際に、必ずどの座標系かを確認するようにしてください。
UCS から WCS への座標変換は trans 関数を使うことによって行えます。OCS の座標は【押し出し方向】といったものと関連し、AutoCAD 独特の仕組みを理解しないと使いこなすことはできません。
座標系の説明は、稿を改めて行います。
図形名の取得
AutoLISP関数 |
---|
(entnext [ename]) |
ename:【図形名】 |
図面データベースの最初、あるいは次の【図形名】を返します。 |
戻り値:【図形名】、またはnil |
entnext 関数は、引数が与えられなければ図面データベースの最初の【図形名】が返ります。【図形名】が引数に与えられれば、その次の【図形名】を返します。この関数によって、図面データベースを連続して走査していくことができます。
戻り値は該当の【図形名】で、次の【図形名】が存在しない、つまり引数に最後の【図形名】を与えた場合はnilを返します。
_$ (setq ename (entnext))⏎ ;最初の【図形名】を取得
<図形名: 7ffff706140>
_$ (entnext ename)⏎ ;次の【図形名】を取得
<図形名: 7ffff706150>
3Dポリライン等の複合図形は、主図形と後続の頂点などの従属図形のデータで構成されています。従属図形のデータも主図形のデータと同列で並んでいますので、SEQEND のデータが出てくるまで、entnext 関数で走査します。
AutoLISP関数 |
---|
(entlast) |
図面データベース内の最後の【図形名】を返します。 |
戻り値:【図形名】、またはnil |
図面データベース内の最後の【図形名】が返されます。図面データベース内の最後は、最も最近作成された図形です。
_$ (entlast) ⏎
<図形名: 7ffff706160>
複合図形を作成する場合は、主図形のあとに従属図形を作成することになりますが、entlast 関数は主図形の【図形名】を返します。
ハンドル
AutoLISP関数 |
---|
(handent handle) |
handle:文字列 |
ハンドルに対応する【図形名】を返します。 |
戻り値:【図形名】、またはnil |
handent 関数は、ハンドルから図形名を得ます。
ハンドルは、図面を開きなおしても変化しない、一つの図面データベースの中で図形を指すユニークな値です。以下の図形データでは、グループコード -1 が【図形名】で、5 がハンドルを表しています。
ここでハンドルから【図形名】を調べてみると、対応した【図形名】が得られます。
_$ (handent "2A4")⏎
<図形名: 7ffff706140>
図形データの取得
AutoLISP関数 |
---|
(entget ename [applist]) |
ename:【図形名】 applist:リスト |
図形の定義データを取得します。 |
戻り値:連想リスト |
entget関数は、図面データベースから図形データを取得します。図形データは、以下のようなDXFのグループコードで修飾されたリストを束ねた連想リストの形で得られます。
(0 . "LINE")
(330 . <図形名: 7ffff703980>)
(5 . "2A4")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "TOORI")
(100 . "AcDbLine")
(10 38.7276 20.0151 0.0)
(11 56.8298 74.3231 0.0)
(210 0.0 0.0 1.0)
)
ename 引数は、取り出す【図形名】を指定します。
applist 引数は、プログラムつまりアプリケーションにより拡張データを付加された図形で使用されます。詳細は省きますが、拡張データは【テーブル】に登録したアプリケーション名と関連して登録されますので、アプリケーション名を指定することでそれに関連したデータを取り出すことができます。アプリケーション名が指定されなければ、拡張データは見えませんので関係のない他のプログラムから拡張データは保護されます。
以下は図面データベースの最後の図形データを得る例です。
_$ (entget (entlast))⏎
((-1 . <図形名: 7ffff706160>) (0 . "LINE") (330 . <図形名: 7ffff703 … (後略)
得られた図形データは、assoc関数で抽出し、subst関数で新しい値に置換するのが定石です。
簡単なコマンドを例として作成してみます。作成するコマンドは、選択図形からテキストのものを、そのハンドルとテキストの内容を CSV 形式でファイルに書き出すものです。コマンド名は WRITETEXT とします。
(defun recursive:ename->Handle+Text (elist / ename edata etype) (if elist (progn (setq ename (car elist) edata (entget ename) etype (cdr (assoc 0 edata)) ) (if (= etype "TEXT") (append (list (strcat (vl-prin1-to-string (cdr (assoc 5 edata))) "," (vl-prin1-to-string (cdr (assoc 1 edata))) ) ) (recursive:ename->Handle+Text (cdr elist)) ) (recursive:ename->Handle+Text (cdr elist)) ) ) ) ) (defun write-list (alist fp / item *error*) (setq *error* (lambda (msg) (close fp) (prompt (strcat "\n" msg)))) (foreach item alist (write-line item fp)) ) (defun c:writeText (/ ss fileName fp) (if (and (setq ss (ssgetException nil nil nil nil)) (setq fileName (getfiled "ハンドルとテキストを保存" (getvar "MYDOCUMENTSPREFIX") "csv" (+ 1 4 16 128) ) ) (setq fp (open fileName "w")) ;ファイルをオープン ) (progn (write-list (recursive:ename->Handle+Text (ssToList ss)) fp) (close fp) ;ファイルのクローズ ) ) (princ) )
recursive:ename->Handle+Text 関数は再帰的に【図形名】のリストをハンドルとテキストをカンマで区切った文字列に変換します。図形タイプがテキストではない場合は無視します。具体的には entget 関数で図形データを取り出し、assoc 関数で、DXFグループコード 0 のエンティティタイプ、5 のハンドル、1 のテキストの内容をそれぞれ見ています。
write-list 関数は、文字列からなるリストをファイルに書き出します。エラーが起こった際にファイルを閉じるローカルなエラー関数を定義しています。
c:writeText 関数がコマンドの本体です。ssgetException 関数はユーザー入力の例外に対応します。ssToList 関数は、選択セットをLISPのリストに変換します。
このコマンドを利用して次のような図面から、CSV形式のproverb.csvファイルを作成できました。CSV形式はエクセルなどで容易に扱えるスタイルです。

