LISP で図形を選択したいんだけど…
どうすればできるのかなぁ?
こんにちは、メモだよ!!管理人です。
今回は、そんなあなたに、LISP で図形を選択する方法を紹介します。
すでに描かれている図形に対して、なにか操作を行ったり、プロパティを変更したりするためには、その図形を変数に代入しておく必要があります。
どのようにして、図形を選択して変数に代入できるのでしょうか。
それでは、見ていきましょう。
vla-getentity 関数で、図形をクリックして選択して取得
vla-getentity 関数を使用して、クリックしたひとつの図形を取得することができます。
(defun c:GetEntity()
; AutoCAD のオブジェクトを取得
(setq acadObject (vlax-get-acad-object))
; アクティブなドキュメントを取得
(setq activeDocument (vla-get-activedocument acadObject))
; ドキュメントの Utilyty オブジェクトを取得
(setq utility (vla-get-utility activeDocument))
; 選択した図形の VLA オブジェクトを取得
(vla-getentity utility 'vlaObject 'pickedPoint "\nオブジェクトをを選択:")
(princ)
)
この LISP をロードして、GetEntity コマンドを実行してみてください。
「オブジェクトを選択」と表示されるので、オブジェクトをクリックして選択します。
すると、変数 vlaObject にクリックしたオブジェクトが代入されます。
コマンドは問題なく実行できたけど…
本当に変数に代入されているかどうやって確認するの?
変数の内容を確認するには、コマンド ラインに「!」のあとに変数名を追加したものを入力します。
なので、この場合は !vlaObject とコマンド ラインに入力します。
すると、以下のように表示されます。
たとえば、円を選択したときはこのように IAcadCircle と表示されます。
vla-selectonScreen 関数を使用して複数の図形を選択
ひとつの図形を選択する方法はわかったけど…
複数の図形を選択したいときはどうするの?
vla-selectonscreen 関数を使用して、複数の図形を選択できます。
(defun c:SelectEntities()
; AutoCAD のオブジェクトを取得
(setq acadObject (vlax-get-acad-object))
; アクティブなドキュメントを取得
(setq activeDocument (vla-get-activedocument acadObject))
; 選択セットのオブジェクトを取得
(setq selectionSets (vla-get-selectionsets activeDocument))
; 新しい選択セットを追加
(setq ssSelect (vla-add selectionSets "select"))
; 選択セットのオブジェクトを取得
(vla-selectonscreen ssSelect)
(princ)
)
vla-selectonscreen 関数の引数は選択セットなので、事前に select という名前の選択セットを作成しています。
この LISP をロードして、SelectEntities コマンドを実行してみてください。
「オブジェクトを選択」と聞かれるので、クリックでも窓選択でもいいので、図形を選択してEnterキーを押して確定します。
これで、変数 ssSelect に選択したオブジェクトが代入されました。
!ssSelect とコマンド ラインに入力すると、選択セット(IAcadSelectionSet)が設定されているのがわかります。
同じ選択セットは追加できない
それぞれの選択セットは固有のものである必要があります。
なので、同じ名前の選択セットを設定することはできません。
たとえば、SelectEntities コマンドを実行したとに、以下のコードをコマンド ラインに貼り付けて実行してみてください。
(setq ssSelect (vla-add selectionSets "select"))
そして、F2キーを押して見てください。
すると、以下のようなエラーが表示されます。
これは、さっき SelectEntities コマンドを実行して、すでに select という名前の選択セットができているのに、もう一度同じ名前の選択セットを作成しようとしたからです。
え〜…
じゃあどうすればいいの〜?
念のため、事前に同じ名前の選択セットがないか確認して、あれば削除するようにしておいたほう、エラーにならないのでおすすめです。
; 選択セットに、すでに名前があるか確認する関数
(defun HasSelectionSet(selectionSets name / selectionSet selectionName)
(setq selectionSet nil)
(vlax-for item selectionSets
(setq selectionName (vlax-get-property item 'Name))
(if (equal name selectionName)
(setq selectionSet item)
)
)
selectionSet
)
; 選択セットに、すでに名前があったら削除する関数
(defun DeleteSelectionSet(selectionSets name / selectionSet)
(if (setq selectionSet (hasSelectionSet selectionSets name))
(vla-delete selectionSet)
)
(princ)
)
上記のコードで、DeleteSelectionSet 関数を作成したので、以下を実行してみてください。
(deleteSelectionSet selectionSets "select")
これで、変数 ssSelect に代入されている選択セット(名前が select)が削除されます。
これを行ったあとなら、もう一度 (setq ssSelect (vla-add selectionSets "select")) を問題なく実行できます。
ホントだ!!
今度は問題なく実行できた!!
その他の図形選択(窓、クロス窓、直前、最後に作成、すべて)
その他にも、以下の方法で選択できます。
- 窓選択
- クロス窓選択
- 直前の選択
- 最後に作成されたオブジェクト
- すべて
(defun c:SetEntitiesToSelectionSet()
; AutoCAD のオブジェクトを取得
(setq acadObject (vlax-get-acad-object))
; アクティブなドキュメントを取得
(setq activeDocument (vla-get-activedocument acadObject))
; 選択セットのオブジェクトを取得
(setq selectionSets (vla-get-selectionsets activeDocument))
; すでにこれから作成する選択セットと同じ名前があるか確認し、あれば削除
(deleteSelectionSet selectionSets "ssWindow")
(deleteSelectionSet selectionSets "ssCrossWindow")
(deleteSelectionSet selectionSets "ssPrevious")
(deleteSelectionSet selectionSets "ssLast")
(deleteSelectionSet selectionSets "ssAall")
; 新しい選択セットを追加
(setq ssWindow (vla-add selectionSets "ssWindow"))
(setq ssCrossWindow (vla-add selectionSets "ssCrossWindow"))
(setq ssPrevious (vla-add selectionSets "ssPrevious"))
(setq ssLast (vla-add selectionSets "ssLast"))
(setq ssAll (vla-add selectionSets "ssAall"))
; 窓選択やクロス窓選択を行うコーナーの点を設定
(setq corner1 (vlax-3d-point 100 100 0))
(setq corner2 (vlax-3d-point 200 200 0))
; それぞれの選択セットに配置
(vla-select ssWindow acSelectionsetWindow corner1 corner2)
(vla-select ssCrossWindow acSelectionsetCrossing corner1 corner2)
(vla-select ssPrevious acSelectionSetPrevious)
(vla-select ssLast acSelectionSetLast)
(vla-select ssAll acSelectionSetAll)
(princ)
)
; 選択セットに、すでに名前があるか確認する関数
(defun HasSelectionSet(selectionSets name / selectionSet selectionName)
(setq selectionSet nil)
(vlax-for item selectionSets
(setq selectionName (vlax-get-property item 'Name))
(if (equal name selectionName)
(setq selectionSet item)
)
)
selectionSet
)
; 選択セットに、すでに名前があったら削除する関数
(defun DeleteSelectionSet(selectionSets name / selectionSet)
(if (setq selectionSet (hasSelectionSet selectionSets name))
(vla-delete selectionSet)
)
(princ)
)
この LISP をロードして、SetEntitiesToSelectionSet コマンドを実行してみてください。
これで、各変数に選択セットが追加されました。
- 変数 ssWindow:窓選択(コーナーが 100,100 と 200,200)で選択されたオブジェクト
- 変数 ssCrossWindow:クロス窓選択(コーナーが 100,100 と 200,200)で選択されたオブジェクト
- 変数 ssPrevious:直前に選択されたオブジェクト
- 変数 ssLast:最後に作成されたオブジェクト
- 変数 ssAll:すべてのオブジェクト
思った通りのオブジェクトが選択されたかなぁ?
どうやったら確認できるの?
たとえば、変数 ssWindow の図形を確認したいときは、以下のコードを実行するとハイライトされます。
※ ハイライトを解除するには、コマンド ラインに RE と入力して再作図を行います。
(vla-highlight ssWindow :vlax-true)
やったー!!
思ったとおりに、窓選択の図形が選択セットに追加されてる!!