2016-06-10 21 views
1

Ich versuche, eine einfache Kopieroperation zwischen zwei Autocad-Dokumenten über COM in Python zu implementieren.Ausnahme: Ungültiges Objektarray mit 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) 

Dies wirft:

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

Die gleiche Sache kann mit in VBA erreicht werden:

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 

Ich versuchte numpy Arrays Ich habe versucht, auf die IDispatch Schnittstelle Gießen, die IAcadEntity Schnittstelle und IAcadObject ohne Erfolg (wahrscheinlich ein dummer Versuch).

circle = circle.QueryInterface(IAcadEntity) 

Ich habe auch versucht innen site-packages\comtypes\automation.py zu sehen, aber das ist über meine Gehaltsstufe. Die self.vtVT_ARRAY | VT_DISPATCH_set_value_set_value in _set_value ist nicht gut, aber ich vermute, dass das Problem in diesen Zeilen liegt, denn wenn wir Dim arry(0 To 0) As AcadEntity zu Dim arry(0 To 0) As Variant ändern, wird das VBA-Beispiel auch Invalid object array werfen.


sollte ich erwähnen, dass ich unkommentiert zwei Linien in site-packages\comtypes\automation.py:

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

So .... Hilfe ?!

Antwort

0

Inzwischen gibt es einige hässliche Hacks wie:

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

(natürlich können Sie eine Auswahl erstellen gesetzt, aber Sie können nicht eine Auswahl aktiv gesetzt machen, das wäre Wahnsinn)

Bitte post eine bessere Antwort!