Skip to content

Instantly share code, notes, and snippets.

@himika
Created July 3, 2012 03:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save himika/3037464 to your computer and use it in GitHub Desktop.
Save himika/3037464 to your computer and use it in GitHub Desktop.
.tri file exporter for Blender 2.49b 要 pyffi 2.1.10
#!BPY
"""
Name: 'FaceGen TRI (.tri)...'
Blender: 249
Group: 'Export'
Tooltip: 'Write a FaceGen TRI file.'
"""
__author__= "himika"
__version__= "0.1"
__bpydoc__= """\
This script exports a FaceGen TRI file to Blender.
Usage:
Run this script from "File->Export" menu and then write the desired TRI file.
"""
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2012 himika
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import bpy
import Blender
from Blender import Mesh, Draw, Window, Texture, Material, sys
import BPyMesh
import BPyMessages
from pyffi.formats.tri import TriFormat
from itertools import izip
import re
def exportMenu():
global ROTATE_X90, EXPORT_FACES, EXPORT_UV, EXPORT_MORPHS
ROTATE_X90 = Blender.Draw.Create(1)
EXPORT_FACES = Blender.Draw.Create(1)
EXPORT_UV = Blender.Draw.Create(1)
EXPORT_MORPHS = Blender.Draw.Create(1)
# Get USER Options
pup_block = [\
('Rotate X90', ROTATE_X90, 'Rotate X -90'),\
('Faces', EXPORT_FACES, 'Export Faces'),\
('UV', EXPORT_UV, 'Export UV'),\
('Export Morphs', EXPORT_MORPHS, 'Export Morphs')\
]
if not Blender.Draw.PupBlock('Export TRI...', pup_block):
return
Blender.Window.WaitCursor(1)
ROTATE_X90 = ROTATE_X90.val
EXPORT_FACES = EXPORT_FACES.val
EXPORT_UV = EXPORT_UV.val
EXPORT_MORPHS = EXPORT_MORPHS.val
def veckey2d(v):
return round(v.x, 6), round(v.y, 6)
def writeTri(filename):
if not filename.lower().endswith('.tri'):
filename += '.tri'
if not BPyMessages.Warning_SaveOver(filename):
return
print '\nExporting tri: "%s"' % (Blender.sys.expandpath(filename))
# options
exportMenu()
data = TriFormat.Data()
scn = bpy.data.scenes.active
ob = scn.objects.active
mesh = ob.getData(mesh=True)
shapeKeys = mesh.key
numMorphs = 0
if shapeKeys:
shapeKeys = mesh.key.blocks
numMorphs = len(shapeKeys)-1
verts = shapeKeys[0].getData()
else:
verts = mesh.verts
# vertex
for v in verts:
if shapeKeys:
vv = [v.x, v.y, v.z]
else:
vv = [v.co[0], v.co[1], v.co[2]]
if ROTATE_X90:
vv = [vv[0], vv[2], -vv[1]]
tri_v = TriFormat.Vertex()
tri_v.x = vv[0]
tri_v.y = vv[1]
tri_v.z = vv[2]
data.vertices.append(tri_v)
data.num_vertices =len(data.vertices)
print "export Vertices:%d" % (data.num_vertices)
# face
if EXPORT_FACES:
for f in mesh.faces:
tri_f = TriFormat.TriFace()
tri_f.v_1 = f.v[0].index
tri_f.v_2 = f.v[1].index
tri_f.v_3 = f.v[2].index
data.tri_faces.append(tri_f)
data.num_tri_faces = len(data.tri_faces)
print "export Faces:%d" % (data.num_tri_faces)
# UV
if EXPORT_FACES and data.num_tri_faces > 0 and EXPORT_UV and mesh.faceUV:
uv_face_mapping = [[0,0,0,0] for f in mesh.faces]
uv_dict = {}
for i, f in enumerate(mesh.faces):
for uv_index, uv in enumerate(f.uv):
uvkey = veckey2d(uv)
try:
uv_face_mapping[i][uv_index] = uv_dict[uvkey]
except:
uv_face_mapping[i][uv_index] = uv_dict[uvkey] = len(uv_dict)
tri_uv = TriFormat.TexCoord()
tri_uv.u = uv.x
tri_uv.v = uv.y
data.uvs.append(tri_uv)
data.num_uvs = len(data.uvs)
data.has_uv = 1
for i, f in enumerate(mesh.faces):
tri_face = TriFormat.TriFace()
tri_face.v_1 = uv_face_mapping[i][0]
tri_face.v_2 = uv_face_mapping[i][1]
tri_face.v_3 = uv_face_mapping[i][2]
data.uv_tri_faces.append(tri_face)
print "export UVs:%d" % (data.num_uvs)
# Morphs
if EXPORT_MORPHS and numMorphs > 0:
p = re.compile('(.*) \\[\\d+\\]$')
for i in range(numMorphs):
shape_verts = shapeKeys[i+1].getData()
diff_verts = []
max_diff = 0
for bv, nv in izip(verts, shape_verts):
diff = [nv.x - bv.x, nv.y - bv.y, nv.z - bv.z]
diff_verts.append(diff)
if abs(diff[0]) > max_diff:
max_diff = abs(diff[0])
if abs(diff[1]) > max_diff:
max_diff = abs(diff[1])
if abs(diff[2]) > max_diff:
max_diff = abs(diff[2])
if ROTATE_X90:
diff_verts[:] = [(v[0], v[2], -v[1]) for v in diff_verts]
if max_diff > 0:
morphName = shapeKeys[i+1].name
m = p.match(morphName)
if m:
morphName = m.group(1)
print("... Morph:" + morphName)
morph = TriFormat.MorphRecord(argument=len(diff_verts))
morph.name = morphName
morph.set_relative_vertices(diff_verts)
data.morphs.append(morph)
data.num_morphs = len(data.morphs)
ostrm = open(filename, 'wb')
data.write(ostrm)
ostrm.close()
scn = bpy.data.scenes.active
if len(scn.objects.selected) != 1:
raise ValueError("select one object only.")
if __name__=='__main__':
Blender.Window.FileSelector(writeTri, 'Export tri', sys.makename(ext='.tri'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment