2

这是之前用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之类的东西真的没有经验……

4

1 回答 1

1

让一切正常工作可能比看起来应该做的要多。使用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 的所有参数都是您需要注意的......(这是从我的 make-py 输出中获取的 Autocad 注册接口

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}'

这会准确告诉您win32com 认为它想要哪些 COM 类型,因此请确保您至少匹配该类型。

我发现许多输入函数实际上被记录和调用是错误的(我在多次使用 AutoLisp 后才知道这一点)。我们在上面看到的外部值为1581(类似于类名,而不是真正的数据类型),然后是基本上表示(DISPATCH, EMPTY) :(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 痛苦,你还不如提交。

  • Ironpython 和 .NET
    • 我相信这个接口通常比 COM 更受支持
  • Visual Studio 专业版 (2008+)
    • 我从未使用过官方的 VS-Pro 工具(我使用过 PythonWIN 和 MINGW),我不确定是否提供了任何额外的魔法来改变 win32com 处理 AutoCAD 的方式。我知道官方的 AutoCAD ARX 扩展在 Studio 项目中提供了它们的源代码。最坏的情况是你手头有实际的文档,这就是整个 python-AutoCAD 主题被污染的地方。
于 2014-08-25T07:32:23.583 回答