landsat99
发表于 2022-4-20 16:38:35
guangdonglbq 发表于 2022-4-20 14:30
vba是内部程序。如果有大量的操作,用com外部调用的话,最好是用软件生成lisp文件,然后加载、运行。
嗯嗯。多谢大咖解惑。
主要对lisp不熟,,翻了翻,感觉也不太想深入了解。这个lisp除了cad,也没别处使用了,语言特质还相当有个性,纯函数范式。结构组织上好像也没有包,空间,对象,模板这些重用结构 ,数据结构也仅表list一个结构好像,数组,字典 集合 自定义struc通通没有,,赶脚比较猛犸,不想弄了。做dwg文件的图形数据库api也许不错,独立语言的话,分析 计算和代码维护 这个恐怕限制会很大。。。。
目前用lisp调用.py文件,lisp不做任何计算 编辑功能。或py直接平行调用cad。
lisp直接调用py,感觉和cad内部命令一样,功能,界面完全按py的方式来,使用灵活,修改也方便,与其他软件的交互更不用说 那是py的特长。
目前唯一瑕疵是,command shell 调用.py后,shell的运行黑窗在一边放着,比较碍眼。
那就py平行运行吧,完美调用,还不用加载啥的,挺好。
cmcc_gy
发表于 2022-4-20 17:47:14
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化
def ConvertArrays2Variant(self, inputdata, vartype="Variant"):
import pythoncom
if vartype == "ArrayofObjects":# 对象数组
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
if vartype == "Double":# 双精度
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
if vartype == "ShortInteger":# 短整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
if vartype == "LongInteger":# 长整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
if vartype == "Variant":# 变体
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
return outputdata
但是对于这个AddExtrudedSolidAlongPath(Profile, Path)我始终无法搞懂应该如何转化,
object
Type: Block, ModelSpace, PaperSpace
The objects this method applies to.
Profile
Access: Input-only
Type: Region
A profile can only be a Region object.
Path
Access: Input-only
Type: Arc, Circle, Ellipse, Polyline, Spline
The path can only be a Polyline, Circle, Ellipse, Spline, or Arc object.
在chm文件中的说明是传入具体的对象,但是我应该怎么转换呢?
landsat99
发表于 2022-4-20 18:18:07
cmcc_gy 发表于 2022-4-20 17:47
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化
但是对于这个AddExtrudedSol ...
这个def方法,本身是没问题的。另外前面是否有 import win32com ,,没有的话这句加上。
再则 就是profile,path 对象的生成结构,确定正确吗?它的3D面、路径都是3d ponit嵌套构成的,一般只转换ponit即可。
下面的 VBA供参考,把点的格式转换一下即可了,,前面再加个app、document、model的定义。
你试试看再。。
Sub Example_AddExtrudedSolidAlongPath()
' This example extrudes a solid from a region
' along a path defined by a spline.
' The region is created from an arc and a line.
Dim curves(0 To 1) As AcadEntity
' Define the arc
Dim centerPoint(0 To 2) As Double
Dim radius As Double
Dim startAngle As Double
Dim endAngle As Double
centerPoint(0) = 5#: centerPoint(1) = 3#: centerPoint(2) = 0#
radius = 2#
startAngle = 0
endAngle = 3.141592
Set curves(0) = ThisDrawing.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)
' Define the line
Set curves(1) = ThisDrawing.ModelSpace.AddLine(curves(0).startPoint, curves(0).endPoint)
' Create the region
Dim regionObj As Variant
regionObj = ThisDrawing.ModelSpace.AddRegion(curves)
' Define the extrusion path (spline object)
Dim splineObj As AcadSpline
Dim startTan(0 To 2) As Double
Dim endTan(0 To 2) As Double
Dim fitPoints(0 To 8) As Double
' Define the Spline Object
startTan(0) = 10: startTan(1) = 10: startTan(2) = 10
endTan(0) = 10: endTan(1) = 10: endTan(2) = 10
fitPoints(0) = 0: fitPoints(1) = 10: fitPoints(2) = 10
fitPoints(0) = 10: fitPoints(1) = 10: fitPoints(2) = 10
fitPoints(0) = 15: fitPoints(1) = 10: fitPoints(2) = 10
Set splineObj = ThisDrawing.ModelSpace.AddSpline(fitPoints, startTan, endTan)
' Create the solid
Dim solidObj As Acad3DSolid
Set solidObj = ThisDrawing.ModelSpace.AddExtrudedSolidAlongPath(regionObj(0), splineObj)
ZoomAll
End Sub
landsat99
发表于 2022-4-20 18:30:15
本帖最后由 landsat99 于 2022-4-20 18:32 编辑
cmcc_gy 发表于 2022-4-20 17:47
对,我觉得问题就出在转换类型这里,在之前的工作中我尝试过如下的类型转化
但是对于这个AddExtrudedSol ...
另外,感觉这个def 搞复杂了。(不知道是否是对象的一个通用方法)否则没必要。
如果我写的话,<3D Point> 偷懒就下面这个:
def Pnt(x,y,z=0):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8,(x,y,z))
cmcc_gy
发表于 2022-4-20 19:34:55
landsat99 发表于 2022-4-20 18:18
这个def方法,本身是没问题的。另外前面是否有 import win32com ,,没有的话这句加上。
再则 就是pro ...
import win32com.client
ProgramID = "Autocad.Application"# 程序ID
cadapp = win32com.client.Dispatch(ProgramID)# 获取CAD程序
cadapp.Visible = True# 程序可见
doc = cadapp.ActiveDocument# 当前文档
print(doc.Name)# 当前文档的名称
doc.Utility.Prompt("Hello! Autocad from pywin32com.")
msp = doc.ModelSpace# 模型空间
def ConvertArrays2Variant(inputdata, vartype="Variant"):
import pythoncom
if vartype == "ArrayofObjects":# 对象数组
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
if vartype == "Double":# 双精度
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
if vartype == "ShortInteger":# 短整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
if vartype == "LongInteger":# 长整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
if vartype == "Variant":# 变体
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
return outputdata
a = (0,0,0)
Center = ConvertArrays2Variant(a,'Double')
Radius = 10
obj = msp.AddCircle(Center, Radius)
list_obj = []
list_obj.append(obj)
reval_region2 = msp.AddRegion(ConvertArrays2Variant(list_obj,"ArrayofObjects"))
PointsArray = ConvertArrays2Variant((0,10,10,10,10,10,15,10,10),'Double')
StartTangent = ConvertArrays2Variant((10,10,10),'Double')
EndTangent=ConvertArrays2Variant((10,10,10),'Double')
RetVal_1 = msp.AddSpline(PointsArray, StartTangent, EndTangent)
RetVal = msp.AddExtrudedSolidAlongPath(reval_region2,RetVal_1)
不知道为什么他依然出现了同样的错误:
PyDev console: starting.
Python 3.9.8 (tags/v3.9.8:bb3fdcf, Nov5 2021, 20:48:33) on win32
runfile('C:/pycharm_project/pythonProject666/autocad/pywin32/demo555.py', wdir='C:/pycharm_project/pythonProject666/autocad/pywin32')
test.dwg
Traceback (most recent call last):
File "C:\Python3.9.8\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars)# execute the script
File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/pycharm_project/pythonProject666/autocad/pywin32/demo555.py", line 36, in <module>
RetVal = msp.AddExtrudedSolidAlongPath(reval_region2,RetVal_1)
File "<COMObject <unknown>>", line 2, in AddExtrudedSolidAlongPath
TypeError: The Python instance can not be converted to a COM object
guangdonglbq
发表于 2022-4-20 19:38:41
landsat99 发表于 2022-4-20 16:38
嗯嗯。多谢大咖解惑。
主要对lisp不熟,,翻了翻,感觉也不太想深入了解。这个lisp除了cad,也没别处 ...
用程序写lisp文件,预先定义一个生成对象的库函数lisp文件,这样只需要生成数据接口函数就可以。
实际与lisp相关的东西并不多。
landsat99
发表于 2022-4-20 22:15:28
本帖最后由 landsat99 于 2022-4-20 22:17 编辑
cmcc_gy 发表于 2022-4-20 19:34
不知道为什么他依然出现了同样的错误:
PyDev console: starting.
Python 3.9.8 (tags/v3.9.8:bb3f ...
改了一下,用的AddExtrudedSolid,可以生成。
import win32com.client
import pythoncom
ProgramID = "Autocad.Application"# 程序ID
cadapp = win32com.client.Dispatch(ProgramID)# 获取CAD程序
cadapp.Visible = True# 程序可见
doc = cadapp.ActiveDocument# 当前文档
print(doc.Name)# 当前文档的名称
doc.Utility.Prompt("Hello! Autocad from pywin32com.")
msp = doc.ModelSpace# 模型空间
def ConvertArrays2Variant(inputdata, vartype="Variant"):
if vartype == "ArrayofObjects":# 对象数组
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, inputdata)
if vartype == "Double":# 双精度
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, inputdata)
if vartype == "ShortInteger":# 短整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, inputdata)
if vartype == "LongInteger":# 长整型
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I4, inputdata)
if vartype == "Variant":# 变体
outputdata = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, inputdata)
return outputdata
a = (0, 0, 0)
Center = ConvertArrays2Variant(a, 'Double')
Radius = 10
obj = msp.AddCircle(Center, Radius)
list_obj = []
list_obj.append(obj)
reval_region = msp.AddRegion(ConvertArrays2Variant(list_obj, "ArrayofObjects"))
# PointsArray = ConvertArrays2Variant((0,10,10,10,10,10,10,10,10), 'Double')
# StartTangent = ConvertArrays2Variant((10,10,10), 'Double')
# EndTangent=ConvertArrays2Variant((10,10,10), 'Double')
# RetVal_1 = msp.AddSpline(PointsArray, StartTangent, EndTangent)
# RetVal = msp.AddExtrudedSolidAlongPath(reval_region, RetVal_1)
height = 18
taperAngle = 0.1
RetVal = msp.AddExtrudedSolid(reval_region, height, taperAngle)
如果使用 AddExtrudedSolidAlongPath,在vba下好像有Bug。。因为用Acad官方的AddExtrudedSolidAlongPath 的VBA源码(2020版源码-2020acad)都无法运行!
AddExtrudedSolid 则没有问题。 vba、python都可以运行。
landsat99
发表于 2022-4-20 22:23:04
guangdonglbq 发表于 2022-4-20 19:38
用程序写lisp文件,预先定义一个生成对象的库函数lisp文件,这样只需要生成数据接口函数就可以。
实际与l ...
大咖您好。
您提到的“程序写lisp”具体是指?? 是要自己写转换程序吗,还是有现成的工具?这个方案很感兴趣,但完全不了解,您有相关的资料文章可参考推荐吗?
guangdonglbq
发表于 2022-4-20 23:48:28
landsat99 发表于 2022-4-20 22:23
大咖您好。
您提到的“程序写lisp”具体是指?? 是要自己写转换程序吗,还是有现成的工具?这个方案 ...
参考这个http://bbs.mjtd.com/thread-181753-1-1.html
landsat99
发表于 2022-4-21 08:01:20
本帖最后由 landsat99 于 2022-4-21 08:03 编辑
guangdonglbq 发表于 2022-4-20 23:48
参考这个http://bbs.mjtd.com/thread-181753-1-1.html
阅读了您的文章。多谢大咖指导
可否这样 理解您的方案?
用 Lisp封装底层API确保效率;;外部进程Com口调用封装API。
嗯嗯。。各取所长的高效方案就是说,大量耗时的操作用Lisp/Arx封装,外部任何程序用com调用自定义的api即可;;保证了效率也保持了通用性