QQ登录

只需一步,快速开始

扫一扫,访问微社区

犀牛建筑网

查看: 24182|回复: 3

GH计算器的脚本计算器讲解(三)

[复制链接]
发表于 2014-10-25 14:43:23 | 显示全部楼层 |阅读模式
犀牛网校

今天,我们开始讲解GH中的VB脚本代码。

打开GH中的VB编辑器,里面已经预先生成了一些代码,如下,我们逐行讲解:

Option Strict Off
Option Explicit On

上面两个是编译器的对代码的选项,第一个意思是严格定义关闭,如果开启严格定义即Option Strict On那么我们必须保证我们的代码正确无误才能执行,甚至连警告错误都不能有。还好这里按照的不是严格定义。

第二个选项是显示定义,意思 我们定义变量的时候必须显示定义而不能是隐式的,即dim pt as point3d,而不能直接不定义,把pt当成point3d来用,这样的话会提示一个错误

“1. Error (BC30451): 'pt' is not declared. It may be inaccessible due to its protection level. (line 87)”

以上两个选项目前版本还不能用户自己改动。

下面是导入的命名空间,不知道命名空间是何物的童鞋,可以恶补一下。导入这些,方便我们写代码,例如导入rhino.Geometry空间后,里面有个Point3d的结构体,那么我们就可以直接使用Point3d这个结构体,Dim pt as Point3d 而不用麻烦滴写 Dim pt as Rhino.Geometry.Point3d,至于命名空间的其他用途这里就不在赘述。下面介绍一下这些常用的空间。

Imports Rhino
Imports Rhino.Geometry

几何类空间,这个里面几乎每个类都需要知道,如果你想对犀牛里面几何对象了如指掌的话。
Imports Rhino.DocObjects

犀牛物件空间,犀牛文档物件。
Imports Rhino.Collections

犀牛泛型空间,就是很多集合空间,例如图层表,颜色表等。

Imports GH_IO

GH的文件空间。
Imports GH_IO.Serialization

GH文件序列空,这个是GH能保存文档,初始几何对象的一个重要的空间。
Imports Grasshopper
Imports Grasshopper.Kernel
Imports Grasshopper.Kernel.Data

GH的数据空间
Imports Grasshopper.Kernel.Types

GH的类型空间,GH里面所有类型都是GH_xxx例如String实际上是GH_String,GH魔术般的功能都是由这些类型支撑的。

以下是NetFrame框架的一些常用空间。

Imports System
Imports System.IO

系统文件管理空间。
Imports System.Xml

Xml空间。
Imports System.Xml.Linq

XML的linq空间。
Imports System.Linq

Linq空间,不知道Linq为何物的童鞋,要恶补以下,这个很久以前没有引入,后来才引入的,很有用,可以用SQL语句一般的.net语言对各种集合查询。
Imports System.Data
Imports System.Drawing

绘图空间。
Imports System.Reflection

反射空间。
Imports System.Collections

泛型空间,这个要掌握。
Imports System.Windows.Forms

WinForm空间,就是那些界面空间,传言犀牛6要移除,不过后来Steve好像找到了另外的方法,保留此空间引用。
Imports Microsoft.VisualBasic

这个空间使用VB6的同学可能很喜欢。是VB6之前的方法函数。
Imports System.Collections.Generic

泛型空间,这个要掌握。

Imports System.Runtime.InteropServices

运行时交互空间。(本人水平有限,对很多空间功能也不甚了解。)

目前命名空间的导入,我们只能用默认的不能自己导入。我曾向GH官方建议让用户自己导入。他们会在GH2.0里面加入自己导入命名空间的功能,这样我们的自由读就更大了。比如我们可以自己导入正则表达式空间等。

''' <summary>
''' This class will be instantiated on demand by the Script component.
''' </summary>

下面就是脚本类。
Public Class Script_Instance
  Inherits GH_ScriptInstance

#Region "Utility functions"
  ''' <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="text">String to print.</param>
  Private Sub Print(ByVal text As String)
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="format">String format.</param>
  ''' <param name="args">Formatting parameters.</param>
  Private Sub Print(ByVal format As String, ByVal ParamArray args As Object())
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object)
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object, ByVal method_name As String)
    'Implementation hidden in Script Edit mode...
  End Sub
#End Region

上面四个方法,前两个是Out输出端输出的过程函数,这几个过程函数我们都无法修改。但是可以调用。

例如 我们写入如下代码:


后面两个是映射,这两个方法能帮助我们查看一个类中到底有哪些公共方法。首先我们看到代码中有me,这个me实际上是对类本身的一个实例调用,可以去了解一下(me,my,mybase)的区别。

那么我们下面就映射一下看看me下面有哪些方法:


细心的同学会说,咦,怎么没有RunScript方法?是的,这里只映射公共方法,包括父类的公共方法,上面哪些我们在这个类中没有看到,是因为它在父类(GH_ScriptInstance)里面。

下面我们自己在此类中写个方法试试:


实际上我们编辑脚本的过程是在修改这个类。我们甚至可以在此类中自己创建类,所以整个脚本计算器还是很强大的。

#Region "Members"
  ''' <summary>Gets the current Rhino document.</summary>
  Private Readonly RhinoDocument As RhinoDoc
  ''' <summary>Gets the Grasshopper document that owns this script.</summary>
  Private Readonly GrasshopperDocument as GH_Document
  ''' <summary>Gets the Grasshopper script component that owns this script.</summary>
  Private Readonly Component As IGH_Component
  ''' <summary>
  ''' Gets the current iteration count. The first call to RunScript() is associated with Iteration=0.
  ''' Any subsequent call within the same solution will increment the Iteration count.
  ''' </summary>
  Private Readonly Iteration As Integer
   #End Region

上面是脚本的几个私有方法,RhinoDocument用的比较多,这里面我们可以直接遍历犀牛文档中的很多东西,甚至直接创建犀牛物件,下面的例子是获取犀牛里面的图层表。

这里要说明的是Layers是一个LayerTable的实例,是一个集合,里面装的并非是图层名,而是装了很多Layer类。那么为啥我们显示出了图层名字呢?这里是实际上隐式做了很多转换,第一个转换时从Layer类到Layer.Name,我们定义集合类的时候,可以将类里面的一个属性定义为默认显示,这里就将Layer类中的那么属性做为了Layer类的默认显示,第二个转换时从Layer.Name的String类型到A输出端Object类型的转换。A为一个byref类型的参数,我们复制的时候,A的指针会指向Layer.name的地址,那么A就是一个储存了一个String集合的object类型(注意与Python的区别,变量的类型并不随着储存的内容改变)最后由Panel板将整个图层名集合显示出来。至于Panel板对变量的显示机制也是一个很复杂的东西,以后再讲。

   好了,GrasshopperDocument是文档本身,我们获取文档本身的以一些信息,比如电池的个数,路径名等等:


Component是脚本电池计算器本身。

Iteration是运行次数,显示此运算器运行了几次,GH在某个升级中,为每个电池都加入运行次数显示,如下图:


经常注意看看电池到底运行了多少次,有助于我们对计算器运行机制的了解,帮助我们查出一些错误等。而且还有助于我们队列表,树的的了解。

  ''' <summary>
  ''' This procedure contains the user code. Input parameters are provided as ByVal arguments,
  ''' Output parameter are ByRef arguments. You don't have to assign output parameters,
  ''' they will have default values.
  ''' </summary>
  Private Sub RunScript(ByVal x As Object, ByVal y As Object, ByRef A As Object)

End Sub

RunScript是我们经常写代码的地方,我们可以在这里自由发挥。

'<Custom additional code>

  '</Custom additional code>

上面这个地方也是一个好地方,我们可以自定义过程,函数,属性,以及自己定义类。
End Class

好了今天就到这里,我们明天将讲一些简单的实用代码。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

发表于 2014-10-25 14:58:31 | 显示全部楼层
学习中谢谢
回复 支持 反对

使用道具 举报

发表于 2014-10-25 20:11:34 | 显示全部楼层
学习学习 呵呵
回复 支持 反对

使用道具 举报

发表于 2014-10-25 22:57:22 | 显示全部楼层
很好很强大
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们|网站地图|BIM|rhino3d ( 沪ICP备19001822号-2 )

GMT+8, 2024-4-29 04:24 , Processed in 0.052057 second(s), 21 queries .