初心者向けのLISP解説、今回はLISPを使ってオブジェクトを選択し、そのオブジェクトを操作します。
オブジェクトを選択してみよう
LISPでオブジェクトを選択するには、どうすればいいしょうか。
AutoCADで新規図面を開き、線分を1本引きます。そしてコマンドラインに(entsel)と入力しリターンを押してください。すると オブジェクトを選択: と表示されるので、先ほど描いた線分を選択します。コマンドラインに (<図形名: 1413d822cf0> (1510.21 520.992 0.0)) のような文字列が表示されます。これは、選択したオブジェクトのデータ内の名前(図形名)と、選択するときにクリックした点の座標です。オブジェクトを操作するときは、この図形名が必要です。図形名は、その図形のプロパティにアクセスするために必要です。
次の文字列をコピーして、コマンドラインに張り付け、リターンを押してください。
(entget (car (entsel)))
先ほどと同じように、オブジェクトを選択: と表示されるので、もう一度線分を選択してください。今度は以下のような文字列が表示されます。
((-1 . <図形名: 1413d822cf0>) (0 . "LINE") (330 . <図形名: 1413d8169a0>) (5 . "A23F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 -62.8532 150.702 0.0) (11 48552.8 16851.7 0.0) (210 0.0 0.0 1.0))
これは、線分の定義データであり、オブジェクトの持つプロパティを示します。このように関連する一連の値をスペースあるいはピリオドで区切りカッコで囲んだものを、LISPではリストと呼びます。このリストのデータは大きく2種類に分けることができます。1つは(0 . "LINE")のように「.」(ピリオド)で区切られた2つのデータのセットです。このセットをドットペアと呼びます。もう一つは、スペースのみで区切られた複数のデータのセットです。
これらのプロパティを変更することで、オブジェクトを編集します。
文字を操作してみよう
数字を+1する簡単なLISPを元に、基本的なオブジェクトの操作方法を見ていきましょう。新規図面を開きTEXTコマンドで整数の数字をいくつか入力してください。
VLISPエディタを開き、新規ファイルを作成し、以下のコードを貼り付けてください。
(defun c:plusone ( / ename elist txtval dpair num Newnum Newelist Newtxtval Newpair)
(setq ename (car (entsel)))
(setq elist (entget ename))
(setq dpair (assoc 1 elist))
(setq txtval (cdr dpair))
(setq num (atoi txtval))
(setq Newnum (+ 1 num))
(setq Newtxtval (itoa Newnum))
(setq Newpair (cons 1 Newtxtval))
(setq Newelist (subst Newpair (assoc 1 elist) elist))
(entmod Newelist)
(princ)
)
エディタ内のテキストをロードを行い、コマンドラインにplusoneと入力して値が数字である文字オブジェクトを選択してください。+1した数字に変更されましたか?
でも、コード長い!知らない文字列ばっかり!と思った人、ちょっと待ってください。このコードは初心者向けに、1つ1つ段階を踏めるよう、かなり丁寧に書いています。
では1行ずつ説明していきましょう。
1行目
(defun c:plusone ( / ename elist txtval num Newnum Newelist Newtxtval Newpair)
defun関数でLISPコマンドを定義します。コマンド名をplusoneとし、コマンドラインで実行できるようc:を付加します。ローカル変数(この関数内でのみ使用する変数)として、ename elist txtval num Newnum Newelist Newtxtval Newpairの8つを定義します。
変数というのは、取得した値を一時的に入れておく入れ物です。変数を使わずに書くこともできますが、今回はどんな値を取得しているかを分かりやすくするために、あえて細かく変数を使っています。
2行目
(setq ename (car (entsel)))
コードにいくつか( )がある場合は、一番内側の( )から処理されます。
まず、entsel関数でオブジェクトをクリック選択し、図形名とクリックした位置の座標のリストを取得します。次にcar関数で、リストの最初の項目である図形名を取得します。この名前をsetq関数で変数enameに入れます。
3行目
entget関数で図形名からプロパティのリストを取得し、変数elistに入れます。
4行目
(setq txtval (cdr (assoc 1 elist)))
assoc関数でプロパティのリストから、データセットの先頭が1のデータを探します。文字オブジェクトのプロパティでは、1とセットになった値が文字の内容を表しています。cdr関数でリストの先頭以外すなわち文字内容を取得します。これを変数txtvalに入れます。
5行目
(setq num (atoi txtval))
文字内容から取得したtxtvalの値は、見た目は整数ですが文字列扱いのため、atoi関数で整数に変換し、変数numに入れます。
6行目
(setq Newnum (+ 1 num))
+-*/などを使用して、数字の演算ができます。ここでは+を使って、文字の値から取り出した整数に1を加算して、変数Newnumに入れます。
7行目
(setq Newtxtval (itoa Newnum))
文字オブジェクトの値にするために、itoa関数で整数を文字列扱いに変更し、変数Newtxtvalに入れます。
8行目
(setq Newpair (cons 1 Newtxtval))
Newtxtvalを文字オブジェクトのプロパティとして扱えるよう、cons関数で1とのドットペアにして、変数Newpairに入れます。
9行目
(setq Newelist (subst Newpair (assoc 1 elist) elist))
subst関数で、元のプロパティのリストであるelistの文字の値の部分を入れ替えます。入れ替えたリストを変数Newelistに入れます。
10行目
(entmod Newelist)
endmod関数で、オブジェクトの定義データを変数Newelistで修正します。
11行目
(princ)
引数なしのprinc関数を実行し、コマンドラインに空文字が表示されるようにします。
次回は、コードを1ステップずつ実行する方法、そしてそのときにそれぞれの変数にどんな値が入っているのかを確認方法を説明します。
今回のLISPも、TESTフォルダにplusone.lspという名前で保存しておきましょう。>> 後半はこちら
著者について
Twitterでフォローする ウェブサイトを見る このライターによる他のコンテンツ