diff options
author | Willian Padovani Germano <wpgermano@gmail.com> | 2004-01-27 06:34:16 +0300 |
---|---|---|
committer | Willian Padovani Germano <wpgermano@gmail.com> | 2004-01-27 06:34:16 +0300 |
commit | 33dd2f5e0d58427d49f9bdbd3a593af5a9cc6302 (patch) | |
tree | 59fc8dcdd2617c78f6a69dbd88ee578dbe44a63d /release/scripts/ac3d_import.py | |
parent | d482d34ffb7ec92b63a5ffb1fa3237da720cc928 (diff) |
BPython:
- as proposed by Ton, default dir for menu enabled scripts is:
userhome/.blender/scripts if available or (using bprogname -- argv[0]),
blenderInstallationDir/.blender/scripts/ otherwise.
- moved a piece of code from BPY_interface.c to BPY_menus.c to get rid
of a linkage warning reported by J. Walton
-- added the first scripts to release/scripts:
We need time to get more scripts there, but the situation should improve
consistently from now on. Adding three export scripts: cal3d, directX, ac3d.
And one import: ac3d.
Diffstat (limited to 'release/scripts/ac3d_import.py')
-rw-r--r-- | release/scripts/ac3d_import.py | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/release/scripts/ac3d_import.py b/release/scripts/ac3d_import.py new file mode 100644 index 00000000000..3e3d08a1155 --- /dev/null +++ b/release/scripts/ac3d_import.py @@ -0,0 +1,421 @@ +#!BPY + +""" Registration info for Blender menus: +Name: 'AC3D...' +Blender: 232 +Group: 'Import' +Tip: 'Import an AC3D (.ac) file.' +""" + +# -------------------------------------------------------------------------- +# AC3DImport version 2.32-1 Jan 21, 2004 +# Program versions: Blender 2.32+ and AC3Db files (means version 0xb) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Copyright (C) 2004: Willian P. Germano, wgermano@ig.com.br +# +# 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 ***** +# -------------------------------------------------------------------------- + +# Note: +# Blender doesn't handle n-gons (polygons with more than 4 vertices): +# The script triangulates them, but concave polygons come out wrong and need +# fixing. Avoiding or triangulating concave n-gons in AC3D is a simple way to +# avoid problems. + +# Default folder for AC3D models, change to your liking or leave as "": +BASEDIR = "" + +# Set 'GROUP' to 1 to make Blender group imported objects using Empties, +# to reproduce the object hierarchy in the .ac file +GROUP = 0 + +import Blender + +if BASEDIR: + BASEDIR = BASEDIR.replace('\\','/') + if BASEDIR[-1] != '/': BASEDIR += '/' + +errmsg = "" + +class Obj: + + def __init__(self, type): + self.type = type + self.dad = None + self.name = '' + self.data = '' + self.tex = '' + self.texrep = [1,1] + self.texoff = None + self.loc = [0, 0, 0] + self.rot = [] + self.vlist = [] + self.flist = [] + self.matlist = [] + self.kids = 0 + +class AC3DImport: + + def __init__(self, filename): + + global errmsg + + print "Trying to import AC3D model(s) from %s ..." % filename + + self.i = 0 + errmsg = '' + self.importdir = Blender.sys.dirname(filename) + try: + file = open(filename, 'r') + except IOError, (errno, strerror): + errmsg = "IOError #%s: %s" % (errno, strerror) + print errmsg + return None + header = file.read(5) + header, version = header[:4], header[-1] + if header != 'AC3D': + file.close() + errmsg = 'Invalid file -- AC3D header not found.' + print errmsg + return None + elif version != 'b': + print 'AC3D file version 0x%s.' % version + print 'This importer is for version 0xb, so it may fail.' + + self.token = {'OBJECT': self.parse_obj, + 'numvert': self.parse_vert, + 'numsurf': self.parse_surf, + 'name': self.parse_name, + 'data': self.parse_data, + 'kids': self.parse_kids, + 'loc': self.parse_loc, + 'rot': self.parse_rot, + 'MATERIAL': self.parse_mat, + 'texture': self.parse_tex, + 'texrep': self.parse_texrep, + 'texoff': self.parse_texoff} + + self.objlist = [] + self.mlist = [] + self.dads = [] + self.kids = [] + self.dad = None + + self.lines = file.readlines() + self.lines.append('') + self.parse_file() + file.close() + + self.testAC3DImport() + + def parse_obj(self, value): + if self.kids: + while not self.kids[-1]: + self.kids.pop() + self.dad = self.dad.dad + self.kids[-1] -= 1 + new = Obj(value) + new.dad = self.dad + new.name = value + self.objlist.append(new) + + def parse_kids(self, value): + kids = int(value) + if kids: + self.kids.append(kids) + self.dad = self.objlist[-1] + self.objlist[-1].kids = kids + + def parse_name(self, value): + name = value.split('"')[1] + self.objlist[-1].name = name + + def parse_data(self, value): + data = self.lines[self.i].strip() + self.objlist[-1].data = data + + def parse_tex(self, value): + texture = value.split('"')[1] + self.objlist[-1].tex = texture + + def parse_texrep(self, trash): + trep = self.lines[self.i - 1] + trep = trep.split() + trep = [float(trep[1]), float(trep[2])] + self.objlist[-1].texrep = trep + self.objlist[-1].texoff = [0, 0] + + def parse_texoff(self, trash): + toff = self.lines[self.i - 1] + toff = toff.split() + toff = [float(toff[1]), float(toff[2])] + self.objlist[-1].texoff = toff + + def parse_mat(self, value): + i = self.i - 1 + lines = self.lines + line = lines[i].split() + mat_name = '' + mat_col = mat_spec_col = [0,0,0] + mat_alpha = 1 + + while line[0] == 'MATERIAL': + mat_name = line[1].split('"')[1] + mat_col = map(float,[line[3],line[4],line[5]]) + mat_spec_col = map(float,[line[15],line[16],line[17]]) + mat_alpha = float(line[-1]) + mat_alpha = 1 - mat_alpha + self.mlist.append([mat_name, mat_col, mat_spec_col, mat_alpha]) + i += 1 + line = lines[i].split() + + self.i = i + + def parse_rot(self, trash): + i = self.i - 1 + rot = self.lines[i].split(' ', 1)[1] + rot = map(float, rot.split()) + self.objlist[-1].rot = rot + + def parse_loc(self, trash): + i = self.i - 1 + loc = self.lines[i].split(' ', 1)[1] + loc = map(float, loc.split()) + self.objlist[-1].loc = loc + + def parse_vert(self, value): + i = self.i + lines = self.lines + obj = self.objlist[-1] + vlist = obj.vlist + n = int(value) + + while n: + line = lines[i].split() + line = map(float, line) + vlist.append(line) + n -= 1 + i += 1 + + self.i = i + + rot = obj.rot + if rot: + nv = len(vlist) + for j in range(nv): + v = vlist[j] + t = [0,0,0] + t[0] = rot[0]*v[0] + rot[3]*v[1] + rot[6]*v[2] + t[1] = rot[1]*v[0] + rot[4]*v[1] + rot[7]*v[2] + t[2] = rot[2]*v[0] + rot[5]*v[1] + rot[8]*v[2] + vlist[j] = t + + loc = obj.loc + dad = obj.dad + while dad: + for j in [0, 1, 2]: + loc[j] += dad.loc[j] + dad = dad.dad + + for v in vlist: + for j in [0, 1, 2]: + v[j] += loc[j] + + def parse_surf(self, value): + i = self.i + is_smooth = 0 + double_sided = 0 + lines = self.lines + obj = self.objlist[-1] + matlist = obj.matlist + numsurf = int(value) + + while numsurf: + flags = lines[i].split() + flaglow = 0 + if len(flags[1]) > 3: flaglow = int(flags[1][3]) + flaghigh = int(flags[1][2]) + is_smooth = flaghigh & 1 + twoside = flaghigh & 2 + mat = lines[i+1].split() + mat = int(mat[1]) + if not mat in matlist: matlist.append(mat) + refs = lines[i+2].split() + refs = int(refs[1]) + i += 3 + face = [] + faces = [] + fuv = [] + rfs = refs + + while rfs: + line = lines[i].split() + v = int(line[0]) + uv = [float(line[1]), float(line[2])] + face.append([v, uv]) + rfs -= 1 + i += 1 + + if flaglow: + while len(face) >= 2: + cut = face[:2] + faces.append(cut) + face = face[1:] + + if flaglow == 1: + face = [faces[-1][-1], faces[0][0]] + faces.append(face) + + else: + while len(face) > 4: + cut = face[:4] + face = face[3:] + face.insert(0, cut[0]) + faces.append(cut) + + faces.append(face) + + for f in faces: + f.append(mat) + f.append(is_smooth) + f.append(twoside) + self.objlist[-1].flist.append(f) + + numsurf -= 1 + + + self.i = i + + def parse_file(self): + i = 1 + lines = self.lines + line = lines[i].split() + + while line: + kw = '' + for k in self.token.keys(): + if line[0] == k: + kw = k + break + i += 1 + if kw: + self.i = i + self.token[kw](line[1]) + i = self.i + line = lines[i].split() + + def testAC3DImport(self): + global GROUP + scene = Blender.Scene.GetCurrent() + + bmat = [] + for mat in self.mlist: + name = mat[0] + m = Blender.Material.New(name) + m.rgbCol = (mat[1][0], mat[1][1], mat[1][2]) + m.specCol = (mat[2][0], mat[2][1], mat[2][2]) + m.alpha = mat[3] + bmat.append(m) + + for obj in self.objlist: + if obj.type == 'world': + continue + elif obj.type == 'group': + if not GROUP: continue + empty = Blender.Object.New('Empty') + empty.name = obj.name + scene.link(empty) + if self.dads: + dadobj = Blender.Object.get(self.dads.pop()) + dadobj.makeParent([empty]) + while obj.kids: + self.dads.append(empty.name) + obj.kids -= 1 + continue + mesh = Blender.NMesh.New() + if (obj.data): mesh.name = obj.data + mesh.hasFaceUV(1) + + tex = None + if obj.tex != '': + try: + tex = Blender.Image.Load(obj.tex) + # Commented because it's unnecessary: + #tex.xrep = int(obj.texrep[0]) + #tex.yrep = int(obj.texrep[1]) + except: + try: + obj.tex = self.importdir + '/' + obj.tex + tex = Blender.Image.Load(obj.tex) + except: + print "Couldn't load texture: %s" % obj.tex + + for v in obj.vlist: + bvert = Blender.NMesh.Vert(v[0],v[1],v[2]) + mesh.verts.append(bvert) + + objmat_indices = [] + for mat in bmat: + if bmat.index(mat) in obj.matlist: + objmat_indices.append(bmat.index(mat)) + mesh.materials.append(mat) + for f in obj.flist: + twoside = f[-1] + is_smooth = f[-2] + fmat = f[-3] + f=f[:-3] + bface = Blender.NMesh.Face() + bface.smooth = is_smooth + if twoside: bface.mode |= Blender.NMesh.FaceModes['TWOSIDE'] + if tex: + bface.mode |= Blender.NMesh.FaceModes['TEX'] + bface.image = tex + bface.materialIndex = objmat_indices.index(fmat) + if obj.texoff: + uoff = obj.texoff[0] + voff = obj.texoff[1] + urep = obj.texrep[0] + vrep = obj.texrep[1] + for vi in range(len(f)): + f[vi][1][0] *= urep + f[vi][1][1] *= vrep + f[vi][1][0] += uoff + f[vi][1][1] += voff + + for vi in range(len(f)): + bface.v.append(mesh.verts[f[vi][0]]) + bface.uv.append((f[vi][1][0], f[vi][1][1])) + mesh.faces.append(bface) + + mesh.mode = 0 + object = Blender.NMesh.PutRaw(mesh) + object.setName(obj.name) + object.setEuler([1.5707963,0,0]) # align ac3d w/ Blender + if self.dads: + dadobj = Blender.Object.get(self.dads.pop()) + dadobj.makeParent([object]) + + print '...done!' + +# End of class AC3DImport + +def filesel_callback(filename): + test = AC3DImport(filename) + +Blender.Window.FileSelector(filesel_callback, "Import AC3D") |