【AutoCAD LISP】LISP で図形を選択する方法

2022年2月17日

【AutoCAD LISP】LISP で図形を選択する方法

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 とコマンド ラインに入力します。

すると、以下のように表示されます。

!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)

やったー!!

思ったとおりに、窓選択の図形が選択セットに追加されてる!!

窓選択の図形がハイライトされた

-API
-