Skip to content

Instantly share code, notes, and snippets.

@valda
Created March 4, 2012 20:38
Show Gist options
  • Save valda/1974695 to your computer and use it in GitHub Desktop.
Save valda/1974695 to your computer and use it in GitHub Desktop.
2つの tri ファイル内の任意のモーフをコピーしたり合成したりするスクリプト 要 pyffi 2.1.11 くらい
# -*- coding: utf-8; mode: python -*-
#
# tri ファイル間でモーフをコピーしたり、任意の比率で混ぜあわせたりするスクリプ㌧
# 要 pyffi 2.1.11 くらい、Python 2.7.2 で動作確認
#
# 使い方:
# なにもオプションを指定しなければモーフのコピーのみを行います。
# モーフの指定は "ファイル名:モーフ名" です。出力ファイル名の規定値は out.tri です
# 例) python MergeMorph.py femaleheadchargen1.tri:EyesType28 femaleheadchargen2:EyesType28
# ファイル femaleheadchargen1.tri 内のモーフ EyesType28 を femaleheadchargen2:EyesType28 にコピーし、out.tri に出力
#
# -r(--rate) オプションでモーフ1の変形量を % で指定できます(100% を指定するとコピーと同義です)。-o(--outfile)で出力ファイル名を指定できます。
# 例) python MergeMorph.py -r 20 -o new_eyesfemalechargen.tri eyesfemalechargen.tri:EyesType2 eyesfemalechargen.tri:EyesType28
# ファイル eyesfemalechargen.tri:EyesType2 と eyesfemalechargen.tri:EyesType28 と 20:80 の割合で合成し、new_eyesfemalechargen.tri に出力
#
# --add オプションをつけると加算合成を行います、
# 例) python MergeMorph.py --add --r 30 -o tareme_eyesfemalechargen.tri rantweaked\eyesfemalechargen.tri:EyesBack eyesfemalechargen.tri:EyesType28
# ファイル rantweaked\eyesfemalechargen.tri 内のモーフ EyesBack を eyesfemalechargen.tri:EyesType28 へ 30% 加算し、tareme_eyesfemalechargen.tri に出力
#
import sys
import re
from optparse import OptionParser
from pyffi.formats.tri import TriFormat
parser = OptionParser(usage="usage: %prog [options] FILE1:morphname FILE2:morphname")
parser.add_option("--add", action="store_true", dest="addmode", help="Choose add mode.", default=False)
parser.add_option("-r", "--rate", action="store", type="int", dest="rate", help="Blend(add) rate. (default 100%)", default=100)
parser.add_option("-o", "--outfile", dest="outfile", help="Write output to FILE. (default out.tri)", default="out.tri", metavar="FILE")
(opts, args) = parser.parse_args(sys.argv)
if len(args) < 3:
parser.print_help()
exit()
if opts.rate > 100:
print('Rate was out of range, set to 100.')
opts.rate = 100
if opts.rate < 1:
print('Rate was out of range, set to 0.')
opts.rate = 1
def ParseFile(filename_with_morphname):
refile = re.compile('^(.*):([a-z0-9_]+)$',re.IGNORECASE)
m = refile.match(filename_with_morphname)
if m:
filename = m.group(1)
morphname = m.group(2)
else:
filename = args[1]
morphname = 'basis'
return (filename, morphname)
def ReadMorph(filename, morphname):
istrm = open(filename, 'rb')
data = TriFormat.Data()
data.inspect(istrm)
print("Reading file: %s" % (filename))
print("TRI version 0x%x, Num Vertices %d, Num Morphs %d" % (data.version, data.num_vertices, data.num_morphs))
data.read(istrm)
#print("Morphs: "+', '.join([str(morph.name.decode("ascii")) for morph in data.morphs]))
for morph in data.morphs:
if str(morph.name.decode("ascii")) == morphname:
return (data, morph)
# モーフが見つからない場合は新規追加
print("Morph name not found: %s, create new morph." % (morphname))
morph = data.add_morph(morphname, [[0.0]*3]*data.num_vertices)
morph.name = morphname # add_morph で name が設定されないのは bug?
return (data,morph)
# FILE1 のモーフを読み込み
(filename1, morphname1) = ParseFile(args[1])
(data1, morph1) = ReadMorph(filename1, morphname1)
# FILE2 のモーフを読み込み
(filename2, morphname2) = ParseFile(args[2])
(data2, morph2) = ReadMorph(filename2, morphname2)
if len(morph1.vertices) != len(morph2.vertices):
print "The number of vertices is not equal."
exit()
if opts.addmode:
print 'Add mode'
# 加算モード
# モーフ2にモーフ1の頂点を rate のパーセンテージ分加算する
verts3 =[tuple([(p1*opts.rate/100)+ p2 for p1, p2 in zip(v1, v2)]) for v1, v2 in zip(morph1.get_relative_vertices(), morph2.get_relative_vertices())]
else:
# ブレンドモード
if opts.rate == 100:
print '100% copy mode'
# rate 100% の場合は単純に上書きコピー
verts3 = morph1.get_relative_vertices()
else:
# それぞれの比率で足し合わせる
rate1 = opts.rate
rate2 = 100 - opts.rate
print 'Blend mode: %d:%d' % (rate1, rate2)
verts3 =[tuple([(p1*rate1/100) + (p2*rate2/100) for p1, p2 in zip(v1, v2)]) for v1, v2 in zip(morph1.get_relative_vertices(), morph2.get_relative_vertices())]
# 更新された tri を outfileに保存
morph2.set_relative_vertices(verts3)
ostrm = open(opts.outfile, 'wb')
data2.write(ostrm)
ostrm.close()
print "Wrote to '%s'" % opts.outfile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment