diff options
Diffstat (limited to 'release/scripts/ac3d_export.py')
-rw-r--r-- | release/scripts/ac3d_export.py | 828 |
1 files changed, 0 insertions, 828 deletions
diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py deleted file mode 100644 index 57f27c7e3a2..00000000000 --- a/release/scripts/ac3d_export.py +++ /dev/null @@ -1,828 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: -Name: 'AC3D (.ac)...' -Blender: 243 -Group: 'Export' -Tip: 'Export selected meshes to AC3D (.ac) format' -""" - -__author__ = "Willian P. Germano" -__url__ = ("blender", "blenderartists.org", "AC3D's homepage, http://www.ac3d.org", - "PLib 3d gaming lib, http://plib.sf.net") -__version__ = "2.44 2007-05-05" - -__bpydoc__ = """\ -This script exports selected Blender meshes to AC3D's .ac file format. - -AC3D is a simple commercial 3d modeller also built with OpenGL. -The .ac file format is an easy to parse text format well supported, -for example, by the PLib 3d gaming library (AC3D 3.x). - -Supported:<br> - UV-textured meshes with hierarchy (grouping) information. - -Missing:<br> - The 'url' tag, specific to AC3D. It is easy to add by hand to the exported -file, if needed. - -Known issues:<br> - The ambient and emit data we can retrieve from Blender are single values, -that this script copies to R, G, B, giving shades of gray.<br> - Loose edges (lines) receive the first material found in the mesh, if any, or a default white material.<br> - In AC3D 4 "compatibility mode":<br> - - shininess of materials is taken from the shader specularity value in Blender, mapped from [0.0, 2.0] to [0, 128];<br> - - crease angle is exported, but in Blender it is limited to [1, 80], since there are other more powerful ways to control surface smoothing. In AC3D 4.0 crease's range is [0.0, 180.0]; - -Config Options:<br> - toggle:<br> - - AC3D 4 mode: unset it to export without the 'crease' tag that was -introduced with AC3D 4.0 and with the old material handling;<br> - - global coords: transform all vertices of all meshes to global coordinates;<br> - - skip data: set it if you don't want mesh names (ME:, not OB: field) -to be exported as strings for AC's "data" tags (19 chars max);<br> - - rgb mirror color can be exported as ambient and/or emissive if needed, -since Blender handles these differently;<br> - - default mat: a default (white) material is added if some mesh was -left without mats -- it's better to always add your own materials;<br> - - no split: don't split meshes (see above);<br> - - set texture dir: override the actual textures path with a given default -path (or simply export the texture names, without dir info, if the path is -empty);<br> - - per face 1 or 2 sided: override the "Double Sided" button that defines this behavior per whole mesh in favor of the UV Face Select mode "twosided" per face atribute;<br> - - only selected: only consider selected objects when looking for meshes -to export (read notes below about tokens, too);<br> - strings:<br> - - export dir: default dir to export to;<br> - - texture dir: override textures path with this path if 'set texture dir' -toggle is "on". - -Notes:<br> - This version updates:<br> - - modified meshes are correctly exported, no need to apply the modifiers in Blender;<br> - - correctly export each used material, be it assigned to the object or to its mesh data;<br> - - exporting lines (edges) is again supported; color comes from first material found in the mesh, if any, or a default white one.<br> - - there's a new option to choose between exporting meshes with transformed (global) coordinates or local ones;<br> - Multiple textures per mesh are supported (mesh gets split);<br> - Parents are exported as a group containing both the parent and its children;<br> - Start mesh object names (OB: field) with "!" or "#" if you don't want them to be exported;<br> - Start mesh object names (OB: field) with "=" or "$" to prevent them from being split (meshes with multiple textures or both textured and non textured faces are split unless this trick is used or the "no split" option is set. -""" - -# $Id$ -# -# -------------------------------------------------------------------------- -# AC3DExport version 2.44 -# Program versions: Blender 2.42+ and AC3Db files (means version 0xb) -# new: updated for new Blender version and Mesh module; supports lines (edges) again; -# option to export vertices transformed to global coordinates or not; now the modified -# (by existing mesh modifiers) mesh is exported; materials are properly exported, no -# matter if each of them is linked to the mesh or to the object. New (2.43.1): loose -# edges use color of first material found in the mesh, if any. -# -------------------------------------------------------------------------- -# Thanks: Steve Baker for discussions and inspiration; for testing, bug -# reports, suggestions, patches: David Megginson, Filippo di Natale, -# Franz Melchior, Campbell Barton, Josh Babcock, Ralf Gerlich, Stewart Andreason. -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004-2007: Willian P. Germano, wgermano _at_ 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, -# -------------------------------------------------------------------------- - -import Blender -from Blender import Object, Mesh, Material, Image, Mathutils, Registry -from Blender import sys as bsys - -# Globals -REPORT_DATA = { - 'main': [], - 'errors': [], - 'warns': [], - 'nosplit': [], - 'noexport': [] -} -TOKENS_DONT_EXPORT = ['!', '#'] -TOKENS_DONT_SPLIT = ['=', '$'] - -MATIDX_ERROR = 0 - -# flags: -LOOSE = Mesh.EdgeFlags['LOOSE'] -FACE_TWOSIDED = Mesh.FaceModes['TWOSIDE'] -MESH_TWOSIDED = Mesh.Modes['TWOSIDED'] - -REG_KEY = 'ac3d_export' - -# config options: -GLOBAL_COORDS = True -SKIP_DATA = False -MIRCOL_AS_AMB = False -MIRCOL_AS_EMIS = False -ADD_DEFAULT_MAT = True -SET_TEX_DIR = True -TEX_DIR = '' -AC3D_4 = True # export crease value, compatible with AC3D 4 loaders -NO_SPLIT = False -ONLY_SELECTED = True -EXPORT_DIR = '' -PER_FACE_1_OR_2_SIDED = True - -tooltips = { - 'GLOBAL_COORDS': "transform all vertices of all meshes to global coordinates", - 'SKIP_DATA': "don't export mesh names as data fields", - 'MIRCOL_AS_AMB': "export mirror color as ambient color", - 'MIRCOL_AS_EMIS': "export mirror color as emissive color", - 'ADD_DEFAULT_MAT': "always add a default white material", - 'SET_TEX_DIR': "don't export default texture paths (edit also \"tex dir\")", - 'EXPORT_DIR': "default / last folder used to export .ac files to", - 'TEX_DIR': "(see \"set tex dir\") dir to prepend to all exported texture names (leave empty for no dir)", - 'AC3D_4': "compatibility mode, adds 'crease' tag and slightly better material support", - 'NO_SPLIT': "don't split meshes with multiple textures (or both textured and non textured polygons)", - 'ONLY_SELECTED': "export only selected objects", - 'PER_FACE_1_OR_2_SIDED': "override \"Double Sided\" button in favor of per face \"twosided\" attribute (UV Face Select mode)" -} - -def update_RegistryInfo(): - d = {} - d['SKIP_DATA'] = SKIP_DATA - d['MIRCOL_AS_AMB'] = MIRCOL_AS_AMB - d['MIRCOL_AS_EMIS'] = MIRCOL_AS_EMIS - d['ADD_DEFAULT_MAT'] = ADD_DEFAULT_MAT - d['SET_TEX_DIR'] = SET_TEX_DIR - d['TEX_DIR'] = TEX_DIR - d['AC3D_4'] = AC3D_4 - d['NO_SPLIT'] = NO_SPLIT - d['EXPORT_DIR'] = EXPORT_DIR - d['ONLY_SELECTED'] = ONLY_SELECTED - d['PER_FACE_1_OR_2_SIDED'] = PER_FACE_1_OR_2_SIDED - d['tooltips'] = tooltips - d['GLOBAL_COORDS'] = GLOBAL_COORDS - Registry.SetKey(REG_KEY, d, True) - -# Looking for a saved key in Blender.Registry dict: -rd = Registry.GetKey(REG_KEY, True) - -if rd: - try: - AC3D_4 = rd['AC3D_4'] - SKIP_DATA = rd['SKIP_DATA'] - MIRCOL_AS_AMB = rd['MIRCOL_AS_AMB'] - MIRCOL_AS_EMIS = rd['MIRCOL_AS_EMIS'] - ADD_DEFAULT_MAT = rd['ADD_DEFAULT_MAT'] - SET_TEX_DIR = rd['SET_TEX_DIR'] - TEX_DIR = rd['TEX_DIR'] - EXPORT_DIR = rd['EXPORT_DIR'] - ONLY_SELECTED = rd['ONLY_SELECTED'] - NO_SPLIT = rd['NO_SPLIT'] - PER_FACE_1_OR_2_SIDED = rd['PER_FACE_1_OR_2_SIDED'] - GLOBAL_COORDS = rd['GLOBAL_COORDS'] - except KeyError: update_RegistryInfo() - -else: - update_RegistryInfo() - -VERBOSE = True -CONFIRM_OVERWRITE = True - -# check General scripts config key for default behaviors -rd = Registry.GetKey('General', True) -if rd: - try: - VERBOSE = rd['verbose'] - CONFIRM_OVERWRITE = rd['confirm_overwrite'] - except: pass - - -# The default material to be used when necessary (see ADD_DEFAULT_MAT) -DEFAULT_MAT = \ -'MATERIAL "DefaultWhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 \ -spec 0.5 0.5 0.5 shi 64 trans 0' - -# This transformation aligns Blender and AC3D coordinate systems: -BLEND_TO_AC3D_MATRIX = Mathutils.Matrix([1,0,0,0], [0,0,-1,0], [0,1,0,0], [0,0,0,1]) - -def Round_s(f): - "Round to default precision and turn value to a string" - r = round(f,6) # precision set to 10e-06 - if r == int(r): - return str(int(r)) - else: - return str(r) - -def transform_verts(verts, m): - vecs = [] - for v in verts: - x, y, z = v.co - vec = Mathutils.Vector([x, y, z, 1]) - vecs.append(vec*m) - return vecs - -def get_loose_edges(mesh): - loose = LOOSE - return [e for e in mesh.edges if e.flag & loose] - -# --- - -# meshes with more than one texture assigned -# are split and saved as these foomeshes -class FooMesh: - - class FooVert: - def __init__(self, v): - self.v = v - self.index = 0 - - class FooFace: - def __init__(self, foomesh, f): - self.f = f - foov = foomesh.FooVert - self.v = [foov(f.v[0]), foov(f.v[1])] - len_fv = len(f.v) - if len_fv > 2 and f.v[2]: - self.v.append(foov(f.v[2])) - if len_fv > 3 and f.v[3]: self.v.append(foov(f.v[3])) - - def __getattr__(self, attr): - if attr == 'v': return self.v - return getattr(self.f, attr) - - def __len__(self): - return len(self.f) - - def __init__(self, tex, faces, mesh): - self.name = mesh.name - self.mesh = mesh - self.looseEdges = [] - self.faceUV = mesh.faceUV - self.degr = mesh.degr - vidxs = [0]*len(mesh.verts) - foofaces = [] - for f in faces: - foofaces.append(self.FooFace(self, f)) - for v in f.v: - if v: vidxs[v.index] = 1 - i = 0 - fooverts = [] - for v in mesh.verts: - if vidxs[v.index]: - fooverts.append(v) - vidxs[v.index] = i - i += 1 - for f in foofaces: - for v in f.v: - if v: v.index = vidxs[v.v.index] - self.faces = foofaces - self.verts = fooverts - - -class AC3DExport: # the ac3d exporter part - - def __init__(self, scene_objects, file): - - global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT - - header = 'AC3Db' - self.file = file - self.buf = '' - self.mbuf = [] - self.mlist = [] - world_kids = 0 - parents_list = self.parents_list = [] - kids_dict = self.kids_dict = {} - objs = [] - exp_objs = self.exp_objs = [] - tree = {} - - file.write(header+'\n') - - objs = \ - [o for o in scene_objects if o.type in ['Mesh', 'Empty']] - - # create a tree from parents to children objects - - for obj in objs[:]: - parent = obj.parent - lineage = [obj] - - while parent: - parents_list.append(parent.name) - obj = parent - parent = parent.getParent() - lineage.insert(0, obj) - - d = tree - for i in xrange(len(lineage)): - lname = lineage[i].getType()[:2] + lineage[i].name - if lname not in d.keys(): - d[lname] = {} - d = d[lname] - - # traverse the tree to get an ordered list of names of objects to export - self.traverse_dict(tree) - - world_kids = len(tree.keys()) - - # get list of objects to export, start writing the .ac file - - objlist = [Object.Get(name) for name in exp_objs] - - meshlist = [o for o in objlist if o.type == 'Mesh'] - - # create a temporary mesh to hold actual (modified) mesh data - TMP_mesh = Mesh.New('tmp_for_ac_export') - - # write materials - - self.MATERIALS(meshlist, TMP_mesh) - mbuf = self.mbuf - if not mbuf or ADD_DEFAULT_MAT: - mbuf.insert(0, "%s\n" % DEFAULT_MAT) - mbuf = "".join(mbuf) - file.write(mbuf) - - file.write('OBJECT world\nkids %s\n' % world_kids) - - # write the objects - - for obj in objlist: - self.obj = obj - - objtype = obj.type - objname = obj.name - kidsnum = kids_dict[objname] - - # A parent plus its children are exported as a group. - # If the parent is a mesh, its rot and loc are exported as the - # group rot and loc and the mesh (w/o rot and loc) is added to the group. - if kidsnum: - self.OBJECT('group') - self.name(objname) - if objtype == 'Mesh': - kidsnum += 1 - if not GLOBAL_COORDS: - localmatrix = obj.getMatrix('localspace') - if not obj.getParent(): - localmatrix *= BLEND_TO_AC3D_MATRIX - self.rot(localmatrix.rotationPart()) - self.loc(localmatrix.translationPart()) - self.kids(kidsnum) - - if objtype == 'Mesh': - mesh = TMP_mesh # temporary mesh to hold actual (modified) mesh data - mesh.getFromObject(objname) - self.mesh = mesh - if mesh.faceUV: - meshes = self.split_mesh(mesh) - else: - meshes = [mesh] - if len(meshes) > 1: - if NO_SPLIT or self.dont_split(objname): - self.export_mesh(mesh, ob) - REPORT_DATA['nosplit'].append(objname) - else: - self.OBJECT('group') - self.name(objname) - self.kids(len(meshes)) - counter = 0 - for me in meshes: - self.export_mesh(me, obj, - name = '%s_%s' % (obj.name, counter), foomesh = True) - self.kids() - counter += 1 - else: - self.export_mesh(mesh, obj) - self.kids() - - - def traverse_dict(self, d): - kids_dict = self.kids_dict - exp_objs = self.exp_objs - keys = d.keys() - keys.sort() # sort for predictable output - keys.reverse() - for k in keys: - objname = k[2:] - klen = len(d[k]) - kids_dict[objname] = klen - if self.dont_export(objname): - d.pop(k) - parent = Object.Get(objname).getParent() - if parent: kids_dict[parent.name] -= 1 - REPORT_DATA['noexport'].append(objname) - continue - if klen: - self.traverse_dict(d[k]) - exp_objs.insert(0, objname) - else: - if k.find('Em', 0) == 0: # Empty w/o children - d.pop(k) - parent = Object.Get(objname).getParent() - if parent: kids_dict[parent.name] -= 1 - else: - exp_objs.insert(0, objname) - - def dont_export(self, name): # if name starts with '!' or '#' - length = len(name) - if length >= 1: - if name[0] in TOKENS_DONT_EXPORT: # '!' or '#' doubled (escaped): export - if length > 1 and name[1] == name[0]: - return 0 - return 1 - - def dont_split(self, name): # if name starts with '=' or '$' - length = len(name) - if length >= 1: - if name[0] in TOKENS_DONT_SPLIT: # '=' or '$' doubled (escaped): split - if length > 1 and name[1] == name[0]: - return 0 - return 1 - - def split_mesh(self, mesh): - tex_dict = {0:[]} - for f in mesh.faces: - if f.image: - if not f.image.name in tex_dict: tex_dict[f.image.name] = [] - tex_dict[f.image.name].append(f) - else: tex_dict[0].append(f) - keys = tex_dict.keys() - len_keys = len(keys) - if not tex_dict[0]: - len_keys -= 1 - tex_dict.pop(0) - keys.remove(0) - elif len_keys > 1: - lines = [] - anyimgkey = [k for k in keys if k != 0][0] - for f in tex_dict[0]: - if len(f.v) < 3: - lines.append(f) - if len(tex_dict[0]) == len(lines): - for l in lines: - tex_dict[anyimgkey].append(l) - len_keys -= 1 - tex_dict.pop(0) - if len_keys > 1: - foo_meshes = [] - for k in keys: - faces = tex_dict[k] - foo_meshes.append(FooMesh(k, faces, mesh)) - foo_meshes[0].edges = get_loose_edges(mesh) - return foo_meshes - return [mesh] - - def export_mesh(self, mesh, obj, name = None, foomesh = False): - file = self.file - self.OBJECT('poly') - if not name: name = obj.name - self.name(name) - if not SKIP_DATA: - meshname = obj.getData(name_only = True) - self.data(len(meshname), meshname) - if mesh.faceUV: - texline = self.texture(mesh.faces) - if texline: file.write(texline) - if AC3D_4: - self.crease(mesh.degr) - - # If exporting using local coordinates, children object coordinates should not be - # transformed to ac3d's coordinate system, since that will be accounted for in - # their topmost parents (the parents w/o parents) transformations. - if not GLOBAL_COORDS: - # We hold parents in a list, so they also don't get transformed, - # because for each parent we create an ac3d group to hold both the - # parent and its children. - if obj.name not in self.parents_list: - localmatrix = obj.getMatrix('localspace') - if not obj.getParent(): - localmatrix *= BLEND_TO_AC3D_MATRIX - self.rot(localmatrix.rotationPart()) - self.loc(localmatrix.translationPart()) - matrix = None - else: - matrix = obj.getMatrix() * BLEND_TO_AC3D_MATRIX - - self.numvert(mesh.verts, matrix) - self.numsurf(mesh, foomesh) - - def MATERIALS(self, meshlist, me): - for meobj in meshlist: - me.getFromObject(meobj) - mats = me.materials - mbuf = [] - mlist = self.mlist - for m in mats: - if not m: continue - name = m.name - if name not in mlist: - mlist.append(name) - M = Material.Get(name) - material = 'MATERIAL "%s"' % name - mirCol = "%s %s %s" % (Round_s(M.mirCol[0]), Round_s(M.mirCol[1]), - Round_s(M.mirCol[2])) - rgb = "rgb %s %s %s" % (Round_s(M.R), Round_s(M.G), Round_s(M.B)) - ambval = Round_s(M.amb) - amb = "amb %s %s %s" % (ambval, ambval, ambval) - spec = "spec %s %s %s" % (Round_s(M.specCol[0]), - Round_s(M.specCol[1]), Round_s(M.specCol[2])) - if AC3D_4: - emit = Round_s(M.emit) - emis = "emis %s %s %s" % (emit, emit, emit) - shival = int(M.spec * 64) - else: - emis = "emis 0 0 0" - shival = 72 - shi = "shi %s" % shival - trans = "trans %s" % (Round_s(1 - M.alpha)) - if MIRCOL_AS_AMB: - amb = "amb %s" % mirCol - if MIRCOL_AS_EMIS: - emis = "emis %s" % mirCol - mbuf.append("%s %s %s %s %s %s %s\n" \ - % (material, rgb, amb, emis, spec, shi, trans)) - self.mlist = mlist - self.mbuf.append("".join(mbuf)) - - def OBJECT(self, type): - self.file.write('OBJECT %s\n' % type) - - def name(self, name): - if name[0] in TOKENS_DONT_EXPORT or name[0] in TOKENS_DONT_SPLIT: - if len(name) > 1: name = name[1:] - self.file.write('name "%s"\n' % name) - - def kids(self, num = 0): - self.file.write('kids %s\n' % num) - - def data(self, num, str): - self.file.write('data %s\n%s\n' % (num, str)) - - def texture(self, faces): - tex = "" - for f in faces: - if f.image: - tex = f.image.name - break - if tex: - image = Image.Get(tex) - texfname = image.filename - if SET_TEX_DIR: - texfname = bsys.basename(texfname) - if TEX_DIR: - texfname = bsys.join(TEX_DIR, texfname) - buf = 'texture "%s"\n' % texfname - xrep = image.xrep - yrep = image.yrep - buf += 'texrep %s %s\n' % (xrep, yrep) - self.file.write(buf) - - def rot(self, matrix): - rot = '' - not_I = 0 # not identity - matstr = [] - for i in [0, 1, 2]: - r = map(Round_s, matrix[i]) - not_I += (r[0] != '0')+(r[1] != '0')+(r[2] != '0') - not_I -= (r[i] == '1') - for j in [0, 1, 2]: - matstr.append(' %s' % r[j]) - if not_I: # no need to write identity - self.file.write('rot%s\n' % "".join(matstr)) - - def loc(self, loc): - loc = map(Round_s, loc) - if loc != ['0', '0', '0']: # no need to write default - self.file.write('loc %s %s %s\n' % (loc[0], loc[1], loc[2])) - - def crease(self, crease): - self.file.write('crease %f\n' % crease) - - def numvert(self, verts, matrix): - file = self.file - nvstr = [] - nvstr.append("numvert %s\n" % len(verts)) - - if matrix: - verts = transform_verts(verts, matrix) - for v in verts: - v = map (Round_s, v) - nvstr.append("%s %s %s\n" % (v[0], v[1], v[2])) - else: - for v in verts: - v = map(Round_s, v.co) - nvstr.append("%s %s %s\n" % (v[0], v[1], v[2])) - - file.write("".join(nvstr)) - - def numsurf(self, mesh, foomesh = False): - - global MATIDX_ERROR - - # local vars are faster and so better in tight loops - lc_ADD_DEFAULT_MAT = ADD_DEFAULT_MAT - lc_MATIDX_ERROR = MATIDX_ERROR - lc_PER_FACE_1_OR_2_SIDED = PER_FACE_1_OR_2_SIDED - lc_FACE_TWOSIDED = FACE_TWOSIDED - lc_MESH_TWOSIDED = MESH_TWOSIDED - - faces = mesh.faces - hasFaceUV = mesh.faceUV - if foomesh: - looseEdges = mesh.looseEdges - else: - looseEdges = get_loose_edges(mesh) - - file = self.file - - file.write("numsurf %s\n" % (len(faces) + len(looseEdges))) - - if not foomesh: verts = list(self.mesh.verts) - - materials = self.mesh.materials - mlist = self.mlist - matidx_error_reported = False - objmats = [] - for omat in materials: - if omat: objmats.append(omat.name) - else: objmats.append(None) - for f in faces: - if not objmats: - m_idx = 0 - elif objmats[f.mat] in mlist: - m_idx = mlist.index(objmats[f.mat]) - else: - if not lc_MATIDX_ERROR: - rdat = REPORT_DATA['warns'] - rdat.append("Object %s" % self.obj.name) - rdat.append("has at least one material *index* assigned but not") - rdat.append("defined (not linked to an existing material).") - rdat.append("Result: some faces may be exported with a wrong color.") - rdat.append("You can assign materials in the Edit Buttons window (F9).") - elif not matidx_error_reported: - midxmsg = "- Same for object %s." % self.obj.name - REPORT_DATA['warns'].append(midxmsg) - lc_MATIDX_ERROR += 1 - matidx_error_reported = True - m_idx = 0 - if lc_ADD_DEFAULT_MAT: m_idx -= 1 - refs = len(f) - flaglow = 0 # polygon - if lc_PER_FACE_1_OR_2_SIDED and hasFaceUV: # per face attribute - two_side = f.mode & lc_FACE_TWOSIDED - else: # global, for the whole mesh - two_side = self.mesh.mode & lc_MESH_TWOSIDED - two_side = (two_side > 0) << 1 - flaghigh = f.smooth | two_side - surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow) - if lc_ADD_DEFAULT_MAT and objmats: m_idx += 1 - matstr = "mat %s\n" % m_idx - refstr = "refs %s\n" % refs - u, v, vi = 0, 0, 0 - fvstr = [] - if foomesh: - for vert in f.v: - fvstr.append(str(vert.index)) - if hasFaceUV: - u = f.uv[vi][0] - v = f.uv[vi][1] - vi += 1 - fvstr.append(" %s %s\n" % (u, v)) - else: - for vert in f.v: - fvstr.append(str(verts.index(vert))) - if hasFaceUV: - u = f.uv[vi][0] - v = f.uv[vi][1] - vi += 1 - fvstr.append(" %s %s\n" % (u, v)) - - fvstr = "".join(fvstr) - - file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr)) - - # material for loose edges - edges_mat = 0 # default to first material - for omat in objmats: # but look for a material from this mesh - if omat in mlist: - edges_mat = mlist.index(omat) - if lc_ADD_DEFAULT_MAT: edges_mat += 1 - break - - for e in looseEdges: - fvstr = [] - #flaglow = 2 # 1 = closed line, 2 = line - #flaghigh = 0 - #surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow) - surfstr = "SURF 0x02\n" - - fvstr.append("%d 0 0\n" % verts.index(e.v1)) - fvstr.append("%d 0 0\n" % verts.index(e.v2)) - fvstr = "".join(fvstr) - - matstr = "mat %d\n" % edges_mat # for now, use first material - refstr = "refs 2\n" # 2 verts - - file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr)) - - MATIDX_ERROR = lc_MATIDX_ERROR - -# End of Class AC3DExport - -from Blender.Window import FileSelector - -def report_data(): - global VERBOSE - - if not VERBOSE: return - - d = REPORT_DATA - msgs = { - '0main': '%s\nExporting meshes to AC3D format' % str(19*'-'), - '1warns': 'Warnings', - '2errors': 'Errors', - '3nosplit': 'Not split (because name starts with "=" or "$")', - '4noexport': 'Not exported (because name starts with "!" or "#")' - } - if NO_SPLIT: - l = msgs['3nosplit'] - l = "%s (because OPTION NO_SPLIT is set)" % l.split('(')[0] - msgs['3nosplit'] = l - keys = msgs.keys() - keys.sort() - for k in keys: - msgk = msgs[k] - msg = '\n'.join(d[k[1:]]) - if msg: - print '\n-%s:' % msgk - print msg - -# File Selector callback: -def fs_callback(filename): - global EXPORT_DIR, OBJS, CONFIRM_OVERWRITE, VERBOSE - - if not filename.endswith('.ac'): filename = '%s.ac' % filename - - if bsys.exists(filename) and CONFIRM_OVERWRITE: - if Blender.Draw.PupMenu('OVERWRITE?%t|File exists') != 1: - return - - Blender.Window.WaitCursor(1) - starttime = bsys.time() - - export_dir = bsys.dirname(filename) - if export_dir != EXPORT_DIR: - EXPORT_DIR = export_dir - update_RegistryInfo() - - try: - file = open(filename, 'w') - except IOError, (errno, strerror): - error = "IOError #%s: %s" % (errno, strerror) - REPORT_DATA['errors'].append("Saving failed - %s." % error) - error_msg = "Couldn't save file!%%t|%s" % error - Blender.Draw.PupMenu(error_msg) - return - - try: - test = AC3DExport(OBJS, file) - except: - file.close() - raise - else: - file.close() - endtime = bsys.time() - starttime - REPORT_DATA['main'].append("Done. Saved to: %s" % filename) - REPORT_DATA['main'].append("Data exported in %.3f seconds." % endtime) - - if VERBOSE: report_data() - Blender.Window.WaitCursor(0) - - -# -- End of definitions - -scn = Blender.Scene.GetCurrent() - -if ONLY_SELECTED: - OBJS = list(scn.objects.context) -else: - OBJS = list(scn.objects) - -if not OBJS: - Blender.Draw.PupMenu('ERROR: no objects selected') -else: - fname = bsys.makename(ext=".ac") - if EXPORT_DIR: - fname = bsys.join(EXPORT_DIR, bsys.basename(fname)) - FileSelector(fs_callback, "Export AC3D", fname) |