AutoLISP

提供:GizmoLabs - だいたい CAD LISP なサイト
2016年10月23日 (日) 22:41時点におけるGizmon (トーク | 投稿記録)による版 (→‎AutoCAD 2011)

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 に最適なエディタとしては括弧の補完機能や字下げ機能があると便利で、以下のようなものがある。

以下は、市販エディタ。


  • ちなみに、AutoLISP は XLISP1.0 からの派生と言われている。>> バージョン履歴とサポートAPI
  • AutoCAD の 2.18 より搭載された。
  • VisualLISP は、Basis Software, Inc. の Vital LISP を買収したものがベースになっている。Wikipedia

AutoLisp 関数の構文

AutoLisp の構文は非常にシンプルである。以下に例を示す。

caption

解説
上の例では、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 関数一覧的で便利かも。

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 以降では独自の暗号化(AES、DES)と AutoCAD でコンパイルされた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 (2014からは gcad.lsp)があると、ファイルを開始するたびに読み込み・実行される。
自動ロードファイルはファイルの初期化前に実行されるため、command 関数は使ってはいけない。 AutoCAD の場合は、S::STARTUP 関数に記述する事になっている。

IJCAD で自動ロードする場合の注意点

  • IJCAD 2014 / 2015 / 2016
    • 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, ≒ JDraf) *1
× ×
AutoCAD
AutoCAD(Mac版) × × ×
AutoCAD LT × × × ×
BricsCAD ×
IJCAD ○*3
IntelliCAD系CAD △*4 ×
nanoCAD △*2 × ×
ZWCAD ×
  • *1 … ファイル名8文字+拡張子だけ。パス指定フルパスのみ。
  • *2 … 日本語の扱いが良くない。
  • *3 … 自前でコンパイルは出来ない。IJCAD 2016 時点
  • *4 … 部分的なサポート。

32bit と 64bit

  • 近年の AutoCAD は 32bit版と64bit版があるが、AutoLISPではその差は特になく気にしなくてもいい。
    • 整数の範囲は 64bit版でも 32bitの範囲(-2147483647 ~ 2147483647)
; 整数範囲外の計算
(= 2147483650 (+ 2147483647 3)) ; 整数だと範囲外の解になる計算は正しくない
nil

(= 2147483650 (+ 2147483647 3.0))  ; 浮動小数点が絡む計算なら整数範囲外の解になる計算は正しい
T

(atoi "2150000000")
2147483647

(atoi "-2150000000")
-2147483647
  • 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 (/ 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)

特殊フォーム

特殊フォームは一般的な 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 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

追加

旧機能

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

追加

AutoCAD 2010

変更

  • help - ヘルプ機能を呼び出す。HTML ドキュメントのサポートを追加するように関数が更新された。

AutoCAD 2009

追加

関連書籍