原文:https://blog.csdn.net/Hulunbuir/article/details/83715279
---------------------
Python AutoCAD 选择集
详见:https://blog.csdn.net/Hulunbuir/article/details/95446723 。
特别感谢ke1078 同学提供图案填充相关代码,详细代码见本文第5部分。
待解决的问题:
1、如何使用GetAttributes()直接获取块属性;
2、动态块属性如何读取及修改。
以上问题如哪位大神已解决还请在评论区附上代码,在此跪谢!
一、前沿
Pyautocad库由俄罗斯工程师Roman Haritonov开发,用于简化使用Python语言书写AutoCAD ActiveX Automation脚本,因官方参考实例较少,为了方便大家交流和学习,特将pyautocad模块的基本用法,做如下简要说明。
1、Pyautocad库的安装
如已安装Anaconda,在 Anaconda Prompt 中键入 pip install pyautocad 便可自动完成该库的导入;如未安装 Anaconda,也可 pip 手动导入,其在PyPI(Python Package Index)上的注册地址为: https://pypi.org/project/pyautocad 。
2、版本说明
Python:3.6.0
CAD:2014
Pyautocad:0.2.0
3、ActiveX Automation
ActiveX Automation是ActiveX为Windows用户提供的一项重要技术,可以使各应用程序间通过数据嵌入或链接的方式共享数据,并在Windows系统统一管理下进行协调,让这些应用程序以一定的流程相互沟通,相互控制,即一个程序暴露其可用对象,另一个程序控制这些对象,设置属性、调用方法,从而实现某种功能,完成所要求的动作。
AutoCAD程序开放某些对象给Windows系统,使用程序语言并通过ActiveX Automation,我们就可以对这些对象进行存取。 AutoCAD ActiveX接口的主要构件就对象,每一个显露的对象均精确代表一个AutoCAD组件。
AutoCAD以分层结构来组织对象,分层结构的视图称为“对象模型”,如下图所示。Application对象是AutoCAD ActiveX Automation对象模型的根对象,通过它,用户可以访问任何其他的对象或任何对象指定的特性或方法。对象模型给出了上级对象与下级对象之间的访问关系。
AutoCAD对象都至少具有一个属性,用于描述对象。例如,圆具有半径、面积、线型等属性,通过这些属性能描述出一个具体的圆。
二、与CAD的连接
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' =========================== Author = Hulunbuir Email:liyang@alu.hit.edu.cn =========================== ''' " # ******************************************** 与CAD的连接 ********************************************* # " from pyautocad import Autocad acad = Autocad(create_if_not_exists=True) # 连接正在运行的CAD程序; # 若CAD未运行,则程序自动启动CAD,启动较慢,请耐心等待; # 自动启动的CAD文件采用默认名称Drawing1。 acad.prompt("Hello! Autocad from Python.") # 在CAD命令行显示"Hello! Autocad from Python.",用于测试对CAD的控制是否成功; # 此时,注意观察命令行,若无反应可按F2,查看命令输入历史。 print(acad.doc.Name) # 获得与Python连接的正在运行的CAD文件名。 " # ************************************************ END ************************************************ # "
三、系统设置
详见:https://blog.csdn.net/Hulunbuir/article/details/96587211 。
四、图层
详见:https://blog.csdn.net/Hulunbuir/article/details/96588654 。
五、绘图
详见:https://blog.csdn.net/Hulunbuir/article/details/96589272 。
六、修改
" # ******************************************** 1、复制及删除 ******************************************** # " # 1、复制及删除 copyObj = EllObj.Copy() # 原位置复制,复制的图元与原图元重合。 copyObj.Delete() " # ******************************************** 2、平移及旋转 ******************************************** # " # 2、平移及旋转 startPnt = APoint(0, 0) endPnt = APoint(30, 0) EllObj.Move(startPnt,endPnt) BasePoint = APoint(0, 0) RotationAngle = math.radians(30) EllObj.Rotate(BasePoint, RotationAngle) # BasePoint为旋转基点,即旋转轴过此点且平行于z轴; # RotationAngle为旋转角度(弧度制),角度正负由右手系确定。 " # ******************************************** 3、镜像及缩放 ******************************************** # " # 3、镜像及缩放 startPnt = APoint(50, 50) endPnt = APoint(50, -50) MirObj = EllObj.Mirror(startPnt, endPnt) # startPnt为镜像线起点,endPnt为镜像线终点; # 镜像后原图元不删除。 BasePoint = APoint(0, 0) ScaleFactor = 5 SclEntObj = EllObj.ScaleEntity(BasePoint, ScaleFactor) # ScaleFactor为缩放比例。 " # *********************************************** 4、阵列 ********************************************** # " # 4、阵列 ## (1)、矩形阵列 numberOfRows = 5 numberOfColumns = 5 numberOfLevels = 1 distanceBwtnRows = 20 distanceBwtnColumns = 20 distanceBwtnLevels = 1 retObj = EllObj.ArrayRectangular(numberOfRows, numberOfColumns, numberOfLevels, distanceBwtnRows, distanceBwtnColumns, distanceBwtnLevels) ## (2)、环形阵列 centerPoint = APoint(30, 0) noOfObjects = 4 angleToFill = 3.14 retObj = EllObj.ArrayPolar(noOfObjects, angleToFill, centerPoint) " 运行上述(1)、(2)代码报错,报错内容为:KeyError: 9。" " 报错原因未知,虽然报错,但能顺利执行,不影响使用。" " 可利用try...except...finally...机制,处理此类报错。" " # ************************************************ END ************************************************* # "
七、块组
" # *********************************************** 1、块 ************************************************ # " # 1、块 ## (1)、创建新块 grip = APoint(20, 0) blockObj = acad.ActiveDocument.Blocks.Add(grip, "HIT_Block") # 新建块的名称为"HIT_Block"; # grip为块定位夹点所在位置。 ## (2)、添加图元到块 center = APoint(0, 0) radius = 10 CircleObj = blockObj.AddCircle(center, radius) center = APoint(40, 10) majAxis = APoint(10, 0, 0) EllObj = blockObj.AddEllipse(center, majAxis, 0.5) ## (3)、插入块 ### ①、从当前文件中插入块 insertionPnt = APoint(0, 0) RetVal = acad.model.InsertBlock(insertionPnt, "HIT_Block", 1, 1, 1, 0 ) # acad.model.InsertBlock(InsertionPoint, Name, Xscale, Yscale, ZScale, Rotation); # insertionPnt为块的插入点,即块的定位夹点与图纸空间中的该点对齐。 ### ②、从外部文件中插入块 insertionPnt = APoint(10, 0) RetVal = acad.model.InsertBlock(insertionPnt, "D:\AutoCAD\Harbin.dwg", 1, 1, 1, 0 ) # 外部文件名尽量与当前文件中的各块名称不同; # 插入后外部文件名将作为其在当前文件中的块名; # 外部文件的坐标原点为其作为块的定位夹点。 ## (4)、添加属性到块 height = 1 # 字高 mode = 2 # 模式 prompt = "Attribute_Prompt" # 提示 insertionPoint = APoint(0, 0) tag = "Attribute_Tag" # 标记 value = "Attribute_Value" # 默认 attributeObj = blockObj.AddAttribute(height, mode, prompt, insertionPoint, tag, value) ## (5)、已有块属性的读取 # RetVal = object.GetAttributes() 此方法在不借助其他库的情况下如何使用暂时未知; # 采用把块炸开将属性部分暴露出来,然后提取其相关信息的方式获取属性信息; # 此方式虽然曲折,但至少可行; # 为了清晰直观,文本代码暂未考虑效率问题,故代码行数较多。 # 不采用如下方式,直接炸开块会报错。 try: RetVal.Explode() # 炸开块 except: RetVal.Delete() # 删除重复 for obj in acad.iter_objects("AttributeDefinition"): # 以下获取块的属性信息 # 如果想获取某一特定块的属性信息可以用ObjectID识别特定块 print(obj.ObjectName) print(obj.TagString) print(obj.TextString) print(obj.PromptString) " # *********************************************** 2、组 ************************************************ # " # 2、组 ## (1)、创建新组 groupObj = acad.ActiveDocument.Groups.Add("Harbin Institute of Technology") # 新建组的名称为"Harbin Institute of Technology" " 因没有解决对象数组无效问题,故暂无法将图元添加到组中 " " # ************************************************ END ************************************************ # "
八、注释
标注是向图形中添加测量注释的过程,我们可以为各种对象沿各个方向创建标注。要简化图形组织和标注缩放,建议在图纸空间上创建标注,而不是在模型空间中创建标注。为了方便理解,关于标注的部分概念如下图所示。
" # ********************************************** 1、文字 *********************************************** # " # 1、文字 ## (1)、创建新文本 textString = "Harbin Institute of Technology" insertPnt = APoint(0, 0) height = 2.5 textObj = acad.model.AddText(textString, insertPnt, height) # textString:文本内容;height:字高; # 系统默认对齐夹点位于文字基线左侧; # 采用系统默认对齐方式时,insertPnt为对齐夹点的位置坐标; # 当用户自定义对齐方式时,insertPnt以对齐方式中的为准。 ## (2)、对齐方式 AlignNum = 7 textObj.Alignment = AlignNum # AlignNum为对齐夹点位置标识号,其取值范围为[0,14]; # 0 基线左对齐、1 基线居中对齐、2 基线右对齐; # 7 表示对齐夹点位于top cennter; insertPnt = APoint(0, 10) textObj.TextAlignmentPoint = insertPnt # 设置对齐夹点在图纸空间中的绝对位置,可为任意一已知点; # 若用户自定义对齐方式,则需设置此项。 # # (3)、文本缩放 " # ******************************************** 2、文本样式 ********************************************* # " # 2、文本样式 ## (1)、创建文字样式 txtStyleObj = acad.ActiveDocument.TextStyles.Add("HIT_TxtStyle") ## (2)、将特定文字样式设为当前 acad.ActiveDocument.ActiveTextStyle = acad.ActiveDocument.TextStyles.Item("Standard") ## (3)、设置字体 ### ①、为当前文本样式设置字体 acad.ActiveDocument.ActiveTextStyle.SetFont("楷体", False, False, 1, 0 or 0) # acad.ActiveDocument.ActiveTextStyle.SetFont(Typeface, Bold, Italic, charSet, PitchandFamily) # Typeface 字体名称; # Bold 加粗,布尔值,False为不加粗字体; # Italic 倾斜,布尔值,False为倾斜字体; # CharSet 字体字符集,1为默认字符集; # PitchAndFamily 字节及笔画形式。 ### ②、为特定文本样式设置字体 ## (4)、设置字体倾斜角度 " # ******************************************** 3、尺寸标注 ********************************************* # " # 3、尺寸标注 ## (1)、线性及旋转线性标注 import math XLine1Point = APoint(5, 25) XLine2Point = APoint(25, 35) DimLineLocation = APoint(10, 20) RotationAngle = math.radians(0) dimRotObj = acad.model.AddDimRotated(XLine1Point, XLine2Point, DimLineLocation, RotationAngle) # XLine1Point 第一尺寸界线的起点; # XLine2Point 第二尺寸界线的起点; # DimLineLocation 尺寸线定位点,尺寸线或其延长线过该点; # RotationAngle 尺寸线与水平方向的夹角,去弧度制; # RotationAngle=0 水平标注,RotationAngle=90 竖直标注。 ## (2)、对齐标注 ExtLine1Point = APoint(5, 25) ExtLine2Point = APoint(25, 35) TextPosition = APoint(-5, 25) dimAliObj = acad.model.AddDimAligned(ExtLine1Point, ExtLine2Point, TextPosition) # ExtLine1Point 第一尺寸界线的起点; # ExtLine2Point 第二尺寸界线的起点; # TextPosition 尺寸线定位点,尺寸线或其延长线过该点。 # dimObj.Update ## (3)、角度标注 AngleVertex = APoint(0, 0) FirstEndPoint = APoint(6, 8) SecondEndPoint = APoint(6, -8) TextPoint = APoint(10, 10) dimAngObj = acad.model.AddDimAngular(AngleVertex, FirstEndPoint, SecondEndPoint, TextPoint) # AngleVertex 角度顶点; # FirstEndPoint 第一尺寸界线端点; # SecondEndPoint 第二尺寸界线端点; # TextPoint 尺寸圆弧线定位点,即尺寸圆弧线过该点。 ## (4)、弧长标注 ArcCenter = APoint(0, 0) FirstEndPoint = APoint(6, 8) SecondEndPoint = APoint(6, -8) ArcPoint = APoint(20, 0) dimArcObj = acad.model.AddDimArc(ArcCenter, FirstEndPoint, SecondEndPoint, ArcPoint) # ArcCenter 圆弧中心; # FirstEndPoint 第一尺寸界线端点; # SecondEndPoint 第二尺寸界线端点; # ArcPoint 尺寸圆弧线定位点,即尺寸圆弧线过该点。 ## (5)、直径及半径标注 ChordPoint = APoint(0, 10) FarChordPoint = APoint(0, -10) LeaderLength = 40 dimDiaObj = acad.model.AddDimDiametric(ChordPoint, FarChordPoint, LeaderLength) # ChordPoint 圆任意一直径的端点; # FarChordPoint 直径的另一端点; # LeaderLength 引线长度,为点ChordPoint到标准文字定位夹点的距离; # 标注类型可在相应的系统变量如DIMUPT等中更改。 Center = APoint(0, 0) ChordPoint = APoint(10, 0) LeaderLength = 10 dimRadObj = acad.model.AddDimRadial(Center, ChordPoint, LeaderLength) # Center 被标注圆或圆弧的圆心 " # ******************************************** 4、标注样式 ********************************************* # " # 4、标注样式 ## (1)、创建新标注样式 DimStyleObj = acad.ActiveDocument.DimStyles.Add("HIT_DimStyle") print(dimAliObj.StyleName) # 打印标注对象的标准样式名称 # 系统自带标注样式 ISO-25 ## (2)、将特定标注样式设为当前 acad.ActiveDocument.ActiveDimStyle = acad.ActiveDocument.DimStyles.Item("HIT_DimStyle") # 说明:以下设置为<样式替代> # 标注样式替代是对当前标注样式中的指定设置所做的更改; # 它与在不更改当前标注样式的情况下更改尺寸标注系统变量等效; # 使用标注样式替代,无需更改当前标注样式便可临时更改标注系统变量。 ## (3)、设置尺寸线及尺寸界限 ### ①、超出标记 ### ②、基线间距 ### ③、超出尺寸线 acad.ActiveDocument.SetVariable("DIMEXE", 1.25) # 指定尺寸界线超出尺寸线的距离。 ### ④、起点偏移量 acad.ActiveDocument.SetVariable("DIMEXO", 0.625) # 设定自图形中定义标注的点到尺寸界线的偏移距离。 ## (4)、设置箭头 ### ①、设定尺寸线箭头类型。 acad.ActiveDocument.SetVariable("DIMBLK", "_ARCHTICK") # "_ARCHTICK"表示建筑标记 ### ②、设定引线箭头。 ### ③、尺寸线箭头大小 acad.ActiveDocument.SetVariable("DIMASZ", 2.5) ## (5)、设置标注文字 ### ①、文字样式 acad.ActiveDocument.SetVariable("DIMTXSTY", "HIT_TxtStyle") ### ②、文字高度 acad.ActiveDocument.SetVariable("DIMTXT", 2.5) # 设定当前标注文字样式的高度; # 如果在此选项卡上指定的字样式具有固定的文字高度,则该高度将替代在此处设置的文字高度; # 如果要在此处设置标注文字的高度,请确保将文字样式的高度设置为 0。 ### ③、文字位置 acad.ActiveDocument.SetVariable("DIMTAD", 1) # 控制标注文字相对尺寸线的垂直位置; # 0 表示标注文字在尺寸界线之间居中放置; # 1 表示将标注文字放置在尺寸线上方,从尺寸线到文字最低基线的距离为当前 DIMGAP 的值。 acad.ActiveDocument.SetVariable("DIMJUST", 0) # 水平控制标注文字在尺寸线上相对于尺寸界线的水平位置; # 0 表示将文字置于尺寸线之上,并在尺寸界线之间置中对正。 acad.ActiveDocument.SetVariable("DIMGAP", 0.625) # 设定文字相对尺寸线的位置。 ### ④、文字对齐 acad.ActiveDocument.SetVariable("DIMTIH", 0) # 控制所有标注类型(坐标标注除外)的标注文字在尺寸界线内的位置; # 0 表示将文字与尺寸线对齐; # 1 表示水平绘制文字。 acad.ActiveDocument.SetVariable("DIMTOH", 0) # 控制标注文字在尺寸界线外的位置。 ## (6)、设置主单位 ### ①、线性标注精度 acad.ActiveDocument.SetVariable("DIMDEC", 2) # 设定标注文字中的小数位数; # 2 表示显示小数点后三位; ### ②、小数分隔符 acad.ActiveDocument.SetVariable("DIMDSEP", ".") # "."表示小数分隔符,也可设置为","。 acad.ActiveDocument.SetVariable("DIMADEC", -1) # 设置角度标注精度与线性标注精度相同 " # ******************************************** 5、多重引线 ********************************************* # " # 5、多重引线 ## (1)、创建多重引线 ArrowPnt = APoint(0, 0) BaselinePnt = APoint(10, 10) PntsArray = np.array([ArrowPnt, BaselinePnt]) PntsArray = PntsArray.reshape(1, PntsArray.shape[0] * PntsArray.shape[1])[0] MLeaderObj = acad.model.AddMLeader(PntsArray, 0) # ArrowPnt 箭头位置; # BaselinePnt 基线位置 ; # 1 表示多重引线的索引号,为正整数。 ## (2)、设置箭头大小 MLeaderObj.ArrowheadSize = 2 # 指箭头高度; # 此项将覆盖系统变量DIMASZ的值。 ## (3)、设置基线长度 MLeaderObj.DoglegLength = 8 ## (4)、设置基线间隙 MLeaderObj.LandingGap = 3 # 基线端点到文字起点的距离 ## (5)、指定文字样式 MLeaderObj.TextStyleName = "HIT_TxtStyle" ## (6)、指定文字内容 MLeaderObj.TextString = "HIT" " # ************************************************ END ************************************************ # "
九、文件
" # ******************************************** 1、打开文件 ********************************************* # " " 以下代码请不要在一个文件中同时运行,否则会报错,原因是逻辑冲突。" " 在D盘创建新文件夹并命名为AutoCAD " # 1、打开文件 acad.ActiveDocument.Application.Documents.Open("D:\AutoCAD\PyAutoCAD.dwg") # CAD程序中至少存在一个打开的图形空间,否则报错,报错内容为:无法获取Document对象。 " # ******************************************** 2、新建文件 ********************************************* # " # 2、新建文件 DrawingObj = acad.ActiveDocument.Application.Documents.Add("") # 无法直接命名,新建的文件为系统默认名称,即Drawing1、Drawing2等; # 若更改名称,在关闭时定义。 " # ******************************************** 3、设定当前 ********************************************* # " # 3、设定当前 ## (1)、已知文件名设为当前 acad.ActiveDocument.Application.Documents("PyAutoCAD.dwg").Activate() # 将PyAutoCAD.dwg设为当前文件。 ## (2)、未知文件名设为当前 DrawingObj.Activate() # 将New_Drawing设为当前文件。 " # ***************************************** 4、关闭并保存变更 ****************************************** # " # 4、关闭并保存变更 ## (1)、关闭已存在文件 acad.ActiveDocument.Application.Documents("PyAutoCAD.dwg").Close(True, "PyAutoCAD_已变更.dwg") # 关闭PyAutoCAD.dwg文件。 # True 布尔值,为系统默认,表示打开文件后关闭前文件若发生变更,则保存变更,并另存为PyAutoCAD_已变更.dwg # 此时文件夹中同时存在未变更的"PyAutoCAD.dwg"和已变更的"PyAutoCAD_已变更.dwg" # 若第二项空缺,则新文件名为"PyAutoCAD.dwg",覆盖之前未变更的文件。 ## (2)、关闭新建文件 DrawingObj .Close(True, "HIT.dwg") # 关闭New_Drawing文件。 # 文件夹中仅存在"HIT.dwg"一个文件。 ## (3)、关闭当前文件 acad.ActiveDocument.Close() # 关闭当前文档。 " # ******************************************** 5、另存为 *********************************************** # " # 5、另存为 ## (1)、当前文件另存为 acad.ActiveDocument.SaveAs("D:\AutoCAD\PyAutoCAD_SaveAs", 61) # 将当前文件另存为PyAutoCAD_SaveAs.dxf; # 此时,程序关闭当前文件,将PyAutoCAD_SaveAs.dxf切换为当前文件。 # 61表示另存为文件的类型是AutoCAD 2013 DXF,常用类型如下: # 12 AutoCAD 2000 DWG (*.dwg),13 AutoCAD 2000 DXF (*.dxf); # 24 AutoCAD 2004 DWG (*.dwg),25 AutoCAD 2004 DXF (*.dxf); # 36 AutoCAD 2007 DWG (*.dwg),37 AutoCAD 2007 DXF (*.dxf); # 48 AutoCAD 2010 DWG (*.dwg),49 AutoCAD 2010 DXF (*.dxf); # 60 AutoCAD 2013 DWG (*.dwg),61 AutoCAD 2013 DXF (*.dxf); # 系统默认为AutoCAD 2013 DWG (*.dwg)。 ## (2)、指定文件另存为 acad.ActiveDocument.Application.Documents("PyAutoCAD.dwg").SaveAs("D:\AutoCAD\PyAutoCAD_SaveAs", 61) # 将特定文件PyAutoCAD.dwg另存为PyAutoCAD_SaveAs.dxf。 " # ************************************************ END ************************************************ # "
十、API
官网:https://pyautocad.readthedocs.io >> API
" # *********************************************** 1、api ********************************************** # " # 1、api - Main Autocad interface ## (1)、get_selection(text='Select objects') # 从屏幕中选择图元,并获取其特性; # 以直线为例,其余图元类似,代码如下: select_lineobj = acad.get_selection(text="请选择直线,按Enter键确认") lineobj = select_lineobj[0] # lineobj为从屏幕中选择的直线对象; # 0为对象索引号,若选择的直线个数为n,对象索引号应不大于n-1. print(lineobj.StartPoint) # 所选直线起点坐标 print(lineobj.EndPoint) # 所选直线终点坐标 print(lineobj.Length) # 所选直线长度 print(lineobj.ObjectID) # 所选直线的ID号 " # ********************************************** 2、types ********************************************* # " # 2、types - 3D Point and other AutoCAD data types " # ********************************************** 3、utils ********************************************* # " # 3、utils - Utility functions " # ***************************************** 4、contrib.tables ***************************************** # " # 4、contrib.tables - Import and export tabular data from popular formats " # ********************************************** 5、cache ********************************************* # " # 5、cache - Cache all object’s attributes " # ************************************************ END ************************************************ # "
十一、尾声
以上,便是pyautocad模块的使用方法简介,因篇幅有限,某些非关键功能未做详细介绍,如有疑问,欢迎邮件来询。
仅以此文为我断断续续近3个月的Python调用CAD学习做一个总结,同时也为有需要的人提供多一点参考。
胸藏文墨怀若谷,腹有诗书气自华,希望各位都能在知识的pāo子里快乐徜徉。
因个人水平有限,文中难免有所疏漏,还请各位大神不吝批评指正。
最后,祝各位攻城狮们,珍爱生命,保护发际线!
本文部分内容,源于网络!
欢迎大家点赞、评论及转载,转载请注明出处!
为我打call,不如为我打款!
打赏可备注邮箱,本人会将上述源代码发送给各位土豪!