【Grasshopper基础7】如何重写Grasshopper电池的预览 DrawViewportWires / DrawViewportMeshes

本文介绍如何在Grasshopper中自定义电池的预览效果,包括实现渲染逻辑、调整渲染范围以及提高渲染效率的方法。

经过【基础1~6】的介绍,相信大家对Grasshopper电池的开发的框架已经又有更深的了解了, 甚至已经在实现各种奇奇怪怪的 逻辑了。无论是在电池上修改原有功能还是增加新的功能,都是通过继承自GH_Component类,再在其基础上要么override原来的默认实现,要么就是继承新的接口。

在这里对前面的内容小小地总结一下:一个自定义GH电池必须实现的overrides

  • RegisterInputParams // 用于注册输入参数
  • RegisterOutputParams // 用于注册输出参数
  • SolveInstance // 用于真正实现电池对输入参数的处理及提供输出参数的数据
  • ComponentGuid // 用于获得电池类的全局唯一标识id
  • 构造函数,必须实现NameNickNameCategory以及SubCategory属性的赋值

那么,除了这些一个自定义GH电池必须要实现的自定义构造之外,我们自然而然地会去想还有什么方法可以override,这些方法能够帮助我们实现什么功能呢?

我们这次就来看看一对可以重写的函数:

  • DrawViewportWires
  • DrawViewportMeshes

它们是负责将GH电池中的数据展示在Rhino主界面的Viewport视口中的方法。在渲染帧时,GH文档会负责调用每个电池的这两个方法,来完成对电池内容的展示。比如我们在GH中组成的点、线、面会在选中时以绿色(未选中时以红色)渲染至Rhino视口中,这其实就归功于这两个方法。

Record_2021_02_09_11_09_11_988

不过,很多时候我们想要实现自己的显示逻辑,比如在某些生成的几何图形/视口上展示文字、提供额外几何图形预览,又或者是单纯地不想显示某些几何图形,这些都需要重写上述两个方法。

渲染的逻辑

在真正开始动手重写方法前,最重要的还是需要知道Grasshopper预览的底层原理。毕竟是要动手重改默认的实现,在不清楚原实现的前提下就贸然动手,这无异于放着地图不要一头扎进森林,很容易就迷失了。

下面是有关于Grasshopper渲染的几个基本要素:

  1. 渲染的请求是由 Rhino 的渲染通道发出的
  2. Rhino中视口画面的 每一帧都会发出一次渲染请求
  3. Grasshopper中几何数据的请求是由GH_Document统一管理和缓存需要渲染的数据
  4. GH_Document的缓存仅仅是缓存哪些电池需要渲染,对于具体渲染的内容不缓存
  5. GH_Document会对每个需要渲染的电池跑一个大循环,调用上述提到的方法 (DrawViewportxxxx) 来完成渲染

渲染是一个对执行效率要求 特别高 的过程,可以这么简单地理解:我们平时使用的显示器一般都是60Hz刷新率,那么就是1秒60帧,所以留给每一帧渲染的时间仅有不到17ms的时间。于是,我们需要尽可能不要在渲染的过程中执行任何耗时的操作(例如一个大循环+各种复杂数据处理等),渲染过程最好只是数据的读取。


再重申一遍,不要在渲染方法里写任何耗时操作


在了解渲染的最基本的几个之后,DrawViewportWiresDrawViewportMeshes 又分别是干什么的呢?

Wires & Meshes

我们都见过Grasshopper右上角的几个按钮,其中有两个就是用来切换预览模式的(Shaded模式和WireFrame模式)

  • Shaded 模式
    WeChat Screenshot_20210209143450

  • WireFrame 模式
    WeChat Screenshot_20210209143504

可见,如果电池输出的预览包含面信息时,这两个模式渲染的内容是不一样的。在WireFrame模式仅仅会有轮廓线信息,而Shaded则是二者都有。在方法调用层面的情况如下:

  • 如果渲染模式是 WireFrame ,则仅有DrawViewportWires被调用
  • 如果渲染模式是 Shaded,则DrawViewportWiresDrawViewportMeshes都会被调用
  • 如果二者都被调用(即在 Shaded 渲染模式下),DrawViewportWires会先被调用

因此,要实现自定义预览,我们可以依据我们在对应选项中所展示的内容,把要预览的图形在相应的方法中实现即可 —— 预览的线条放入DrawViewportWires,预览的面以及其他复杂的图形放入DrawViewportMeshes。如此以来,对于显卡能力稍差的用户也能通过关闭Shaded渲染来获得较好的交互体验。

不过,仅仅实现这两个自定义方法,某些时候 是无法成功地在Rhino中显示预览图形的。这里提到的 某些时候 大部分时候是特指我们的电池没有输入/输出参数,或者所有参数为非图形数据的时候。终极原因就是GH_Component中还自带了两个属性:

  • IsPreviewCapable
  • ClippingBox

IsPreviewCapable

前面提到了GH_Document会对所有电池是否需要渲染进行一个缓存,这个IsPreviewCapable属性就是用来判断电池是否会进入缓存列表中的。这个属性的默认实现是对电池的出口的所有参数进行遍历,如果发现其中有可以预览的内容时,就会返回一个 true 值来使得电池进入预览缓存。

这个属性的默认实现(在GH_Component类中的实现)大概是这样的

public virtual bool IsPreviewCapable
{
   
   
    get
    {
   
   
        foreach (var item in Params) // 对电池的每个参数遍历
        {
   
   
            if (item is IGH_PreviewObject obj
                && 
                obj.IsPreviewCapable)
                
评论 19
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值