上のnmaya2.pyから、アトリビュートをいくつでも追加できるように改良してみます。
作成できるノードの種類と、アトリビュートは以下の通りです。
import sys
import copy
class ObjectSet(object):
def __init__(self, sobjs=None):
self.objs = []
self.saveobjs = sobjs
def setObj(self, obj):
self.objs.append(obj)
def save(self):
if not self.saveobjs:
return
self.saveobjs(self.objs)
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
class TriPoly(object):
def __init__(self, p1, p2, p3):
self.p = [[p1, p2, p3]]
class Nodebase(object):
def __init__(self, attr={}):
self.attr = copy.copy(attr)
self.observer = {}
def _update(self, node, src, dest):
self.setAttr(dest, node.getAttr(src))
self._compute()
def _notify_observers(self, src):
if self.observer.has_key(src):
node, dest = self.observer[src]
node._update(self, src, dest)
def _compute(self):
pass
def connectAttr(self, src, node, dest):
self.observer[src] = [node, dest]
self._notify_observers(src)
def getAttr(self, aname):
return self.attr[aname]
def setAttr(self, aname, val):
self.attr[aname] = val
self._notify_observers(aname)
def addAttr(self, aname, default=0.0):
self.attr[aname] = default
class MakeTriPoly(Nodebase):
def __init__(self):
tp = TriPoly(Point(0, 0), Point(0, 1), Point(1, 0))
attr = {'out': tp}
super(MakeTriPoly, self).__init__(attr)
class MoveTriPoly(Nodebase):
def __init__(self, n=0, x=0.0, y=0.0):
attr = {'in': None, 'out': None, 'num': n, 'mx': x, 'my': y}
super(MoveTriPoly, self).__init__(attr)
def _compute(self):
tp = self.getAttr('in')
f = tp.p[0]
num = self.getAttr('num')
f[num].x += self.getAttr('mx')
f[num].y += self.getAttr('my')
self.setAttr('out', tp)
class Shape(Nodebase):
objset = None
def __init__(self):
if self.objset:
self.objset.setObj(self)
attr = {'in': None, 'out': None}
super(Shape, self).__init__(attr)
def _compute(self):
tp = self.getAttr('in')
self.setAttr('out', tp)
def saveAllObjs(objs):
n = 0
for o in objs:
print 'g tri' + str(n)
fs = o.getAttr('out')
for p in fs.p:
print 'vn 0 1 0'
print 'v ',p[0].x, ' 0 ',p[0].y
print 'v ',p[1].x, ' 0 ',p[1].y
print 'v ',p[2].x, ' 0 ',p[2].y
print 'f ' + str(3*n+1) + '//' + str(n+1) + ' ' + str(3*n+2) + '//' + str(n+1) + ' ' + str(3*n+3) + '//' + str(n+1)
n += 1
Shape.objset = ObjectSet(saveAllObjs)
def save():
Shape.objset.save()
def quit():
sys.exit(0)
execfile(sys.argv[1])
for x in range(0, 10):
for y in range(0, 10):
m1 = MakeTriPoly()
mv1 = MoveTriPoly()
mv1.setAttr('num', 0)
mv1.setAttr('mx', x)
mv1.setAttr('my', y)
m1.connectAttr('out', mv1, 'in')
mv2 = MoveTriPoly()
mv2.setAttr('num', 1)
mv2.setAttr('mx', x)
mv2.setAttr('my', y)
mv1.connectAttr('out', mv2, 'in')
mv3 = MoveTriPoly()
mv3.setAttr('num', 2)
mv3.setAttr('mx', x)
mv3.setAttr('my', y)
mv2.connectAttr('out', mv3, 'in')
s1 = Shape()
mv3.connectAttr('out', s1, 'in')
m2 = MakeTriPoly()
mv4 = MoveTriPoly()
mv4.setAttr('num', 0)
mv4.setAttr('mx', x)
mv4.setAttr('my', y + 1)
m2.connectAttr('out', mv4, 'in')
mv5 = MoveTriPoly()
mv5.setAttr('num', 1)
mv5.setAttr('mx', x + 1)
mv5.setAttr('my', y)
mv4.connectAttr('out', mv5, 'in')
mv6 = MoveTriPoly()
mv6.setAttr('num', 2)
mv6.setAttr('mx', x)
mv6.setAttr('my', y)
mv5.connectAttr('out', mv6, 'in')
s2 = Shape()
mv6.connectAttr('out', s2, 'in')
save()
quit()
これらのサンプルスクリプトでは、以下のような問題点・改良点があります。
m1 = MakeTriPoly()
mv1 = MoveTriPoly(0, 1, 0)
mv1.setAttr('mx', 3)
m1.connectAttr('out', mv1, 'in')
s1 = Shape()
mv1.connectAttr('out', s1, 'in')
poly = mv1.getAttr('out')
print poly.p[0][0].x
mv1.setAttr('mx', 5)
poly = mv1.getAttr('out')
print poly.p[0][0].x