シンプルなモデリングツール 2 にTimeノードを追加して、アニメーションデータを作成できるようにしてみます。
以下のスクリプトでは、Timeノードの追加以外に以下の変更を加えています。
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, fn): if self.saveobjs == None: return self.saveobjs(self.objs, fn) 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 Observer(object): def __init__(self): self.observer = {} def append(self, src, node, dest): if self.observer.has_key(src): self.observer[src].append([node, dest]) else: self.observer[src] = [[node, dest]] def get(self, src): if self.observer.has_key(src): return self.observer[src] return {} def delete(self, src, node, dest): if not self.observer.has_key(src): return nlist = [] for nd in self.observer[src]: if node is nd[0] and src is nd[1]: continue nlist.append(nd) self.observer[src] = nlist class Nodebase(object): def __init__(self, attr={}): self.attr = attr self.observer = Observer() def update(self, node, src, dest): if node != self: self.setAttr(dest, node.getAttr(src)) self.compute() def notify_observers(self, src): for obs in self.observer.get(src): obs[0].update(self, src, obs[1]) def compute(self): pass def attributeAffects(self, src, dest): self.connectAttr(src, self, dest) def connectAttr(self, src, node, dest): self.observer.append(src, node, dest) self.notify_observers(src) def getAttr(self, aname): return copy.deepcopy(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} Nodebase.__init__(self, 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} Nodebase.__init__(self, attr) self.attributeAffects('num', 'out') self.attributeAffects('mx', 'out') self.attributeAffects('my', 'out') self.attributeAffects('in', 'out') def compute(self): tp = self.getAttr('in') if(tp == None): return f = tp.p[0] num = self.getAttr('num') f[num].x += self.getAttr('mx') f[num].y += self.getAttr('my') self.setAttr('out', tp) self.notify_observers('out') class Shape(Nodebase): objset = None def __init__(self): if self.objset: self.objset.setObj(self) attr = {'in': None, 'out': None} Nodebase.__init__(self, attr) self.attributeAffects('in', 'out') def compute(self): tp = self.getAttr('in') self.setAttr('out', tp) self.notify_observers('out') class Time(Nodebase): def __init__(self): attr = {'outTime': 0} Nodebase.__init__(self, attr) def saveAllObjs(objs, fn): fp = open(fn, 'w') n = 0 for o in objs: fp.write('g tri' + str(n) + '\n') fs = o.getAttr('out') for p in fs.p: fp.write('vn 0 1 0\n') fp.write('v ' + str(p[0].x) + ' 0 ' + str(p[0].y) + '\n') fp.write('v ' + str(p[1].x) + ' 0 ' + str(p[1].y) + '\n') fp.write('v ' + str(p[2].x) + ' 0 ' + str(p[2].y) + '\n') face = 'f ' for i in range(1, 4): face += str(3*n+i) + '//' + str(n+1) + ' ' face += '\n' fp.write(face) n += 1 fp.close() Shape.objset = ObjectSet(saveAllObjs) time1 = Time() def saveAnimData(s, e, fn): for f in range(s, e+1): time1.setAttr('outTime', f) Shape.objset.save(fn + str(f) + '.obj') execfile(sys.argv[1])
m1 = MakeTriPoly() mv1 = MoveTriPoly(0) m1.connectAttr('out', mv1, 'in') mv2 = MoveTriPoly(1) mv1.connectAttr('out', mv2, 'in') mv3 = MoveTriPoly(2) mv2.connectAttr('out', mv3, 'in') s1 = Shape() mv3.connectAttr('out', s1, 'in') time1.connectAttr('outTime', mv1, 'mx') time1.connectAttr('outTime', mv2, 'mx') time1.connectAttr('outTime', mv3, 'mx') saveAnimData(1, 3, "tmp")
後からnmaya4.py にノードを追加したいときは、Nodebaseを親クラスとするクラスを作成し、必要なメソッドを上書きします。
m1 = MakeTriPoly() mv1 = MoveTriPoly(0) m1.connectAttr('out', mv1, 'in') mv2 = MoveTriPoly(1) mv1.connectAttr('out', mv2, 'in') mv3 = MoveTriPoly(2) mv2.connectAttr('out', mv3, 'in') s1 = Shape() mv3.connectAttr('out', s1, 'in') mul1 = Multi(0.1) time1.connectAttr('outTime', mul1, 'input') mul1.connectAttr('output', mv1, 'mx') mul1.connectAttr('output', mv2, 'mx') mul1.connectAttr('output', mv3, 'mx') saveAnimData(1, 3, "tmp")(実行方法)
startframe = 1 endframe = 10 m1 = MakeTriPoly() mv1 = MoveTriPoly(0) m1.connectAttr('out', mv1, 'in') mv2 = MoveTriPoly(1) mv1.connectAttr('out', mv2, 'in') mv3 = MoveTriPoly(2) mv2.connectAttr('out', mv3, 'in') s1 = Shape() mv3.connectAttr('out', s1, 'in') mul1 = Multi(0.6) time1.connectAttr('outTime', mul1, 'input') mul1.connectAttr('output', mv1, 'my') mul1.connectAttr('output', mv2, 'my') mul1.connectAttr('output', mv3, 'my') e1 = Expression() e1.setAttr('expression', 'self.output = (3.0*math.sin((2*math.pi)*self.input/float(' + str(endframe) + ')) + 1.0)/2.0') time1.connectAttr('outTime', e1, 'input') e1.connectAttr('output', mv1, 'mx') e1.connectAttr('output', mv2, 'mx') e1.connectAttr('output', mv3, 'mx') saveAnimData(startframe, endframe, "expression")(実行方法)
import pymel.core as pm for i in range(1,11): pm.importFile("OBJデータのあるフォルダ名"+str(i)+".obj")