PyComCAD介紹及開發方法
- 2021 年 2 月 27 日
- 筆記
項目地址://github.com/JohnYang1210/PycomCAD
歡迎給項目打個Star!
1.綜述
提到Autocad在工業界的二次開發,VB或者Lisp可能作為常用的傳統的程式語言。但是,Python語言簡潔,優雅,學習門檻低,理應在Autocad二次開發中佔有一席之地,加上Python豐富而強大的第三方庫,更讓Python對於Autocad二次開發任務如虎添翼,使得快速開發出符合工程師自身需求的功能成為可能。Pycomcad恰恰就是獲取Autocad API的介面庫。
Pycomcad的底層庫是win32com
和pythoncom
,其中,win32com負責獲取Autocad的介面,包括一些枚舉值,pythoncom主要負責進行數據類型轉換。Pycomcad設計理念非常的簡單,就是把win32com中多層調用的函數或者屬性包裹為一個函數,用以方便記憶調用以及減少敲碼次數,而不用每次都按照AutoCAD對象模型樹一層一層的調用。
當涉及到Autocad中特定對象的方法或者屬性,比如已創建的圓,塊對象有哪些屬性及方法?可以查看本倉庫下的acadauto.chm
文件。
2.底層庫安裝
pip install pywin32
將會安裝win32com和pythoncom庫。
3.簡單小例子
#準備工作
import sys
import win32com.client
import math
sys.path.append(r'D:\programming\pycomcad\PycomCAD') #這裡填寫pycomcad.py所在的文件夾
from pycomcad import *
acad=Autocad() #打開Autocad,如果已有打開的Autocad,則對該Autocad進行連接
if not acad.IsEarlyBind: #判斷是否是EarlyBind,如果不是則打開Earlybind模式
acad.TurnOnEarlyBind()
acad.ShowLineweight(True) #設置打開線寬
#進行繪製
line=acad.AddLine(Apoint(0,0),Apoint(100,0)) #繪製線
circle=acad.AddCircle(Apoint(100,0),10) #繪製圓
circleBig=acad.AddCircle(Apoint(0,0),110)
circleInner=acad.AddCircle(Apoint(0,0),90)
for i in range(15):
angle=math.radians(24)
line.Copy()
circle.Copy()
line.Rotate(Apoint(0,0),angle) #對線和圓進行複製並旋轉
circle.Rotate(Apoint(0,0),angle)
text=acad.AddText('Code makes a better world!',Apoint(0,0),20) #繪製文字
text.Alignment=win32com.client.constants.acAlignmentTopCenter #設置文字的alignment方向
text.Move(Apoint(0,0),Apoint(0,-150)) #移動文字
underLine=acad.AddLine(Apoint(-175,-180),Apoint(175,-180)) #繪製下劃線
underLine.Lineweight=win32com.client.constants.acLnWt030
underLine.Copy()
underLine.Offset(5) #向上偏移下劃線
# 保存文件
acad.SaveAsFile(r'pycomcad.dwg')
繪製出如下圖形:
4.Pycomcad的基本架構
4.1 指定特定版本
如果個人電腦上裝有多個版本的Autocad,我們想針對特定版本的Autocad進行二次開發,只需要修改pycomcad.py
中win32com.client.Dsipatch
函數中的ProgID
就可以了(比如要指定Autocad2016版本,只需要修改為self.acad=win32com.client.Dispatch('AutoCAD.Application.20')
,本倉庫默認為Autocad.Application
:
class Autocad:
def __init__(self):
try:
self.acad=win32com.client.Dispatch(`ProgID`) #修改此處的ProgID
self.acad.Visible=True
except:
Autocad.__init__(self)
Autocad版本號與ProgID對應關係表如下:
AutoCAD Production | ProgID |
---|---|
AutoCAD 2004 | AutoCAD.Application.16 |
AutoCAD 2005 | AutoCAD.Application.16.1 |
AutoCAD 2006 | AutoCAD.Application.16.2 |
AutoCAD 2007 | AutoCAD.Application.17 |
AutoCAD 2008 | AutoCAD.Application.17.1 |
AutoCAD 2009 | AutoCAD.Application.17.2 |
AutoCAD 2010 | AutoCAD.Application.18 |
AutoCAD 2011 | AutoCAD.Application.18.1 |
AutoCAD2014 | AutoCAD.Application.19 |
AutoCAD2016 | AutoCAD.Application.20 |
4.2 模組級函數
- Apoint :點函數,傳入x,y,z(可選,默認為0),其返回值作為其他函數的輸入值。如在上面的例子中,
AddLine
與AddCircle
方法均需輸入Apoint函數的返回值 - ArrayTransform:將任何型式的數組轉換為所需要的實數型數組,多用於pycomcad模組內部使用
- VtVertex:將分散的數據轉換為實數型數組,多用於pycomcad模組內部使用
- VtFloat:將僅有數字的列錶轉換為實數型列表
- VtInt:將僅有整數的列錶轉換為整數型列表
- VtVariant:將變數型列錶轉換為變數型列表
- AngleDtoR:將°轉換為radian,也可以用math.radians
- AngleRtoD:將radian轉換為°,也可以用math.degrees
- FilterType,FilterData,過濾規則中將DXF碼傳入,也可以用VtInt(ft),VtVariant(fd),詳細參見
GetSelectionSets
方法說明
有關數據轉換更詳細的資訊見: //www.cnblogs.com/johnyang/p/12617881.html .
4.3 Early-bind模式還是Lazy-bind模式
在上面例子中,我們用到了acad.IsEarlybind
屬性,以及acad.TurnOnEarlyBind
方法,那麼什麼是early-bind模式,什麼是lazy-bind模式呢?
默認地,pycomcad是lazy-bind模式,意思就是pycomcad對於特定的對象,比如線,圓等的方法,屬性,以及常量枚舉值,事先是不知道的,而early-bind模式下,pycomcad就提前知道了特定的對象的類型,方法,屬性。實際上,這對於我們進行二次開發是有比較大的影響的,因為有時候我們需要知道選中的對象到底是什麼樣的類型,然後根據其類型,進行不同的操作。比如,對於early-bind模式,pycomcad能識別win32com.client.constants.acRed
枚舉值,而lazy-bind模式下,不能對其進行識別。建議把early-bind模式打開。
Autocad對象,比如它是acad
,它的IsEarlyBind
屬性可以判斷目前Autocad的模式是哪一種,如果是early-bind模式,則返回True
,否則返回False
,如果是lazy-bind,那麼可以調用TrunOnEarlyBind()
方法來轉變為Early-bind模式。
有關Early-bind和Lazy-bind模式的資訊,詳見我的博文://www.cnblogs.com/johnyang/p/12521301.html
4.4 模組的主要方法及屬性
- 系統變數
方法 | 作用 |
---|---|
SetVariable | 設置系統變數 |
GetVariable | 獲取系統變數 |
- 文件處理
方法 | 作用 |
---|---|
OpenFile | 打開文件 |
CreateNewFile | 新建文件 |
SaveFile | 保存 |
SaveAsFile | 將文件保存至設定路徑下 |
Close | 關閉文件 |
PurgeAll | Purge文件 |
Regen | Regen文件 |
GetOpenedFile | 返回指定的已經打開的文件 |
ActivateFile | 指定已經打開的文件為當前工作文件 |
DeepClone | 跨文件間複製對象 |
屬性 | 作用 |
---|---|
OpenedFilenames | 返回已經打開的所有文件列表 |
OpenedFilenumbers | 返回已經打開的文件的數量 |
CurrentFilename | 返回當前文件名 |
FilePath | 返回當前文件路徑 |
IsSaved | 如果當前文件保存了,則返回True,否則False |
- 精細繪圖設置
方法 | 作用 |
---|---|
ZoomExtents | 極限放大 |
ZoomAll | 顯示整個圖形 |
GridOn | 打開/關閉柵格 |
SnapOn | 打開/關閉捕捉狀態 |
- 創建實體
方法 | 作用 |
---|---|
AddPoint | 創建點 |
AddLine | 創建線 |
AddLwpline | 創建LightWeight多段線 |
AddCircle | 創建圓 |
AddArc | 創建圓弧 |
AddTable | 創建表 |
AddSpline | 創建擬合曲線 |
AddEllipse | 創建橢圓 |
AddHatch | 創建填充 |
AddSolid | 創建實心面 |
- 引用及選擇
方法 | 作用 |
---|---|
Handle2Object | 通過實體引用的Handle值獲取實體本身 |
GetEntityByItem | 通過實體的索引來獲取實體 |
GetSelectionSets | 獲取選擇集(選擇及過濾機制詳見//www.cnblogs.com/johnyang/p/12934674.html) |
- 圖層
方法 | 作用 |
---|---|
CreateLayer | 創建圖層 |
ActivateLayer | 激活圖層 |
GetLayer | 獲取圖層對象 |
屬性 | 作用 |
---|---|
LayerNumbers | 返回圖層的總數 |
LayerNames | 返回圖層名列表 |
Layers | 返回圖層集 |
ActiveLayer | 返回當前圖層 |
- 線型
方法 | 作用 |
---|---|
LoadLinetype | 載入線型 |
ActivateLinetype | 激活線型 |
ShowLineweight | 顯示/關閉線型 |
屬性 | 作用 |
---|---|
Linetypes | 返回線型集 |
- 塊
方法 | 作用 |
---|---|
CreateBlock | 創建塊 |
InsertBlock | 插入塊 |
- 用戶坐標系
方法 | 作用 |
---|---|
CreateUCS | 創建用戶坐標系 |
ActivateUCS | 激活用戶坐標系 |
GetCurrentUCS | 獲取當前用戶坐標系 |
ShowUCSIcon | 顯示/關閉用戶坐標系圖標 |
- 文字
方法 | 作用 |
---|---|
CreateTextStyle | 創建文字樣式 |
ActivateTextStyle | 激活文字樣式 |
GetActiveFontInfo | 獲取活動字體資訊 |
SetActiveFontFile | 設定活動字體文件 |
AddText | 創建單行文字 |
AddMText | 創建多行文字 |
- 尺寸與標註
方法 | 作用 |
---|---|
AddDimAligned | 創建平行尺寸標註對象 |
AddDimRotated | 創建之地那個角度標註對象 |
AddDimRadial | 創建半徑型尺寸標註對象 |
AddDimDiametric | 創建直徑型尺寸標註對象 |
AddDimAngular | 創建角度型尺寸標註對象 |
AddDimOrdinate | 創建坐標型尺寸標註 |
AddLeader | 創建導線型標註 |
CreateDimStyle | 創建標註樣式 |
GetDimStyle | 獲取標註樣式 |
ActivateDimStyle | 激活標註樣式 |
屬性 | 作用 |
---|---|
DimStyleNumbers | 返回標註樣式數量 |
DimStyleNames | 返回標註樣式名列表 |
DimStyle0 | 返回index為0的標註樣式對象 |
DimStyles | 返回標註樣式集體 |
ActiveDimStyle | 返回當前標註樣式 |
- Utility方法
Utility實際上就是與用戶交互,比如用戶輸入字母,數字,做出選擇等。
方法 | 作用 |
---|---|
GetString | 獲取字元串 |
AngleFromXAxis | 獲取線與X軸的夾角 |
GetPoint | 獲取空間一點的位置 |
GetDistance | 獲取兩點距離 |
InitializeUserInput | 初始化用戶輸入選項 |
GetKeyword | 獲取用戶做出的選擇 |
GetEnity | 點選實體 |
GetReal | 獲取用戶輸入的實數 |
GetInteger | 獲取用戶輸入的整數 |
Prompt | 給出提示 |
以上各種方法的詳細用法,可以通過help命令查詢,或者直接在源碼中查詢,不再贅述。
4.5 列印
列印目前沒有直接納入pycomcad中Autocad類方法,通過pycomcad來實現列印功能的用法詳見博文://www.cnblogs.com/johnyang/p/14359725.html
5 與Pycomcad一起使用的第三方庫
Python具備豐富而強大的第三方庫,這也使快速開發出符合特定需求功能的Autocad二次開發程式成為可能。理論上,我們無法完全窮舉出所有與Pycomcad一起使用的第三方庫,因為特定需求本身就蘊含了無限可能,面對同一需求,實現的方法也不盡相同,使用的其他第三方庫也不一樣,下面列舉出我自己在實際開發工作中常用到的其他第三方庫,僅供參考。
第三方庫 | 作用 |
---|---|
sys | 剛需,將pycomcad所在路徑添加到python搜索路徑中,否則需要將pycomcad所在路徑手動添加到環境變數,以使得python可以搜索到pycomcad.py |
os | 在作業系統下進行的操作,如路徑,文件的查詢,添加等。 |
shutil | 更高級的文件操作庫 |
math | 簡單的數學運算 |
numpy | 向量化數值計算,避免了層層的for循環,在繪製不同比例的圖形,非常有用 |
pandas | 與excel,csv交互,比如用excel上的數據來繪圖,或者收集,儲存圖中的數據 |
tkinter | 圖形介面化二次開發程式 |
PyQt5 | 同tkinter,但比tkinter更為強大 |
itertools | 創建特定循環迭代器的函數集,比如數學上的排列,組合 |
docx | 與docx文件進行交互 |
6 從Autocad中調用二次開發程式
當我們通過pycomcad實現了某些自動化/自定義工作的功能後,如果需要頻繁使用該程式,那麼每次都直接運行腳本,顯然有些繁瑣,那麼有沒有辦法可以從Autocad中直接調用寫號的二次開發程式呢?
答案是有的,目前可以通過打包程式為exe文件(Pyinstaller的簡單使用可參考我的博文://www.cnblogs.com/johnyang/p/10868863.html ),然後用lsp文件來調用打包的exe文件(不需要掌握lsp,很簡單的一個語句),最後在Autocad中通過命令來調用該lsp文件就可以了。詳見我的博文://www.cnblogs.com/johnyang/p/14415515.html
7 實戰開發案例及不斷升級…
隨著實際工作中遇到的開發需求越來越多,PycomCAD也在不斷的升級中。如果你對該項目有任何的興趣,可以clone它,嘗試將它應用到實際工作中去,給本項目打個star。如果你發現有價值的功能需要被添加到PycomCAD中,可以pull request它,或者通過郵箱聯繫我:[email protected]
。讓我們一起攜手,把PycomCAD打造的更為健壯,強大!
實戰開發程式可參考 //github.com/JohnYang1210/DesignWorkTask.
8 打賞及鳴謝
維護項目不易,如果該項目有幫到您,可以請部落客喝杯咖啡~
微信二維碼
支付寶二維碼
English version of Introduction:
Introduction and development manual of PyComCAD
1.Overview
In terms of the secondary development of Autocad in Engineering field, VB or Lisp may be choosen as the common and traditional programming language.However,Python shall play an important role as for this task with the power of easy-to-write and the elegance of conciseness, and Pycomcad exactly acts as an convenient way to get the API of Autocad.
The base modules of Pycomcad are win32com
and pythoncom
,and win32com is responsible for getting the interface of Autocad including some constant values in the module level,pythoncom deals with the data type conversion.The methodology of Pycomcad is very easy and that is wrapping up calling functions of the multilayers to be single class methods or properties so that makes API function easier to memory and save your keystroke.
When refering to the methods or properties of specific created entity in Autocad,It’s better to look up acadauto.chm
provided in this repository.
2.Base module installation
pip install pywin32
will install both win32com and pythoncom.
3.Basic structure of Pycomcad
3.1 Module-level functions
These functions are used to convert data type.Details about data type convertion can be referred to //www.cnblogs.com/johnyang/p/12617881.html .
3.2 Early-bind mode Or Lazy-bind mode
This blog(//www.cnblogs.com/johnyang/p/12521301.html) written by myself may be consulted to learn about topics related to early-bind and lazy-bind mode.
By default,pycomcad is lazy-bind mode and that means pycomcad knows nothing about the method or property of specified entity,even the type of the entity itself.And actually, this has a huge impact on programming because we shall know clearly the type of entities in Autocad in order to do something different according to the type of selected entity.For example, as for EarlyBind mode,pycomcad will recognize win32com.client.constants.acRed,which is a constant value, while LazyBind mode will not recognize it.
Autocad object,assuming to acad
, in Pycomcad has two properties to examin whether the module is earlybind or not and turn on earlybind mode if it is not,and they are acad.IsEarlyBind
and acad.TurnOnEarlyBind
.
Please note that,if there are multi-version Autocad on your PC, whether the Autocad object in pycomcad is EarlyBind or not will depend on the specific version of opened Autocad.So it’s recommended to turn on all version’s EarlyBind mode.
3.3 Major structure of module
- System variable
- File processing
- Precise drawing setting
- Entity creation
- Refer and select entity
- Layer
- Linetype
- Block
- User-defined coordinate system
- Text
- Dimension and tolerance
- Utility object
Detailed information can be found in pycomcad.py
and acadauto.chm
.
4.Practical case and updating …
Some actual application of pycomcad in my practical work can reffer to //github.com/JohnYang1210/DesignWorkTask. With the increasing requirement encountered in daily work and for the integrity of module, pycomcad shall be evolving up to date constantly.
If you have any interest in this project,clone it,see the source and apply it to the real work.There are still so many function to add or update, once you find it,pull request it or contact with me through email:[email protected], Let’s work together to make Pycomcad more robust,integrated,concise and more powerful!
5 Donation
It’s not easy for maintaining this project, and if you find it is useful , you can donate me a cup of caffee!
WeChat QR Code
Alipay QR Code