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

来源:互联网 发布:php web 开发 编辑:程序博客网 时间:2024/06/05 07:49

此文章来自 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 接口 而且你希望将其转换到新的界面,那么请按照以下几点来操作

  1. 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


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

 

原创粉丝点击