DIESELマクロをLISPコマンド化する
以前に、メニューマクロ用の簡単なカスタマイズとして、クイックグループ化の解説をしたことがありました。
今回は、これをコマンド化して使用できるようにしてみたいと思います。
コマンド名を決める
たとえば、"QG" というコマンド名にしたいとします。コマンド化するにあたって、BricsCAD で Lite から利用可能な LISP API を活用します。
LISPプログラムをコマンドとして読み込ませる場合、関数名を "C:" で始まる形で定義する決まりになっていますので、関数名を "C:QG" として定義することになります。
関数の定義は Defun 関数で行いますので、雛形としては以下のようになります。
(defun C:QG () ; クイックグループのコマンド
; なにかの処理
(princ)
)
LISPの開発環境 BLADE を実行する
BricsCAD には、LISPの開発環境として BLADE というLISPエディターが搭載されています。BLADE を使うと、LISP プログラムのコーディングやロード、デバックなどを行う事ができます。
新しいLISPファイルを作成する
BLADEを実行すると、新規ファイルが Document.lsp としてあらかじめ表示されますのでこのファイルにそのまま LISPのコードを記述していけます。
別のファイルを新たに作成したい場合は、「新しいファイルを追加」から追加することができます。
新規ファイルに前述の雛形のコードを記述しましょう。
LISP をコーディングする
関数の ”; なにかの処理 ”の部分に実際の処理を書いていくわけですが、今回はメニューに登録されているマクロを LISP に移植する形になりますので、まずは DIESEL マクロの内容を単純にLISP式に変換してみます。
メニューマクロ: ^C^C-group;c;*;;$M=$(if,$(getvar,cmdactive),\;,)
マクロをLISP式に変換 :(command "-group" "c" "*" "" (if (getvar "cmdactive") "\")
変換したLISP式を関数に入れ込むと以下のような感じになります。
(defun C:QG ()
(command
"-group" "c" "*" ""
(if (getvar "cmdactive") "\")
)
(princ)
)
さてこれで動くでしょうか?
LISP コードをチェックする
LISPのコードを入力したら、Lisp+Dclの「構文と変数のチェック」からLISPコードのチェックをしてみましょう。
チェックを実行すると以下のような画面が表示されます。
左上の赤字のところに注目してみると、C:QG の関数にはエラーが3つあるという表示になっています。中央部分には、エラーが発生している場所とエラー内容が表示されています。
エラーを修正する
エラーの内容としては、3つともカッコの数が合わないという内容になっています。もう一度コードを良く見ましょう。
括弧の数は合っているようです。ではなぜエラーが出るのか。
更によく見ると "\" の部分から後は文字扱いの緑色になっていることがわかります。
DIESELマクロでは、¥ は入力待ちを意味しますが、LISP のコード中に現れる ”\” または半角 ”¥” の文字は、特殊な扱いの文字で1文字だとエスケープ文字として扱われます。
今回の場合だと、\ の後の ” をエスケープしている形になるので、”” で文字として扱うはずの部分が閉じられていないままになってしまっています。
Lisp の command 関数内で 入力待ちをする場合は代わりに pause を利用することが出来るので書き換えてみますと、次のイメージのようになります。
文字扱いの緑色の文字になっていたところがなくなり、通常のコードの色になりましたね。これで治ったはずですのでもう一度「構文と変数のチェック」でチェックしてみましょう。
メッセージ内容が若干わかりにくいですが、エラーが 0 になったことがわかります。
プログラムをロードして動作をチェックする
エラーが無くなったので、LISPコードをロードしてみましょう。
ロードは、BLADE の Lisp+Dcl メニューから「Lispファイルをホストアプリケーションにロード」を選択して行うことが出来ます。
メニューに表示されている通り、Alt+Ctrl+Cのショートカットでもロードできます。
ロードを実行した後で、BLADE を閉じて BricsCAD に戻るとコマンドウィンドウの履歴にC:QGと表示されている事がわかります。
QGコマンドがロードされて使える状態になっているので実行してみましょう。Q を入力すると、コマンドのリスト内にQGがあることが確認できます。QG[Enter]でも、リストから QG を選択でもどちらでも実行できます。
実行すると ”; error : Function cancelled” と表示され停止してしまいました。
残念ながら構文や変数以外のエラーがあるようです。確認のために、BricsCAD のシステム変数 cmdecho をオンにした状態で QGコマンドを実行してみると、次のようにメッセージが表示されます。
途中までは実行されていて、command関数の最後の部分
(if (getvar "cmdactive") pause "")
のところで止まってしまったようです。
実は command は、コマンドの内容を順番に書いていく、スクリプト的な形で実行される関数なのですが、途中に LISP関数を入れて処理を分岐するといったことは出来ません。
if 関数で ”cmdactive” をチェックして pause と ””(空文字=Enter)とに分岐しているのは、図形を先に選んでいるかどうかでコマンドの流れに図形選択ステップがあるかないか、の差が出る点に対応するための処理になります。
このような場合 どうするかというと、色々方法はありますが一つは先に図形を選択して選択セットを作成しておく方法がとれます。
選択セットは (ssget) という関数で取得出来るので、それを変数にいれるようにすると、次のようになります。
(setq ss (ssget)) ; 選択セットを取得
先に選択しておくことで、コマンドがアクティブかどうかで分岐をする必要がなくなるので、LISPコードとしては次のようになります。
(defun C:QG (/ ss)
(setq ss (ssget)) ; 選択セットを取得
(command "-group" "c" "*" "" ss "")
(princ)
)
シンプルになりましたね。
これを再度読み込んで動きを試してみましょう。
ssget の関数は、図形を選択している状態で実行するとその図形を取得してくれたりしますので、今回やりたいことではそのままで問題ないです。
(defun C:QG (/ ss)
で関数名のあとに (/ ss) という記述をしていますが、これは、/ 以降の変数名をローカル変数として扱うようにする記述です。なくても動きますが、このように記述することで余計なメモリを消費しないようにしています。
以上で、マクロからのLISPコマンド化は完了です。
気をつけるポイントはありますが、そこまで難しくなく移植できるということがわかるかと思います。
DESファイルにエンコードする
DESファイルへのエンコードは、コードを秘匿化したり、コードを自動調整して効率がいい形に変換したり、ファイルサイズを小さくしたり、名前空間を別にしておいたりできます。
今回のようなごく短い単純なプログラムでは、DESファイルにするメリットはほぼ無いですが、配布時に便利ですので DESファイルにする方法だけ解説します。
DESファイルへのエンコード手順
1.BLADE のウィンドウにあるプロジェクトから、「DEScorderファイルデバッグ」を選択します。
2. DES Encoder for LISP … のダイアログが表示されるので DES File のタブが表示されていることを確認します。日本語化はされていませんが、難しいツールではないので使うのは簡単です。
3.sauce 欄の右にあるボタンから、エンコードしたいファイルを選択します。(標準では現在開いているファイルが表示されます。)
4.Target欄は、エンコードされたファイル名が表示されます。
5.ターゲット欄の右にある緑色のボタンをクリックすると、エンコードされます。
6.エクスプローラ等で lispファイルと同じフォルダに同名で拡張子が .des になっているファイルが出来ていることを確認します。
7..des のファイルを APPLOAD コマンドや BricsCAD へのドラッグ&ドロップ で読み込んで動作を確認します。問題なく動けば完了です。
ソースコードでの検証で問題がなく、エンコードしたファイルの場合に問題が発生する場合は、サポートリクエストにソースとエンコードしたファイルを添付して、詳細な現象と合わせてレポートして下さい。
一部日本語に関連する処理を行うコードがうまくエンコードできないことが確認されています。
では、よいCADライフを!🍝