1. 程式人生 > >AutoLisp 選擇對象函數 ssget 用法

AutoLisp 選擇對象函數 ssget 用法

結束 -a length 二進制 type 半徑 對象類型 元素 targe

語法

(ssget [sel-method] [pt1 [pt2]] [pt-list] [filter-list])

ssget 的參數均為可選參數,需要註意的是可選參數之間的組合條件。
以下語法表示中 <parameter> 尖括號代表必選,[parameter] 方括號代表可選。


一、選擇集的窗口參數

  • [sel-method] 字符串類型,不區分大小寫,指定一個選擇方法。
  • [pt1 [pt2]] 表類型,由三個數字的點參數表,表示 xyz 坐標,也可以是僅包括xy 的坐標。
  • [pt-list] 表類型,由點參數表組成的表。

C 窗交(反選)

如果指定了該參數,則必須跟一對點創建一個矩形窗口,與矩形窗口相交的對象均被加入選擇集。
參數語法: (ssget "c" <pt1> <pt2> [filter-list])


此時,[pt-list] 參數不能出現,否則 ssget 將會返回一個錯誤提示:錯誤的點參數
示例:

(setq pt1 (getpoint "First Pt:"))
(setq pt2 (getpoint "Second Pt:"))
(setq ss (ssget "c" pt1 pt2))
  • 1
  • 2
  • 3

W 窗口(正選)

與 C 參數語法及用法類似,但功能不同,只有在矩形窗口內完整的對象才會被加入選擇集。
參數語法: (ssget "w" <pt1> <pt2> [filter-list])
參數前加下劃線 “_w” 可以使代碼在不同版本的CAD平臺下兼容,建議寫上。

CP 圈交(多邊形反選)

如果指定了該參數,則必須用構成多邊形的點表響應,與多邊形相交的對象被加入選擇集。
參數語法: (ssget "CP" <pt-list> [filter-list])
此時點參數 [pt1] [pt2] 不能出現,而且,CP 參數依賴 <pt-list> 的順序來構成一個多邊形。
例如四個點按順序連接為一個8字型,而不是一個矩形,ssget 將返回一個空選擇集,即使對象與窗口相交。
如果參數為少於3個點的表,也將返回一個 nil。
示例:

(setq pt1 (getpoint "Piont1:"))
(setq pt2 (getpoint "Piont2:"))
(setq pt3 (getpoint "Piont3:"))
(setq pt4 (getpoint "Piont4:"))
(setq ss (ssget "c" (list pt1 pt2 pt4 pt4)))
  • 1
  • 2
  • 3
  • 4
  • 5

WP 圈圍(多邊形正選)

與 CP 參數語法及用法類似,但只有被多邊形窗口包圍的對象才會被加入選擇集。
參數語法: (ssget "wp" <pt-list> [filter-list])

F 欄選

將參數點表連接為一條折線,與折線相交的對象被加入選擇集。
參數語法: (ssget "f" <pt-list> [filter-list])
pt-list 最少由2個點組成表,CP/WP 參數最少需要 3 個點。

P 前一批創建的圖形

包括 CAD 命令或 LISP 程序創建的圖形對象。
參數語法: (ssget "p" [filter-list])
P 參數不能和 [pt1 [pt2]] [pt-list] 任何一個點參數組合,否則將返回一個錯誤,有的 CAD 版本會返回 nil
當分解(EXPLODE)一個 CAD 圖形時,p 方法特別有用,可以一次性建立分解後的所有對象選擇集。

L 最後一個創建的對象

包括 CAD 命令或 LISP 程序創建的對象,註意和 P 參數的區別。
參數語法: (ssget "l" [filter-list])
在獲取最後一個對象的圖元名時,以下代碼是等價的,但是後者不能提供直接過濾功能。

(ssname (ssget “L”) 0) == (entlast)

I 隱含窗口選擇

參數語法: (ssget “i” [filter-list])
CAD 命令有兩種執行方式,第一種先命令後選擇,第二種先選擇後命令。所以在 Lisp 中也允許先選擇後命令,
而且這方式可以通過系統變量 pickfirst 來關閉(值為 0),此時 I 參數失效,(ssget “i”) 將返回 nil。
選擇對象後,可以用 (sssetfirst nil) 取消選擇集的亮顯狀態。

X 整個文件

在當前打開的CAD文件中選擇所有對象,包括關閉、凍結圖層中的圖元和可見屏幕外的圖元,不分大小寫。
參數語法: (ssget "x" [filter-list])
X 用法與 A 用法等價,(ssget “A”) 也是選擇所有對象。

:E 拾取框

用拾取框選擇對象,此時 ssget 將不再拉出一個矩形窗口,直到點右鍵結束選擇。
參數語法: (ssget ":E" [filter-list])
與 :E 對應的 :N 參數為只能拉出一個矩形窗口選擇,而不能通過點選拾取對象。

:S 僅允許單一選擇集

使用:s參數時,ssget 將點選對象一次就會結束,無論是否選中對象,未選中則返回 nil,可節省一次回車確認。
參數語法: (ssget ":S" [filter-list])
說明: “:S” 參數和 “:E” 可以同時使用,例如: (ssget "_:S:e")
以下參數可以組合使用, “+” 或 “-“,例如:(ssget "_:S+D")

:D 重復選擇

允許同一個對象多次加入選擇集,每選擇一次,則加入一次。
參數語法: (ssget ":D" [filter-list])
例如:畫兩條直線,然後運行代碼 (setq ss (ssget ":D")),框選3次直線後。(sslength ss) 返回 6

:L 不選擇鎖定圖層對象

註意: L、:L、-L 的參數是不同的。
參數語法: (ssget ":L" [filter-list])
ssget 默認選擇所有圖層對象,這樣在程序中需判斷圖層是否鎖定,才能編輯,否則 lisp 代碼將返回錯誤。

其他方法還有A :A -A _:V _:U _:R -M -P :P -G -L :? 等參數以及組合用法,有興趣的朋友可以測試。
這些參數的用法官方並未在語法參考裏公布,估計是程序測試留下的接口,CAD 更新時可能被關閉,不建議使用。

註意事項:

  • ssget 帶點參數調用時,可能會受到自動捕捉的影響,一般先將系統變量 osmode 置零。
  • ssget 點參數包圍的矩形、多邊形應在當前繪圖區域內可見,否則 ssget 僅返回可見區域內的對象選擇集。
  • 創建選擇集會消耗 AutoCAD 的臨時文件存儲區,所以 AutoLISP 不允許同時創建多於 128 個選擇集。
    例如:畫一個圓,然後執行以下代碼:
    (repeat 130 (setq a (cons (ssget "l") a)))
    這段程序循環了 130 次,AutoCAD提示 “錯誤: 超出選擇集數量的最大範圍”,如果繼續調用 (ssget) 將返回 nil;此時,只有清空選擇集變量 (setq a nil) 才能繼續調用 ssget。
  • ssget 選擇時沒有自定義提示,如果特別需要可用第三方函數,比如飛詩的: Fsxm-ssget

二、選擇集的過濾條件

[filter-list] 過濾條件,表類型,指定與屬性(DXF 組碼)匹配的對象被加入選擇集。
常用支持過濾的 DXF 組碼:

  • 0 實體類型
  • -4 條件運算, SSGET 的專用組碼,包括邏輯條件與關系條件
  • 1 圖元文字內容
  • -3 擴展數據
  • 2 屬性標記、塊名
  • 6 線型名
  • 7 文字樣式
  • 8 圖層名
  • 40 CIRCLE 直徑或 TEXT 文字高度
  • 62 顏色號

0 組碼

指定對象實體類型,語法 ‘((0 . types)),對象類型 types 為字符,不分大小寫,常用的實體類型如下:

"POINT"、"TEXT"、"MTEXT"      點、單行文本、多行文本
"LINE"、"LWPOLYLINE"、"SPLINE"    直線、多段線、樣條曲線
"CIRCLE"、"ARC"、"ELLIPSE"        圓、圓弧、橢圓
"HATCH"、"DIMENSION"     填充、標註
"ATTDEF"、"INSERT"       屬性文字、圖塊
  • “,” 邏輯或,對象類型可多選,名稱用 “,” 分隔。例如,創建直線和文本的選擇集:

    (ssget ‘((0 . “TEXT,LINE”)))

    框選對象後,將只有直線和文本被選中(亮顯)並加入選擇集。

  • “~” 邏輯非,用來排除某類型。例如:創建除過圖塊的選擇集

    (ssget ‘((0 . “~INSERT,LINE”)))

    顯然,第二個類型 LINE 毫無意義,因為第一個 ~INSERT 非圖塊類型範圍包含了 LINE 類型。

  • “*” 通配符,用來表示模糊類型。例如,創建所有直線的選擇集:

    (ssget ‘((0 . “*LINE”)))

    框選對象後,可以將 “LINE”、”LWPOLYLINE”、”SPLINE”、”MLINE” 類型加入選擇集,和以下過濾條件等價:

    (ssget ‘((0 . “LINE,LWPOLYLINE,SPLINE,MLINE”)))

    通常我們用後者實現精確過濾。

    其他:(ssget ‘((0 . “*E”))) 選擇過濾所有直線、圓、橢圓的類型,因為他們的尾字母都是 E。
    (ssget ‘((0 . “*”))) 與 (ssget) 等價,相當於全選。
    (ssget ‘((0 . “~*”))) Lisp 都不知道你要幹嘛了,因為它什麽也選不上。

  • 0 組碼可以和其他組碼組成 list 表過濾。例如,選擇半徑為 20 的圓:

    (ssget ‘((0 . “CIRCLE”)(40 . 20)))

    通常,對於字符類型組碼均支持通配過濾語法,包括線型名、文字樣式、圖層等。
    例如:選擇非 0 層的所有對象

    (ssget ‘((8 . “~0”)))

  • 註意:並不是所有組碼都支持過濾,例如下面過濾條件將返回 nil,即使存在句柄為 “25F” 的圓。

    (ssget ‘((0 . “CIRCLE”)(5 . “2*”)))

-4 組碼

邏輯條件運算

用 -4 組碼和邏輯運算符組成表對,將一個或幾個表項包夾。邏輯運算符對大小寫不敏感。
表對必須成對出現,如:(-4 . "<xx")...(-4 . "xx>"), 常用的邏輯運算符如下:

or   項目並集
and  項目交集
not  不含此項
xor  兩項異或
  • or 並集。例如,選擇直線和文本:

    (ssget ‘((-4 . "<or")(0 . "line")(0 . "text")(-4 . "or>")))

    顯然與 (ssget ‘((0 . “text,LINE”))) 等價,但後者寫法更簡潔。
    例如,選擇顏色為紅色和綠色的文字和直線:

    (ssget ‘((0 . "TEXT,LINE")(-4 . "<or")(62 . 1)(62 . 3)(-4 . "or>")))

  • and 交集。例如,選擇圖層為 “notes”,顏色為綠色的單行文本:

    (ssget ‘((-4 . "<and")(0 . "text")(8 . "notes")(62 . 3)(-4 . "and>")))

  • not 非。例如,選擇非 “notes” 層的實體對象:

    (ssget ‘((-4 . "<not")(8 . "notes")(-4 . "not>")))

    顯然與 (ssget ‘((8 . “~notes”))) 等價。
    註意:非運算只能有一個表項被包夾,否則 ssget 將返回 nil。

  • xor 異或。即半加法,實現二進制加法的不進位運算。邏輯意義: 相同為0,相異為1。
    例如,選擇在 “notes” 層不是綠色、或是綠色而不在 “notes” 層的文本對象:

    (ssget ‘((0 . "text")(-4 . "<xor")(8 . "notes")(62 . 3)(-4 . "xor>")))

    註意:異或運算只能有兩項,如果超過兩項或只有一項,ssget 將返回 nil。

  • 邏輯運算可以嵌套,組成更復雜的條件運算。
(ssget ‘((0 . "text")
        (-4 . "<or")
        (-4 . "<and")(8 . "0")(62 . 1)(-4 . "and>")
        (-4 . "<and")(8 . "notes")(62 . 3)(-4 . "and>")
        (-4 . "or>")
))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

關系條件運算

用 -4 組碼和關系運算符組成表對,放在需要比較的表項前。
與成對出現的邏輯條件不同,關系表對單個出現,常用關系運算符如下:

"*"    通配符
"="    等於
"!="   不等於
"<>"   不等於
"<"    小於
"<="   小於或等於
">"    大於
">="   大於或等於
"&"    按位與
"&="   按位屏蔽相等(僅適用於組值為整型的組)

例如:選擇半徑大於或等於20的圓

(ssget ‘((0 . "CIRCLE")(-4 . ">=")(40 . 20)))

選擇半徑20的圓,顏色不是紅色

(ssget ‘((0 . "CIRCLE")(-4 . "<and")(-4 . "!=")(62 . 1)(40 . 20)(-4 . "and>")))

對於含有多個元素的比較,如點坐標,可用 “,” 隔開關系運算符。
選擇圓心坐標 x>100, y<120, z=0,圖層名以 cir 開始的圓

(ssget ‘((0 . "CIRCLE")(-4 . ">,<,=")(10 100 120 0)(8 . "cir*")))

選擇圖形顏色不是隨層 (bylayer) 的對象,可用以下代碼
(ssget ‘((-4 . "&")(62 . 255)))
我們知道 CAD 的索引顏色數為 1-255,用 2 個字節表示,隨層的顏色為 0,在 DXF 組碼中並不顯示。
此時如果用 (ssget ‘((-4 . “>”)(62 . 0))) 來過濾是不對的,隨層顏色的圖形也將被選上。
如果用二進制的 8 個 1 與當前顏色數進行邏輯與的位運算 &,其結果都不是 0, 即為真, 2^8=255

1 組碼

文本內容的匹配運算(與 wcmatch 函數語法相同),相當於簡單正則。
對於包含大量文本對象的圖形,有時候需要精確的過濾條件,可以通過以下特殊符號來實現:

"*"  通配符,代表一個或多個任意字符
"|"  管道符,用來連接並列字符,表示或的關系
"?"  占位符,代表一個任意字符
"#"  數字符,代表一個0-9的字符
"@"  字母符,代表一個a-z,A-Z字符
"."  特殊字符,代表一個除字母和數字的其他字符
"~"  符號非運算
"`"  轉義字符(數字 1 左邊那個字符)
","  分隔兩個模式的表達式
"[]" 限位符,用中括號包括一個表達式,表示一位字符
  • 例1: CAD 中有以下 3 組 TEXT 文本

    ① X=35.614 ② Y=356.201 ③ Z=11.526

    • 要求匹配以 “X=” 這兩個字母開始的單行文本

      (ssget ‘((0 . “TEXT”) (1 . “X=*”)))

      返回第 ① 組文本的選擇集
      解讀: “X=” 不是通配運算符,在此表示精確匹配,後面加 “*” 是任意符號。

    • 要求匹配以 “X=” 或 “Y=” 這兩個字母開始的單行文本

      (ssget ‘((0 . “TEXT”) (1 . “[X|Y]=*”)))

      返回第 ①、② 組文本選擇集
      解讀: 並列出現的字符,用 “|” 連接。

    • 要求匹配 包含數字小於 100 的單行文本

      (ssget ‘((0 . “TEXT”) (1 . “@=##[.]*)))

      返回第 ①、③ 組文本選擇集
      解讀: “##” 代表兩個數字,兩個數字連接最大只能是 99。小數點單獨出現用方括號 [.]
      如果僅僅是 “.”,而沒有方括號,則代表任意特殊符號。

  • 例2: 我們再試驗一組復雜的文本,在 CAD 中寫入以下 10 組 TEXT 文本

    ① abcde ② 12345 ③ -25.390 ④ *&@125 ⑤ F35
    ⑥ #54-65 ⑦ 頭文字 ⑧ 36 75 ⑨ F ⑩ /(*&%@!

    • 要求匹配 包含數字 文本

      (ssget ‘((0 . “TEXT”) (1 . “#“)))

      以上代碼將選中 ②③④⑤⑥⑧ 包含數字的 6 組文本
      解讀: “#” 代表一個數字字符,

    • 要求匹配 以*開始的 文本

      (ssget ‘((0 . “TEXT”) (1 . “`**”)))

      以上代碼將選中 ④ 以*開始的 1 組文本
      解讀: 因為 "*" 是通配符,要匹配語法中的專用字符用轉義 "‘*"

    • 要求匹配 不含特殊字符 文本

      (ssget ‘((0 . “TEXT”) (1 . “~*.*”)))

      以上代碼將選中 ①②⑤⑦⑨,註意:負號和小數點也是特殊符號
      解讀: “.” 代表一個特殊字符,前後加 “.” 包含一個特殊字符,不含特殊字符就是 “~*.*”

    • 要求匹配 純數字 的單行文本,包含負號和小數點

      (setq ss (ssget ‘((0 . “TEXT”) (1 . “~*[~.–9]*))))

      解讀: 負負得正,兩次取非可獲取數字本身,括號內 “[~.-]”, 意為包含小數點和負號。
      註意, 220-11 不能參加計算的數字也會被包括其中。

  • 下面給出常用匹配規則,歡迎測試
    匹配數字,不含小數點和正負號: “~*[~0-9]*” 如: 9824
    匹配 26 個小寫字母: “~*[~a-z]*” 如: loveu
    匹配大寫字母或數字: “~*[~A-Z],~[~0-9]*” 如: NASAA 或 9527
    匹配大寫字母和數字混排: “~*[~A-Z|0-9]*” 如: F36D
    空格是一個很特殊的字符,用一個空格可以匹配任意個空格,其他字符沒有這個特性。
    例如: (wcmatch " " " ") 返回 T

-3 組碼

擴展數據過濾。ALISP 中可以用如下方法給圖形添加擴展數據,增加自定義組碼及表值。

  • 第一步,註冊一個擴展對象應用名

    (regapp “xapp”)

  • 第二步,選擇一個圖元並返回組碼

    (setq En (entget (car (entsel))))

  • 第三步,定義加入圖元的擴展數據

    (setq data ‘((-3 (“xapp” (1000 . “你好中國”)))))

  • 第四步,將擴展數據附著更新圖元

    (entmod (append En data))

  • 完成,我們可以檢查一下擴展數據

    (assoc -3 (entget (car (entsel)) ‘(“xapp”)))

    結果返回 (-3 (“xapp” (1000 . “你好中國”)))
    采用這種方法添加擴展數據,用 EXPLODE 命令不能清除。

與 -3 組碼無關的話題。
用 VLisp 函數給圖元添加數據比較簡單,無需提前註冊名稱,例如
(vlax-ldata-put (car (entsel)) "xa" "你好中國")
查詢數據如下:
(vlax-ldata-get (car (entsel)) "xa")
返回 "你好中國"
采用這種方法,用 EXPLODE 命令可以炸開擴展數據,相當於清除圖元的擴展數據。

在某些二次開發的 CAD 程序中,擴展數據被大量使用,用來分類圖元對象(圖層分類法容易被修改)。
這時候的 ssget 方顯英雄本色,用來精確選擇,再適合不過。在參數化制圖時,添加擴展數據,當參數
發生變化時,很容易遍歷修改這些對象,由於擴展數據的不可見和不可分解的特性,不會被用戶誤操作。
這時候只需要用下面代碼即可完成過濾,連對象類別的 0 組碼 都不需要了。

(ssget ‘((-3 (“xapp”))))

AutoLisp 選擇對象函數 ssget 用法