AutoLISP
AutoLisp の概要
AutoLisp は、AutoCAD や IJCAD など一部のAutoCAD互換ソフトで利用できるインタープリタ型プログラミング言語。 AutoCAD や IJCAD でコマンドやシステム変数、ダイアログ ボックス(DCL)を呼び出すことができる。 AutoCAD LT においては利用できない。(AutoCAD LT で AutoLisp の機能を利用可能にするソフトウェアも存在したが、LT2002 以降のバージョンに対応したものはなくなっている。)
IJCAD における AutoLisp は、AutoCAD の互換機能として存在し、一部の関数や外部定義関数を除けば、ほぼ同様に利用することが出来る。 (利用可能な関数などの情報については、AutoLisp関数互換表 と 追加・変更された AutoLISP 関数 を参照。)
一番長くサポートされている API (バージョン履歴とサポートAPI参照) であり、他に利用可能なAPIに比べ CAD のバージョンアップに伴う影響を受けにくい API といえる。
- ちなみに、AutoLISP は XLISP1.0 からの派生と言われている。>> バージョン履歴とサポートAPI
- AutoCAD の 2.18 より搭載された。
- VisualLISP は、Basis Software, Inc. の Vital LISP を買収したものがベースになっている。Wikipedia
AutoLisp 関数の構文
AutoLisp の構文は非常にシンプルである。以下に例を示す。
解説
上の例では、foo 関数には 1 つの必須引数 string と、1 つの省略可能な引数 number があり、引数 number は追加で指定することができる。一般に、引数の名前は予期されるデータ タイプを表している。
この foo 関数で有効な呼び出しと無効な呼び出しの例をを示す。
- 有効な呼び出し例
- (foo "catch")
- (foo "catch" 22)
- (foo "catch" 22 31)
- 無効な呼び出し例
- (foo 44 13) ; <- 引数 string が無い
- (foo "fi" "foe" 44 13) ; <-引数 number に文字が指定されている
- (foo) ; <- 引数が無い。
無効な呼び出しを行うとエラーになり、処理が中断される。
コメントの記述
LISP プログラムのファイル中のコメントは、
- 単一行コメント : ";" (セミコロン)以降から改行位置までがコメントとして扱われます。
- 複数行のコメント : ";|" で始まり "|;" で終わる形で記述し、その間がコメントして扱われます。
一部の互換CADは、複数行コメントの記述に対応していません。
AutoLISP のデータ タイプ
AutoLISP には以下のデータタイプがある。AutoLISPをフル活用するには、データタイプの使い方を理解する事は必須と言っていい。
関数の機能別一覧
以下は関数を分類分けしたもの。他に、目次からのアクセスが AutoLISP 関数一覧的で便利かも。
- 基本関数:
- ユーティリティ関数:
- 選択セット
- オブジェクト
- シンボル テーブル関数:
- 拡張データ処理
- オブジェクト処理
- 選択セット操作
- シンボル テーブル処理の各関数
- メモリ管理関数
- ダイアログ ボックス関数
- ai_関数
- Visual LISP の拡張関数:(ActiveX)
- リアクタ関数
- VLX 名前空間関数
- 名前空間対話関数
- Windows レジストリ処理関数
- 画層状態関数
AutoLISP プログラムの作成
AutoLISP のプログラムは、以下の 3つのファイル形式のうちのいずれかで作成する。
- LSP ファイル(.lsp) ・・・ AutoLISP プログラム コードが記述された ASCII テキストファイル。(日本だと Shift-JIS の文字コードが一般的)
- FAS ファイル(.fas) ・・・ 1 つの LSP プログラム ファイルのコンパイル済みバイナリ ファイル。
- VLX ファイル(.vlx) ・・・ 1 つ以上の LSP ファイルとダイアログ コントロール言語(DCL)ファイルの両方または一方をコンパイルしたファイル。
- IJCAD では、LISP プログラムを秘匿化したい場合は、AutoCAD に搭載されている、PROTECT.EXE か ebatch社(IntelliJAPANの前身)からでていた IJPROLSP.EXE を利用して暗号化する。どちらも難読化レベルの秘匿化のため、暗号強度としては弱く、割りと簡単に復号化できる。
- IJCAD2013 以降では独自の暗号化(AES、DES)と AutoCAD でコンパイルされたFAS、VLXファイルの読み込みに対応。
- AutoCAD は Shifs-JIS の文字コードなので、ユニコードの文字を扱うような場合はそのままの記述はできず、¥U+xxxx といったコードポイントで記述する必要がある。
AutoCAD では、AutoCAD 2000 以降 Visual LISP (VLISP) の環境搭載されコンパイラ、デバッガ、などを備えた統合開発環境(IDE)を備えているため、その上で AutoLISP プログラムを記述していくことが出来る。 互換 CAD の中では、BricsCAD が、V18.2 のバージョンにて BLADE という対話型の開発環境(IDE)が搭載されている。 IJCAD などのその他の IDE が無い互換製品はテキストエディタなどによる開発となる。
LISP の開発につかうテキストエディタは括弧の補完機能や字下げ機能があると便利で、以下のようなものがある。
- Notepad ++
- xyzzy や emacs など
以下は、市販エディタ。
- 秀丸 ・・・ 秀丸用ハイライトのセット
- EmEditor
- MIFES など
また、AutoCAD やその他多くの互換 CAD では、短い構文は次のようにコマンドプロンプトに直接記述して実行することが出来る。
コマンド: (+ 1 2 3 4 5 ) 15 <- 実行結果
AutoLISP プログラムの使用
AutoLISP のプログラム(.lsp のファイル)は、まずそのプログラムをCADへロードする必要がある。
ロードは、コマンド プロンプトに対して load 関数を使用して AutoLISP コードを入力する。 load 関数が正常に終了すると、ファイル内の最後の式の値がコマンド プロンプト領域に表示される。これは通常そのファイルで定義されている最後の関数の名前か、新しくロードされた関数の使用説明となる。
load 関数が失敗すると、AutoLISP のエラー メッセージが表示される。 load 関数の失敗は、AutoLISPファイルのコーディング間違いや、コマンド プロンプトに対して間違ったファイル名を入力した場合に起こる。
load 関数の構文は、次のとおり。
(load filename [onfailure])
この構文は、load 関数に 2 つの引数があることを示している。 1つ目の filename は、読み込むAutoLISPファイル名(とパス)で必須。 2つ目の onfailure は省略可能で、失敗した場合のメッセージを入力する。 コマンドラインからの入力で AutoLISP ファイルをロードする場合は通常、filename 引数のみを指定する。
次の例は、AutoLisp ファイル newfile.lsp をロードしている。
コマンド: (load "newfile")
拡張子 .lsp は省略可能。この形式は、現在のライブラリ パス上のどの LSP ファイルに対しても動作する。
ライブラリ パス上にない AutoLisp ファイルをロードする場合は、filename 引数として、ファイル名を絶対パスで指定する必要がある。
コマンド: (load "d:/files/morelisp/newfile") または コマンド: (load "d:\\files\\morelisp\\newfile")
注 : フォルダ パスを指定する場合、スラッシュ(/)または 2つの円記号(¥¥)を区切り記号として使用する必要がある。通常Windowsで利用される単一の円記号(¥)での指定は、2つの円記号(¥¥)となる。これは、AutoLisp では単一の円記号(¥)には特別な意味があるため。
- 尚、AutoCAD と IJCAD 共に LISPファイルを CAD のウィンドウに ドラッグ&ドロップしても読み込まれる。
自動ロード
- AutoCAD では、パスの通っているフォルダにある acad.lsp があると起動時に読み込み・実行される。また、acaddoc.lsp ファイル があるとファイルを開始するたびに読み込み・実行される。
- システム変数:ACADLSPASDOC を1にすると、図面が開かれるたびに acad.lsp をロードする。
- システム変数:LISPINIT を1にすると、図面が開かれるたび、作成されるたびに LISP 環境が初期化される。(SDI モード時に変数値を引き継ぎたいなら0にする)
- IJCAD では、パスの通っているフォルダにある icad.lsp (2014 からは gcad.lsp)があると、ファイルを開始するたびに読み込み・実行される。
- 自動ロードファイルはファイルの初期化前に実行されるため、command 関数は使ってはいけない。 AutoCAD の場合は、S::STARTUP 関数に記述する事になっている。
IJCAD で自動ロードする場合の注意点
- IJCAD 2014 / 2015 / 2016 / 2017 / 2018
- gcad.lsp が起動時に読み込まれ、ACADLSPASDOC が 1 だと、gcad.lsp が毎回読み込まれる。。
- 図面毎に名前空間が分かれている。LISPINIT は無効。
- IJCAD 2013
- icad.lsp が毎回読み込まれる。
- 図面毎に名前空間が分かれていないため、自動ロードで何か初期化を行う処理がある場合、別の図面を開いたときにすでに開いている変数値などが上書きされてしまう可能性があるため、特に複数のファイルにまたがる処理をする場合は注意が必要である。
- IJCAD 8
- icaddoc.lsp が有効になったので、ドキュメント毎に読み込みたい処理は icad.lsp ではなく icaddoc.lsp に記述しておくと良い。(2012.04 のアップデートから)
- ACADLSPASDOC が有効になったので、初期値では icad.lsp を起動時にしか読み込まない。icaddoc.lsp +icad.lsp の両方を読み込みたければ ACADLSPASDOC=1 にしておくと良い。(読み込まれる順番は icad.lsp -> icaddoc.lsp)
- 名前空間が一応分かれてるので変数はドキュメント毎。 LISPINIT が有効なので、変数を共有したい場合は LISPINIT=2、開いたファイルにアクティブドキュメントの変数をコピーして使うなら 0 に切り替えておく。
- IJCAD 7
- 図面毎に名前空間が分かれているような動きだが完全じゃないので、ファイルの close などで変数が上書きされた状態になったりする可能性がある。複数のファイルにまたがる処理をする場合は注意が必要。
- IJCAD 6
- 図面毎に名前空間が分かれていないため、自動ロードで何か初期化を行う処理がある場合、別の図面を開いたときにすでに開いている変数値などが上書きされてしまう可能性があるため、特に複数のファイルにまたがる処理をする場合は注意が必要である。
AutoLISP が使える CAD ソフト
製品名 | LSP対応 | DCL対応 | VL関数対応 | FAS/VLX対応 |
---|---|---|---|---|
Ares CAD(≒ Draftsight) *1 | × | × | × | × |
Ares CAD COMed (≒ Draftsight有料版, ≒ CorelCAD) *1 |
○ | △ | × | × |
AutoCAD | ○ | ○ | ○ | ○ |
AutoCAD(Mac版) | ○ | × | × | × |
AutoCAD LT | × | × | × | × |
BricsCAD(全グレード) | ○ | ○ | ○ | × |
IJCAD(STD or PRO グレード) | ○ | ○ | ○ | ○*3 |
IntelliCAD系CAD | ○ | ○ | △*4 | × |
nanoCAD | △ | △*2 | × | × |
ZWCAD | ○ | ○ | ○ | × |
- *1 … ファイル名8文字+拡張子だけ。パス指定フルパスのみ。
- *2 … 日本語の扱いが良くない。
- *3 … 自前でコンパイルは出来ない。IJCAD 2018 時点
- *4 … 部分的なサポート。
32bit と 64bit
- 近年の AutoCAD は 32bit版と64bit版があるが、AutoLISP ではその差は特になく気にしなくてもいい。
- 整数の範囲は 64bit版でも 32bitの範囲(-2147483647 ~ 2147483647)
<syntaxhighlight lang="lisp" line>
- 整数範囲外の計算
(= 2147483650 (+ 2147483647 3)) ; 整数だと範囲外の解になる計算は正しくない nil
(= 2147483650 (+ 2147483647 3.0)) ; 浮動小数点が絡む計算なら整数範囲外の解になる計算は正しい T
(atoi "2150000000") 2147483647
(atoi "-2150000000") -2147483647 </syntaxhighlight>
- IJCAD は 2014 から 64bit版がある。(2014.11現在)
- ARX や .NET など他の言語のカスタマイズを読み込むときに AutoLISP を使ったりする。(以下サンプル)
<syntaxhighlight lang="lisp" line>
- AutoCAD が 64bit版かどうか
(defun cadx64-app ()
(vl-load-com) (> (strlen (vl-prin1-to-string (vlax-get-acad-object))) 40)
)
- OS(CPU) が64bitかどうか 64bitだったら 数値、それ以外は nil
(defun cadx64-os (/ result)
(if (= "x86" (getenv "PROCESSOR_ARCHITECTURE")) (progn (if (getenv "PROCESSOR_ARCHITEW6432") (setq result 6432) ; OS & Process 32 bit (setq result nil) ; 32 bit process on 64bit OS - WOW64 )) (setq result 64) ; OS & Process 64bit )
result) </syntaxhighlight>
特殊フォーム
特殊フォームは一般的な AutoLISP 関数呼び出しとは異なる方法で引数を評価する。一般的な関数は、関数に渡されたすべての引数を評価してからそれらの引数に基づいて実行するが、特殊フォームは、すべての引数を評価しないか、または特定の条件の下でのみいくつかの引数を評価する。
以下は特殊フォームとみなされる AutoLISP 関数。
AutoLisp のエラーコード
AutoLISP で生成されるエラー コードの値と意味は次のとおり。AutoLISP の関数呼び出しによって発生したエラーを CAD が検出すると、システム変数 ERRNO に次の値のいずれかが設定される。
(getvar "errno") を使用すると、AutoLISP のアプリケーションで現在の ERRNO の値を検査できる。
システム変数 ERRNO は、ゼロにクリアされない場合があるため、AutoLISP の関数がエラーをレポートした直後に検査しないと、その値が示すエラーは誤っている可能性がある。この変数は、図面を新規作成したり図面を開いたときに、必ずクリアされる。
注:ERRNO の値とその意味は、将来変更される可能性がある。
- 値 … 意 味
- 0 … エラーはありません
- 1 … 無効なシンボル テーブル名です
- 2 … 無効な図形名または選択セット名です
- 3 … 選択セットの最大数を超えました
- 4 … 無効な選択セットです
- 5 … ブロック定義が不正に使用されました
- 6 … xref が不正に使用されました
- 7 … オブジェクトを選択: クリックが失敗しました
- 8 … 図形ファイルの終わりです
- 9 … ブロック定義ファイルの終わりです
- 10 … 最後の図形が見つかりません
- 11 … ビューポート オブジェクトを不正に削除しようとしました
- 12 … PLINE[ポリライン]中は操作できません
- 13 … 無効なハンドルです
- 14 … ハンドルが使用可能になっていません
- 15 … 座標変換要求に無効な引数があります
- 16 … 座標変換要求に無効な空間があります
- 17 … 削除した図形が不正に使用されました
- 18 … 無効なテーブル名です
- 19 … 無効なテーブル関数の引数です
- 20 … 読み込み専用の変数に代入しようとしました
- 21 … ゼロ値は許されていません
- 22 … 値が範囲外です
- 23 … 複雑な REGEN の処理中です
- 24 … 図形タイプを変更しようとしました
- 25 … 不正な画層名です
- 26 … 不正な線種名です
- 27 … 不正な色名です
- 28 … 不正な文字スタイル名です
- 29 … 不正なシェイプ名です
- 30 … 図形タイプのフィールドが不正です
- 31 … 削除した図形を変更しようとしました
- 32 … Seqend 従属図形を変更しようとしました
- 33 … ハンドルを変更しようとしました
- 34 … ビューポートの可視性を変更しようとしました
- 35 … 図形はロックされている画層にあります
- 36 … 不正な図形タイプです
- 37 … 不正なポリライン図形です
- 38 … ブロック内の複合化図形が不完全です
- 39 … 無効なブロック名フィールドです
- 40 … ブロック フラグ フィールドが重複しています
- 41 … ブロック名フィールドが重複しています
- 42 … 不正な法線ベクトルです
- 43 … ブロック名がありません
- 44 … ブロック フラグがありません
- 45 … 名前のないブロックが無効です
- 46 … ブロック定義が無効です
- 47 … 必須フィールドがありません
- 48 … 拡張データ(XDATA)のタイプが認識できません
- 49 … XDATA 内のリストのネストが正しくありません
- 50 … APPID フィールドの位置が正しくありません
- 51 … XDATA の最大サイズを超えました
- 52 … オブジェクトを選択: null 応答です
- 53 … APPID が重複しています
- 54 … ビューポート図形を作成または変更しようとしました
- 55 … xref、xdef、xdep を作成または変更しようとしました
- 56 … ssget フィルタ: リストが途中で終わっています
- 57 … ssget フィルタ: テスト オペランドがありません
- 58 … ssget フィルタ: opcode(-4)文字列が無効です
- 59 … ssget フィルタ: ネストが正しくないか条件条項が空です
- 60 … ssget フィルタ: 条件条項の始まりと終わりが一致していません
- 61 … ssget フィルタ: 条件条項における引数の数が誤っています(NOT または XOR)
- 62 … ssget フィルタ: ネストの最大数を超えました
- 63 … ssget フィルタ: グループ コードが無効です
- 64 … ssget フィルタ: 文字列テストが無効です
- 65 … ssget フィルタ: ベクトル テストが無効です
- 66 … ssget フィルタ: 実数テストが無効です
- 67 … ssget フィルタ: 整数テストが無効です
- 68 … ディジタイザがタブレット モードではありません
- 69 … タブレットが位置合わせされていません
- 70 … タブレット引数が無効です
- 71 … ADS エラー: 新規のリザルト バッファを割り当てられません
- 72 … ADS エラー: null ポインタを検出しました
- 73 … 実行ファイルを開けません
- 74 … アプリケーションは既にロードされています
- 75 … 最大数のアプリケーションが既にロードされています
- 76 … アプリケーションを実行できません
- 77 … 互換性のないバージョン番号です
- 78 … ネストしたアプリケーションをロード解除できません
- 79 … アプリケーションがロード解除を拒否しました
- 80 … アプリケーションが現在ロードされていません
- 81 … メモリが不足しているのでアプリケーションをロードできません
- 82 … ADS エラー: 変換マトリックスが無効です
- 83 … ADS エラー: シンボル名が無効です
- 84 … ADS エラー: シンボル値が無効です
- 85 … ダイアログ ボックスの表示中は AutoLISP/ADS を操作できません
AutoCAD における AutoLISPの仕様追加・変更履歴
AutoCAD 2019
追加・変更なし。
AutoCAD 2018
追加・変更なし。 ActiveX ライブラリから IAcadFileDependencies と IAcadFileDependency のクラスが削除されたので、LISP でもVLA-* の関数で、上記ライブラリに関連する関数が使用できなくなった。(下に記載。)外部参照やフォント、印刷スタイルなど、図面ファイルに添付・参照されているファイルをごにょごにょするのに便利だったため注意が必要。
- メソッド
vla-CreateEntry vla-IndexOf vla-Item vla-RemoveEntry vla-UpdateEntry
- プロパティ
vla-get-AffectsGraphics vla-get-Count vla-get-Feature vla-get-FileDependencies vla-get-FileName vla-get-FileSize vla-get-FingerprintGuid vla-get-FoundPath vla-get-FullFileName vla-get-Index vla-get-IsModified vla-get-ReferenceCount vla-get-TimeStamp vla-get-VersionGuid
AutoCAD 2017
追加・変更なし。
AutoCAD 2016
旧機能
- getcfg - acad20xx.cfg ファイルの AppData セクションからアプリケーション データを取得。
- setcfg - acad20xx.cfg ファイルの AppData セクションにアプリケーション データを書き出し。
- 注: getcfg 関数と setcfg は互換性を保つために現在も使用可能な関数で、今後のリリースで削除される可能性がある。代わりに vl-registry-read および vl-registry-write 関数の使用が推奨されている。
AutoCAD 2015
追加・変更なし
AutoCAD 2014
追加
- findtrustedfile - 指定されたファイルを AutoCAD の信頼できるファイル パスで検索する。
- showhtmlmodalwindow - HTML ドキュメントを含むモーダル ウィンドウを表示する。新しい JavaScript API と一体で使用。
変更
- findfile - AutoCAD のサポート ファイル パスと信頼できるファイル パスを検索する。新しい信頼できるアプリケーション パスを検索するように更新。
AutoCAD 2013
追加
- vlax-machine-product-key - HKLM(HKEY_LOCAL_MACHINE)の AutoCAD の Windows レジストリ パスを返す。
旧機能
- vlax-product-key - AutoCAD の Windows レジストリ パスを返す。
AutoCAD 2012
追加
- command-s - AutoCAD コマンドと指定された入力を実行する。
- *pop-error-mode* - *push-error-using-command* または *push-error-using-stack* に対する以前の呼び出しを終了するエラー処理関数。
- *push-error-using-command* - カスタム *error* ハンドラ内での command 関数の使用を示すエラー処理関数。
- *push-error-using-stack* - カスタム *error* ハンドラ内での AutoLISP スタックの変数の使用を示すエラー処理関数。
AutoCAD 2011
追加
- dumpallproperties - 図形のサポートされるプロパティを取得する。
- getpropertyvalue - 図形のプロパティの現在の値を返す。
- ispropertyreadonly - 図形のプロパティの読み込み専用状態を返す。
- setpropertyvalue - 図形のプロパティ値を設定する。
AutoCAD 2010
変更
- help - ヘルプ機能を呼び出す。HTML ドキュメントのサポートを追加するように関数が更新された。
AutoCAD 2009
追加
- initcommandversion - 次のコマンドを指定したバージョンで実行する。