選択フィルタ

提供:GizmoLabs - だいたい CAD LISP なサイト

選択フィルタリストの引数

ssget 等で特定の条件を満たすオブジェクトのみ選択をする場合、フィルタ リストの引数を記述する。 例えば、特定の画層上のオブジェクトや、特定のタイプのオブジェクト、特定の色のオブジェクトオブジェクト、指定以上のサイズのオブジェクトというような選択セットを取得できる。

フィルタリストは、entget が返すリストと同じ形式の DXF グループ コードを使用した連想リストで、図形のどの特性(1 つまたは複数)を調べさせて、どの値と一致していなければならないかを指定する。(グループ コードのリストは、『DXF リファレンス』を参照)。


ssget 関数は、図形名(グループ -1)、ハンドル(グループ 5)、および拡張データ(Xdata)コード(1000 以上のグループ)以外のすべてのグループ コードを認識する。フィルタリスト引数に無効なグループ コードを指定した場合は、ssget により無視される。拡張データ(Xdata)を持つオブジェクトを検索するには、コード -3 を使用する。

以下は、ssget でのフィルタリストの使用例。

; ユーザにオブジェクト選択を要求し、文字オブジェクトだけを選択セットに追加。
(setq ss1 (ssget '((0 . "TEXT"))))

; ユーザにオブジェクト選択を要求し、文字とマルチテキストオブジェクトだけを選択セットに追加。
(setq ss1 (ssget '((0 . "TEXT,MTEXT"))))   

; 直前に作成された選択セットから線分を含む選択セットを作成。
(setq ss1 (ssget "P" '((0 . "LINE")))) 
 
; 画層"寸法"上にある、窓内のすべてのオブジェクトの選択セットを作成。
(setq ss1 (ssget "W" pt1 pt2 '((8 . "寸法"))) )  

; データベース内の円オブジェクトの選択セットを作成。
(setq ss1 (ssget "X" '((0 . "CIRCLE"))))  
 
;  暗黙の選択セット(PICKFIRST が有効なときに選択されたオブジェクト)に含まれるすべての青(5番)の線分オブジェクトの選択セットを作成。
; 注意:このフィルタでは、ByLayer または ByBlock の色を持つ線分は選択されない。
(ssget "I" '((0 . "LINE") (62 . 5))) 

; 半径(グループ コード 40)が 2.0 以上 のすべての円の選択セットを作成。
(ssget "X" '((0 . "CIRCLE") (-4 . ">=") (40 . 2.0))) 

; APPNAMEアプリケーションの拡張データを含む全ての円オブジェクトの選択セットを作成。
(ssget "X" '((0 . "CIRCLE") (-3 ("APPNAME"))))

; APP1またはAPP2 アプリケーションの拡張データを含む全ての円オブジェクトを選択
(ssget "X" '((0 . "CIRCLE") (-3 ("APP1")("APP2"))))
(ssget "X" '((0 . "CIRCLE") (-3 ("APP[12]"))))     ; 同、ワイルドカードを使用した例
(ssget "X" '((0 . "CIRCLE") (-3 ("APP1,APP2"))))   ; 同、ワイルドカードを使用した例

; 匿名ブロック *U2 の選択セットを作成。ワイルドカードを使用した例
(ssget "X" '((2 . "`*U2"))) 

; 特定の名前を持つブロック(ここでは FOO, BAR, BAZZ)を除外して選択
(ssget "X" '((0 . "INSERT") 
           (-4 . "<NOT") 
             (-4 . "<OR") 
               (2 . "FOO") (2 . "BAR") (2 . "BAZZ")
             (-4 . "OR>")
           (-4 . "NOT>")
           (-3 ("MK_CAD"))))

; こうもかける
(ssget "X" '((0 . "INSERT") 
           (-4 . "<NOT") 
               (2 . "FOO,BAR,BAZZ")
           (-4 . "NOT>")
           (-3 ("MK_CAD"))))

選択セット操作の例

  • 現在の図面の最初と最後の図形を含む選択セットを作成する。
(setq fname (entnext))         ; 図面内の最初の図形を取得。
(setq lname (entlast))         ; 図面内の最後の図形を取得。
(if (not fname)
 (princ "¥n図面内に図形はありません。")")
 (progn
   (setq ourset (ssadd fname)) ; 最初の図形の選択セットを作成。
   (ssadd lname ourset)        ; 選択セットに最後の図形を追加。
 )
)
  • この例は、1 つの図形しかなくても正しく実行される(fname とlnameは同じ値になる)。既に選択セットに含まれている図形名を ssadd に渡しても、その要求は無視され、エラーにはならない。
  • 選択セットの最後の図形名を取得する
(setq sset (ssget)) ; 選択セットを作成するようユーザに要求。
(setq ent1 (ssname sset 0))  ; sset 内の最初の図形の名前を取得。
(setq ent4 (ssname sset 3))  ; sset 内の 4 番目の図形の名前を取得。
(if (not ent4)
 (princ "¥n最低 4 つの図形を選択しなければなりません。 ")")
)
(setq ilast (sslength sset)) ; sset 内の最後の図形のインデックスを取得し、sset 内の最後の図形の名前を取得する
(setq lastent (ssname sset (1- ilast)))
  • 選択セットへの図形追加で、選択セットに図形が重複して含まれることはない。同じ図形を複数回追加しても、2 回目以降の追加は無視される。したがって、sslength は、指定された選択セット内の図形の正確な数を返す。


フィルタ リストのグループ演算子

次にしめす論理グループ演算子を使用してネストしたブール式を作成することにより、グループをテストすることができる。

  • 開始 … 囲まれるもの… 終了
  • "<AND" … 1つ以上のオペランド … "AND>"
  • "<OR" … 1つ以上のオペランド … "OR>"
  • "<XOR" … 2つのオペランド … "XOR>"
  • "<NOT" … 1つのオペランド … "NOT>"

グループ演算子は、関係演算子と同じように、グループ コード -4 で指定する。グループ演算子はペアで使用するため、フィルタ リスト内で正しく対応付けられていなくてはならない。対応が正しくないと ssget の呼び出しは失敗する。

次に、フィルタ リストのグループ演算子の例をしめす。

;;; 半径 1.0 のすべての円と画層 "ABC" 上のすべての線分を選択する。
;;; グループ演算子では大文字と小文字が区別されないので、"AND>"、"<OR" の代わりに 
;;; "and>"、"<or" を使用することもできる。 

(ssget "X" 
 '(
    (-4 . "<OR")
       (-4 . "<AND")
         (0 . "CIRCLE")
         (40 . 1.0)
       (-4 . "AND>")
       (-4 . "<AND")
         (0 . "LINE")
         (8 . "ABC")
       (-4 . "AND>")
    (-4 . "OR>")
  )
)


  • 分類演算子はグループ -3 の中では使用できない。グループ -3 で指定された複数のアプリケーション名には、暗黙的に AND 演算子が適用される。
  • 拡張データに対して他のグループ演算子を使用する場合、個別にグループ -3 を指定し、必要に応じてそれらをグループ化すること。
; アプリケーション "APP1" か "APP2" のどちらか一方だけの拡張データを持っているすべての円を選択する指定の例。
(ssget "X" 
 '((0 . "CIRCLE")
     (-4 . "<XOR")
       (-3 ("APP1"))
       (-3 ("APP2"))
     (-4 . "XOR>")
  ))

; 256(BYLAYER)に設定されていない色の線分を選択。
(ssget '((0 . "LINE") (-4 . "<NOT") (62 . 256) (-4 . "NOT>")))

フィルタ リストの関係演算子

特に指定しない限り、filter-list 内の各項目と一致するかどうかがテストされる。しかし、数値グループ(整数、実数、点、ベクトル)に対しては、関係演算子を指定する特殊なグループ コード -4 を含めることで他の関係を指定できる。 グループ -4 の値には、filter-list 内の次のグループに適用される関係演算子を示す文字列を指定する。

次のコードは、半径(グループ コード 40)が 2.0 以上 のすべての円を選択する。

(ssget "X" '((0 . "CIRCLE") (-4 . ">=") (40 . 2.0)))

指定可能な関係演算子は次の通り。

  • 演算子 … 説 明
  • "*" … すべてのもの(常に真)
  • "=" … 等しい
  • "!=" … 等しくない
  • "/=" … 等しくない
  • "<>" … 等しくない
  • "<" … より小さい
  • "<=" … より小さいか等しい
  • ">" … より大きい
  • ">=" … より大きいか等しい
  • "&" … ビット方式の AND(整数グループのみ)
  • "&=" … ビット方式のマスクが等しい(整数グループのみ)

  • 関係演算子の使用法は、テストするグループの種類によって異なる。
  • ビット演算子("&" と "&=")を除くすべての関係演算子は、実数値グループと整数値グループの両方に対して有効。
  • ビット演算子 "&" と "&=" は、整数値グループに対してだけ有効。ビット方式の AND(論理積)"&" は、((integer_group & filter) /= 0)の場合、つまり、マスク内の設定されているビットのいずれかのビットが整数グループでも設定されている場合に、真になる。
  • ビット方式のマスク "&=" は、((integer_group & filter) = filter)の場合、つまり、マスク内の設定されているすべてのビットが integer_group でも設定されている場合に、真になる(integer_group で他のビットが設定されていてもチェックされない)。
  • 点グループの場合、X、Y、Z に対するテストを結合して単一の文字列にできる。このとき、各演算子をカンマで区切る(たとえば、">,>,*")。文字列から演算子を省略すると、すべてを選択する演算子 "*" とみなされる (たとえば、"=,<>" では Z がチェックされない)。
  • 方向ベクトル(グループ タイプ 210)は、演算子 "*"、"="、"!=" (または「不等号」演算子のいずれか)で比較できる。
  • 文字列グループには関係演算子を使用できない。ワイルドカードを使用する。


; 高度が 4.0 の円を選択。
(ssget '((0 . "CIRCLE") (-4 . "*,*,=") (10 0.0 0.0 4.0)))

; X=1,Z=1 が始点の線を選択。(Y座標はどこでもいい。) 
(ssget '((0 . "LINE") (-4 . "=,*,=") (10 1.0 0.0 1.0)))

; 閉じた LWPolylinesを選択。
(ssget '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1)))