![c1986e89bf6bd7f72c58ecc3097dd545.png](https://i-blog.csdnimg.cn/blog_migrate/2bc72a003db997b842d60b5892c61ef0.jpeg)
在PythonScript中使用混合编程的方式,借助AutoCAD内置的LISP语言来对AutoCAD进行一些简单的操控和处理,就会面临一个问题,那就是数据传递。因为Dynamo与LISP使用不同的数据处理方式,如同两种完全不同的语言,尽管作为最基础的数据,数字和字符串,在所有语言中看到的样子是一样的,但是如何把它们在不同的语言之间传递会是个问题。
最简而易见的解决方案是通过一个中间文件,如同Dynamo作为Revit和AutoCAD的中间桥梁一样,使用一个文件来作为LISP和Python之间的数据传递。但是这样会有比较高的要求,首先需要中间文件的内容结构比较清晰,其次,两种不同的语言都需要能按照统一标准来读取和写入这个中间文件才行。对于比较少的数据传递,这样就有点杀鸡用牛刀了。
那么有没有更加简单一些的方式呢?有。
那就是借助于AutoCAD内置提供给用户的几个系统变量。我们可以使用系统变量来作为这个中间文件的替代,从而实现数据的传递。
AutoCAD内置共提供给用户15个个性变量,分别对应于字符串类型,整数类型和实体类型,每种类型五个。这些系统变量的名称为USERI1~USERI5,USERR1~USERR5,及USERS1~USERS5。总体看来还是很富余的。不过在Dynamo内对数字分辨的是采用比较模糊的方式,就叫Number,不太分整数实数,因此USERI1~USERI5基本不需要使用。
使用这些变量,需要注意一点,那就是要像微信小程序一样,用后恢复变量原值。为了实现这个目标,需要在修改之前保存其原有数据,再赋新值。新值被Python或LISP读取后,再使用之前保存的数据写回去,实现恢复变量的原值。
这个也是LinkDWG中给实体打标签时传递数据所用的方法。
下面来看看两种语言中各自如何处理字符串及数字:
Python:
可以使用当前文档的GetVariable及SetVariable这一对方法实现对系统变量的操作
doc.SetVariable("UserS1", MyPythonData)
MyPythonData = doc.GetVariable("UserS1")
AutoLISP:
需要使用LISP函数setvar及getvar实现操作系统变量
(setvar "users1" MyLISPData)
(setq MyLISPData (getvar "users1"))
-------------------------分隔线------------------------
对于字符串,还可以使用DWG图形的SummaryInfo来脱离实体,直接使用DWG文件本身来同时保存用户化的Key及Value,而且这个信息也是可以永久跟随DWG被保存起来的。最新版的LinkDWG已经开始扩充了一个新的分支:DataTransfer来协助做AutoLISP及Python之间数据的传递,目前可用的Python上的节点为ViaSummaryInfo。
![f358a672bdd2586a7b6b1630115c4ccf.png](https://i-blog.csdnimg.cn/blog_migrate/cb7548f81fe059288f6065e053dce8d5.jpeg)
这个节点是个复合节点,同时支持Python端的设置(Mode=“Set”)、读取(Mode=“Get”)及删除(Mode=“Del”)。
LISP端的节点需要等待进一步的研究才能实现。
-------------------------分割线------------------------
除了基础的字符串及数字类型外,可能还需要传递一些选择的物体,这个时候就不能使用系统变量了,需要使用AutoCAD的当前选择集来实现。对于需要传递的物体,首先在AutoCAD内执行Select命令将他们保存成当前的选择集,然后就可以方便地为两种语言调用:
===> Python:
objects = doc.ActiveSelectionSet
===> LISP:
(setq objects (ssget "_p"))
选择集是对象集合,在Python中可以使用for循环来遍历,在LISP中可以使用ssname函数来遍历其中的每一个元素