AutoLISP
AutoLisp は、AutoCAD や IJCAD など一部のAutoCAD互換ソフトで利用できるインタープリタ型プログラミング言語。 AutoCAD や IJCAD でコマンドやシステム変数、ダイアログ ボックス(DCL)を呼び出すことができる。 AutoCAD LT においては利用できない。(AutoCAD LT で AutoLisp の機能を利用可能にするソフトウェアも存在したが、LT2002 以降のバージョンに対応したものはなくなっている。)
IJCAD における AutoLisp は、AutoCAD の互換機能として存在し、一部の関数や外部定義関数を除けば、ほぼ同様に利用することが出来る。 (利用可能な関数などの情報については、AutoLisp関数互換表 と 追加・変更された AutoLISP 関数 を参照。)
一番長くサポートされている API (バージョン履歴とサポートAPI参照) であり、他に利用可能なAPIに比べCADのバージョンアップに伴う影響を受けにくい API といえる。 開発環境として AutoCAD には、Visual LISP という 対話型の開発環境(IDE)が搭載されているが、IJCAD では特定の開発環境はないため、一般的なテキストエディタによる開発となる。
LISP に最適なエディタとしては括弧の補完機能や字下げ機能があると便利で、以下のようなものがある。
- Notepad ++
- xyzzy や emacs など
以下は、市販エディタ。
- 秀丸 ・・・ 秀丸用ハイライトのセット
- EmEditor
- MIFES など
- ちなみに、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) ; <- 引数が無い。
無効な呼び出しを行うとエラーになり、処理が中断される。
AutoLISP のデータ タイプ
AutoLISP には以下のデータタイプがある。AutoLISPをフル活用するには、データタイプの使い方を理解する事は必須と言っていい。
関数の機能別一覧
以下は関数を分類分けしたもの。他に、目次からのアクセスがAutoLISP 関数一覧的で便利かも。
- 基本関数:
- ユーティリティ関数:
- 選択セット
- オブジェクト
- シンボル テーブル関数:
- 拡張データ処理
- オブジェクト処理
- 選択セット操作
- シンボル テーブル処理の各関数
- メモリ管理関数
- ダイアログ ボックス関数
- ai_関数
- Visual LISP の拡張関数:(ActiveX)
- リアクタ関数
- VLX 名前空間関数
- 名前空間対話関数
- Windows レジストリ処理関数
- 画層状態関数
AutoLISP プログラムの作成
AutoLISP のプログラムは、以下の 3つのファイル形式のうちのいずれかで作成する。
- LSP ファイル(.lsp) ・・・ AutoLISP プログラム コードが記述された ASCII テキスト ファイル。
- FAS ファイル(.fas) ・・・ 1 つの LSP プログラム ファイルのコンパイル済みバイナリ ファイル。
- VLX ファイル(.vlx) ・・・ 1 つ以上の LSP ファイルとダイアログ コントロール言語(DCL)ファイルの両方または一方をコンパイルしたファイル。
- IJCAD では、LISPプログラムを秘匿化したい場合は、AutoCAD に搭載されている、PROTECT.EXE か ebatch社(IntelliJAPANの前身)からでていた IJPROLSP.EXE を利用して暗号化する。
- IJCAD2013 では独自の暗号化と FASファイルとVLXファイルに対応。(読み込みのみ)
AutoCAD では、AutoCAD 2000 以降 Visual LISP (VLISP) 環境が備わりコンパイラ、デバッガ、などを備えた統合開発環境(IDE)を備えているため、その上で AutoLISP プログラムを記述していくことが出来る。
IJCAD では、IDEは備わっていないため、テキストエディタにより記述していく。
また、AutoCAD・IJCAD どちらの環境でも、短い構文は次のようにコマンドプロンプトに直接記述して実行することが出来る。
コマンド: (+ 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 があると、ファイルを開始するたびに読み込み・実行される。
- 自動ロードファイルはファイルの初期化前に実行されるため、command 関数は使ってはいけない。 AutoCAD の場合は、S::STARTUP 関数に記述する事になっている。
IJCAD で自動ロードする場合の注意点
- IJCAD 2014
- 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, ≒ JDraf) *1 |
○ | △ | × | × |
AutoCAD | ○ | ○ | ○ | ○ |
AutoCAD(Mac版) | ○ | × | × | × |
AutoCAD LT | × | × | × | × |
BricsCAD | ○ | ○ | ○*4 | × |
IJCAD | ○ | ○ | ○*4 | ○*3 |
IntelliCAD系CAD | ○ | ○ | △*5 | × |
nanoCAD | △ | △*2 | × | × |
ZWCAD | ○ | ○ | ○*4 | × |
- *1 … ファイル名8文字+拡張子だけ。パス指定フルパスのみ。
- *2 … 日本語の扱いが良くない。
- *3 … 自前でコンパイルは出来ない。2014時点
- *4 … ほぼ同等なサポート。
- *5 … 部分的なサポート。
32bit と 64bit
- 近年の AutoCAD は 32bit版と64bit版があるが、AutoLISPではその差は特になく気にしなくてもいい。
- IJCAD は 2014 から 64bit版がある。(2014.11現在)
- ARX や .NET など他の言語のカスタマイズを読み込むときにAutoLISPを使ったりする。(以下サンプル)
; 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 () (vl-load-com) (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE")) )
特殊フォーム
特殊フォームは一般的な 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 を操作できません