AutoLISPでフェンストリムや窓選択などを使う時は、他の図形に影響しないようにAutoLISP作業用画層を作ってで作図するようにするといいです。
作業用画層以外をフリーズするときは、先に画層状態を保存しておいて作業後に復元します。
例
下記のプログラムは星を描くコマンドSTARです。
(defun c:STAR ( / L P B C D E F)
(defun L (A) (polar P(* pi (/ A 180)) 600))
(setq P (getPoint "星の中心点:")
B (L 90.0) C (L 306.0) D (L 162.0) E (L 18.0) F (L 234.0)
);setq
(command-s "._LINE" B C D E F B "")
(foreach X (list B C D E F)
(command-s "._TRIM" "" "F" P (polar P (angle P X) (/(distance P X)2)) """"))
(princ));defun
オブジェクトスナップも影響するし、星全体が画面上にないとトリムされないのでズームを引きで600の円が入る範囲が画面上にある状態で試してみて下さい。
(オブジェクトスナップ対策は別記事で。トリム時のズームについてはコチラの記事を)
このコマンドは星五角形作成し、さらにコマンドTRIM[トリム]で余分な線を消して星にします。
しかし、もし他に図形がある所でこのコマンドを実行すると、トリムしたい部分がされなかったり、トリムしたくなかった他の図形がトリムされてしまいます。
対策
AutoLISP処理用画層を作って、その画層以外はフリーズして作図します。
オン/オフ フリーズなどの画層状態は関数 layerstate-save で保存、layerstate-restoreで復元、layerstate-deleteで消去できます。
そして、layerstate-hasはその名前の画層状態がすでに保存されているかどうかを調べる関数です。
AutoLISP処理用画層、画層状態は、残しておくと、画層がすでにある場合も想定して作らなければいけないのと、誰か画層を使うなど予期せぬこともあるので、AutoLISP内で使う時に作成、使い終わったらその都度消去した方が無難です。
他とは絶対被らないような名前にしましょう。ここでは、画層状態はJagaImoLisp_Work_State、作業用画層はJagaimoLisp_Work_Layerという名前にします。
もし心配なら、tblsearch や layerstate-hasを使って、while で同じ名前があれば数字を足していき他とは被らない名前になったら実行などとしてもいいかもしれません。
作図用画層で作図するプログラム例
さて、先ほどのコマンドSTARに、作業用画層で作図する処理を加えます。
新しいコマンド名はSTAR2です。
- 現在画層を変数CuLyに入れる。
- 現在の画層状態をJagaImoLisp_Work_Stateという名前で保存。
- JagaimoLisp_Work_Layerという名前の画層を作り現在画層にする。
- 現在画層以外をフリーズ。(画層名に*を使うと現在画層以外すべてフリーズできる。)
- 作図後、全ての図形を選択して元の現在画層にする。
- 元の現在画層を解凍して現在画層にする。
- 画層 JagaimoLisp_Work_Layerを消去。
- 画層状態 JagaImoLisp_Work_Stateを復元。
- 画層状態 JagaImoLisp_Work_Stateを消去。
- コマンド REGENを実行。
これらの処理が加わったものが下記のプログラムです。
(defun c:STAR2 (/ L P B C D E F CuLy)
(defun L (A) (polar P(* pi (/ A 180)) 600))
(setq P (getPoint "星の中心点:")
B (L 90.0) C (L 306.0) D (L 162.0) E (L 18.0) F (L 234.0)
);setq
;▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
;|ここでは現在画層と画層状態の保存し、作業用画層を作り、それ以外の画層をフリーズします。|;
(setq CuLy (getvar "CLAYER"))
(layerstate-save "JagaImoLisp_Work_State" nil nil)
(command-s ".-LAYER"
"_N" "JagaimoLisp_Work_Layer"
"_SET" "JagaimoLisp_Work_Layer"
"_F" "*"
""
);LAYER
;△△△△△△△△△△△△△△△△△△△△△△△△△
; 作図する部分です。作業用画層上で作図されます。
(command-s "._LINE" B C D E F B "")
(foreach X (list B C D E F)
(command-s "._TRIM" "" "F" P (polar P (angle P X) (/(distance P X)2)) """")
);foreach
;▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
;|作図した星を変数CuLyに入れたコマンド実行時の現在画層にし、
現在画層を戻し、必要なくなった作業用画層は消します。|;
(command-s "._CHANGE" (ssget "all") "" "_P" "_LA" CuLy "")
(command-s "._LAYER" "_T" CuLy "_SET" CuLy "")
(command-s "_laydel" "N" "JagaimoLisp_Work_Layer" "" "Y")
;|保存しておいた元の画層状態に復元します。復元後は画層状態を消します。
復元後、正しく表示されないこともあるので、REGENを入れておきます|;
(layerstate-restore "JagaImoLisp_Work_State" nil nil)
(layerstate-delete "JagaImoLisp_Work_State")
(command-s "._REGEN")
;△△△△△△△△△△△△△△△△△△△△△△△△△
(princ))
エラー処理も忘れずに
エラー処理は、ユーザーがESCを押してキャンセルしたり、何かしらのエラーが起こって中断されたときに実行される処理のことです。
画層状態を変更するコマンドを作った時は、作業中の画層状態で終わってしまわぬように、画層状態を復元するエラー処理を入れておきましょう。
エラー処理について詳しくはこちらを。
エラー処理を加えた例。
(defun c:STAR3 (/ *error* STAR3_End L P B C D E F CuLy)
;-----------------------------------------
;-----------------------------------------
;エラー処理 エラーが起きたらSTAR3_Endを実行
(defun *error* (msg)
(princ msg)
(STAR3_End)
(princ))
;画層復元処理(終了時かエラー時に実行)
(defun STAR3_End ()
;元の現在画層に戻す
(if CuLy
(command-s "._LAYER" "_T" CuLy "_SET" CuLy "")
)
;Lisp作業用の画層を消す
(if (tblsearch "Layer" "JagaimoLisp_Work_Layer")
(command-s "_laydel" "N" "JagaimoLisp_Work_Layer" "" "Y")
);if
;画層状態を復元、保存した画層状態を消す
(if (layerstate-has "JagaImoLisp_Work_State")
(progn (layerstate-restore "JagaImoLisp_Work_State" nil nil)
(layerstate-delete "JagaImoLisp_Work_State")
(command-s "._REGEN")
);progn
);if
);end
;-----------------------------------------
;-----------------------------------------
(defun L (A) (polar P(* pi (/ A 180)) 600))
(setq P (getPoint "星の中心点:") B (L 90.0) C (L 306.0) D (L 162.0) E (L 18.0) F (L 234.0))
;▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
;|ここでは現在画層と画層状態の保存し、作業用画層を作り、それ以外の画層をフリーズします。|;
(setq CuLy (getvar "CLAYER"))
(layerstate-save "JagaImoLisp_Work_State" nil nil)
(command-s ".-LAYER" "_N" "JagaimoLisp_Work_Layer" "_SET" "JagaimoLisp_Work_Layer" "_F" "*" "")
;△△△△△△△△△△△△△△△△△△△△△△△△△
; 作図する部分です。作業用画層上で作図されます。
(command-s "._LINE" B C D E F B "")
(foreach X (list B C D E F)
(command-s "._TRIM" "" "F" P (polar P (angle P X) (/(distance P X)2)) """")
);foreach
;▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
;|作図した星を変数CuLyに入れたコマンド実行時の現在画層にし、
画層復元処理が入ったSTAR3_Endを実行します。|;
(command-s "._CHANGE" (ssget "all") "" "_P" "_LA" CuLy "")
(STAR3_End)
;△△△△△△△△△△△△△△△△△△△△△△△△△
(princ))
まとめ
- フェンストリムを使うAutoLISPを作成したとき、他の図形があると影響する。
- 作図用画層を作成してそれ以外はオフかフリーズして作図するようにするといい。
- layerstate-saveは画層状態を保存する関数。
- layerstate-restoreは画層状態を復元する関数。
- layerstate-deleteは保存した画層状態を消す関数。
- layerstate-hasはすでにその名前の画層状態が保存されているか調べる関数。
- AutoLISPで自動処理のための画層状態や画層は使う時に作成してその度に消去が無難。
- 作業用に画層状態を変更するコマンドは中断時に復元するようエラー処理が必要。
関連記事
画層フリーズに使った画層名指定に使える *(ワイルドカード)について。
この星を作図するコマンドの場合だと、UNDO[元に戻す]で戻るとき、トリム5回、線分5回戻ることになります。
こういう作図コマンドは、[開始(BE)] [終了(E)]を入れて1つの動作にすると便利です。
Comments