# vim:ts=4:et # ##### BEGIN GPL LICENSE BLOCK ##### # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # import os import sys import bpy import bmesh from mathutils import Vector,Matrix from math import pi def active_uv(mesh): for uvt in mesh.uv_textures: if uvt.active: return uvt return None def make_face(bmface, mesh): uvtex = active_uv(mesh) uvfaces = mesh.uv_layers[uvtex.name].data face = mesh.polygons[bmface.index] mat = mesh.materials[face.material_index] uvs = uvfaces[face.loop_start:face.loop_start + face.loop_total] uvs = list(map(lambda a: a.uv, uvs)) v = list(face.vertices[-3:]) v.reverse() return (mesh.vertices[v[0]].co, mesh.vertices[v[1]].co, mesh.vertices[v[2]].co, mat.name, 0, 0, 0, 1, 1) def make_brushes(obj): act = bpy.context.scene.objects.active bpy.context.scene.objects.active = obj bpy.ops.object.editmode_toggle() brushmesh = bmesh.from_edit_mesh(obj.data).copy() bpy.ops.object.editmode_toggle() bpy.context.scene.objects.active = act brushes = [] face_set = set(brushmesh.faces) while face_set: face_queue = [face_set.pop()] brush = [] while face_queue: face = face_queue.pop() brush.append(face) for edge in face.edges: for link_face in edge.link_faces: if link_face in face_set: face_set.remove(link_face) face_queue.append(link_face) brushes.append(brush) mesh = obj.to_mesh(bpy.context.scene, True, 'PREVIEW') mesh.transform(obj.matrix_world) for b in brushes: for i in range(len(b)): b[i] = make_face(b[i], mesh) return brushes def export_mesh(obj): qfe = obj.qfentity edict = entity_dict(qfe) if qfe.classname: edict["classname"] = qfe.classname ec = bpy.context.scene.qfmap.entity_classes.get(edict["classname"]) if not ec or ec.size: edict["origin"] = "{l.x:.0f} {l.y:.0f} {l.z:.0f}".format(l=obj.location) return edict, [] return edict, make_brushes(obj) def export_lamp(obj): qfe = obj.qfentity edict = entity_dict(qfe) if qfe.classname: edict["classname"] = qfe.classname if not edict.get("classname"): edict["classname"] = "light" edict["origin"] = "{l.x:.0f} {l.y:.0f} {l.z:.0f}".format(l=obj.location) light = obj.data edict["light"] = light.distance return edict def vector_str(vect): return "{v.x:.0f} {v.y:.0f} {v.z:.0f}".format(v=vect) def export_empty(obj): qfe = obj.qfentity edict = entity_dict(qfe) if qfe.classname: edict["classname"] = qfe.classname edict["origin"] = vector_str(obj.location) return edict def write_brush(outfile, brush): outfile.write("{\n") for f in brush: outfile.write("( {} ) ( {} ) ( {} ) {} {} {} {} {} {}\n".format( vector_str(f[0]), vector_str(f[1]), vector_str(f[2]), f[3], f[4], f[5], f[6], f[7], f[8])) outfile.write("}\n") def write_entity(outfile, edict, brushes): outfile.write("{\n") for item in edict.items(): outfile.write("\"{item[0]}\" \"{item[1]}\"\n".format(item=item)) for brush in brushes: write_brush(outfile, brush) outfile.write("}\n") def entity_dict(ent): edict = {} for field in ent.fields: edict[field.name] = field.value return edict def export_map(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False world_objects = [] entities = [] for obj in bpy.context.scene.objects: qfe = obj.qfentity edict = entity_dict(qfe) if (obj.type == 'MESH' and (qfe.classname == 'worldspawn' or (not qfe.classname and "classname" not in edict))): world_objects.append(obj) elif (obj.type in {'MESH', 'LAMP', 'EMPTY'} and (qfe.classname or ("classname" in edict))): entities.append(obj) world_brushes = [] world_dict = {"classname":"worldspawn"} for obj in world_objects: world_dict.update(entity_dict(obj.qfentity)) world_brushes.extend(make_brushes(obj)) outfile = open(filepath, "wt") write_entity(outfile, world_dict, world_brushes) for obj in entities: if obj.type == 'MESH': edict, brushes = export_mesh(obj) elif obj.type == 'LAMP': brushes = [] edict = export_lamp(obj) elif obj.type == 'EMPTY': brushes = [] edict = export_empty(obj) write_entity(outfile, edict, brushes) outfile.close() bpy.context.user_preferences.edit.use_global_undo = True return {'FINISHED'}