繪製順序(draw order)是如何影響 grasshopper 的計算順序的

通常狀況下,grasshopper 的計算是沿着鏈接線從左至右進行的。首先被計算的是左邊的組件,而後觸發下游組件,直到 canvas 所有計算完成爲止。在你使用 grasshopper 幾個月以後,想都不用想就知道這是固然的。算法

直到有一天你想用 grasshopper 違反這個基本邏輯。我最近接到一個任務,須要用 Honybee 計算強光。強光計算組件使用了一個 Rhino 相機,這意味着當強光將要被正確計算的時候,相機要移動到正確的位置。canvas

我決定使用霍斯特相機控制(Horseter camera control)來調整相機,因而就有了這麼個東西:ssh

這個計算取決於相機 已經 被放置到正確的位置上。換句話來講,相機 必須 在計算完成以前被放到正確的位置。看出問題了嗎?若是沒有相機組件的輸出,計算模型確定來自「buidling」組件。所以,保證相機在計算完成以前移動到正確的位置是不可能的。ui


 

Grasshopper 首先計算的是哪個組件?spa

首先講一點基礎知識。當 Grasshopper 計算組件的時候,有一個屬性叫作 expired(終止)。若是一個組件須要計算,它就會被標上 expired=true。若是組件已經更新了,再也不須要計算,它就會被標上 expired=false。當你更改一個組件的時候(好比修改了它的輸入值),它就會被打上 expired 標誌。而且當一個組件被標誌爲 expired,全部下游組件(也就是右邊的組件)都會被標誌爲 expired。code

簡單來講,「expired」代表這個組件正在等待重算。對象

當 Grasshopper 有了一個已終止組件列表的時候,它必須決定以什麼方式去重算。Grasshopper 是從左至右進行重算的,從一個沒有已終止的輸入的組件開始。blog

對於大多數 Grasshopper 文件來講,這個解釋已經夠清楚了。但事實是,有更多複雜的算法在等着它。注意,在個人圖中,能夠計算組件的有效順序不止一種:string

  • Building, setCam, Docals, result
  • Building, Docals, setCam, result

因此 Grasshopper 有兩種選擇來肯定首先計算的組件,它總歸會選一個的,因此背後確定有它選擇計算順序的更深層次的緣由。我並無多作其餘探索,就去了 Grasshopper 論壇,看到了這篇文章,提問了一個問題。it


 

不會影響計算順序的東西:

Grasshopper 的計算順序不會被下列因素影響:

  • 組件位置(也就是x,y座標)
  • 輸入或輸出的順序
  • 組件內的數據
  • 組件的類型*

那麼會被哪些因素影響呢?


 

Grasshopper 的繪製順序

計算順序被一個關鍵性的因素左右:繪製順序(draw order)。在後臺, Grasshopper 把你的文件中的全部組件複製到一個列表中,列表的順序就是繪製的順序。

被稱爲「繪製順序」是由於它決定了哪個組件被「繪製」時能覆蓋其餘組件。請看下圖 panel 是如何覆蓋其餘 panel 的,這就是「繪製順序」的具體實現。

 

你能夠經過快捷鍵輕易地更改繪製順序:

  • CTRL+B 把組件送到下面
  • CTRL+F 把組件送到上面

 


Grasshopper 是如何利用繪製順序來計算的?

繪製順序不只僅是幫助你美化 Grasshopper 畫布— 它也一樣左右着計算順序。當 Grasshopper 在處理畫布的時候,基本上是這樣的狀況:

  1. Grasshopper 根據你的畫布中的全部組件,生成了一個列表。它的順序和繪製順序是同樣的,0 號元素被繪製在全部元素的下面,其餘元素則根據列表的順序依次繪製在上面。
  2. Grasshopper 找到繪製在最後面的已終止的組件,要求它重算自身。
  3. 在這個組件真正開始計算任何東西以前,首先它會去檢查有沒有已終止的輸入。若是有,就讓這些輸入也重算自身。
  4. 一樣,這些組件在它們開始計算以前也會檢查輸入,直到找到一個沒有已終止輸入,可是自身已終止的組件爲止,這個組件會重算自身並設置爲非終止。
  5. 回到步驟 2,重複直到沒有已終止的組件。

 


如何肯定繪製順序?

最簡單的肯定繪製順序,同時也是肯定計算順序的方法,是經過拖拽組件來看看哪一個覆蓋在上面。最底下的組件會被首先計算。若是咱們不滿意這個順序,能夠經過 CTRL+B 和CTRL+F 來更改。

 

看起來是 setCam 先被計算,耶!

等等 —— 並無那麼簡單! 若是 setCam 組件在 DoCals 下面,可是 result 組件在 setCam 和 DoCals 的下面呢?「result」會被 Grasshopper 首先觸發,它也會接着觸發 DoCals。因此即便 setCam 是在 DoCals 的下面,因爲 results 的願緣由,setCam 也會在 DoCals 以後計算。

咱們須要確保 setCam 在全部組件以前計算,而不只僅是 DoCals。咱們能夠用 CTRL+B 快捷鍵實現,可是怎麼肯定它正確運行了呢?沒有視覺上的反饋是否快捷鍵已經把組件送到了最下面,咱們只有手動地去確認每一個組件。

 


如何肯定繪製順序 —— 給極客

再一次,C# 拯救世界!用一個 C# 組件,咱們能夠獲得 Grasshopper 文件中全部對象的一個列表 —— 以繪製順序。用一個 timer 和一個鏈接的 panel,咱們能夠加一些額外的功能 —— 點擊任何一個組件,在 panel 中會顯示「selected」。

 

你能夠複製如下代碼到一個 C# 組件中,而且在圖中設置好。啓動 timer,選擇任何一個組件(或多個組件)。

 

1 var rtnlsit = new List<string>();
2 
3 foreach (IGH_DocumentObject obj in GrasshopperDocument.Objects)
4 {
5     if(obj.Attributes.Selected) rtnlist.Add(obj.NickName + "(" + obj.Name + ")SELECTED");
6     else rtnlist.Add(obj.NickName + "(" + obj.Name + ")");
7     A = rtnlist;
8 }

 

使用這個組件, 能夠驗證咱們成功地把 setCam 設置到了繪製順序列表的最底層。

 

咱們選擇的組件是列表中的 0 號元素,因此確實被放到了畫布中全部組件的最下面。 太好了!

相關文章
相關標籤/搜索