はじめに
この記事は下記の記事の続編のため、もしこれを見ながら挑戦する人は下記の記事を見ることをおすすめします。
前回に引き続きSverchokに予め用意されている Circle を使わずに基本的なノードがどのように相互作用するかを理解するために手動でCircleを作る
参照元
これはSverchok のレッスンの第二部
動的なポリゴン(原文の翻訳)
平面を形成するポリゴンを作るためには頂点をリンクする必要があり、現状では手動で行っています。(原文にはこのように書いてあるが、このブログではFormula による手入力でのリスト作成方法は使えなかった為UVConnectionを使っている)。4つより多くの頂点を扱う必要がある場合、そのリストの作成を自動化したいと思うでしょう。そして頂点の数が変更されたら動的に新しいセグメントが追加されるように作りたいと思うのではないでしょうか?
これは一般的なタスクですので、UV Connectという専用のノードがありますが、より基本を学ぶ為にそれを使うことは避けます。
これらのものを自分で構築する方法を学ぶことはノードでビジュアルプログラミングを学ぶための最良の方法です。
このレッスンは下記の状態から始める
ポリゴンのインデックスリストの生成
リストを自動生成するには、頂点がいくつあるかを知る必要があります。
Add -> List Main -> List Length
List Length ノードは入力リストデータの長さを返します。どのレベルのデータの長さがほしいかを設定する事もできます。
- Vector in の出力を List Length の入力に接続する
- List Length の出力を Stethoscope の入力に接続する
- Stethoscope が値を出力している事がわかる
- Stethoscope が値を出力している事がわかる
データ長は4です。nを最後の頂点とした時[0, 1, 2, ...n]
のようなリストがほしくなります。Pythonで書く場合はこのように書くでしょう。
n = 4 range(start = 0, end=n, step=1) >>[0,1,2,...n]
ポリゴンのためのインデックスリストを生成するためには、整数の順数列が必要です。Sverchokにはそのようなノードがあり、そのノードはStart、StepとCountをパラメータとして受け付けます。
これは Number Range(step mode)と言われるものです。
↓↓↓公式ページのレッスンの通りに手順を記載するが、この方法では正しく動作しない
Add -> Number -> Number Range
- Number Range を配置し、int、step mode にする
- start が0で、step が1で有ることを確認
- List Length の出力をNumber Range の count へ接続
- UV ConnectionノードをViewer Draw Mk3 のedges から抜く
- Number Range の出力を Viewer Draw Mk3 のedgesへ接続
- 任意で Stethoscopeを配置しNumber Range の出力を接続して出力内容を確認する
画像を確認すると3D viewport には何も表示されておらず、Number Rangeの出力は[[0,1,2,3]]
となっており2次元配列となっている。
これに対しUV Connectionの出力は、[[(0, 1, 2, 3)]]
となっており、3次元配列になっている。おそらくこの次元の違いにより動作していない。
しかしここでの目的であったNumber Rangeを使ったリストの作成方法は理解できたため、UV Connectionを使って回避する。
↑↑↑ここまで
回避策
円形頂点の生成
すでにある4つの頂点は既に円形のパスを持っている。なので少し変更するだけで円が表示できる。
- 右端の Number Rangeを Range モードにする
- start 0.00 、stop 2.00、step 0.2 にする
2.0 / 0.2 = 10
これが意味するのは Number Range が今出力するのが[0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8]
という事です。最後が 2.0でない事に注意してください。このモードは最終値を除きます。(非包括的という)
円が見えてきたでしょう。
頂点の均等な広がりを強制
上記の例では 0.2 のステップにしていました。この距離は手動で設定しますがこのステップ値の計算はすぐに面倒になります。この計算を行ってくれるノードを追加しましょう。
どうすればよいか考えてみてください。
私は 1 / number_vertices
みたいなノードがほしいです。このためには Math ノードと頂点数を表すA Number ノードが必要となります。
Add -> Numbers -> Scalar Math
Add -> Numbers -> A Number
- Scalar Mathノードのモードを / (division) にして分子に2.0を設定
- A Number ノードの出力を Scalar Mathノードの下へ接続
- A Number ノードの整数値を調整する。例えば14に設定
- Scalar Mathノードの出力を右端のNumber RangeのStepへ接続
ノードが混雑し始めたので最小化する
ノードは小さくできます。この機能は Hide と呼ばれ、任意のノードを選択して H または矢印をクリックします。
ポリゴンは簡単、辺はどうでしょう??
頂点から要求された辺のインデックスリストを作るノードがあることを思い出してください。しかし、Sverchokのモジュール機能を探索する事が目的の為、独自の辺作成機能を作りましょう。
辺のイデックスリストは[[0,1],[1,2],[2,3],[3,0]]
のような形をしています。可変数の頂点であればこのようになるでしょう[[0,1],[1,2],...,[n-1,n],[n,0]]
。ただリストの開始部分と終了部分を示しただけという事に注意してください。
Pythonであればループやリスト内包表記を使ってこのように表現できるでしょう
# for loop n = 5 for i in range(n): print(i, (i+1) % n) >> 0 1 >> 1 2 >> 2 3 >> 3 4 >> 4 0 # list comprehension n = 5 edges = [[i, (i+1) % n] for i in range(n)] print(edges) >> [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]]
Sverchok における最後の結果は同じですが、方法は異なります。
最後の辺を除いてそれぞれの辺の2番目のインデックスは最初のインデックス+1です。最後の辺はエッジのリングを閉じ、最初の頂点に戻ります。本質的にこれはラップアラウンドです。またはこれを2つのリストと捉える事もできるでしょう。一つはもう一つによって1つづつシフトされます。
SverchokにはList shiftというノードがあります。List zipで2つのリストを一緒に Zipします。
add -> List -> List Struct -> List Shift
add -> List -> List Main -> List Zip
- Number Range の出力を List zipの最初のソケットに接続
- Number Range の出力を List shift の最初のソケットに接続
- ラップアラウンドを作るため、List shiftの levelを1にし、shiftは-1にする
- List shift の出力を List zipの2番目に接続
- List zip の出力をStethoscope Mk2に接続し出力値を確認する
- List zip の出力をViewer Draw Mk3のedgesに接続
補足
Viewer Draw に一つ以上の頂点とポリゴンを渡すと自動的に辺が作られる。つまり実査にはオブジェクトのポリゴンがすでにある場合、辺は渡す必要はありません。それらはポリゴンのインデックスから純粋に推測されます。
最後に
List zipとList shiftなるものが登場した。個人的にはとても勉強になった。