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

此文章来自 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


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

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值