python pyautocad,how to contruct an objectlist for COM

只愿长相守 提交于 2019-12-22 18:05:12

问题


This is an real project write by VBA before. I want change it to python for data processing is heavely. And, use 'ActiveX Automation scripts for AutoCAD with Python' method. code is below.My question is, how to contruct an object list for AddRegion? Maybe comtypes have some topic about VARINT. I really have no experience about COM and so on...

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


Getting it all to work right can be more work than it seems like it should be. Reading data using python; not so bad. Writing data, bit trickier. Casual user / Beginners; be warned of what your getting into.


What you will probably need

It helps tremendously if you are familiar with autolisp, because it just works better (in this case), is documented better, and integrates better,... and you will likely need it to milk 'unknown/hidden/undocumented' information that python isn't telling you. (see the vlax- and vla- series of lisp functions).

Next you need win32com make_py and gen_py scripts from the command line, or you can use win32com.client.gencode while staying mostly in python.

Be prepared to visually parse very ugly text (and I wasn't even talking about lisp =] ). Be prepared to fail, and get excited to find out why.

Most of it has to do with COM-Variants. And then you get wierd stuff like Variant-Variant-Arrays. If you check out win32com.client.pythoncom, you will notice all of the datatypes are mapped to integers. (VT_BOOL is 11 for example).


The Nitty Gritty

Next time you attempt a ModelSpace.AddCircle, pay attention to the debug output you get; All of the parameters passed to InvokeTypes are what you need to watch for... (this is taken from my make-py output for the Autocad Registered Interfaces

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

This tells you exactly which COM types win32com THINKS it wants, so make sure you are at least matching that.

I have found that many input functions are actually documented and invoked wrong (I learned this after much back and forth with AutoLisp). What we see above has a value of 1581 on the outside (which is something like a class name, not really a datatype), and then tuple that basically says (DISPATCH, EMPTY):(9,0), and then an array of VT_VARIANTS:((12,1),(12,1)).

There is usually a missing outer wrapper that COM was expecting, and for some reason make-py does not realize this. if you go through extensive AutoLisp vlax- nonsense, you will notice their is an additional wrapper around that one. I believe it is either a VARIANT_ARRAY, or quite literally, a VARIANT-VARIANT-ARRAY (quadruple pointer or something). The codes for this are (vt_array=8192, vt_variant=12).

Im sorry I don't remember specifics, but I believe the portion reading ((12,1),(12,1)), should become (8192, 12, ((12,1),(12,1))), or something like that. Even once you do figure out what it should be, Im not sure if their is a quick fix. As of AutoCAD 2010, for me, this meant going through the ungodly large gen_py output, finding the functions I really wanted, and manually changing the InvokeTypes() call to match what COM was expecting.

Everything worked simply as expected after that.


Possible Workarounds

COM is ugly. If you are new to python, but semi-experienced in AutoCAD (meaning you want to do some fairly hefty automation), stay away from the python->win32com->AutoCAD pipeline. Use LISP. As much as that pains me to say, your gonna end up writing so many LISP test cases and debuggers to accompany your python pains, you might as well just commit.

  • Ironpython and .NET
    • I believe this interface is much more supported than COM in general
  • Visual Studio Professional (2008+)
    • I never used official VS-Pro tools (I used PythonWIN and MINGW), Im not sure if there is any extra magic provided that would change how win32com handles AutoCAD. I know the official AutoCAD ARX extensions provide their source in a Studio project. Worst case you would have actual documentation close at hand, which is where this entire topic of python-AutoCAD becomes tainted.


来源:https://stackoverflow.com/questions/15204971/python-pyautocad-how-to-contruct-an-objectlist-for-com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!