2008年11月9日日曜日

blender - プレビュー&OSA付きレンダ可能なエッジ生成スクリプト

簡単に言うと、大神のエッジを少ししょぼくしたもの。

追記
*注意:レンダ結果が非常にヘボイため、プレビュー画面でエッジが必要で、レンダ結果はどうでもいいという人専用。
(そんな人は俺以外いない気がするが・・・・)

プレビュー



OSA付きレンダ


標準のEdgeでは実現不可能な、OSA(FSA)x16 + FullSampling も可能
(OutputのSaveBuffersをONにするとFullSamplingが出て来て、それを押すとOSAがFSAに変る。ただし、めちゃくちゃ遅い)


ちなみにモデリング画面


使い方
0.危険なスクリプトなので、必ずバックアップ!!
1.オブジェクトモードで下記スクリプトを実行
2.エッジ用メッシュを選択し、マテリアルノードを以下のように追加
 (*エッジ用メッシュは e__ではじまる名前になっている)
3.Textureモードで黒くなって見えないメッシュがあれば、エッジ用メッシュを選択してエディットモードで法線裏返すか、エッジが要らない部分であれば消去する
  
removeOnlyを1にして実行すると、以前生成されたエッジ用オブジェクトを消去できるけど、マテリアルとかまで管理してないです。




import Blender
from Blender import *

import types

EDGE_PREFIX = 'e__'
EDGE_SIZE = 0.02
EDGE_COLOR = [0.0, 0.0, 0.0]

# return targetObjects and delete preEdgeObjects
def getAllTargets(root, res_targets, sce):
for obj in root.getChildren():
if type(obj) is types.ListType:
res_targets.append(getAllTargets(obj, res_targets))
if obj == None:
continue
if type(obj.getData()) != Types.NMeshType:
continue
name = obj.getName()
if name[0:len(EDGE_PREFIX)] == EDGE_PREFIX:
sce.objects.unlink(obj)
continue

res_targets.append(obj)


def copyForEdge(sce, removeOnly):
global EDGE_PREFIX, EDGE_SIZE, EDGE_COLOR

# get target objects
targetObjects = []
getAllTargets(sce, targetObjects, sce)

if removeOnly == 1:
return

# unselect all
sce.objects.selected = []

# make material
edgeMat = Material.New(EDGE_PREFIX + 'edgeCol')
edgeMat.setRGBCol(EDGE_COLOR)
MODES = Material.Modes
mode = MODES.ZTRANSP | MODES.SHADELESS
edgeMat.setMode(mode)

# duplicate for edge
for obj in targetObjects:
obj.sel = 1

Blender.Object.Duplicate(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
edgeObj = sce.objects.active
edgeName = EDGE_PREFIX + edgeObj.getName()
edgeObj.setName(edgeName)

# apply size and filp normals
size = edgeObj.getSize()
#edgeObj.setSize(size[0]+EDGE_SIZE, size[1]+EDGE_SIZE, size[2]+EDGE_SIZE)
mesh = edgeObj.getData(0, 1)
for v in mesh.verts:
vec = Mathutils.Vector(v.no[0], v.no[1], v.no[2])
vec.normalize()
v.co[0] = v.co[0] + vec.x * EDGE_SIZE
v.co[1] = v.co[1] + vec.y * EDGE_SIZE
v.co[2] = v.co[2] + vec.z * EDGE_SIZE

mesh.mode = Mesh.Modes.NOVNORMALSFLIP
mesh.flipNormals()

uvs = mesh.getUVLayerNames()
cols = mesh.getColorLayerNames()
for uv in uvs:
mesh.removeUVLayer(uv)
for col in cols:
mesh.removeColorLayer(col)

mesh.materials = [edgeMat]
for f in mesh.faces:
f.mat = 0

mesh.update()

edgeObj.sel = 0
obj.sel = 0

# excute
print 'start'
removeOnly = 0
copyForEdge(Blender.Scene.GetCurrent(), removeOnly)
print 'end'



さて、これを更に、マテリアルノードでpyNodeとして使えるように改造できると(できるのか?)ZやViewVectorが使えそうな気がする。

0 件のコメント: