Script SOPでたくさん線を描く


SOPで線を描きたい!

oFやProcessingのDrawLineのようにTouchDesignerでも線を書きたいと思ったのですが、シェーダーを使わずに実現する情報がありませんでした。内容的には薄いですが記録に残しておきます。

どのように実装する?

結論としては、Script SOPでscriptOp.appendPoly(n,closed=False),n>2です。

一旦結論は忘れてもらって、どうやったら線をいっぱいかけるのでしょう。
1. まずCopy SOPやLeplicator+Merge SOPなどを思いつきます。Line SOPをReplicatorなどで複製して始点と終点を調整して...一番簡単ですが、スケールしなさそうですね。
2. 次に思いつくのがinstancingです。デフォルトのLine SOPは(0,0,0),(1,0,0)を結ぶ線になっているので、ExecuteなどでPythonを書き、線を引きたい二点と原点を結ぶベクトルについての回転行列からオイラー角を求めた上で始点まで移動させてあげれば完璧...のはずなのですが計算が合わない...断念。この方法だとToyoshi MoriokaさんのPixel Stormなどと連携させれば高速に描画できるなぁと思っていたのですが。またチャレンジします。
3. さて、本題はここからです。Script SOPポリゴンかけるなら線もかけるのでは?

まずポリゴンを一つ描画してみます。

script1_callbacks
def onSetupParameters(scriptOp):
    return

def onPulse(par):
    return

def onCook(scriptOp):
    scriptOp.clear()

    p0=scriptOp.appendPoint()
    p0.x=-1
    p0.y=0
    p0.z=0
    p1=scriptOp.appendPoint()
    p1.x=1
    p1.y=0
    p1.z=0
    p2=scriptOp.appendPoint()
    p2.x=0
    p2.y=1
    p2.z=0

    poly=scriptOp.appendPoly(3,closed=True,addPoints=False)
    poly[0].point=scriptOp.points[0]
    poly[1].point=scriptOp.points[1]
    poly[2].point=scriptOp.points[2]
    return


できました。
次に、(-1,0,0)と(1,0,0)を結ぶ線を描こうとします。
そこで、poly=scriptOp.appendPoly以降を以下のように変更します。

script1_callbacks
poly=scriptOp.appendPoly(2,closed=True,addPoints=False)
    poly[0].point=scriptOp.points[0]
    poly[1].point=scriptOp.points[1]
    # poly[2].point=scriptOp.points[2]
    return


何も描画されない

ここでappendPolyメソッドの引数であるclosedに注目します。確かに線だとポリゴンといってもそもそも閉じてない...closed=Falsenにしてみます。

script1_callbacks
poly=scriptOp.appendPoly(2,closed=False,addPoints=False)
    poly[0].point=scriptOp.points[0]
    poly[1].point=scriptOp.points[1]
    # poly[2].point=scriptOp.points[2]
    return


なんか線が出てきた!

ということは、ポイントに対してappendPoly(n, closed=False)さえしてあげれば、いくらでも点がかけることがわかります。以下のように数はいくつになっても大丈夫です。

script1_callbacks
import random
def onSetupParameters(scriptOp):
    return

def onPulse(par):
    return

def onCook(scriptOp):
    scriptOp.clear()

    n=10
    poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
    for i in range(n):
        p=poly[i].point
        p.x=random.random()
        p.y=random.random()
        p.z=random.random()
    return

さらに、一つのScript SOP内で複数の線(ポリゴン?)に分けて描くこともできます。

script1_callbacks
import random
def onSetupParameters(scriptOp):
    return

def onPulse(par):
    return

def onCook(scriptOp):
    scriptOp.clear()

    n=3
    poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
    for i in range(n):
        p=poly[i].point
        p.x=random.random()
        p.y=random.random()
        p.z=random.random()

    n=3
    poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
    for i in range(n):
        p=poly[i].point
        p.x=random.random()
        p.y=random.random()
        p.z=random.random()
    return

かけました! 以上です。
もっと良い方法がありましたらコメント頂けると幸いです。よろしくお願いします。