Python AutoCAD 選擇集


阿陽的 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 , 便可查看各種數據類型的轉化。


在這裏插入圖片描述

PyWin32幫助文檔的獲取

在這裏插入圖片描述

VARIANT的查詢

四、創建測試圖元

[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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章