Python3操作AutoCAD:利用pyautocad库能够自动化地进行CAD画图

2018.12.28重要更新!笔者建议放弃这个库,使用dxfgrabber的python库进行批量处理CAD的dxf文件,如果是dwg,也可以去搜索一下专门读取dwg的Python库。dxfgrabber功能强大,文档齐全!

笔者其实是一名机器学习算法工程师,工作中最痛苦的事儿就是标注数据。而我遇到的不仅仅是标注类别、标签之类的,我需要标注户型图中餐厅和客厅的分区多边形,这个就需要我读取户型图数据(也就是坐标点),然后画图画出来,分析后进行分区画框(其实就是找出分区坐标点)。这个项目工作任务量还是很大,难度也不低,标注数据难度更大。我需要写脚本,否则我哪里知道坐标点怎么标呀。各种画图工具其实也没多大用,我就想着自己开发一个分区标注工具,核心就是利用pyautocad库将已有坐标点画出来,在CAD软件上进行矩形框的添加,再利用程序将分区坐标点读取出来,自动写入户型图格式文件中。这样我需要做的仅仅就是看户型图画框这么简单的数据标注工作。

项目核心还是利用pyautocad进行api操作。官网上关于这个库的文档资料很少,讲解得也不全。我这里就总结各种常用的操作,也就是我用到的操作。(说白了,这个库就是将数据通过接口输入给CAD应用里进行操作,所以在画图过程中,CAD进程一定不能关闭,本质还是CAD在画图,而且画线操作不能太快,CAD应用来不及反应也可能会报错,这个问题有待解决)

pyautocad的Github地址:https://github.com/reclosedev/pyautocad

从里面可以看到源码,找到基本用法,也能找到官方文档。(建议好好阅读,本来讲解就少,不能随便看看,出bug的几率很大)

pyautocad

pyautocad包可以用任何版本的cad进行操作,实际上接口都是一样的。文档中首先给出连接cad的代码:

from pyautocad import Autocad

# 自动连接上cad,只要cad是开着的,就创建了一个 对象。这个对象连接最近打开的cad文件。 
# 如果此时还没有打开cad,将会创建一个新的dwg文件,并自动开启cad软件
acad = Autocad(create_if_not_exists=True)
# acad.prompt() 用来在cad控制台中打印文字 
acad.prompt("Hello, Autocad from Python")
# acad.doc.Name储存着cad最近打开的图形名
print acad.doc.Name

其实接下来就可以利用文档中给的接口进行画图了,每个接口不难理解,但是接口参数没有详细的例子很是头疼。我使用过的接口在下面,笔者尽量将参数写清楚:

#导入APoint类是非常必要的,画图都是靠点来画,而且CAD中所有的点都必须用APoint类进行包裹。APoint(10,30),
# 其中10代表点的x坐标,30代表点的y坐标。
from pyautocad import APoint
import math

# 画直线,p1是画线的第一个点,p2是第二个点
acad.model.AddLine(p1,p2)

# 添加文本,第一个参数就是添加的文本字符串,第二p是被APoint类包裹的点,也就是说在哪个坐标下显示文本,15是文本字体大小
text = acad.model.AddText("{0}".format(text), p, 15)
# 文本从p1点移动到p2点
text.move(p1, p2)

# 画圆,第一个参数p就是APoint类包裹的点,也就是圆心位置,第二参数10是半径大小
acad.model.AddCircle(p, 10)

# 画圆弧,第一个参数是在哪个点画圆弧,第二个参数是半径,第三个是开始弧(弧度制,不是角度制),第四个点是结束弧。
acad.model.AddArc(p, radius, math.radians(90), math.radians(270))

# 保存cad图到指定位置,第一个参数一定是保存的绝对路径!!,64是保存的一种格式,笔者从1到100都试了一遍,
# 有一些是可以生成图的,都是CAD可以打开的文件类型格式。其实跟着笔者写64就好!
acad.doc.SaveAs("{0}".format(save_path), 64)

那接下来就可以结合Python画图了,来个例子(很官方):

from pyautocad import Autocad, APoint


acad = Autocad(create_if_not_exists=True)
acad.prompt("Hello, Autocad from Python\n")
print(acad.doc.Name)

p1 = APoint(0, 0)
p2 = APoint(50, 25)
for i in range(5):
    text = acad.model.AddText('Hi %s!' % i, p1, 2.5)
    acad.model.AddLine(p1, p2)
    acad.model.AddCircle(p1, 10)
    p1.y += 10

dp = APoint(10, 0)
# !!!!!!!遍历cad图形对象以及访问/修改对象属性
for text in acad.iter_objects('Text'):
    print('text: %s at: %s' % (text.TextString, text.InsertionPoint))
    text.InsertionPoint = APoint(text.InsertionPoint) + dp

for obj in acad.iter_objects(['Circle', 'Line']):
    print(obj.ObjectName)

结果是:
Python3操作AutoCAD:利用pyautocad库能够自动化地进行CAD画图_第1张图片

这个方法提取可以PolyLine的各个顶点,帮我我项目的大忙了。!!!

for item in acad.iter_objects("PolyLine"):
    print(item.Coordinates)
'''
(-462.01707322354014, 719.8251441314151, 207.17175903027055, 1056.4031530064085, 
389.6778054895749, 574.9096117303479, -143.80140284041954, 434.6687742615859, 
-326.30744929972207, -60.84885181138725, -564.9692056597924, 308.45202158973643,
 -327.4641724567995, 461.94033545845366, -593.0470534647193, 546.8614421365228, 
 -616.4452718779175, 803.9696476627087)
'''
# 第1、2个元素构成第一个坐标, 3、4个元素构成第二个坐标,以此类推,每两个元素构成一个坐标。

错误参考:

Python3操作AutoCAD:利用pyautocad库能够自动化地进行CAD画图_第2张图片
其他的具体都可以去官网去仔细研究,来一张户型图的CAD图结束这一篇技术分享博客吧!
Python3操作AutoCAD:利用pyautocad库能够自动化地进行CAD画图_第3张图片

2018.10.26更新内容:
  1. 对acad.model.AddPolyline() 方法的使用,以及参数的详解
from pyautocad import Autocad
import numpy as np

acad = Autocad(create_if_not_exists=True)

# 1. 必须给出x,y,z坐标,但是z左边如果不是0,好像AddPolyline()函数也只能画平面
rectangle = [[1074, 732, 0],
             [1074, 592, 0],
             [1036, 592, 0],
             [1036, 732, 0],
             [1074, 732, 0]]

# 2. 必须让坐标点都是浮点数, 3. 而且左边必须用array函数包裹,这里用numpy可以,推荐!
rectangle = np.array([[float(_) for _ in point] for point in rectangle])

# 4. API只支持1行多列的1维数组
rectangle = rectangle.reshape(1, rectangle.shape[0] * rectangle.shape[1])[0]

# 使用AddPolyline()方法画多边形线段
acad.model.AddPolyline(rectangle)

# 获取多边形的坐标
for item in acad.iter_objects("PolyLine"):
    print(item.Coordinates)

可视化结果:
Python3操作AutoCAD:利用pyautocad库能够自动化地进行CAD画图_第4张图片

你可能感兴趣的:(python库,机器学习,全栈工程师)