例外:带有comtypes的无效对象数组

时间:2016-06-10 22:12:15

标签: python-2.7 com autocad comtypes

我尝试通过Python中的COM在两个Autocad文档之间实现一个简单的复制操作。

from pyautocad import Autocad, APoint
from comtypes.client import GetBestInterface
# Get acad application
acad = Autocad(create_if_not_exists=True)
# Create a new document
doc1 = GetBestInterface(acad.Application.Documents.Add())
# add a circle in this document and make it visible
circle = GetBestInterface(doc1.ModelSpace.AddCircle(APoint(0.0, 0.0), 1.0))
doc1.Application.ZoomExtents()
# create another document
doc2 = GetBestInterface(acad.Application.Documents.Add())
# and copy the circle to the new document
doc1.CopyObjects([circle], doc2.ModelSpace)

这引发:

Traceback (most recent call last):
  File "copy_bug.py", line 13, in <module>
    doc1.CopyObjects([circle], doc2.ModelSpace)
  File "Anaconda2\lib\site-packages\comtypes\__init__.py", line 655, in call_with_inout
    rescode = func(self_, *args, **kw)
_ctypes.COMError: (-2145320837, None, (u'Invalid object array', u'AutoCAD.Application', u'C:\\Program Files\\Autodesk\\AutoCAD 2015\\HELP\\OLE_ERR.CHM', -2145320837, None))

同样的事情可以在VBA中完成:

Dim doc1 As AcadDocument
Set doc1 = ThisDrawing.Application.Documents.add
Dim pt(0 To 2) As Double
pt(0) = 0#: pt(1) = 0#: pt(2) = 0#
Dim circ As AcadCircle
Set circ = doc1.ModelSpace.AddCircle(pt, 1)

ThisDrawing.Application.ZoomExtents

Dim doc2 As AcadDocument
Set doc2 = ThisDrawing.Application.Documents.add

Dim arry(0 To 0) As AcadEntity
Set arry(0) = circ
doc1.CopyObjects arry, doc2.ModelSpace

我尝试了numpy数组,我尝试转换到IDispatch接口,IAcadEntity接口和IAcadObject但没有成功(可能是一个愚蠢的尝试)。

circle = circle.QueryInterface(IAcadEntity)

我还尝试查看site-packages\comtypes\automation.py内部,但这高于我的工资等级。在self.vt中将VT_ARRAY | VT_DISPATCH设置为_set_value没有任何好处,但我怀疑问题是这样的,因为如果我们将Dim arry(0 To 0) As AcadEntity更改为Dim arry(0 To 0) As Variant VBA示例也会抛出Invalid object array

我应该提一下,我在site-packages\comtypes\automation.py中取消了两行:

# These are not yet implemented:
POINTER(IUnknown): VT_UNKNOWN,
POINTER(IDispatch): VT_DISPATCH,

所以....帮忙?!

1 个答案:

答案 0 :(得分:0)

与此同时,还有一些丑陋的黑客:

Dim doc1 As AcadDocument
Set doc1 = ThisDrawing.Application.Documents.add
Dim pt(0 To 2) As Double
pt(0) = 0#: pt(1) = 0#: pt(2) = 0#
Dim circ As AcadCircle
Set circ = doc1.ModelSpace.AddCircle(pt, 1)

ThisDrawing.Application.ZoomExtents
Dim EXTMIN As Variant: EXTMIN = ThisDrawing.GetVariable("EXTMIN")
Dim EXTMAX As Variant: EXTMAX = ThisDrawing.GetVariable("EXTMAX")

Call ThisDrawing.SendCommand( _
    "_SELECT Window " & CStr(EXTMIN(0)) & "," & CStr(EXTMIN(1)) & _
    " " & CStr(EXTMAX(0)) & "," & CStr(EXTMAX(1)) & vbNewLine)
doc1.SendCommand ("_COPYBASE 0,0" & vbNewLine)

Dim doc2 As AcadDocument
Set doc2 = ThisDrawing.Application.Documents.add
doc2.SendCommand ("_PASTECLIP 0,0" & vbNewLine)
from pyautocad import Autocad, APoint
from comtypes.client import GetBestInterface

acad = Autocad(create_if_not_exists=True)
doc1 = GetBestInterface(acad.Application.Documents.Add())
circle = GetBestInterface(doc1.ModelSpace.AddCircle(APoint(0.0, 0.0), 1.0))
doc1.Application.ZoomExtents()

EXTMIN = doc1.GetVariable("EXTMIN")
EXTMAX = doc1.GetVariable("EXTMAX")

doc1.SendCommand( "_SELECT Window %f,%f %f,%f\n\r" % (
    EXTMIN[0], EXTMIN[1], EXTMAX[0], EXTMAX[1]))
doc1.SendCommand ("_COPYBASE 0,0\n\r")

doc2 = GetBestInterface(acad.Application.Documents.Add())
doc2.SendCommand ("_PASTECLIP 0,0\n\r")

(当然你可以创建一个选择集,但你不能激活选择集;这将是疯狂的)

请发表更好的答案!