landsat99 发表于 2022-4-20 11:18:41

有人Python开发Autocad吗?都是COM,好像很少讨论

有人Python开发Autocad吗?都是COM,与vba的接口资料基本一致,好像很少讨论。。这不应该呀。。


开个小贴,抛砖引玉。

landsat99 发表于 2022-4-20 16:38:35

guangdonglbq 发表于 2022-4-20 14:30
vba是内部程序。如果有大量的操作,用com外部调用的话,最好是用软件生成lisp文件,然后加载、运行。

嗯嗯。多谢大咖解惑。

主要对lisp不熟,,翻了翻,感觉也不太想深入了解。这个lisp除了cad,也没别处使用了,语言特质还相当有个性,纯函数范式。结构组织上好像也没有包,空间,对象,模板这些重用结构 ,数据结构也仅表list一个结构好像,数组,字典 集合 自定义struc通通没有,,赶脚比较猛犸,不想弄了。做dwg文件的图形数据库api也许不错,独立语言的话,分析 计算和代码维护 这个恐怕限制会很大。。。。

目前用lisp调用.py文件,lisp不做任何计算 编辑功能。或py直接平行调用cad。

lisp直接调用py,感觉和cad内部命令一样,功能,界面完全按py的方式来,使用灵活,修改也方便,与其他软件的交互更不用说 那是py的特长。

目前唯一瑕疵是,command shell 调用.py后,shell的运行黑窗在一边放着,比较碍眼。

那就py平行运行吧,完美调用,还不用加载啥的,挺好。

yswoyh 发表于 2022-4-21 16:42:19

前些日子做了一个测试,VB,python,vb.net
VB6.0利用ActiveX 操作CAD 画圆 10000个圆 用时 10.05秒
VB.net 利用objectARX技术 操作CAD画圆速度最快 ,画10000圆,用时 0.39 秒
python 利用ActiveX 操作CAD画圆 10000个圆 用时 27.95秒
下面是代码
Private Declare Function GetTickCount Lib "kernel32" () As Long
Dim Acadapp As Object
Dim acaddoc As Object
Dim StartT As Long'获取运算开始时间
Dim SpendT As Long'获取运算结束时间

Private Sub Form_Load()
    StartT = GetTickCount
    Set Acadapp = GetObject(, "autocad.application")
    Set acaddoc = Acadapp.ActiveDocument
    Dim pt(0 To 2) As Double
    Dim a As Object
    Dim i As Long
    pt(0) = 0: pt(1) = 0
    For i = 1 To 10000
      Set a = acaddoc.ModelSpace.AddCircle(pt, 10)      '画圆
      Set a = acaddoc.ModelSpace.AddText(pt(1), pt, 5)    '写文字
      pt(1) = pt(1) + 10
    Next i
    SpendT = GetTickCount - StartT
    acaddoc.Utility.Prompt ("本次操作耗时:" & Format(SpendT / 1000, "0.00") & "秒")
    End
End Sub


#python 利用ActiveX 操作CAD画圆 10000个圆 用时 27.95秒
#代码量最少
#                            加一个添加文字用时56.60秒
from pyautocad import Autocad,APoint
import time
time_start=time.time()
acad=Autocad()
p1=APoint(0,0)
for i in range(0,10000):
    acad.model.AddCircle(p1,10)
    acad.model.AddText(p1.y, p1,5)
    p1.y+=10
time_end=time.time()
acad.prompt(time_end-time_start)





'VB.net 利用objectARX技术 操作CAD画圆速度最快 ,画10000圆,用时 0.39 秒
'引用CAD安装目录下的 acdbmgd.dll,acmgd.dll这两个文件,将本地复制设置为false
'编译生成,用 netload 命令加载程序,执行命令 netCircle
'                                             加一个添加文字用时1.89秒
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Colors
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime

Public Class Class1
    Public StartTime As System.DateTime
    Public EndTime As System.DateTime
    Public ts As System.TimeSpan
    <CommandMethod("netCircle")> Public Sub CreateCircle()
      StartTime = System.DateTime.Now
      Dim pt(0 To 2) As Double
      Dim i As Integer
      pt(0) = 0 : pt(1) = 0 : pt(2) = 0
      For i = 1 To 10000                                     '画10000个圆
            Dim circleId As ObjectId = AddCircle(New Point3d(pt(0), pt(1), pt(2)), 5)
            pt(1) = pt(1) + 10
      Next i
      EndTime = System.DateTime.Now
      ts = EndTime.Subtract(StartTime)
      Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
      ed.WriteMessage("画" & i - 1 & "圆,用时 " & ts.TotalSeconds.ToString & " 秒")
      'MsgBox(ts.TotalSeconds.ToString)
    End Sub

    Public Shared Function AddCircle(ByVal cenPt As Point3d, ByVal radius As Double) As ObjectId
      ' 在内存中创建一个圆对象
      Dim ent As New Circle(cenPt, Vector3d.ZAxis, radius)
      ' 调用AppendEntity函数,将圆加入到模型空间.
      Dim entId As ObjectId = AppendEntity(ent)
      Return entId
    End Function
    ' 将图形对象加入到模型空间的函数.
    Public Shared Function AppendEntity(ByVal ent As Entity) As ObjectId
      ' 得到当前文档图形数据库.
      Dim db As Database = HostApplicationServices.WorkingDatabase
      Dim entId As ObjectId
      Using trans As Transaction = db.TransactionManager.StartTransaction
            ' 以读方式打开块表.
            Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
            ' 以写方式打开模型空间块表记录.
            Dim btr As BlockTableRecord = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
            ' 将图形对象的信息添加到块表记录中,并返回ObjectId对象.
            entId = btr.AppendEntity(ent)
            ' 把图形对象添加到事务处理中.
            trans.AddNewlyCreatedDBObject(ent, True)
            ' 提交事务处理.
            trans.Commit()
      End Using
      Return entId
    End Function
    ' 由插入点、文字内容、文字高度和倾斜角度创建单行文字的函数.
    Public Shared Function AddText(ByVal position As Point3d, ByVal textString As String, ByVal height As Double, ByVal oblique As Double) As ObjectId
      Try
            ' 在内存中创建单行文字对象.
            Dim ent As New DBText()
            ' 设置文字插入点.
            ent.Position = position
            '设置文字内容.
            ent.TextString = textString
            '设置文字高度.
            ent.Height = height
            '设置文字倾斜角.
            ent.Oblique = oblique
            ' 调用EntityToModelSpace函数,将单行文字加入到模型空间.
            Dim entId As ObjectId = AppendEntity(ent)
            Return entId
      Catch
            ' 创建失败,则返回一个空的ObjectId.
            Dim nullId As ObjectId = ObjectId.Null
            Return nullId
      End Try
    End Function
End Class

guangdonglbq 发表于 2022-4-20 12:10:27

看这个http://bbs.mjtd.com/thread-180587-1-1.html

landsat99 发表于 2022-4-20 12:42:24

guangdonglbq 发表于 2022-4-20 12:10
看这个http://bbs.mjtd.com/thread-180587-1-1.html

你好呀。上面项目是IronPython的吧,属.net。。。不是标准CPython:lol

IronPython基本不算python,另类小众分支,,它这个仅一层py的语法外衣,可用资源仅限.net, cpy成千上万的包它基本都用不了。。。ironpy微软的实验项目,目前基本废弃了

cpy的价值在u通用型,特指可使用 numpy scipy pandas numba anaconda..这类C实现通用库的标准版本

guangdonglbq 发表于 2022-4-20 13:00:22

那你用pyautocad库吧

landsat99 发表于 2022-4-20 13:10:14

guangdonglbq 发表于 2022-4-20 13:00
那你用pyautocad库吧

嗯嗯。pyautocvd 的头部连接 各类图素绘制 编辑等等写法确实方便,同是局限性也不小,,,尤其是cad属性类的CRUD..

win32compythoncom主要使用,稳定性还不错

guangdonglbq 发表于 2022-4-20 13:28:23

外部com操作耗时较长,使用要注意。

landsat99 发表于 2022-4-20 14:14:46

本帖最后由 landsat99 于 2022-4-20 14:17 编辑

guangdonglbq 发表于 2022-4-20 13:28
外部com操作耗时较长,使用要注意。
com效率确实先天不足;P。。这是个不大不小的缺陷。一般情况下,运行速度不是瓶颈,工具通用型,编写的便捷性倒是首要因素。

前几天测了次 10万同心圆生成速度。都是几行的简单代码,,
lisp   大约5秒,
vba   10秒,
c++    1.2秒,(没有mfc,所以g++试的,。估计用vc++会更快)
python150秒,
(win10 + acad2020)

过两天试试java调用activex,估计比python快不了多少,都是com,编译的也快不到哪里去。。
vba 倒是出乎意料,com口跑的挺快。vba这个是线程内的吧,不是外部com/activex??咋这么快?

guangdonglbq 发表于 2022-4-20 14:30:02

vba是内部程序。如果有大量的操作,用com外部调用的话,最好是用软件生成lisp文件,然后加载、运行。

cmcc_gy 发表于 2022-4-20 14:54:34

你好,我是一个新手,我有一个问题想请教以下,关于在cad中添加三维实体
我在使用pywin32与cad建立通讯,我想利用方法RetVal = object.AddExtrudedSolidAlongPath(Profile, Path) 添加,但是关于参数的输入我很迷惑。他会有这样的报错:TypeError: The Python instance can not be converted to a COM object

landsat99 发表于 2022-4-20 15:59:04

cmcc_gy 发表于 2022-4-20 14:54
你好,我是一个新手,我有一个问题想请教以下,关于在cad中添加三维实体
我在使用pywin32与cad建立通讯, ...

很明确,接口定义有问题。

文件头 是否定义了app,document,modlespace的各个层级,,定义的格式是否正确。另外,参数里的点 线这些实体是否已转换类型。

其它调用方法 属性安手册写即可 这不会有问题的。
页: [1] 2 3 4 5 6
查看完整版本: 有人Python开发Autocad吗?都是COM,好像很少讨论