【Grasshopper进阶】强制Grasshopper电池输入/输出参数数据结构扁平化 (i.e. Flatten/拍平/展开…)

我们都知道,Grasshopper中一个很重要的概念就是数据结构,把数据输入到电池某个端口时,根据数据的结构的不同(列表/数据树),电池对数据会做出不同的响应。这也是为什么在我们在Grasshopper中进行参数化建模时,经常会使用到电池两端输入/输出参数的几个改变数据结构的选项 —— FlattenGraft

我们在任何一个Grasshopper电池的输入、输出端参数上,或者是某个数据存储电池上点击鼠标右键,都会看到一个菜单弹出,里面包含了几种改变数据结构的选项。

在这里插入图片描述

这种数据结构的快速改变的确会方便电池使用者快速实现数据操作,但对于Grasshopper不熟练的使用者,或者某种电池机制不需要数据树来构建具有深度的数据结构时,数据树这样一种结构可能会造成电池运行效率很低,甚至出错的情况。相信大家在Grasshopper学习过程中也遇到过很多次这种情况。

在某些情况,作为电池的开发者,我们不希望电池会收到数据树作为输入,我们希望电池永远是以“列表”形式处理数据。此时,我们第一反应的解决方案会是:

  1. 在电池的 RegisterInputParams 中,注册输入参数为 GH_ParamAccess.tree
  2. SolveInstance 中,执行 DA.GetDataTree 获得输入端的数据树后,直接使用 FlattenData 函数获取其列表形式的数据,并加以处理。

这种方法没有任何问题,但其最大的问题是在于作为用户在使用时,尤其是对Grasshopper数据结构有比较好的理解的用户往往会感到困惑。“为什么数据是以数据树的结构输入,但输出却是一个列表?”此时我们就需要用某种方式传达给用户,“数据被扁平化了,且一定会扁平化”。

那么,既然Grasshopper给我们提供了右键菜单对数据结构进行改变,我们是不是可以通过这种原生的方式告诉用户,这里的数据被扁平化?答案是可以的,请看下面的动图。

在这里插入图片描述

动图中,上方的GH原生电池可以实现对输入端数据的扁平化,也可以自主取消,而下方的电池,输入端被强制扁平化,且不可以被取消,这里这个电池很自然地给用户传递一个“数据在输入时会被扁平化处理”的信息。

实现该功能需要用到Grasshopper电池内的事件。每次我们改变任何输入/输出参数的时候,电池的 SolutionExpire 事件会被触发,通过查看代码发现其代理为

public delegate void SolutionExpiredEventHandler(IGH_DocumentObject sender, GH_SolutionExpiredEventArgs e);

我们需要做的其实就是在这个事件上加入一个“将输入参数扁平化”的代理方法,这样每次事件触发的时候,我们就会同时强制把输入参数进行扁平化。

在我们自定义电池中新添加一个 override 方法 AddedToDocumentAddedToDocument 这个方法会在电池被拖入Grasshopper画布上的一瞬间执行,十分适合在这里加入事件监听此类电池初始化代码。由于 SolutionExpire 这个事件的发起者(sender)是我们电池本身(因为是电池自身的输入/输出值发生改变,所以是电池自己发出SolutionExpire事件),而事件参数(EventArgs)值到底是什么我们并不关心。

public override void AddedToDocument(GH_Document document)
{
    base.AddedToDocument(document);
    SolutionExpired += (sender, args) => {
        ((GH_Component)sender).Params.Input[0].DataMapping = GH_DataMapping.Flatten;
    };
}

具体希望改变第几个输入/输出参数的数据结构,仅需把上面代码中的Input[0]部分修改即可,例如想改变第二个输出参数的数据结构,就要使用Output[1]。同时,如果想要强制Graft或者强制采用默认数据格式也是可以实现的,仅需将右端的赋值语句改为对应的 enum 值即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值