2008年5月8日木曜日

blender - PythonのNode実験(1)

単純にノードの移植に使うのも芸が無いと思って、こんなクソコードを書いてみた。
(マテリアルノード用)


import Blender
from Blender import Node

outline = (1.0, 0.0, 0.0, 1.0);

class MOutline(Node.Scripted):
def __init__(self, sockets):
color = Node.Socket('color', val = [1.0, 1.0, 1.0, 1.0])
sockets.i = [color]
sockets.o = [color]

# xmin, xmax = { y : x, ... }
# ymin, ymax = { x : y, ... }
self.xmin = {}
self.xmax = {}
self.ymin = {}
self.ymax = {}

def __call__(self):
ocol = self.i['color']

x = self.shi.pixel[0]
y = self.shi.pixel[1]

if y in self.xmin:
if x < self.xmin[y]:
self.xmin[y] = x
if x == self.xmin[y]:
ocol = outline
else:
self.xmin[y] = x

if y in self.xmax:
if x > self.xmax[y]:
self.xmax[y] = x
if x == self.xmax[y]:
ocol = outline
else:
self.xmax[y] = x

if x in self.ymin:
if y < self.ymin[x]:
self.ymin[x] = y
if y == self.ymin[x]:
ocol = outline
else:
self.ymin[x] = y

if x in self.ymax:
if y > self.ymax[x]:
self.ymax[x] = y
if y == self.ymax[x]:
ocol = outline
else:
self.ymax[x] = y

self.o['color'] = ocol

__node__ = MOutline


これは何かというと、1ピクセルのエッジをマテリアルノードで出したかったので、
1ピクセル毎に渡されてくる座標をマップ(辞書)に保存しておいて、
とりあえずxとyが最小最大になるピクセルの色を変えてみた、というコード。Pythonは興味なくて、いつもクソコードばかり書いてすいません。
しかもこの方法は、凹型だと間に線が出ないので、全く実用的では無いんですが、テストということで。(本気でやるなら、凸包のアルゴリズムを使用するのと、下記のプレビューで使用されてる問題を何とかしないといけない。それかpixel以外の入力を使って何とかするか…)


最初のcallで保存しておいて、2回目のcallで色を変えることを前提にしてます。
今までのノードでは、こんな使い方は出来ないんですが、__node__はグローバル領域に置いてあり、
updateのタイミングでしか再生成されないっぽい?と感じ、やってみました。

結果はこちら



やはり予想通りupdateのタイミングでしか再生成されないようです。よって、1度目のレンダリングでは真っ赤になりましたが、2度目のレンダリングでこの通り、1ピクセルのエッジが出ました。ただし、この__node__は、マテリアルパネルのプレビューや、NodeEditorのプレビューにも使われているので、その分余計な座標も保存されるので、使えないかなぁー


しかし、今回の実験で、かなりの可能性を秘めていることが分かったと思います。
まぁ、こんなクソコードよりも、ここにある素晴らしいサンプルが参考になります。

もうこれは、Nodeというかシェーダープログラミングに近いですねー。

0 件のコメント: