您的位置:首页 > 其它

Rhino gha开发如何添加动态参数

2013-09-26 13:37 1031 查看
此文章来自 http://www.grasshopper3d.com/forum/topic/listForContributor?user=30xopnbe87ou3
Grasshopper3d的官方论坛,由david Rutten 编写

GHA Developers: implementing variable parameters

GHA开发者:如何实现动态参数的接口

Dear GHA developers. As you may have noticed the preferred gui for variable parameters has changed in 0.8.0060. The old gui is still available, but has been marked Obsolete and will soon no longer be visible in Visual Studio autocomplete.

亲爱的GHA 开发者。在GH0.8.0060版本中你也许会注意到,动态参数图形界面已经跟以前的不一样了。旧的界面仍然可以使用,但是已经被标记为旧的了而且不久就会自动的不在Visual Studio里面使用(gha是用vs开发的)

If you have a GH_Component class that implements IGH_VarParamComponent and you wish to switch over to the new gui, please do the following:

如果你有个GH_Component 的类,需要实现IGH_VarParamComponent 接口 而且你希望将其转换到新的界面,那么请按照以下几点来操作

Make a duplicate of the class and give it a different ComponentId

1,复制你的类并且赋予它一个不同的计算器ID

Rename the original class to xxxx_Legacy or something and change the exposure toHidden. This will for all intents and purposes hide the old component while still allowing Grasshopper to deserialize it from files.

2,按照xxxx_Legacy或者其他格式重命名原来的类并且将exposure属性设置为Hidden.这样做的意图和目的都是为了能隐藏旧的计算器并且仍然允许gh(Grasshopper的简称)从文件中读取它。

In the duplicate class, remove the implementation of IGH_VarParamComponent and instead implementIGH_VariableParameterComponent.Never implement both in a single component!

3,在复制的类中,移除 对IGH_VarParamComponent接口的实现将其替换为对IGH_VariableParameterComponent的实现。永远不要在同一个计算器中将二者都实现。

The new interface should be easier to implement (details below) than the old one and it will provide the Zooming User Interface rather than the pop-up menu interface.

4,新的接口将比旧的更容易实现(详见下文),新的接口将提供缩放式的使用接口,而非显示一个菜单。

Methods to implement for IGH_VariableParameterComponent:

实现新接口的方法如下:

CanInsertParameter. This method is called when Grasshopper needs to know whether or not it is allowed to insert a parameter at the given location. This method is called a lot (potentially) so make it spiffy. If you return True,
a ZUI insert icon will be visible at high zoom levels.

1,CanInsertParameter.这个方法将在gh需要知道是否允许在指定位置插入参数的时候调用。这方法被调用的次数比较多(潜在的来说)所以将其制作的很简洁。如果你返回True,当将界面缩放的比较大的时候,一个缩放用户解决插入按钮将会被显示。

CanRemoveParameter. This method is called when Grasshopper needs to know whether or not it is allowed to remove the parameter at the given location. This method is called a lot (potentially) so make it spiffy. If you return True,
a ZUI delete icon will be visible at high zoom levels.

2,CanRemoveParameter.这个方法在gh需要知道是否允许在指定位置插入参数时调用。这个方法同样很简洁,如果你返回True,那么当缩放计算器时会显示一个减号按钮。

CreateParameter. If a new parameter is about to be inserted, this method will be called to instantiate it. You must return a validIGH_Param instance or insertion will abort. Typically it's enough to:return new Param_Integer();

3,CreateParameter.如果一个新的参数将要被插入,这个方法将会被调用去实例化它。你必须返回一个可用的IGH_Param实例否则插入将被取消。

DestroyParameter. If an existing parameter is about to be destroyed this method will be called. This is your last chance to stop deletion (though ideally if you didn't want it to be deleted you should have returned false from insideCanRemoveParameter).
You don't actually have to do anything in DestroyParameter() except return true, it's just there to inform you.

4,DestroyParameter.如果一个已经存在的参数将被删掉,那么这个方法被调用。这是你最后的机会阻止删除(尽管一般情况下如果你不想让参数被删除应该在CanRemoveParameter里面返回False)。实际上除了DestoryParameter返回True你什么都没做,只是让你知道有这个方法。

VariableParameterMaintenance. Again, you don't have to do anything here, but it's a great spot to make sure everything is hunky-dory. If for example your parameters must adhere to a specific naming scheme, or they have to beOptional,
or their access needs to be List or.... this would be the best place to put that code.VariableParameterMaintenance() will be called every time a change is made to variable parameters and also when the component is deserialized.

5,VariableParameterMaintenance.同样,你在这个地方不需要做任何事情。不过它是一个确保一切正常的不错的地方。例如,你的参数必须符合一个指定的组合,或者他们必须是可选的,或者他们的数据源必须是列表又或者.....这里将是一个很好的地方去写这些代码。

I'll try and write a topic for this in the SDK documentation as soon as possible but until then, feel free to ask any questions about this here.

我将尽快在SDK帮助文档中试着写一篇文章关于动态参数的文章,不过到那为止,你可以在这里随意的问任何关于动态参数的问题。

The Params object has 3 events which you can register that will inform you when parameters change:

和参数相关的有以下三个事件可以注册,这些事件能通知你参数的改变。

ParameterNickNameChanged(ByVal sender As Object, ByVal e As GH_ParamServerEventArgs)

ParameterSourcesChanged(ByVal sender As Object, ByVal e As GH_ParamServerEventArgs)

ParameterChanged(ByVal sender As Object, ByVal e As GH_ParamServerEventArgs)

The first two are only used for specific events (nicknames and sources respectively), the third one is always raised (even when one of the specific ones is raised first).

前两个只能用于指定的事件(别名和输入源事件),第三个总是被激发(甚至前两个任何一个发生,这个事件就发生)

You can register handlers for these events in the component constructor if you want.

如果你愿意的话,你可以在计算器的构造函数中注册这些事件的处理程序。

--

David Rutten

大卫.鲁钝

david@mcneel.com

Poprad, Slovakia

波普拉德,斯洛伐克

以下是动态参数的示例代码。

Public Class SortDataComponent
Inherits GH_Component
Implements IGH_VariableParameterComponent
Public Sub New()
'I'd recommend not using multi-line descriptions, but if you really want to I suppose you could.
MyBase.New("Seg_Sort", "Sort", "对一列数据进行排序" & Environment.NewLine & "(Sort Data List)", "SEG", "List")
End Sub
Public Overrides ReadOnly Property ComponentGuid As System.Guid
Get
Return New Guid("4D71128B-BED7-40cc-9DBC-75DB68BDC627")
End Get
End Property
Protected Overrides ReadOnly Property Internal_Icon_24x24() As System.Drawing.Bitmap
Get
Return My.Resources.Sortdata
End Get
End Property

Protected Overrides Sub RegisterInputParams(ByVal pManager As Grasshopper.Kernel.GH_Component.GH_InputParamManager)
' Environment.NewLine is better than vbCrLf because it's always the correct newline characters for whatever system is curring (Mac, Linux, Windows).
pManager.AddGenericParameter("Seg_Key", "K", "作为排序键值的数据列表" & Environment.NewLine & "(List of sortable keys)", GH_ParamAccess.list)
pManager.AddGenericParameter("Seg_A", "A", "可选,以同样的方式将此列表排序" & Environment.NewLine & "(Optional list of values to sort synchronously)", GH_ParamAccess.list)
End Sub
Protected Overrides Sub RegisterOutputParams(ByVal pManager As Grasshopper.Kernel.GH_Component.GH_OutputParamManager)
pManager.AddGenericParameter("Seg_Key", "K", "排序后的键值" & Environment.NewLine & "(Sorted keys)", GH_ParamAccess.list)
pManager.AddGenericParameter("Seg_A", "A", "同步后的数据列表" & Environment.NewLine & "(Synchronous values in A)", GH_ParamAccess.list)
End Sub

Protected Overrides Sub SolveInstance(ByVal DA As Grasshopper.Kernel.IGH_DataAccess)
Dim keyGoo As New List(Of IGH_Goo)
If (Not DA.GetDataList(0, keyGoo)) Then Return

'We need to decide whether we have numbers, strings, or some combination of the above.
Dim containsNumbers As Boolean = False
Dim containsStrings As Boolean = False

For Each goo As IGH_Goo In keyGoo
If (TypeOf goo Is GH_Integer) Then
containsNumbers = True
Continue For
End If
If (TypeOf goo Is GH_Number) Then
containsNumbers = True
Continue For
End If
containsStrings = True
Next

Dim keys As Array
If (containsStrings) Then
'We have at least one non-numeric value, which means we're going to treat them all as strings.
'So now create an array of strings for all the key values:
Dim stringKeys As String() = Nothing
Array.Resize(stringKeys, keyGoo.Count)
For i As Int32 = 0 To stringKeys.Count - 1
If (keyGoo(i) Is Nothing) Then
stringKeys(i) = String.Empty
Else
stringKeys(i) = keyGoo(i).ToString
End If
Next
keys = stringKeys

ElseIf (containsNumbers) Then
'We have only numbers, create a double array from all the keys:
Dim doubleKeys As Double() = Nothing
Array.Resize(doubleKeys, keyGoo.Count)
For i As Int32 = 0 To keyGoo.Count - 1
If (keyGoo(i) Is Nothing) Then
doubleKeys(i) = Double.NaN
Else
Dim num As Double = Double.NaN
GH_Convert.ToDouble(keyGoo(i), num, GH_Conversion.Both)
doubleKeys(i) = num
End If
Next
keys = doubleKeys
Else
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Keys must consist of either numeric or textual data")
Return
End If

'Iterate over the synchronous parameters
For i As Int32 = 1 To Params.Input.Count - 1
Dim values As New List(Of IGH_Goo)
If (DA.GetDataList(i, values)) Then
If (values.Count <> keyGoo.Count) Then
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Keys and values collections must be of equal size")
Continue For
End If

Dim valueArray As Array = values.ToArray()
SortArrays(keys, valueArray)
DA.SetDataList(i, valueArray)
End If
Next

'Ultimately sort the keys array for real.
Array.Sort(keys)
DA.SetDataList(0, keys)
End Sub
Private Sub SortArrays(ByVal keys As Array, ByVal values As Array)
keys = DirectCast(keys.Clone(), Array)
Array.Sort(keys, values)
End Sub

#Region "Variable Parameter logic"
Public Function CanInsertParameter(ByVal side As Grasshopper.Kernel.GH_ParameterSide, ByVal index As Integer) As Boolean Implements Grasshopper.Kernel.IGH_VariableParameterComponent.CanInsertParameter
If (side = GH_ParameterSide.Output) Then Return False
If (index = 0) Then Return False
Return True
End Function
Public Function CanRemoveParameter(ByVal side As Grasshopper.Kernel.GH_ParameterSide, ByVal index As Integer) As Boolean Implements Grasshopper.Kernel.IGH_VariableParameterComponent.CanRemoveParameter
If (side = GH_ParameterSide.Output) Then Return False
If (Params.Input.Count < 2) Then Return False
If (index = 0) Then Return False
Return True
End Function
Public Function CreateParameter(ByVal side As Grasshopper.Kernel.GH_ParameterSide, ByVal index As Integer) As Grasshopper.Kernel.IGH_Param Implements Grasshopper.Kernel.IGH_VariableParameterComponent.CreateParameter
Dim output As New Param_GenericObject()
Params.RegisterOutputParam(output, index)
Dim input As New Param_GenericObject()
input.NickName = String.Empty
Return input
End Function
Public Function DestroyParameter(ByVal side As Grasshopper.Kernel.GH_ParameterSide, ByVal index As Integer) As Boolean Implements Grasshopper.Kernel.IGH_VariableParameterComponent.DestroyParameter
Params.UnregisterOutputParameter(Params.Output(index))
Return True
End Function
Public Sub VariableParameterMaintenance() Implements Grasshopper.Kernel.IGH_VariableParameterComponent.VariableParameterMaintenance
'Fix all inputs, then match all outputs.
For i As Int32 = 1 To Params.Input.Count - 1
Dim param As IGH_Param = Params.Input(i)
If (param.NickName = String.Empty) Then
param.NickName = GH_ComponentParamServer.InventUniqueNickname("ABCDEFGHIJKLMNOPQRSTUVWXYZ", Params.Input)
End If

param.Name = String.Format("Values {0}", param.NickName)
param.Description = "可选,以同样的方式将此列表排序" & Environment.NewLine & "(Optional list of values to remap synchronously)"
param.Access = GH_ParamAccess.list
param.Optional = True
Next

'Now synch all outputs.
RepairParameterMatching()

For i As Int32 = 1 To Params.Input.Count - 1
Params.Output(i).Name = Params.Input(i).Name
Params.Output(i).NickName = Params.Input(i).NickName
Params.Output(i).Description = String.Format("同步后的数据列表" & Environment.NewLine & "(Synchronous values in {0})", Params.Output(i).NickName)
Next
End Sub
Private Sub RepairParameterMatching()
If (Params.Output.Count = Params.Input.Count) Then Return
Do
If (Params.Output.Count = Params.Input.Count) Then Exit Do
If (Params.Output.Count < Params.Input.Count) Then
Params.RegisterOutputParam(New Param_GenericObject())
Else
Params.UnregisterOutputParameter(Params.Output(Params.Output.Count - 1))
End If
Loop
VariableParameterMaintenance()
End Sub
#End Region
End Class


编译之后的计算器图片如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: