quakeforge/tools/io_qfmap/__init__.py
Bill Currie 709ab05713 Add preliminary support for entity properties.
Only classname and flags are supported right now, and only classname gets
set when the entity is added (via the add menu).
2012-09-09 13:22:52 +09:00

252 lines
7.9 KiB
Python

# 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 #####
# copied from io_scene_obj
# <pep8 compliant>
bl_info = {
"name": "Quake map format",
"author": "Bill Currie",
"blender": (2, 6, 3),
"api": 35622,
"location": "File > Import-Export",
"description": "Import-Export Quake maps",
"warning": "not even alpha",
"wiki_url": "",
"tracker_url": "",
# "support": 'OFFICIAL',
"category": "Import-Export"}
# To support reload properly, try to access a package var, if it's there,
# reload everything
if "bpy" in locals():
import imp
if "import_map" in locals():
imp.reload(import_map)
if "export_map" in locals():
imp.reload(export_map)
from pprint import pprint
import bpy
from bpy.props import BoolProperty, FloatProperty, StringProperty, EnumProperty
from bpy.props import FloatVectorProperty, PointerProperty
from bpy_extras.io_utils import ExportHelper, ImportHelper, path_reference_mode, axis_conversion
from bpy.app.handlers import persistent
from .entityclass import EntityClassDict
from . import entity
from . import import_map
#from . import export_map
def ecm_draw(self, context):
layout = self.layout
for item in self.menu_items:
if type(item[1]) is str:
ec = context.scene.qfmap.entity_classes.entity_classes[item[1]]
if ec.size:
icon = 'OBJECT_DATA'
else:
icon = 'MESH_DATA'
op = layout.operator("object.add_entity", text=item[0], icon=icon)
op.entclass=item[1]
if ec.comment:
pass
else:
layout.menu(item[1].bl_idname)
class EntityClassMenu:
@classmethod
def clear(cls):
while cls.menu_items:
if type(cls.menu_item[0][1]) is not str:
bpy.utils.unregister_class(cls.menu_items[0][1])
cls.menu_items[0][1].clear()
del cls.menu_items[0]
@classmethod
def build(cls, menudict, name="INFO_MT_entity_add", label="entity"):
items = list(menudict.items())
items.sort()
menu_items = []
for i in items:
i = list(i)
if type(i[1]) is dict:
if i[0]:
nm = "_".join((name, i[0]))
else:
nm = name
i[1] = cls.build(i[1], nm, i[0])
menu_items.append(i)
attrs = {}
attrs["menu_items"] = menu_items
attrs["draw"] = ecm_draw
attrs["bl_idname"] = name
attrs["bl_label"] = label
attrs["clear"] = cls.clear
menu = type(name, (bpy.types.Menu,), attrs)
bpy.utils.register_class(menu)
return menu
@persistent
def scene_load_handler(dummy):
for scene in bpy.data.scenes:
if hasattr(scene, "qfmap"):
scene.qfmap.script_update(bpy.context)
def ec_dir_update(self, context):
self.entity_classes.from_source_tree(self.dirpath)
name = context.scene.name + '-EntityClasses'
if name in bpy.data.texts:
txt = bpy.data.texts[name]
else:
txt = bpy.data.texts.new(name)
txt.from_string(self.entity_classes.to_plist())
self.script = name
def ec_script_update(self, context):
self.script_update(context)
class AddEntity(bpy.types.Operator):
'''Add an entity'''
bl_idname = "object.add_entity"
bl_label = "Entity"
entclass = StringProperty(name = "entclass")
def execute(self, context):
keywords = self.as_keywords()
return entity.add_entity(self, context, **keywords)
class QFEntityClasses(bpy.types.PropertyGroup):
wadpath = StringProperty(
name="wadpath",
description="Path to search for wad files",
subtype='DIR_PATH')
dirpath = StringProperty(
name="dirpath",
description="Path to qc source tree",
subtype='DIR_PATH',
update=ec_dir_update)
script = StringProperty(
name="script",
description="entity class storage",
update=ec_script_update)
entity_classes = EntityClassDict()
ecm = EntityClassMenu.build({})
def script_update(self, context):
if self.script in bpy.data.texts:
script = bpy.data.texts[self.script].as_string()
self.entity_classes.from_plist(script)
menudict = {}
entclasses = self.entity_classes.entity_classes.keys()
for ec in entclasses:
ecsub = ec.split("_")
d = menudict
for sub in ecsub[:-1]:
if sub not in d:
d[sub] = {}
elif type(d[sub]) is str:
d[sub] = {"":d[sub]}
d = d[sub]
sub = ecsub[-1]
if sub in d:
d[sub][""] = ec
else:
d[sub] = ec
self.__class__.ecm = EntityClassMenu.build(menudict)
class QFECPanel(bpy.types.Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = 'scene'
bl_label = 'QF Entity Classes'
@classmethod
def poll(cls, context):
return True
def draw(self, context):
layout = self.layout
scene = context.scene
layout.prop(scene.qfmap, "wadpath")
layout.prop(scene.qfmap, "dirpath")
layout.prop(scene.qfmap, "script")
class ImportMap(bpy.types.Operator, ImportHelper):
'''Load a Quake map File'''
bl_idname = "import_mesh.quake_map"
bl_label = "Import map"
filename_ext = ".map"
filter_glob = StringProperty(default="*.map", options={'HIDDEN'})
def execute(self, context):
keywords = self.as_keywords (ignore=("filter_glob",))
return import_map.import_map(self, context, **keywords)
class ExportMap(bpy.types.Operator, ExportHelper):
'''Save a Quake map File'''
bl_idname = "export_mesh.quake_map"
bl_label = "Export map"
filename_ext = ".map"
filter_glob = StringProperty(default="*.map", options={'HIDDEN'})
@classmethod
def poll(cls, context):
return (context.active_object != None
and type(context.active_object.data) == bpy.types.Mesh)
def execute(self, context):
keywords = self.as_keywords (ignore=("check_existing", "filter_glob"))
return export_map.export_map(self, context, **keywords)
def menu_func_import(self, context):
self.layout.operator(ImportMap.bl_idname, text="Quake map (.map)")
def menu_func_export(self, context):
self.layout.operator(ExportMap.bl_idname, text="Quake map (.map)")
def menu_func_add(self, context):
self.layout.menu(context.scene.qfmap.ecm.bl_idname, icon='PLUGIN')
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.qfmap = PointerProperty(type=QFEntityClasses)
bpy.types.INFO_MT_file_import.append(menu_func_import)
bpy.types.INFO_MT_file_export.append(menu_func_export)
bpy.types.INFO_MT_add.append(menu_func_add)
bpy.app.handlers.load_post.append(scene_load_handler)
entity.register()
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
bpy.types.INFO_MT_add.remove(menu_func_add)
if __name__ == "__main__":
register()