目 錄
阿陽的 AutoCAD 二次開發簡明教程,本系列博客僅用於個人學習,除此之外,無其他任何用途。
Blog Links
因個人能力有限,該系列博客難免有所疏漏/錯誤,不妥之處還請各位批評指正。
一、前沿
用戶要對已有的一些對象進行刪除、複製、移動等編輯操作,都需要選中被操作的對象。選擇對象或對操作對象進行篩選的過程,稱爲構造選擇集。選擇對象可以只選擇一個對象,也可以同時選擇多個對象。AutoCAD 中常用構造選擇集有直接拾取、窗口、窗交、欄選等多種方式。[1]
本文簡要介紹在 CAD 二次開發過程中幾種常用選擇對象即構造選擇集的方法。
二、連接CAD的方式
爲了保證代碼的順利運行,本文采用 win32com 庫連接 CAD,具體代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
=============================
Author:DalNur
Email: [email protected]
=============================
'''
import win32com.client
import pythoncom
acad = win32com.client.Dispatch("AutoCAD.Application.19")
# AutoCAD.Application.19爲 ProgID
doc = acad.ActiveDocument
doc.Utility.Prompt("Hello AutoCAD\n")
mp = doc.ModelSpace
print(doc.Name)
2.1. ProgID
根據 CAD 版本的不同, ProgID 可能發生變化,部分版本 CAD 的 ProgID 如下:
AutoCAD 版本 | ProgID |
---|---|
2010 | AutoCAD.Application.18 |
2014 | AutoCAD.Application.19 |
常見版本 CAD 的 ProgID 詳見博文: autocad application 版本 。
其餘版本 CAD 的 ProgID 在官方二次開發幫助文檔中查看,具體查找位置如下圖所示。
官方二次開發幫助文檔的獲取方式詳見博文:Python pyautocad庫 使用簡介 前沿部分。
三、數據轉換
說明:本人非計算機專業出身,文中某些表述可能不嚴謹甚至錯誤,還請各位見諒。
Python 中的數據類型較少,且對數據本身的要求也較爲寬鬆,如一個列表中的各個元素可以分別屬於不同的數據類型,這雖然有利於降低程序的編寫難度,但也對 CAD 的二次開發產生了一些不必要的麻煩。
在 CAD 二次開發過程中,很多函數/方法的參數要求輸入的數據類型爲 Variant (array of objects) ,但在 Python 中似乎又沒有哪一種數據類型與之直接相對應,若採用 list 代替 Variant,那麼程序無法順利執行,報錯爲 “ 對象數組無效 ”。因此,需要某種轉換方式,將Python中定義的變量轉換爲能夠被CAD識別的數據類型 Variant 。
VARIANT 結構體主要是使用在 COM(組件對象模型)中用於傳遞參數使用,它的存在主要是爲了保持一個在 COM 參數傳遞方法的統一性,它幾乎包含了所有普通常用類型的數據類型的傳遞,如整型,浮點型,布爾型等,以及相應類型的指針類型,如整型指針。[3]
部分類型與變量對應關係如下表:
Member name | Description |
---|---|
VT_EMPTY | Indicates that a value was not specified. |
VT_R8 | Indicates a double value. |
VT_DISPATCH | Indicates an IDispatch pointer. |
另外,NumPy arrays can be passed as VARIANT arrays arguments. The array is converted to a SAFEARRAY according to its type. [4] ( 此爲 comptypes 庫幫助文檔原文,本人對計算機瞭解有限,爲了不曲解原文,此處不做翻譯),部分對應關係如下:
NumPy type | VARIANT type |
---|---|
int32, int, intc, int_ | VT_I4 |
uint32, uint, uintc | VT_UI4 |
float64, float_ | VT_R8 |
comtypes 是一個輕量級的 python com 包,其中文網站詳見:https://www.cnpython.com/pypi/comtypes;官方文檔詳見:comtypes 1.1.3 documentation 。
NumPy 是用 Python 進行科學計算的基礎軟件包,其官方的中文文檔詳見網站: Numpy 中文網 。
本文用到的數據轉化函數代碼如下:
def vtpnt(x, y, z=0):
"""座標點轉化爲浮點數"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
def vtobj(obj):
"""轉化爲對象數組"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)
def vtFloat(list):
"""列表轉化爲浮點數"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)
def vtInt(list):
"""列表轉化爲整數"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)
def vtVariant(list):
"""列表轉化爲變體"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)
其他數據類型的轉化方式可查詢 PyWin32 的官方幫助文檔,它的獲取方式如下:首先確保你已經成功安裝了 pywin32 模塊,然後在搜索神器 Everything 的搜索欄中輸入 PyWin32.chm,便可得到其所在的路徑,打開文件 PyWin32.chm,在搜索欄中輸入 pythoncom.VT_ARRAY , 便可查看各種數據類型的轉化。
四、創建測試圖元
[pnt1, pnt2, pnt3, pnt4, pnt5, pnt6] = [vtpnt(-40, -40), vtpnt(500, 500), vtpnt(300, 200),
vtpnt(600, 200), vtpnt(700, 200), vtpnt(100, 0)]
LineObj = mp.AddLine(pnt1, pnt2)
CircleObj = mp.AddCircle(pnt3, 100)
ArcObj = mp.AddArc(pnt4, 50, 0, 1.57)
EllObj = mp.AddEllipse(pnt5, pnt6, 0.5)
五、創建選擇集
創建名稱爲 SS1 的選擇集。
try:
doc.SelectionSets.Item("SS1").Delete()
except:
print("Delete selection failed")
slt = doc.SelectionSets.Add("SS1")
六、常規選擇
6.1. 屏幕拾取
slt.SelectOnScreen()
print("請在屏幕拾取圖元,以Enter鍵結束")
obj = slt[0]
print(obj.ObjectID)
print(slt)
6.2. 選擇過定點圖元
pnt = APoint(0, 0)
slt.SelectAtPoint(pnt)
obj = slt[0]
print(obj.StartPoint) # 當不止一個圖元過點pnt時,slt中的元素也不止一個。
6.3. 多邊形框選
多邊形由給定各點依次連直線形成,最終實現該多邊形區域內的全選。
pnts = [-50, -50, 0, -50, 550, 0, 550, 550, 0, 550, -50, 0, -50, -50, 0]
pnts=vtFloat(pnts)
slt.SelectByPolygon(6, pnts) # acSelectionSetWindowPolygon = 6
obj = slt[0]
print(obj.ObjectID)
obj = slt[1]
print(obj.ObjectID)
6.4. 全選
slt.Select(5) # acSelectionSetAll = 5
obj = slt[0]
print(obj.layer)
七、快速選擇
7.1. 語法
- object.Select(Mode, Point1, Point2, FilterType, FilterData)
- object:SelectionSet. The object this method applies to 。
- Mode:選擇模式,AcSelect enum,具體含義下表。
- Point1:3維座標點。
- Point2:3維座標點。
- FilterType:A DXF group code specifying the type of filter to use 。
- FilterData:The value to filter on 。
Mode | enum | Description |
---|---|---|
acSelectionSetWindow | 0 | Selects all objects completely inside a rectangular area whose corners are defined by Point1 and Point2. |
acSelectionSetCrossing | 1 | Selects objects within and crossing a rectangular area whose corners are defined by Point1 and Point2. |
acSelectionSetPrevious | 3 | Selects the most recent selection set. This mode is ignored if you switch between paper space and model space and attempt to use the selection set. |
acSelectionSetLast | 4 | Selects the most recently created visible objects. |
acSelectionSetAll | 5 | Selects all objects. |
7.2. DXF組碼
詳見:CADVBA中的選擇集過濾及DXF組碼錶 。
CAD中的選擇集過濾----有條件選擇AutoCAD實體 (二) 。
此外,在二次開發幫助文檔 ActiveX Developer’s Guide 中,搜索 DXF ,便可得到官方的權威解釋,操作如下:
7.3. 實例
選擇 0 圖層上所有半徑大於 5 的圓並刪除,代碼如下:
filterType = [0, -4, 40, 8] # 定義過濾類型
filterData = ["Circle", ">=", 5, "0"] # 設置過濾參數
filterType = vtInt(filterType) # 數據類型轉化
filterData = vtVariant(filterData) # 數據類型轉化
slt.Select(5, 0, 0, filterType, filterData) # 實現過濾
obj = slt[0]
print(obj.Diameter)
slt.Erase() # 刪除符合條件的所有圓
八、GetEntity
以下代碼實現將用戶選擇的圖元的顏色更改爲紅色。
print("請在屏幕中鼠標左鍵點選圖元,未選中則報錯!") # try...except處理報錯
rtnObj = doc.Utility.GetEntity() # 返回對象
print(rtnObj)
print("所選圖元的ID:", rtnObj[0].ObjectID)
print("鼠標單擊處的座標:", rtnObj[1])
sltObject = doc.ObjectIdToObject(rtnObj[0].ObjectID) # 圖元ID轉化爲對應的圖元
clr = doc.Application.GetInterfaceObject("AutoCAD.AcCmColor.19")
clr.SetRGB(255, 0, 0) # 創建紅色
sltObject.TrueColor = clr # 指定顏色
doc.Application.Update()
九、致謝
選擇集功能的順利實現離不開 ke1078 同學的大力支持,特此感謝!
十、尾聲
以上,便是關於 AutoCAD 選擇集 的一些基本代碼,因篇幅有限,某些非關鍵功能未做詳細介紹,如有疑問,歡迎郵件來詢。
鑑於,相關示例代碼相對較少,特寫本文,一方面是爲自己的階段性學習做一個總結,另一方面更是爲有需要的人提供多一點參考。
如果您已實現一些本文未提及的功能,還請在評論區呈現,以便爲後續學習者提供更多的幫助。
胸藏文墨懷若谷,腹有詩書氣自華,希望各位都能在知識的 pāo 子裏快樂徜徉。
因本人野生學習 Python,水平確實有限,文中難免有所疏漏,還請各位大神不吝批評指正。
最後,祝各位攻城獅們,珍愛生命,保護髮際線!
本文部分內容,源於網絡!
歡迎大家點贊、評論及轉載,轉載請註明出處!
爲我打call,不如爲我打款!
打賞可備註郵箱,本人將贈送本系列博客的全部 Python 源代碼。
十、參考文獻
[1]. AutoCAD中構造選擇集的方法. 機械製圖課堂.
[2]. 基於Python AutoCAD ActiveX 二次開發,pyautocad應用技術. 爲中華崛起而.
[3]. VARIANT的使用方法. xinzhiyounizhiyouni.
[4]. comtypes 1.1.3 documentation