明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: landsat99

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

[复制链接]
 楼主| 发表于 2022-4-20 16:38 来自手机 | 显示全部楼层
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平行运行吧,完美调用,还不用加载啥的,挺好。
回复 支持 2 反对 0

使用道具 举报

发表于 2022-4-20 17:47 | 显示全部楼层
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化
  1.   def ConvertArrays2Variant(self, inputdata, vartype="Variant"):
  2.         import pythoncom
  3.         if vartype == "ArrayofObjects":  # 对象数组
  4.             outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
  5.         if vartype == "Double":  # 双精度
  6.             outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
  7.         if vartype == "ShortInteger":  # 短整型
  8.             outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
  9.         if vartype == "LongInteger":  # 长整型
  10.             outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
  11.         if vartype == "Variant":  # 变体
  12.             outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
  13.         return outputdata
复制代码

但是对于这个AddExtrudedSolidAlongPath(Profile, Path)我始终无法搞懂应该如何转化,


object
Type: Block, ModelSpace, PaperSpace
The objects this method applies to.

Profile
Access: Input-only
Type: Region
A profile can only be a Region object.

Path
Access: Input-only
Type: Arc, Circle, Ellipse, Polyline, Spline
The path can only be a Polyline, Circle, Ellipse, Spline, or Arc object.

在chm文件中的说明是传入具体的对象,但是我应该怎么转换呢?

 楼主| 发表于 2022-4-20 18:18 | 显示全部楼层
cmcc_gy 发表于 2022-4-20 17:47
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化

但是对于这个AddExtrudedSol ...

这个def方法,本身是没问题的。另外前面是否有 import win32com ,,没有的话这句加上。

再则 就是profile,path 对象的生成结构,确定正确吗?它的3D面、路径都是3d ponit嵌套构成的,一般只转换ponit即可。
下面的 VBA供参考,把点的格式转换一下即可了,,前面再加个app、document、model的定义。

你试试看再。。


  1. Sub Example_AddExtrudedSolidAlongPath()
  2.     ' This example extrudes a solid from a region
  3.     ' along a path defined by a spline.
  4.     ' The region is created from an arc and a line.
  5.    
  6.     Dim curves(0 To 1) As AcadEntity

  7.     ' Define the arc
  8.     Dim centerPoint(0 To 2) As Double
  9.     Dim radius As Double
  10.     Dim startAngle As Double
  11.     Dim endAngle As Double
  12.     centerPoint(0) = 5#: centerPoint(1) = 3#: centerPoint(2) = 0#
  13.     radius = 2#
  14.     startAngle = 0
  15.     endAngle = 3.141592
  16.     Set curves(0) = ThisDrawing.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)
  17.    
  18.     ' Define the line
  19.     Set curves(1) = ThisDrawing.ModelSpace.AddLine(curves(0).startPoint, curves(0).endPoint)
  20.         
  21.     ' Create the region
  22.     Dim regionObj As Variant
  23.     regionObj = ThisDrawing.ModelSpace.AddRegion(curves)
  24.    
  25.     ' Define the extrusion path (spline object)
  26.     Dim splineObj As AcadSpline
  27.     Dim startTan(0 To 2) As Double
  28.     Dim endTan(0 To 2) As Double
  29.     Dim fitPoints(0 To 8) As Double
  30.    
  31.     ' Define the Spline Object
  32.     startTan(0) = 10: startTan(1) = 10: startTan(2) = 10
  33.     endTan(0) = 10: endTan(1) = 10: endTan(2) = 10
  34.     fitPoints(0) = 0: fitPoints(1) = 10: fitPoints(2) = 10
  35.     fitPoints(0) = 10: fitPoints(1) = 10: fitPoints(2) = 10
  36.     fitPoints(0) = 15: fitPoints(1) = 10: fitPoints(2) = 10
  37.     Set splineObj = ThisDrawing.ModelSpace.AddSpline(fitPoints, startTan, endTan)
  38.    
  39.     ' Create the solid
  40.     Dim solidObj As Acad3DSolid
  41.     Set solidObj = ThisDrawing.ModelSpace.AddExtrudedSolidAlongPath(regionObj(0), splineObj)
  42.     ZoomAll
  43.    
  44. End Sub


 楼主| 发表于 2022-4-20 18:30 | 显示全部楼层
本帖最后由 landsat99 于 2022-4-20 18:32 编辑
cmcc_gy 发表于 2022-4-20 17:47
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化

但是对于这个AddExtrudedSol ...

另外,感觉这个def 搞复杂了。(不知道是否是对象的一个通用方法)否则没必要。

如果我写的话,<3D Point> 偷懒就下面这个:


  1. def Pnt(x,y,z=0):
  2.     return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8,(x,y,z))



发表于 2022-4-20 19:34 | 显示全部楼层
landsat99 发表于 2022-4-20 18:18
这个def方法,本身是没问题的。另外前面是否有 import win32com ,,没有的话这句加上。

再则 就是pro ...

  1. import win32com.client
  2. ProgramID = "Autocad.Application"  # 程序ID
  3. cadapp = win32com.client.Dispatch(ProgramID)  # 获取CAD程序
  4. cadapp.Visible = True  # 程序可见
  5. doc = cadapp.ActiveDocument  # 当前文档
  6. print(doc.Name)  # 当前文档的名称
  7. doc.Utility.Prompt("Hello! Autocad from pywin32com.")
  8. msp = doc.ModelSpace  # 模型空间

  9. def ConvertArrays2Variant(inputdata, vartype="Variant"):
  10.     import pythoncom
  11.     if vartype == "ArrayofObjects":  # 对象数组
  12.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
  13.     if vartype == "Double":  # 双精度
  14.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
  15.     if vartype == "ShortInteger":  # 短整型
  16.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
  17.     if vartype == "LongInteger":  # 长整型
  18.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
  19.     if vartype == "Variant":  # 变体
  20.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
  21.     return outputdata
  22. a = (0,0,0)
  23. Center = ConvertArrays2Variant(a,'Double')
  24. Radius = 10
  25. obj = msp.AddCircle(Center, Radius)
  26. list_obj = []
  27. list_obj.append(obj)
  28. reval_region2 = msp.AddRegion(ConvertArrays2Variant(list_obj,"ArrayofObjects"))
  29. PointsArray = ConvertArrays2Variant((0,10,10,10,10,10,15,10,10),'Double')
  30. StartTangent = ConvertArrays2Variant((10,10,10),'Double')
  31. EndTangent  =ConvertArrays2Variant((10,10,10),'Double')
  32. RetVal_1 = msp.AddSpline(PointsArray, StartTangent, EndTangent)

  33. RetVal = msp.AddExtrudedSolidAlongPath(reval_region2,RetVal_1)
复制代码


不知道为什么他依然出现了同样的错误:
PyDev console: starting.
Python 3.9.8 (tags/v3.9.8:bb3fdcf, Nov  5 2021, 20:48:33) [MSC v.1929 64 bit (AMD64)] on win32
runfile('C:/pycharm_project/pythonProject666/autocad/pywin32/demo555.py', wdir='C:/pycharm_project/pythonProject666/autocad/pywin32')
test.dwg
Traceback (most recent call last):
  File "C:\Python3.9.8\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/pycharm_project/pythonProject666/autocad/pywin32/demo555.py", line 36, in <module>
    RetVal = msp.AddExtrudedSolidAlongPath(reval_region2,RetVal_1)
  File "<COMObject <unknown>>", line 2, in AddExtrudedSolidAlongPath
TypeError: The Python instance can not be converted to a COM object
发表于 2022-4-20 19:38 | 显示全部楼层
landsat99 发表于 2022-4-20 16:38
嗯嗯。多谢大咖解惑。

主要对lisp不熟,,翻了翻,感觉也不太想深入了解。这个lisp除了cad,也没别处 ...

用程序写lisp文件,预先定义一个生成对象的库函数lisp文件,这样只需要生成数据接口函数就可以。
实际与lisp相关的东西并不多。
 楼主| 发表于 2022-4-20 22:15 | 显示全部楼层
本帖最后由 landsat99 于 2022-4-20 22:17 编辑
cmcc_gy 发表于 2022-4-20 19:34
不知道为什么他依然出现了同样的错误:
PyDev console: starting.
Python 3.9.8 (tags/v3.9.8:bb3f ...

改了一下,用的AddExtrudedSolid,可以生成。

  1. import win32com.client
  2. import pythoncom

  3. ProgramID = "Autocad.Application"  # 程序ID
  4. cadapp = win32com.client.Dispatch(ProgramID)  # 获取CAD程序
  5. cadapp.Visible = True  # 程序可见
  6. doc = cadapp.ActiveDocument  # 当前文档
  7. print(doc.Name)  # 当前文档的名称
  8. doc.Utility.Prompt("Hello! Autocad from pywin32com.")
  9. msp = doc.ModelSpace  # 模型空间

  10. def ConvertArrays2Variant(inputdata, vartype="Variant"):
  11.     if vartype == "ArrayofObjects":  # 对象数组
  12.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
  13.     if vartype == "Double":  # 双精度
  14.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
  15.     if vartype == "ShortInteger":  # 短整型
  16.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
  17.     if vartype == "LongInteger":  # 长整型
  18.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
  19.     if vartype == "Variant":  # 变体
  20.         outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
  21.     return outputdata

  22. a = (0, 0, 0)
  23. Center = ConvertArrays2Variant(a, 'Double')
  24. Radius = 10
  25. obj = msp.AddCircle(Center, Radius)
  26. list_obj = []
  27. list_obj.append(obj)
  28. reval_region = msp.AddRegion(ConvertArrays2Variant(list_obj, "ArrayofObjects"))

  29. # PointsArray = ConvertArrays2Variant((0,10,10,10,10,10,10,10,10), 'Double')
  30. # StartTangent = ConvertArrays2Variant((10,10,10), 'Double')
  31. # EndTangent  =ConvertArrays2Variant((10,10,10), 'Double')
  32. # RetVal_1 = msp.AddSpline(PointsArray, StartTangent, EndTangent)
  33. # RetVal = msp.AddExtrudedSolidAlongPath(reval_region[0], RetVal_1)

  34. height = 18
  35. taperAngle = 0.1
  36. RetVal = msp.AddExtrudedSolid(reval_region[0], height, taperAngle)



如果使用 AddExtrudedSolidAlongPath,在vba下好像有Bug。。  因为用Acad官方的AddExtrudedSolidAlongPath 的VBA源码(2020版源码-2020acad)都无法运行!

AddExtrudedSolid 则没有问题。 vba、python都可以运行。

 楼主| 发表于 2022-4-20 22:23 | 显示全部楼层
guangdonglbq 发表于 2022-4-20 19:38
用程序写lisp文件,预先定义一个生成对象的库函数lisp文件,这样只需要生成数据接口函数就可以。
实际与l ...

大咖您好。

您提到的“程序写lisp”具体是指?? 是要自己写转换程序吗,还是有现成的工具?这个方案很感兴趣,但完全不了解,您有相关的资料文章可参考推荐吗?
发表于 2022-4-20 23:48 | 显示全部楼层
landsat99 发表于 2022-4-20 22:23
大咖您好。

您提到的“程序写lisp”具体是指?? 是要自己写转换程序吗,还是有现成的工具?这个方案 ...

参考这个http://bbs.mjtd.com/thread-181753-1-1.html
 楼主| 发表于 2022-4-21 08:01 | 显示全部楼层
本帖最后由 landsat99 于 2022-4-21 08:03 编辑

阅读了您的文章。多谢大咖指导   

可否这样 理解您的方案?
用 Lisp封装底层API确保效率;;外部进程Com口调用封装API。

嗯嗯。。各取所长的高效方案  就是说,大量耗时的操作用Lisp/Arx封装,外部任何程序用com调用自定义的api即可;;保证了效率也保持了通用性
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-27 06:09 , Processed in 0.203870 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表