Python SolidWorks 二次开发---SolidWorks中SketchManager对象的CreateSpline方法踩坑

Python SolidWorks 二次开发—SolidWorks中SketchManager对象的CreateSpline方法踩坑



前言

最近比较忙,一直没有更新内容,周末有个网友询问他遇到的一个问题,问题是他使用CreateSpline函数时无法生成相应的样条曲线,让我帮帮看看是否能解决,周末没有时间处理,今天早上来试了下,确实是有问题,不过也有解决办法,这里将解决办法记录以下,有类似需求或问题的朋友可以参考下。


一、问题描述

网友的问题是他在CreateSpline方法时,并没有按照要求创建出需要的样条曲线,网友怀疑是数据没有被正确传递,让我看看是否能帮忙解决。

1、CreatePoint在VBA中的方法定义

CreateSpline在VBA中的定义如下:

Function CreateSpline( _
   ByVal PointData As System.Object _
) As SketchSegment

PointData : 是一个双精度的坐标数组

2、CreatePoint在用makepy.py生成的方法中的定义

CreatePoint在makepy.py生成的文件中定义如下

	def CreateSpline(self, PointData=defaultNamedNotOptArg):
		'Create a sketch spline'
		ret = self._oleobj_.InvokeTypes(37, LCID, 1, (9, 0), ((12, 1),),PointData
			)
		if ret is not None:
			ret = Dispatch(ret, 'CreateSpline', '{83A33DBF-27C5-11CE-BFD4-00400513BB57}')
		return ret

可以看到VBA和Python 中两个的定义是一样的,这样看来应该不会出问题,也很容易解决问题,实际则不然

二、问题出现

1、Python 测试代码

方法本身使用不难,于是就在Python 中简单写了如下测试代码:

import win32com.client
import pythoncom

def main():
    sldver=2018
    swApp=win32com.client.Dispatch(f'SldWorks.Application.{
      
      sldver-1992}')
    swApp.CommandInProgress =True
    swApp.Visible =True
    # 注意此处当前文档是工程图文档
    swModel = swApp.ActiveDoc
    Nothing=win32com.client.VARIANT(9,None)
    boolstatus = swModel.Extension.SelectByID2("上视基准面", "PLANE", 0, 0, 0, False, 0, Nothing, 0)
    swModel.SketchManager.InsertSketch(True)
    swModel.ClearSelection2(True)
    # 样条线的2D数据点
    points=(0.05,0,0,0.1,0.1,0,0.3,0.5,0,0.8,0.2,0)
    pointArray=win32com.client.VARIANT(12,points)
    skSegment = swModel.SketchManager.CreateSpline(pointArray)
    swModel.SketchManager.InsertSketch(True)
    
if __name__ == '__main__':
    main()

2、问题出现

运行以后出现如下错误:

‘NoneType’ object is not callable

出现问题的语句是:

skSegment = swModel.SketchManager.CreateSpline(pointArray)

错误提示是说CreateSpline的是个空类型,没法当函数调用,那这样就没法输入数据点了,也就无法生成相应的样条曲线,所以此方法有问题,不能用,再看看是否还有其他解决措施

3、解决措施

其实CreateSpline方法是个过时的方法,已经用CreateSpline3方法替代(2018版如此),那我们就用最新的方法重新调用下,看是否能解决,以下是更改为CreateSpline3的代码:

import win32com.client
import pythoncom

def main():
    sldver=2018
    swApp=win32com.client.Dispatch(f'SldWorks.Application.{
      
      sldver-1992}')
    swApp.CommandInProgress =True
    swApp.Visible =True
    # 注意此处当前文档是工程图文档
    swModel = swApp.ActiveDoc
    Nothing=win32com.client.VARIANT(9,None)
    boolstatus = swModel.Extension.SelectByID2("上视基准面", "PLANE", 0, 0, 0, False, 0, Nothing, 0)
    swModel.SketchManager.InsertSketch(True)
    swModel.ClearSelection2(True)
    status=win32com.client.VARIANT(16396,None)
    # 样条线的2D数据点
    points=(0.05,0,0,0.1,0.1,0,0.3,0.5,0,0.8,0.2,0)
    pointArray=win32com.client.VARIANT(12,points)
    skSegment = swModel.SketchManager.CreateSpline3(pointArray,Nothing,Nothing,True,status)
    swModel.SketchManager.InsertSketch(True)
 

if __name__ == '__main__':
    main()

按照以上代码运行后,代码不报错,但是依然没有生成相关的样条曲线,这样看来问题就出在CreateSpline3的参数定义上,可是对照参数发现没有问题,再仔细一想问题肯定出在CreateSpline3的第一个参数定义,之前就有过类似的情况,第一个参数实际需要的数组点,那就需要将points转换为数组点,之前的《Python SolidWorks 二次开发—SolidWorks中IMathUtility对象的CreatePoint方法踩坑》就使用过此种赋值,具体如下:

此句代码修改:

pointArray=win32com.client.VARIANT(12,points)

修改后的代码如下:

pointArray=win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8,points)

再运行后已经可以生成样条曲线,问题解决,问题原因也正如网友怀疑的一样,传递的数据格式不正确

4、问题解决后的完整代码

完整代码如下:

import win32com.client
import pythoncom

def main():
    sldver=2018
    swApp=win32com.client.Dispatch(f'SldWorks.Application.{
      
      sldver-1992}')
    swApp.CommandInProgress =True
    swApp.Visible =True
    # 注意此处当前文档是工程图文档
    swModel = swApp.ActiveDoc
    Nothing=win32com.client.VARIANT(9,None)
    boolstatus = swModel.Extension.SelectByID2("上视基准面", "PLANE", 0, 0, 0, False, 0, Nothing, 0)
    swModel.SketchManager.InsertSketch(True)
    swModel.ClearSelection2(True)
    status=win32com.client.VARIANT(16396,None)
    # 样条线的2D数据点
    points=(0.05,0,0,0.1,0.1,0,0.3,0.5,0,0.8,0.2,0)
    pointArray=win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8,points)
    skSegment = swModel.SketchManager.CreateSpline3(pointArray,Nothing,Nothing,True,status)
    swModel.SketchManager.InsertSketch(True)

if __name__ == '__main__':
    main()

三、问题总结

其实出现这样的问题大多都是由于数据传输的时候格式不正确,输入正确的格式后问题都会迎刃而解,以下是可能遇到的一些数据类型的转换,记录以下,方便以后查阅

def vtPoint(x, y, z):
    # 坐标点转化为浮点数
    return VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))


def vtObj(obj):
    # 转化为对象数组
    return VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)


def vtFloat(list):
    # 列表转化为浮点数
    return VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)


def vtInt(list):
    # 列表转化为整数
    return VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)


def vtVariant(list):
    # 列表转化为变体
    return VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)

猜你喜欢

转载自blog.csdn.net/Bluma/article/details/129488541