写在前面
本内容是我作为入坑ghpython开发半年以后,回顾这段时间产生过的一些犹疑,与对应的心得做一个总结,以期许对有类似经历的人有些许帮助。
主要面向对象是觉得gh中的插件并不能满足需求,想进行初步的自定义脚本功能,但是看了一圈教程查了很多资料仍然一头雾水的人。如果大神看到本文中粗略的地方予以指正,我非常感激。
开始编程之前
学什么语言好
这个问题属于老生常谈,对于完全新人,我个人强烈建议是从C#入门。
然后下面的文字完全就不用再看了。
但是我听说python更容易上手
如果担忧上手难度,那就学python。
从哪里开始
官方列了一个指引,地址在这里https://developer.rhino3d.com/guides/。
你说英语不好怎么办?建议装一个网页上的浏览器翻译插件,勉强磕巴也能看。
如何学习python
官方给出了一个python的入门指引,地址在上边网址的一个小节中(https://developer.rhino3d.com/guides/rhinopython/)。
如果看不懂英语,python中文学习资源现在是网上一抓一大把了,可以找第三方的教程学习,需要注意python版本,必须学习python2的教程(虽然实际上rhino用的是ironpython2.7 ),然后再去看官方指引(非常必要)。
python基础知识学习以后就可以开始初步的使用rhinopython进行一些练习,不必要求全盘掌握python才可以进入实战,平白给自己上压力,自己劝退自己。
遇到问题建议使用必应搜索,有条件使用谷歌搜索。
开始编程后的难题
不知道怎么实现自己想要的功能
首先要理解一件事,python不是灵丹妙药,是基于对rhino的理解上深入到代码层来进行功能实现。如果对想要实现的功能,在rhino中就不知道怎么做,那使用python基本上更是完成不了。
在明白了如何手动实现以后,把rhino的操作界面语言切换到英文,记录关键操作中的英文指令。
然后打开官方为rhino.python开发的api列表(Rhino - RhinoScriptSyntax ),查询对应的api,这个api中还提供了对应功能的范例,(如果顺利的查询到了的话)抄着用即可。
举个例子
想创建一个点,记录rhino中的对应命令是’_Point’,查找api列表搜索到了很多结果,不过望文生义,其中应该只有两个是需要的,分别是"AddPoint"和"AddPoints"。
就拿 “AddPoint” 举例,在"AddPoint"中可以看到一段代码:AddPoint(point, y=None, z=None)
和一段对应的说明,以及最后的范例:
import rhinoscriptsyntax as rs rs.AddPoint( (1,2,3) )
如果看了官方的python指引的话就明白如果要使用RhinoScriptSyntax,这一行 ”import rhinoscriptsyntax as rs“ 就必不可少。
如果没看也暂时没关系(有空还是建议去看完),”import rhinoscriptsyntax “指的是从RhinoScriptSyntax导入这些功能以备使用,”…… as rs“则是为了用的时候少打点字,与 ”rs.AddPoint( (1,2,3) )“ 中开头的 "rs"相对应,如果前面是 ”import rhinoscriptsyntax as abc“,那后面就应该是 “abc.AddPoint( (1,2,3) )” 。
RhinoScriptSyntax没有自己需要的功能
对于新手而言,那就惨了。
非常非常非常惨。
这时候有两条路:
- 直接调用 RhinoCommon,办法是 import Rhino
- 使用 rhinoscriptsyntax.Command 复现命令,就像手动在rhino的命令行中做的那样
如果使用 RhinoCommon ,那从python入门就很尴尬,因为大部分的范例只有C#和VB,虽然python节约了入门的时间,同样的函数也可以在python中调用,但是这个时候得开始还债,必须学习C#的基础知识,至少明白其意味着什么才能明白怎么去使用它。
我就在频繁的面对这个困难,这就是我在开头强烈强调从C#入门的原因。
也很抱歉,关于这个部分我也没办法分享我的经验。
不过好在官方对于rhinoscriptsyntax更新的很快,如果C#实在啃不下去,只好等官方更新。
如果使用 rhinoscriptsyntax.Command ,则需要注意性能上的问题,对于多行命令运行的 非常慢 ,不利于大量的使用。在非用不可的情况下建议想办法尽可能地对多个对象同时操作,而不是对一个对象操作完再进行多次重复。
python编译出错了怎么办
新手遇到的大部分情况下是python上的错误,特征是下方报错的 “Traceback” 只有一行。这时候直接在搜索引擎中依靠关键字找寻答案即可。
如果"Traceback" 有多行情况下,则是对调用的函数调用方法出了错,显著特征是代码只有几十行,但是 “Traceback” 中显示的出错行数(line )远超当前文本。真正的错误位置则是最后一行,格式是
line 数字 in script
这个数字就是实际错误代码所在行数。错误内容就具体情况具体分析。
个人经历的奇怪问题与我的野蛮解决办法
***** does not exist in ObjectTable
这根源由于python中自动转换信息格式。
虽然理论上rhinoscriptsyntax返回的是guid:
f6ca4eb2-5ef6-4c8c-a8d5-5861dac8c45e
但是有时候返回的信息长这样:
System.Guid object at 0x00000000000056DF [f6ca4eb2-5ef6-4c8c-a8d5-5861dac8c45e]
这就造成在gh中使用的python,拾取了rhino中的物件后,实际上存储了两个物件信息:
- 一个是在rhino中物件的guid(就是rhino中对象-Geometry的一个唯一标识符);
- 一个是在gh的文档空间中同时对这个物体创建了一个参照(这个描述不是很准确),典型特征是 "0x00000000000056DF"这一串字符在每一次运行时候会变化,而后面的GUID则应该是不变的。
如果把上一个ghpython中输出的物体信息输入到下一个ghpython中时,(在不对电池输入端的Type hint做修改时)输入的实际上是gh空间的参照物体guid,检查guid会发现与上一个电池中输出的信息不同,这时候如果按照guid去查找rhino中的物体,自然就会出现这个错误。
解决办法是对输出结果做一个限制,输出结果单独存储一份guid的字符串信息,避免python中自动转换信息格式。
也就是
str( GUID )
待续