这是之前用VBA写的一个真实项目。
我想将其移至 Python 并使用“带有 Python 的 AutoCAD 的 ActiveX 自动化脚本”方法。这是我的代码:
# -*- coding: utf-8 -*-
from pyautocad import Autocad, APoint, aDouble
acad = Autocad(False, True)
acad.prompt("Hello, Autocad from Python\n")
print acad.doc.Name
xx = acad.model.AddCircle(APoint(0, 0), 10)
print(xx)
yy = acad.model.Add3Dpoly(aDouble([0, 0, 0, 10, 10, 10, 30, 20, 30, 0, 0, 0]))
print(yy.ObjectName)
print(yy.PlotStyleName)
# How to contruct an objectlist for AddRegion?
#regions = acad.model.AddRegion([yy])
#acad.model.AddExtrudedSolid(regions[0], 20, 0)
我的问题是,如何为
AddRegion
构建对象列表?也许 comtypes
有一些关于 VARINT 的话题。我对COM之类的东西真的没有经验……
最佳答案
让一切正常工作可能比看起来应该做的要多。使用python读取数据;还不错。写入数据,有点棘手。休闲用户/初学者;被警告你进入什么。
你可能需要什么
如果您熟悉 autolisp,它会大有帮助,因为它只是工作得更好(在这种情况下),记录得更好,并且集成得更好,......而且您可能需要它来榨取 python 的“未知/隐藏/未记录”信息不告诉你。 (参见 lisp 函数的 vlax- 和 vla- 系列)。
接下来你需要 win32com 命令行中的 make_py 和 gen_py 脚本,或者您可以使用 win32com.client.gencode 而主要停留在python中。
准备好在视觉上解析非常丑陋的文本(我什至没有在谈论 lisp =] )。准备好失败,并兴奋地找出原因。
其中大部分与 COM 变体有关。然后你会得到一些奇怪的东西,比如 Variant-Variant-Arrays。如果您查看 win32com.client.pythoncom ,您会注意到所有数据类型都映射到整数。 (例如 VT_BOOL 为 11)。
坚韧不拔
下次您尝试 ModelSpace.AddCircle 时,请注意您获得的调试输出;
所有传递给 InvokeTypes 的参数是您需要的 注意...(这是从我的 Autocad 注册接口(interface)的 make-py 输出中获取的
def AddLine(self, StartPoint=defaultNamedNotOptArg, EndPoint=defaultNamedNotOptArg):
ret = self._oleobj_.InvokeTypes(
1581, LCID, 1, (9, 0), ((12, 1), (12, 1)),StartPoint, EndPoint)
if ret is not None:
ret = Dispatch(ret, u'AddLine', '{DF524ECB-D59E-464B-89B6-D32822282778}'
这会准确告诉您哪些 COM 类型 win32com 认为 它想要,所以请确保您至少匹配它。
我发现许多输入函数实际上被记录和调用是错误的(我在反复使用 AutoLisp 之后才知道这一点)。我们在上面看到的值为 1581 在外部(类似于类名,而不是真正的数据类型),然后是元组,基本上是 (调度,空) :(9,0),然后是 VT_VARIANTS 数组:((12,1),(12,1))。
COM 所期望的通常缺少一个外包装,并且由于某种原因 make-py 没有意识到这一点。如果你仔细阅读大量的 AutoLisp vlax-nonsense,你会注意到它们是一个额外的包装器。我相信它要么是 VARIANT_ARRAY,要么是字面意义上的 VARIANT-VARIANT-ARRAY(四元指针或其他东西)。代码为 (vt_array=8192, vt_variant=12)。
对不起,我不记得具体细节,但我相信阅读 的部分((12,1),(12,1)) , 应该变成 (8192, 12, ((12,1),(12,1))) , 或类似的东西。即使您确实弄清楚了它应该是什么,我也不确定它们是否可以快速解决。从 AutoCAD 2010 开始,对我来说,这意味着要通过非常大的 gen_py 输出,找到我真正想要的功能,并手动更改 InvokeTypes() 调用以匹配 COM 的预期。
之后一切都按预期工作。
可能的解决方法
COM是丑陋的。如果您是 python 新手,但在 AutoCAD 方面经验不足(这意味着您想做一些相当大的自动化操作),请远离 python->win32com->AutoCAD 管道。使用 LISP。尽管这让我很痛苦,但你最终会编写这么多 LISP 测试用例和调试器来伴随你的 python 痛苦,你还不如提交。
关于python - 如何为 COM 构造对象列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15204971/