2016-06-10 12 views
1

Я пытаюсь реализовать простую операцию копирования между двумя документами Autocad через COM в Python.Исключение: недопустимый массив объектов с comtypes

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, 

Так .... помощь ?!

ответ

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") 

(конечно, вы можете создать набор объектов, но вы не можете сделать выбор установить активным, это было бы безумием)

Пожалуйста, напишите лучший ответ!