Creating a Component with a variable number of output parameters(创建一个动态输出参数的计算器)

 我们来自江河梦小组(Scond Effect Group),工程用到gh,所以必须学习好GH插件,而大部分权威资料都来自国外,所以就组织组员翻译来自GH官方论坛的帖子,以便学习。下面是一篇David的帖子讲解有关如何创建一个拥有动态输出端的计算器,由刘友生同学翻译。

Creatinga Component with a variable number of output parameters

·      Posted by David Rutten on October 27, 2010 at 11:43pm in VB, C# and Python Coding

·      Send MessageView Discussions

This topic is a follow-up from a discussion started by Benjamin Golder. In it I will show thenecessary steps for creating a custom component that has a variable number ofoutput parameters, based on the data structure of the input.

这个话题是由本杰明高德开始的一个讨论的后续。

在这我将展示必要的步骤来创建一个基于数据结构的输入,具有动态输出参数的自定义计算器。

 

I'll create a component that aims to writeall the GH_Paths inside the input data structure into separate outputparameters. I'll add a menu item to the component that allows users to synchthe number of outputs with the current data.

我将创建一个计算器,旨在编写所有的gh路径,里面包含输入数据结构到单独的输出参数。

我将添加组件的一个菜单项允许用户同步输出的数量与当前数据。

我将在计算器上添加一个菜单,这个菜单允许用户用当前数据来确定输出端的参数的数量。

 

Note that there are some bugs I foundrelated to Undo here, but I'll attempt to fix those asap. The mechanismsemployed in this example are correct.

注意这里有一些我发现与撤销相关的漏洞,但我将尝试尽快修复这些。

在本例中使用的机制是正确的。

 

Let's start with the Component classdefinition and the constructor:

让我们开始组件的类定义和构造函数:

Public Class GH_ExampleComponent_VarOutput
Inherits GH_Component

Public Sub New()
MyBase.New("Extract Paths", "ExPath", "Extract all the paths from a tree", "Sets", "Tree")
End Sub

End Class


Now, the RegisterXXXXParams methods:

现在,寄存器XXXX参数方法:

下面是实现注册输入端参数的方法:

Protected Overrides Sub RegisterInputParams(ByVal pManager As GH_Component.GH_InputParamManager)
pManager.Register_GenericParam("Tree", "T", "Data tree to examine", GH_ParamAccess.tree)
End Sub
Protected Overrides Sub RegisterOutputParams(ByVal pManager As GH_Component.GH_OutputParamManager)
'We'll add one output parameter, just to not have a jagged output.
‘我们添加一个输出端参数,仅仅为了不至于让输出端呈现锯齿状(无参数的输出端是锯齿状的)
pManager.Register_PathParam("Path 1", "1", "1st path in tree")
End Sub


SolveInstance() is somewhat special, butnot very complicated:

SolveInstance()有些特别,但不是很复杂:

Protected Overrides Sub SolveInstance(ByVal DA As IGH_DataAccess)
'We have only one input parameter and it is set to Tree, 
‘我们仅有一个输入端参数,将它的数据类型设置为Tree
'so SolveInstance will only be called once for every solution.
‘这样SolveInstance过程对于每一次计算都仅会被调用一次(如果设置为item,数据源有多少个果实就计算多少次,如果设置为list,数据源有多少个branch就计算多少次),数据源可能是item,可能是List,可能是Tree,但是任何数据广义上来说都是Tree,所以讲数据类型设置为Tree,对于一次计算此过程将会被调用一次,理解这点对于使用VB,C#计算器有很大帮助。
'We don't actually need the data inside the input, we're only interested in the paths.
‘我们实际上并不需要输入端里面的数据,我们只对它的路径感兴趣。
'So we don't actually need to call DA.GetDataTree, we can just go in and extract the 
‘所以我们实际上不需要调用Da.getdatatree方法,我们就只进去直接把路径抽离出来。
'paths directly:
Dim paths As IList(Of GH_Path) = Params.Input(0).VolatileData.Paths

'Abort if there is no tree.
‘如果没有树的输入则终止过程
If (paths.Count = 0) Then Return

'Post a warning if the number of output parameters does not 
'equal the number of paths in the tree.
‘当输出端的参数个数不等于树的路径个数的时候弹出一个警告提示
If (paths.Count < Params.Output.Count) Then
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "There are more outputs than paths in the tree.")
ElseIf (paths.Count > Params.Output.Count) Then
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "There are fewer outputs than paths in the tree.")
End If

'Iterate over all paths and assign to output parameters.
‘遍历所有路径,指定到输出端
For i As Int32 = 0 To Math.Min(Params.Output.Count, paths.Count) - 1
DA.SetData(i, paths(i))
Next
End Sub


Adding a menu item to the component menu isrelatively straightforward, however handling the menu command requires a fairbit of logic:

添加组件菜单的一个菜单项是相对简单的,然而处理菜单命令需要大量的逻辑:

Protected Overrides Sub Menu_AppendCustomComponentItems(ByVal iMenu As System.Windows.Forms.ToolStripDropDown)
'Add a single item to the component menu.
‘在计算器菜单中添加一项
Menu_AppendGenericMenuItem(iMenu, "Synch outputs", AddressOf Menu_SynchOutputClicked)
End Sub
Private Sub Menu_SynchOutputClicked(ByVal sender As Object, ByVal e As EventArgs)
'Here we have to synch the number of output parameters with the number
'of paths in the volatile data tree in the input parameter.
‘这里我们将输出端的参数个数与输入端树的路径个数同步
'This requires a few steps:
‘这要求我们必须经过下面几个步骤
'1. Determine whether something needs to happen at all.
‘1,确定哪些事情需要被激发
'2. Record an undo event.
‘2,做一个回滚操作记录
'3. Remove excess outputs or add missing outputs.
‘3,去掉多余或者添加缺失的输出端参数
Dim paths As IList(Of GH_Path) = Params.Input(0).VolatileData.Paths
If (paths.Count = Params.Output.Count) Then Return 'yay, nothing needs to be done.
‘如果路径个数和输出端参数相等那么不需要做任何事情
'Something needs to be done, record an undo state.
‘如果有事情必须做,那么轻记录下来,以便回滚(Ctrl+Z)
RecordUndoEvent("Synch output")

'We either have too few or too many outputs, determine which is the case.
‘我们既不需要多余的参数也不需要太少的参数,确定是那种情况(大神写代码注解都比较啰嗦--)
If (paths.Count > Params.Output.Count) Then
'Add the missing outputs
‘添加缺少的输出端参数
For i As Int32 = Params.Output.Count + 1 To paths.Count
Dim param As New Grasshopper.Kernel.Parameters.Param_GenericObject()
param.Name = "Path " & i.ToString()
param.NickName = i.ToString()

If (i.ToString.EndsWith("1")) Then
param.Description = i.ToString() & "st path in tree"
ElseIf (i.ToString.EndsWith("2")) Then
param.Description = i.ToString() & "nd path in tree"
ElseIf (i.ToString.EndsWith("3")) Then
param.Description = i.ToString() & "rd path in tree"
Else
param.Description = i.ToString() & "th path in tree"
End If

Params.RegisterOutputParam(param)
Next

Else
'Remove excessive outputs
‘移除多余的输出端参数
Do
If (Params.Output.Count <= paths.Count) Then Exit Do
Dim param As IGH_Param = Params.Output(Params.Output.Count - 1)
Params.UnregisterOutputParameter(param)
Loop
End If

Params.OnParametersChanged()
ExpireSolution(True)
End Sub


Finally, we must make sure that thecomponent properly (de)serializes. This means we have to override the Write andRead methods and add additional information to the GHX archive:

最后,我们必须确保组件正确地 ()序列化。这意味着我们必须覆盖写和读的方法以及添加额外的信息到GHX存档里:

最后我们必须确保计算器能正确的被编译和解读。这意味着我们不得不重载Write Read方法,添加额外的信息到GHX文件中。

Public Overrides Function Write(ByVal writer As GH_IO.Serialization.GH_IWriter) As Boolean
'We must make sure that the number of output parameters is correctly stored.
‘我们必须确保输出端参数的个数被正确的存储
'We'll use a special function on the GH_ComponentParamServer to accompish this
'without too much sweat.
‘我们使用在GH_ComponentParamServer中使用一个特别的函数来很轻松的实现这点

Params.WriteParameterTypeData(writer)

Return MyBase.Write(writer)
End Function
Public Overrides Function Read(ByVal reader As GH_IO.Serialization.GH_IReader) As Boolean
'Very important, we must make sure all parameters exist before we 
'start with the main deserialization.
‘很重要,在我们开始主要的编译之前,我们必须确保所有的参数都存在。
Params.Clear()
Params.ReadParameterTypeData(reader)

Return MyBase.Read(reader)
End Function


 

I attached a VB file that contains the codeoutlined above.

我附加了一个VB文件,其中包含了上述的代码。

--

David Rutten

david@mcneel.com

Seattle, WA

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值