<< 辞書と正規化 戻る UV座標のリストを表示する >>

頂点法線 vertex normalを求める

PointsPolygonを求めたいので、各頂点の法線ベクトルを順に辞書に格納していき、空でなければ、加えていくようにしました。
最後に正規化をかけて、できあがり。グローシェーディングの求め方です。本来ならば、外積など関連するものはモジュール化してしまえばよいのですが、まだまだ修行がたりません。
出力したものをエディタ使ってRIBにしてみたら、面が表示されず、頂点indexの順番をreverse()したら、表示されました。理屈で攻めていかなければならないところですが、泥臭いところです。法線を求められたのは、ちょっとうれしいです。佐藤義雄先生の「実習グラフィックス」、メタセコイアマスターガイドを参考にしました。後、LilyEightのアプリBも参考になりました。PolygonからPointsPolygonにするRIB to RIBがあります。
先駆者の資料は役立ちます。
metasequoia python interfaceの中にホントはもっと簡単に求められる方法があるのかもしれません。
まだまだ自己満足なところですが、レンダリング結果はこんな感じでした。
catmull.jpg

サンプルスクリプトです。もう一歩前にすすみたいところです。ありがとうございます。

#norm03.py
import math
doc=MQSystem.getDocument()
out=MQSystem.println

def normalize(x,y,z):
s=math.sqrt(x*x+y*y+z*z)
if s==0.0:s=1
else: s=1.0/s
return x*s,y*s,z*s

def add(a,b):
return [ a[i]+b[i] for i in range(len(a)) ]

obj=doc.object[doc.currentObjectIndex]
out(str(obj.name))

count=obj.numFace
out("面の数:"+str(count))

v=[]
f=[]
for i in range(0,count):
v.append(obj.face[i].numVertex)

for j in range(0,obj.face[i].numVertex):
f.append(obj.face[i].index[j])


v.reverse()
f.reverse()

out(str(list(v)))
out(str(list(f)))


ten=[]
c={}
for k in range(0,obj.numVertex):
out(str(obj.vertex[k].pos.x)+", "+str(obj.vertex[k].pos.y)+", "+str(obj.vertex[k].pos.z))
ten.append((obj.vertex[k].pos.x,obj.vertex[k].pos.y,obj.vertex[k].pos.z))
c[k]=[]


for i in range(0,count):
#out("面のindex:"+str(obj.getFaceIndexFromUniqueID(i+1)))
#out("頂点数"+str(str(obj.face[i].numVertex)))

#out(str(faceid))
for j in range(0,obj.face[i].numVertex):
#out(str(obj.face[i].index[j])+":"+str(ten[obj.face[i].index[j]]))
x1=ten[obj.face[i].index[j-1]][0]
y1=ten[obj.face[i].index[j-1]][1]
z1=ten[obj.face[i].index[j-1]][2]
x2=ten[obj.face[i].index[j]][0]
y2=ten[obj.face[i].index[j]][1]
z2=ten[obj.face[i].index[j]][2]
#out("j+1 "+str(j+1))
if j+1==obj.face[i].numVertex:
x3=ten[obj.face[i].index[0]][0]
y3=ten[obj.face[i].index[0]][1]
z3=ten[obj.face[i].index[0]][2]
else:
x3=ten[obj.face[i].index[j+1]][0]
y3=ten[obj.face[i].index[j+1]][1]
z3=ten[obj.face[i].index[j+1]][2]
nx=(y2-y1)*(z3-z2)-(z2-z1)*(y3-y2)
ny=(z2-z1)*(x3-x2)-(x2-x1)*(z3-z2)
nz=(x2-x1)*(y3-y2)-(y2-y1)*(x3-x2)
if c[obj.face[i].index[j]]==[]:
c[obj.face[i].index[j]]=[-1*nx,-1*ny,-1*nz]
else:
c[obj.face[i].index[j]]=add(c[obj.face[i].index[j]],[-1*nx,-1*ny,-1*nz])
#out(str(c[obj.face[i].index[j]]))
#out(str(normalize(*c[obj.face[i].index[j]])))


for k in range(0,obj.numVertex):
out(str(k)+":"+str(normalize(*c[k])))


  • -
  • -

<< 辞書と正規化 戻る UV座標のリストを表示する >>