python pyautocad,如何为COM构造一个对象列表

时间:2013-03-04 15:24:54

标签: python com automation activex autocad

这是VBA之前编写的真实项目。 我希望将它更改为python以进行数据处理。并且,使用“使用Python的AutoCAD自动化脚本”方法。代码如下。我的问题是,如何构建AddRegion的对象列表?也许comtypes有一些关于VARINT的话题。我真的没有关于COM的经验等等......

    # -*- 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)

1 个答案:

答案 0 :(得分:1)

让一切正常工作可能比应有的工作更多。使用python读取数据;不是那么糟糕写数据有点棘手。临时用户/初学者;警告你进入了什么。


您可能需要什么

如果您熟悉autolisp,它会有很大帮助,因为它只是效果更好(在这种情况下),记录得更好,并且整合得更好,......并且您可能需要它来加入'未知/隐藏/未记录' python没有告诉你的信息。 (参见 vlax - vla - 系列的lisp函数)。

接下来,您需要从命令行使用 win32com make_py和gen_py脚本,或者您可以使用 win32com.client.gencode ,同时主要使用python。

准备在视觉上解析非常丑陋的文本(我甚至没有谈论lisp =])。准备好失败,并兴奋地找出原因。

大部分都与COM-Variants有关。然后你得到像Variant-Variant-Arrays这样的奇怪的东西。如果您查看 win32com.client.pythoncom ,您会注意到所有数据类型都映射到整数。 (VT_BOOL例如11)。


Nitty Gritty

下次尝试使用ModelSpace.AddCircle时,请注意您获得的调试输出; 传递给InvokeTypes的所有参数都是您需要注意的...(这取自我的Autocad注册接口的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 THINKS ,因此请确保您至少匹配它。

我发现许多输入函数实际上是记录在案并且调用错误(我在使用AutoLisp来回后学习了很多)。我们上面看到的外部值 1581 (类似于类名,而不是真正的数据类型),然后基本上说(DISPATCH,EMPTY)的元组 :( 9,0),然后是一个VT_VARIANTS数组:((12,1),(12,1))。

COM期望通常缺少外包装,并且由于某种原因,make-py没有意识到这一点。如果你经历了广泛的AutoLisp vlax - 废话,你会发现它们是围绕那个的另一个包装器。我相信它是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 Professional(2008+)
    • 我从未使用官方VS-Pro工具(我使用过PythonWIN和MINGW),我不确定是否有任何额外的魔法可以改变win32com处理AutoCAD的方式。我知道官方的AutoCAD ARX扩展在Studio项目中提供了它们的源代码。最糟糕的情况是,您可以随时掌握实际文档,这就是整个python-AutoCAD主题被污染的地方。