程式碼區塊有一些基本的速寫方法,簡言之,這些方法可以 顯著 降低資料管理的難度。以下我們將分類講解基本知識,並討論如何使用此速寫來建立與查詢資料。
資料類型
標準 Dynamo
Code Block 對等項
數字
字串
序列
範圍
取得索引處的項目
建立清單
連接字串
條件陳述式
節點
Code Block 對等項
附註
任何運算子 (+、&&、>=、Not... 等等)
+、&&、>=、!... 等等
請注意,「Not」變成「!」,但節點稱為「Not」以便與「階乘」區分
Boolean True
true;
請注意小寫
Boolean False
false;
請注意小寫
定義範圍與序列的方法可以精簡為基本速寫。使用以下影像作為「..」語法的指南,以使用程式碼區塊定義一系列數值資料。瞭解此標記法後,建立數值資料就會非常有效率:
在此範例中,數字範圍由定義
beginning..end..step-size;
的基本 Code Block 語法所取代。以數字方式表示,我們得到:0..10..1;
請注意,語法
0..10..1;
相當於0..10;
步長大小 1 是速寫標記法的預設值。因此0..10;
將產生從 0 到 10 且步長大小為 1 的序列。序列 範例很類似,只是我們使用「#」來說明希望清單包含 15 個值,而非清單中的值不超過 15。在此範例中,我們將定義:
beginning..#ofSteps..step-size:
序列的實際語法為0..#15..2
使用上一步的 #,現在將其放在語法的 step-size 部分。現在,我們產生一個從 beginning 到 end 的 數字範圍,step-size 標記將許多值均勻分佈在這兩個值之間:
beginning..end..#ofSteps
藉由建立進階範圍,我們能以簡單方式使用清單的清單。在以下範例中,我們將隔離變數與主要範圍標記,並建立該清單的另一個範圍。
1.建立巢狀範圍,對含與不含「#」的標記進行比較。套用基本範圍內的相同邏輯,只是變得稍複雜一些。
2.可以在主要範圍內的任何位置定義子範圍,請注意我們可以有兩個子範圍。
3.透過控制範圍內的「end」值,我們可以建立長度不同的多個範圍。
比較以上兩個速寫,並嘗試剖析 子範圍 與 # 標記如何產生結果輸出,來作為邏輯練習。
除了使用速寫建立清單外,我們也可以快速建立清單。這些清單可以包含多種元素類型,也可以進行查詢 (請記住,清單本身就是物件)。總而言之,使用程式碼區塊,您將使用括號 (方括號) 建立清單和查詢清單中的項目:
1.使用字串快速建立清單,並使用項目索引查詢清單。
2.使用變數建立清單,並使用範圍速寫標記查詢清單。
使用巢狀清單進行管理是類似的程序。請注意清單順序,並使用多組方括號呼叫:
1.定義清單的清單。
2.使用單邊括號查詢清單。
3.使用雙邊括號查詢項目。
按一下下方的連結下載範例檔案。
附錄中提供完整的範例檔案清單。
在本練習中,我們將靈活運用新的速寫技能,以建立由範圍與公式定義的炫酷蛋殼曲面。在本練習中,請注意我們如何搭配使用程式碼區塊與既有 Dynamo 節點:我們對處理大量資料的工作使用程式碼區塊,而以視覺方式配置 Dynamo 節點以實現定義的易讀性。
首先,透過連接以上節點以建立曲面。不是使用數字節點來定義寬度與長度,而是按兩下圖元區,然後在程式碼區塊中輸入 100;
。
在 Code Block 中輸入
0..1..#50
,定義介於 0 至 1 之間且分為 50 份的範圍。將該範圍連接至 Surface.PointAtParameter,這會在曲面內為 u 與 v 指定介於 0 與 1 之間的值。請記得在 Surface.PointAtParameter 節點上按一下右鍵,將「交織」變更為「笛卡兒積」。
在此步驟中,我們使用第一個函數在 Z 方向將點的格線上移。此格線將根據基本函數驅動產生的曲面。如以下影像所示新增節點
我們不使用公式節點,而是使用包含
(0..Math.Sin(x*360)..#50)*5;
這一行的 Code Block。為了快速詳細說明這一點,我們將定義內含公式的範圍。此公式是正弦函數。正弦函數會接收 Dynamo 中輸入的角度,因此為了取得完整的正弦波形,我們將 x 值 (這是 0 到 1 的範圍輸入) 乘以 360。接下來,我們希望份數與每列的控制格線點數量相同,所以使用 #50 定義五十份。最後,乘數 5 只是為了增加平移的振幅,方便我們在 Dynamo 預覽中查看效果。
雖然上一個 Code Block 運作地很好,但它並非完全是參數式方法。我們要動態驅動其參數,因此我們將上一步的程式碼行取代為
(0..Math.Sin(x*360*cycles)..#List.Count(x))*amp;
。藉此我們能根據輸入定義這些值。
透過變更滑棒 (範圍從 0 到 10),我們得到一些有趣的結果。
透過對數字範圍執行轉置,我們反轉窗簾波浪的方向:
transposeList = List.Transpose(sineList);
加入 sineList 與 tranposeList 後會得到一個扭曲的蛋殼曲面:
eggShellList = sineList+transposeList;
變更下面指定的滑棒值,將此演算法「變平靜」。
最後,我們使用程式碼區塊查詢資料的隔離部分。若要重新產生具有特定範圍點的曲面,請在 Geometry.Translate 與 NurbsSurface.ByPoints 節點之間加入以上程式碼區塊。這包括文字行:sineStrips[0..15..1];
。這將選取前 16 列的點 (從 50 個點中)。重新建立曲面,我們可以看到已產生點格線的隔離部分。
在最後一個步驟中,為了讓此 Code Block 的參數式程度更高,我們使用範圍從 0 至 1 的滑棒來驅動該查詢。我們使用這一行程式碼執行此作業:
sineStrips[0..((List.Count(sineStrips)-1)*u)];
。這可能有些混亂,但使用該行程式碼可以快速運用介於 0 和 1 之間的乘數來擴充清單長度。
若使用滑棒值 0.53
,會建立一個剛好通過格線中點的曲面。
與預期一致,使用滑棒值 1
時,會從完整的點格線建立一個曲面。
查看視覺圖表,我們可以亮顯程式碼區塊,並查看其中的每項函數。
1.第一個 Code Block 取代 Number 節點。
2.第二個 Code Block 取代 Number Range 節點。
3.第三個 Code Block 取代 Formula 節點 (以及 List.Transpose、List.Count 與 Number Range)。
4 種。第四個 Code Block 查詢清單的清單,取代 List.GetItemAtIndex 節點。
程式碼區塊是 DesignScript 中的深層視窗,是 Dynamo 程式設計語言的核心。DesignScript 可用於從頭開始進行建置以支援探索式設計工作流程,它是一個可讀且簡要的語言,可為較小的位元碼提供即時意見以也可以用於大型且複雜的互動。DesignScript 還形成在後台驅動 Dynamo 大多數方面之引擎的基礎。因為幾乎 Dynamo 節點的所有功能和互動都與指令碼撰寫語言有一對一的關係,所以有獨特的機會以流暢方式在節點式互動與指令碼撰寫之間轉換。
對於初學者,節點可以自動轉換為文字語法,以協助學習 DesignScript,或單純只是為了縮小較大的圖表部分。使用稱為「要編碼的節點」的流程即可達成。在 DesignScript 語法一節會說明更多詳細資訊。經驗更豐富的使用者可以使用程式碼區塊,建立既有功能以及使用許多標準編碼範例的使用者編寫關係的自訂組合。對於初學者和進階使用者之間的使用者,提供了大量的捷徑和程式碼片段可加快您的設計。雖然術語「程式碼區塊」可能會讓非程式設計師覺得有點難以理解,但它其實很容易使用,而且功能強大。初學者可以在進行最少編碼的情況下使用程式碼區塊,進階使用者可定義在 Dynamo 定義的其他位置可進行呼叫的指令碼型定義。
簡而言之,程式碼區塊是視覺指令碼撰寫環境中的文字指令碼撰寫介面。它們可以用作數字、字串、公式和其他資料類型。程式碼區塊是專為 Dynamo 設計的,因此可以在程式碼區塊中定義任意變數,且這些變數會自動新增至節點的輸入:
程式碼區塊可讓使用者靈活決定如何指定輸入。下面提供了幾種不同方式來使用座標建立基本點 (10,5,0):
在您進一步瞭解資源庫中可用的函數後,您可能甚至會發現,鍵入「Point.ByCoordinates」的速度比在資源庫中搜尋和找出正確的節點更快。例如當您鍵入 Point. 時,Dynamo 會顯示一個可能函數的清單以套用到點。這可使得指令碼撰寫更直覺,並協助學習如何在 Dynamo 中套用函數。
您可以透過 Core>Input>Actions>Code Block 找到程式碼區塊。但更快的方式是在圖元區按兩下,程式碼區塊就會出現。此節點因為經常使用,所以被賦予完整的按兩下權限。
程式碼區塊對於資料類型也可以很靈活。使用者可以快速定義數字、字串和公式,程式碼區塊將提供所需的輸出。
在以下圖像中,您可以看到以「舊」的方式進行的作業有點冗長,使用者在介面中搜尋所需的節點,將節點新增至畫布,然後輸入資料。使用程式碼區塊時,使用者可以按兩下畫布以拉取節點,然後使用基本語法鍵入正確資料類型。
number、string 和 formula 節點是 Dynamo 節點的三個範例,與 Code Block 相比可以說是舊式節點。
舊式
程式碼區塊
程式碼區塊是 Dynamo 中的獨有功能,用於動態連接視覺程式設計環境與文字型環境。程式碼區塊可存取所有 Dynamo 節點,並可以在一個節點定義整個圖形。請仔細閱讀本章,因為程式碼區塊是 Dynamo 中的基礎建置材料。
可以在程式碼塊中建立函數,然後在 Dynamo 定義中的其他位置重新呼叫函數。此作業會在參數式檔案中建立另一個控制層,可視為自訂節點的文字版本。在此案例中,「父系」程式碼區塊可隨時存取,可在圖表中的任何位置找到。無需使用線路!
第一行包含關鍵字「def」,然後依次是函數名稱與輸入的名稱 (在括號中)。大括號定義函數的本體。使用「return =」傳回值。定義函數的程式碼區塊沒有輸入或輸出埠,因為會從其他程式碼區塊呼叫。
使用同一檔案中的其他程式碼區塊,只需提供名稱與相同數量的引數即可呼叫函數。其工作方式類似於資源庫中的現成節點。
按一下下方的連結下載範例檔案。
附錄中提供範例檔案的完整清單。
在本練習中,我們將進行根據輸入點清單建立圓球的一般定義。這些圓球的半徑由每個點的 Z 性質驅動。
接下來先建立介於 0 到 100 之間的一系列十個值。將這些值插入 Point.ByCoordinates 節點,以建立對角線。
建立 Code Block 並介紹我們的定義。
使用以下程式碼行:
inputPt 是我們為了表示驅動函數的點而提供的名稱。到現在為止,函數不會執行任何作業,但我們將在後續步驟中建置此函數。
加入 Code Block 函數後,我們加上註解和 sphereRadius 變數,它會查詢每個點的 Z 位置。請記住,inputPt.Z 是一個方法,不需要括號。這是 查詢 既有元素的性質,因此不需要任何輸入:
現在,我們呼叫在另一個 Code Block 中建立的函數。如果在圖元區上按兩下以建立新的 Code Block,然後鍵入 sphereB,我們發現 Dynamo 建議使用我們定義的 sphereByZ 函數。您的函數已加入 intellisense 資源庫!太酷了。
現在,我們呼叫函數,並建立一個稱為 Pt 的變數以插入先前步驟中建立的點:
我們看到輸出全部都是空值。為何會發生這種情況?定義函數時,我們會計算 sphereRadius 變數,但沒有定義函數應 傳回 哪些項目做為 輸出。我們可以在下一步修正此問題。
我們需要在 sphereByZ 函數中加入
return = sphereRadius;
行定義函數的輸出,這是重要的步驟。現在,我們可以看到程式碼區塊的輸出提供每個點的 Z 座標。
現在,我們要編輯 父系 函數以建立實際的圓球。
我們首先使用以下程式碼行定義圓球:
sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius);
接下來,我們將傳回值變更為 sphere,而不是 sphereRadius:
return = sphere;
這會在 Dynamo 預覽中產生一些巨大的圓球!
1.若要調整這些圓球的大小,我們加入圓規來更新圓球半徑值:
sphereRadius = inputPt.Z/20;
現在,我們可以看到分開的圓球,並開始了解半徑與 Z 值之間的關係。
在 Point.ByCoordinates 節點上,透過將交織從「最短清單」變更為「笛卡兒積」,我們建立點的格線。sphereByZ 函數仍完全有效,因此所有點會建立半徑以 Z 值為基礎的圓球。
為了進行測試,我們將原始數字清單插入 Point.ByCoordinates 的 X 輸入。我們現在有一個立方塊的圓球。
注意:如果在您的電腦上需要花很長時間執行此計算,請嘗試將 #10 變更為諸如 #5 等數字。
請記住,我們建立的 sphereByZ 函數是一般函數,因此可以回顧先前課程中的螺旋線,並對其套用函數。
最後一步:運用使用者定義的參數驅動半徑比。若要執行,我們需要為函數建立新輸入,並使用參數取代除數 20。
將 sphereByZ 定義更新為:
在輸入
sphereByZ(Pt,ratio);
中加入 ratio 變數以更新子系 Code Block。將滑棒插入新建立的 Code Block 輸入,並根據半徑比變更半徑的大小。
您可能發現 Dynamo 中節點名稱有一個常見現象:每個節點都使用 . 語法而不含空格。這是因為每個節點頂部的文字都表示指令碼撰寫的實際語法,而 . (或 點標記法 ) 將元素與我們可能呼叫的方法分開。這樣可以從視覺指令碼輕鬆轉換為文字型指令碼。
如果將點標記法做一般的類比,在 Dynamo 中如何處理一個參數式蘋果呢?以下是我們在決定吃蘋果之前先對蘋果執行的一些方法。(注意:這些方法不是實際的 Dynamo 方法)。
蘋果的顏色是什麼?
Apple.color
紅色
蘋果成熟了嗎?
Apple.isRipe
true
蘋果有多重?
Apple.weight
6 盎司。
蘋果來自何處?
Apple.parent
樹
蘋果建立哪些項目?
Apple.children
種子
這個蘋果是本地生長的嗎?
Apple.distanceFromOrchard
60 英里。
我不知道您覺得如何,但根據以上表格的輸出來判斷,這似乎是一個美味的蘋果。我認為我會執行 Apple.eat()。
記住蘋果的類比,我們來看看 Point.ByCoordinates,並示範如何使用程式碼區塊建立一個點。
在 Dynamo 中,程式碼區塊 語法 Point.ByCoordinates(0,10);
產生的結果與 Point.ByCoordinates 節點相同,只是我們可以使用一個節點來建立點。比起將不同節點連接至 X 與 Y,此方法更有效率。
在程式碼區塊中使用 Point.ByCoordinates,我們就是以內建節點 (X,Y) 的順序指定輸入。
您可以透過 Code Block 呼叫資源庫中的任何一般節點,只要該節點不是特殊的 「使用者介面」節點 (具有特殊的使用者介面功能) 即可。例如,您可以呼叫 Circle.ByCenterPointRadius,但是呼叫 Watch 3D 節點意義不大。
一般節點 (資源庫中的大多數節點) 通常分為三種類型。您會發現資源庫在組織時也考慮到了這些品類。在 Code Block 中呼叫時,對這三種類型方法 (或節點) 的處理方式不同。
建立 - 建立 (或建構) 項目
動作 - 對某項目執行動作
查詢 - 取得既有項目的性質
「建立」品類將從零開始建構幾何圖形。我們在程式碼區塊中以從左至右的順序輸入值。這些輸入的順序與節點中從上到下的輸入順序相同。
將 Line.ByStartPointEndPoint 節點與程式碼區塊中對應的語法做比較,可以獲得相同結果。
動作是您對該類型的物件執行的行為。Dynamo 使用許多程式語言中通用的 點標記法 對物件套用動作。確定物件後,輸入點,後接動作名稱。動作類型方法的輸入將放置在括號中,類似於建立類型的方法,只是您不必指定對應節點上看到的第一個輸入。我們改為指定執行動作時所依據的元素:
Point.Add 節點是動作類型節點,因此語法稍有不同。
輸入是 (1) point 以及要加上去的 (2) vector。在 Code Block 中,我們已將點 (物件) 命名為 pt。為了將命名為 vec 的向量加入 pt,我們會編寫 pt.Add(vec) 或採用「物件, 點, 動作」的格式。加入動作僅有一個輸入,也就是 Point.Add 節點的所有輸入減去第一個輸入。Point.Add 節點的第一個輸入是點本身。
查詢類型的方法會取得物件的性質。由於物件本身就是輸入,因此您不必指定任何輸入。不需要使用括號。
節點的交織與程式碼區塊的交織稍有不同。如果是節點,使用者會在節點上按一下右鍵,然後選取要執行的交織選項。如果是程式碼區塊,使用者對於資料的建構方式會有更多的控制。程式碼區塊速寫方法使用 複製指南 設定幾個一維清單應採用的配對方式。角括號 <> 中的數字定義所產生巢狀清單的階層:<1>、<2>、<3> 等。
在此範例中,我們使用速寫來定義兩個範圍 (本章的下一節將講述速寫的更多內容)。簡單來說,
0..1;
相當於{0,1}
,-3..-7
相當於{-3,-4,-5,-6,-7}
。結果將產生包含 2 個 x 值與 5 個 y 值的清單。如果我們不對這些不相符的清單使用複製指南,則會得到包含兩個點的清單,這是長度最短的清單。使用複製指南,我們可以找出 2 個座標與 5 個座標所有可能的組合 (即笛卡兒積)。使用語法 Point.ByCoordinates
(x_vals<1>,y_vals<2>);
,可以得到 兩個 清單,每個清單有 五個 項目。使用語法 Point.ByCoordinates
(x_vals<2>,y_vals<1>);
,可以得到 五個 清單,每個清單有 兩個 項目。
使用此標記法,我們也可以指定哪個清單佔優勢:2 個清單 (各包含 5 個項目) 還是 5 個清單 (各包含 2 個項目)。在此範例中,若變更複製指南的順序,結果將在格線中產生一列點清單或一欄點清單。
以上程式碼區塊方法可能花一點時間才能習慣,而 Dynamo 中提供稱為「要編碼的節點」功能,可以讓程序更輕鬆。若要使用此功能,請在 Dynamo 圖表中選取一系列節點,在圖元區上按一下右鍵,然後選取「要編碼的節點」。Dynamo 會將這些節點及所有輸入與輸出濃縮到一個程式碼區塊中!這不僅是一個強大的工具可學習程式碼區塊,也能讓您處理更高效的參數式 Dynamo 圖表。我們將使用「要編碼的節點」結束以下練習,因此請勿錯過。
按一下下方的連結下載範例檔案。
附錄中提供完整的範例檔案清單。
為了展示程式碼區塊的強大功能,我們要將既有的牽引欄位定義轉換為程式碼區塊形式。使用既有定義可示範程式碼區塊與視覺指令碼如何具有相關性,有助於學習 DesignScript 語法。
先重新建立以上影像中的定義 (或開啟範例檔案)。
請注意,Point.ByCoordinates 的交織已設定為 「笛卡兒積」。
格線中的每個點都會根據其與參考點的距離而沿著 Z 方向上移。
重新建立並增厚曲面,同時在幾何圖形上建立相對於距參考點距離的凸度。
從頭開始,我們先定義參考點:Point.ByCoordinates
(x,y,0);
我們使用的 Point.ByCoordinates 語法與參考點節點上方指定的語法相同。將變數 x 與 y 插入 Code Block,以便我們可以使用滑棒動態更新這些內容。
在 Code Block 的輸入加入一些 滑棒,範圍從 -50 到 50。這樣我們可以跨越整個預設 Dynamo 格線。
在 Code Block 的第二行,我們定義速寫以取代數字序列節點:
coordsXY = (-50..50..#11);
我們將在下一節詳細討論此內容。現在,請注意此速寫相當於視覺指令碼中的 Number Sequence 節點。
現在,我們將從 coordsXY 序列建立點的格線。為了執行此作業,我們要使用 Point.ByCoordinates 語法,但還需要使用我們在視覺指令碼中採用的方式,創造一個清單的 笛卡兒積。為了執行此作業,我們鍵入行:
gridPts = Point.ByCoordinates(coordsXY<1>,coordsXY<2>,0);
角括號表示笛卡兒積參考。請注意,在 Watch3D 節點中,我們有一個橫越 Dynamo 格線的點格線。
現在講解困難的部分:我們希望根據點距參考點的距離,將這些點的格線上移。首先,我們呼叫這一組新點 transPts。由於平移是針對既有元素的動作,因此我們不用
Geometry.Translate...
,而是使用gridPts.Translate
從圖元區上的實際節點,我們可以看到有三個輸入。要平移的 geometry 已經宣告,因為我們正對該元素執行動作 (使用 gridPts.Translate)。其餘兩個輸入將插入函數 direction 與 distance 的括號內。
direction 很簡單,我們使用
Vector.ZAxis()
垂直移動。參考點與每個格線點之間的距離仍需要計算,因此我們使用相同方式對參考點執行此動作:
refPt.DistanceTo(gridPts)
程式碼的最後一行得出平移後的點:
transPts=gridPts.Translate(Vector.ZAxis(),refPt.DistanceTo(gridPts));
我們現在已經有資料結構適當的點格線,可以建立 Nurbs 曲面。我們使用
srf = NurbsSurface.ByControlPoints(transPts);
建構曲面
最後,為了對取面增加一些深度,我們使用
solid = srf.Thicken(5);
建構實體。在此案例中,我們在程式碼中將曲面變厚了 5 個單位,不過也可以將其宣告為變數 (例如將其稱為 thickness),然後使用滑棒控制該值。
只需按一下按鈕,「要編碼的節點」功能即可自動執行我們剛剛完成的整個練習。這不僅在建立自訂定義及可重複使用的程式碼區塊時很有威力,也是瞭解如何在 Dynamo 中編寫指令碼非常有用的工具。
先使用練習的步驟 1 中使用的既有視覺指令碼。選取所有節點,在圖元區上按一下右鍵,然後選取 「要編碼的節點」。非常簡單。
Dynamo 已自動建立文字版本的視覺圖表、交織與全部項目。在您的視覺指令碼上試試看,體驗程式碼區塊的強大功能!