diff options
Diffstat (limited to 'io_scene_ms3d/ms3d_ui.py')
-rw-r--r-- | io_scene_ms3d/ms3d_ui.py | 1723 |
1 files changed, 1723 insertions, 0 deletions
diff --git a/io_scene_ms3d/ms3d_ui.py b/io_scene_ms3d/ms3d_ui.py new file mode 100644 index 00000000..b3e52b1e --- /dev/null +++ b/io_scene_ms3d/ms3d_ui.py @@ -0,0 +1,1723 @@ +# ##### 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 ##### + +# <pep8 compliant> + +############################################################################### +#234567890123456789012345678901234567890123456789012345678901234567890123456789 +#--------1---------2---------3---------4---------5---------6---------7--------- + + +# ##### BEGIN COPYRIGHT BLOCK ##### +# +# initial script copyright (c)2011,2012 Alexander Nussbaumer +# +# ##### END COPYRIGHT BLOCK ##### + + +#import python stuff +from random import ( + randrange, + ) + + +# import io_scene_ms3d stuff +from io_scene_ms3d.ms3d_strings import ( + ms3d_str, + ) +from io_scene_ms3d.ms3d_spec import ( + Ms3dSpec, + ) +from io_scene_ms3d.ms3d_utils import ( + enable_edit_mode, + get_edge_split_modifier_add_if, + set_sence_to_metric, + ) + + +#import blender stuff +from bmesh import ( + from_edit_mesh, + ) +from bpy.utils import ( + register_class, + unregister_class, + ) +from bpy_extras.io_utils import ( + ExportHelper, + ImportHelper, + ) +from bpy.props import ( + BoolProperty, + CollectionProperty, + EnumProperty, + FloatProperty, + FloatVectorProperty, + IntProperty, + StringProperty, + PointerProperty, + ) +from bpy.types import ( + Operator, + PropertyGroup, + Panel, + Armature, + Bone, + Mesh, + Material, + Action, + Group, + UIList, + ) +from bpy.app import ( + debug, + ) + + +class Ms3dUi: + DEFAULT_VERBOSE = debug + + ########################################################################### + FLAG_TEXTURE_COMBINE_ALPHA = 'COMBINE_ALPHA' + FLAG_TEXTURE_HAS_ALPHA = 'HAS_ALPHA' + FLAG_TEXTURE_SPHERE_MAP = 'SPHERE_MAP' + + @staticmethod + def texture_mode_from_ms3d(ms3d_value): + ui_value = set() + if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA) \ + == Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA: + ui_value.add(Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA) + if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA) \ + == Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA: + ui_value.add(Ms3dUi.FLAG_TEXTURE_HAS_ALPHA) + if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP) \ + == Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP: + ui_value.add(Ms3dUi.FLAG_TEXTURE_SPHERE_MAP) + return ui_value + + @staticmethod + def texture_mode_to_ms3d(ui_value): + ms3d_value = Ms3dSpec.FLAG_TEXTURE_NONE + + if Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA in ui_value: + ms3d_value |= Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA + if Ms3dUi.FLAG_TEXTURE_HAS_ALPHA in ui_value: + ms3d_value |= Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA + if Ms3dUi.FLAG_TEXTURE_SPHERE_MAP in ui_value: + ms3d_value |= Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP + return ms3d_value + + + MODE_TRANSPARENCY_SIMPLE = 'SIMPLE' + MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF \ + = 'DEPTH_BUFFERED_WITH_ALPHA_REF' + MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES = 'DEPTH_SORTED_TRIANGLES' + + @staticmethod + def transparency_mode_from_ms3d(ms3d_value): + if(ms3d_value == Ms3dSpec.MODE_TRANSPARENCY_SIMPLE): + return Ms3dUi.MODE_TRANSPARENCY_SIMPLE + elif(ms3d_value == \ + Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF): + return Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF + elif(ms3d_value == Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES): + return Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES + return None + + @staticmethod + def transparency_mode_to_ms3d(ui_value): + if(ui_value == Ms3dUi.MODE_TRANSPARENCY_SIMPLE): + return Ms3dSpec.MODE_TRANSPARENCY_SIMPLE + elif(ui_value == Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF): + return Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF + elif(ui_value == Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES): + return Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES + return None + + + FLAG_NONE = 'NONE' + FLAG_SELECTED = 'SELECTED' + FLAG_HIDDEN = 'HIDDEN' + FLAG_SELECTED2 = 'SELECTED2' + FLAG_DIRTY = 'DIRTY' + FLAG_ISKEY = 'ISKEY' + FLAG_NEWLYCREATED = 'NEWLYCREATED' + FLAG_MARKED = 'MARKED' + + @staticmethod + def flags_from_ms3d(ms3d_value): + ui_value = set() + if (ms3d_value & Ms3dSpec.FLAG_SELECTED) == Ms3dSpec.FLAG_SELECTED: + ui_value.add(Ms3dUi.FLAG_SELECTED) + if (ms3d_value & Ms3dSpec.FLAG_HIDDEN) == Ms3dSpec.FLAG_HIDDEN: + ui_value.add(Ms3dUi.FLAG_HIDDEN) + if (ms3d_value & Ms3dSpec.FLAG_SELECTED2) == Ms3dSpec.FLAG_SELECTED2: + ui_value.add(Ms3dUi.FLAG_SELECTED2) + if (ms3d_value & Ms3dSpec.FLAG_DIRTY) == Ms3dSpec.FLAG_DIRTY: + ui_value.add(Ms3dUi.FLAG_DIRTY) + if (ms3d_value & Ms3dSpec.FLAG_ISKEY) == Ms3dSpec.FLAG_ISKEY: + ui_value.add(Ms3dUi.FLAG_ISKEY) + if (ms3d_value & Ms3dSpec.FLAG_NEWLYCREATED) == \ + Ms3dSpec.FLAG_NEWLYCREATED: + ui_value.add(Ms3dUi.FLAG_NEWLYCREATED) + if (ms3d_value & Ms3dSpec.FLAG_MARKED) == Ms3dSpec.FLAG_MARKED: + ui_value.add(Ms3dUi.FLAG_MARKED) + return ui_value + + @staticmethod + def flags_to_ms3d(ui_value): + ms3d_value = Ms3dSpec.FLAG_NONE + if Ms3dUi.FLAG_SELECTED in ui_value: + ms3d_value |= Ms3dSpec.FLAG_SELECTED + if Ms3dUi.FLAG_HIDDEN in ui_value: + ms3d_value |= Ms3dSpec.FLAG_HIDDEN + if Ms3dUi.FLAG_SELECTED2 in ui_value: + ms3d_value |= Ms3dSpec.FLAG_SELECTED2 + if Ms3dUi.FLAG_DIRTY in ui_value: + ms3d_value |= Ms3dSpec.FLAG_DIRTY + if Ms3dUi.FLAG_ISKEY in ui_value: + ms3d_value |= Ms3dSpec.FLAG_ISKEY + if Ms3dUi.FLAG_NEWLYCREATED in ui_value: + ms3d_value |= Ms3dSpec.FLAG_NEWLYCREATED + if Ms3dUi.FLAG_MARKED in ui_value: + ms3d_value |= Ms3dSpec.FLAG_MARKED + return ms3d_value + + ########################################################################### + ICON_OPTIONS = 'LAMP' + ICON_OBJECT = 'WORLD' + ICON_PROCESSING = 'OBJECT_DATAMODE' + ICON_MODIFIER = 'MODIFIER' + ICON_ANIMATION = 'RENDER_ANIMATION' + ICON_ROTATION_MODE = 'BONE_DATA' + ICON_ERROR = 'ERROR' + + ########################################################################### + PROP_DEFAULT_VERBOSE = DEFAULT_VERBOSE + + ########################################################################### + PROP_DEFAULT_USE_JOINT_SIZE = False + PROP_DEFAULT_JOINT_SIZE = 0.01 + PROP_JOINT_SIZE_MIN = 0.01 + PROP_JOINT_SIZE_MAX = 10.0 + PROP_JOINT_SIZE_STEP = 0.1 + PROP_JOINT_SIZE_PRECISION = 2 + + ########################################################################### + PROP_DEFAULT_USE_ANIMATION = True + PROP_DEFAULT_NORMALIZE_WEIGHTS = True + PROP_DEFAULT_SHRINK_TO_KEYS = False + PROP_DEFAULT_BAKE_EACH_FRAME = True + PROP_DEFAULT_JOINT_TO_BONES = False + PROP_DEFAULT_USE_BLENDER_NAMES = True + PROP_DEFAULT_USE_BLENDER_MATERIALS = False + PROP_DEFAULT_EXTENDED_NORMAL_HANDLING = False + PROP_DEFAULT_APPLY_TRANSFORM = True + PROP_DEFAULT_APPLY_MODIFIERS = True + + ########################################################################### + PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW = 'PREVIEW' + PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER = 'RENDER' + PROP_DEFAULT_APPLY_MODIFIERS_MODE = PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW + + ########################################################################### + PROP_ITEM_ROTATION_MODE_EULER = 'EULER' + PROP_ITEM_ROTATION_MODE_QUATERNION = 'QUATERNION' + PROP_DEFAULT_ANIMATION_ROTATION = PROP_ITEM_ROTATION_MODE_EULER + + ########################################################################### + OPT_SMOOTHING_GROUP_APPLY = 'io_scene_ms3d.apply_smoothing_group' + OPT_GROUP_APPLY = 'io_scene_ms3d.apply_group' + OPT_MATERIAL_APPLY = 'io_scene_ms3d.apply_material' + + +############################################################################### +class Ms3dImportOperator(Operator, ImportHelper): + """ Load a MilkShape3D MS3D File """ + bl_idname = 'import_scene.ms3d' + bl_label = ms3d_str['BL_LABEL_IMPORTER'] + bl_description = ms3d_str['BL_DESCRIPTION_IMPORTER'] + bl_options = {'PRESET', } + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + + filepath = StringProperty( + subtype='FILE_PATH', + options={'HIDDEN', } + ) + + verbose = BoolProperty( + name=ms3d_str['PROP_NAME_VERBOSE'], + description=ms3d_str['PROP_DESC_VERBOSE'], + default=Ms3dUi.PROP_DEFAULT_VERBOSE, + ) + + use_animation = BoolProperty( + name=ms3d_str['PROP_NAME_USE_ANIMATION'], + description=ms3d_str['PROP_DESC_USE_ANIMATION'], + default=Ms3dUi.PROP_DEFAULT_USE_ANIMATION, + ) + + rotation_mode = EnumProperty( + name=ms3d_str['PROP_NAME_ROTATION_MODE'], + description=ms3d_str['PROP_DESC_ROTATION_MODE'], + items=( (Ms3dUi.PROP_ITEM_ROTATION_MODE_EULER, + ms3d_str['PROP_ITEM_ROTATION_MODE_EULER_1'], + ms3d_str['PROP_ITEM_ROTATION_MODE_EULER_2']), + (Ms3dUi.PROP_ITEM_ROTATION_MODE_QUATERNION, + ms3d_str['PROP_ITEM_ROTATION_MODE_QUATERNION_1'], + ms3d_str['PROP_ITEM_ROTATION_MODE_QUATERNION_2']), + ), + default=Ms3dUi.PROP_DEFAULT_ANIMATION_ROTATION, + ) + + use_joint_size = BoolProperty( + name=ms3d_str['PROP_NAME_USE_JOINT_SIZE'], + description=ms3d_str['PROP_DESC_USE_JOINT_SIZE'], + default=Ms3dUi.PROP_DEFAULT_USE_JOINT_SIZE, + ) + + joint_size = FloatProperty( + name=ms3d_str['PROP_NAME_IMPORT_JOINT_SIZE'], + description=ms3d_str['PROP_DESC_IMPORT_JOINT_SIZE'], + min=Ms3dUi.PROP_JOINT_SIZE_MIN, max=Ms3dUi.PROP_JOINT_SIZE_MAX, + precision=Ms3dUi.PROP_JOINT_SIZE_PRECISION, \ + step=Ms3dUi.PROP_JOINT_SIZE_STEP, + default=Ms3dUi.PROP_DEFAULT_JOINT_SIZE, + subtype='FACTOR', + #options={'HIDDEN', }, + ) + + use_joint_to_bones = BoolProperty( + name=ms3d_str['PROP_NAME_JOINT_TO_BONES'], + description=ms3d_str['PROP_DESC_JOINT_TO_BONES'], + default=Ms3dUi.PROP_DEFAULT_JOINT_TO_BONES, + ) + + use_extended_normal_handling = BoolProperty( + name=ms3d_str['PROP_NAME_EXTENDED_NORMAL_HANDLING'], + description=ms3d_str['PROP_DESC_EXTENDED_NORMAL_HANDLING'], + default=Ms3dUi.PROP_DEFAULT_EXTENDED_NORMAL_HANDLING, + ) + + filename_ext = StringProperty( + default=ms3d_str['FILE_EXT'], + options={'HIDDEN', } + ) + + filter_glob = StringProperty( + default=ms3d_str['FILE_FILTER'], + options={'HIDDEN', } + ) + + + @property + def use_euler_rotation(self): + return (Ms3dUi.PROP_ITEM_ROTATION_MODE_EULER \ + in self.rotation_mode) + + @property + def use_quaternion_rotation(self): + return (Ms3dUi.PROP_ITEM_ROTATION_MODE_QUATERNION \ + in self.rotation_mode) + + + # draw the option panel + def draw(self, blender_context): + layout = self.layout + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS) + box.prop(self, 'verbose', icon='SPEAKER') + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_PROCESSING'], + icon=Ms3dUi.ICON_PROCESSING) + box.prop(self, 'use_extended_normal_handling') + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_ANIMATION'], icon=Ms3dUi.ICON_ANIMATION) + box.prop(self, 'use_animation') + if (self.use_animation): + box.prop(self, 'rotation_mode', icon=Ms3dUi.ICON_ROTATION_MODE, + expand=False) + box.prop(self, 'use_joint_size') + if (self.use_joint_size): + col = box.column() + row = col.row() + row.prop(self, 'joint_size') + box.prop(self, 'use_joint_to_bones') + if (self.use_joint_to_bones): + box.box().label(ms3d_str['LABEL_NAME_JOINT_TO_BONES'], + icon=Ms3dUi.ICON_ERROR) + + # entrypoint for MS3D -> blender + def execute(self, blender_context): + """ start executing """ + from io_scene_ms3d.ms3d_import import (Ms3dImporter, ) + return Ms3dImporter( + report=self.report, + verbose=self.verbose, + use_extended_normal_handling=self.use_extended_normal_handling, + use_animation=self.use_animation, + use_quaternion_rotation=self.use_quaternion_rotation, + use_joint_size=self.use_joint_size, + joint_size=self.joint_size, + use_joint_to_bones=self.use_joint_to_bones, + ).read( + blender_context, + self.filepath + ) + + def invoke(self, blender_context, event): + blender_context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL', } + + @staticmethod + def menu_func(cls, blender_context): + cls.layout.operator( + Ms3dImportOperator.bl_idname, + text=ms3d_str['TEXT_OPERATOR'], + ) + + +class Ms3dExportOperator(Operator, ExportHelper): + """Save a MilkShape3D MS3D File""" + bl_idname = 'export_scene.ms3d' + bl_label = ms3d_str['BL_LABEL_EXPORTER'] + bl_description = ms3d_str['BL_DESCRIPTION_EXPORTER'] + bl_options = {'PRESET', } + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + + filepath = StringProperty( + subtype='FILE_PATH', + options={'HIDDEN', } + ) + + verbose = BoolProperty( + name=ms3d_str['PROP_NAME_VERBOSE'], + description=ms3d_str['PROP_DESC_VERBOSE'], + default=Ms3dUi.PROP_DEFAULT_VERBOSE, + ) + + use_blender_names = BoolProperty( + name=ms3d_str['PROP_NAME_USE_BLENDER_NAMES'], + description=ms3d_str['PROP_DESC_USE_BLENDER_NAMES'], + default=Ms3dUi.PROP_DEFAULT_USE_BLENDER_NAMES, + ) + + use_blender_materials = BoolProperty( + name=ms3d_str['PROP_NAME_USE_BLENDER_MATERIALS'], + description=ms3d_str['PROP_DESC_USE_BLENDER_MATERIALS'], + default=Ms3dUi.PROP_DEFAULT_USE_BLENDER_MATERIALS, + ) + + apply_transform = BoolProperty( + name=ms3d_str['PROP_NAME_APPLY_TRANSFORM'], + description=ms3d_str['PROP_DESC_APPLY_TRANSFORM'], + default=Ms3dUi.PROP_DEFAULT_APPLY_TRANSFORM, + ) + + apply_modifiers = BoolProperty( + name=ms3d_str['PROP_NAME_APPLY_MODIFIERS'], + description=ms3d_str['PROP_DESC_APPLY_MODIFIERS'], + default=Ms3dUi.PROP_DEFAULT_APPLY_MODIFIERS, + ) + + apply_modifiers_mode = EnumProperty( + name=ms3d_str['PROP_NAME_APPLY_MODIFIERS_MODE'], + description=ms3d_str['PROP_DESC_APPLY_MODIFIERS_MODE'], + items=( (Ms3dUi.PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW, + ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_1'], + ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_2']), + (Ms3dUi.PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER, + ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_1'], + ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_2']), + ), + default=Ms3dUi.PROP_DEFAULT_APPLY_MODIFIERS_MODE, + ) + + use_animation = BoolProperty( + name=ms3d_str['PROP_NAME_USE_ANIMATION'], + description=ms3d_str['PROP_DESC_USE_ANIMATION'], + default=Ms3dUi.PROP_DEFAULT_USE_ANIMATION, + ) + + normalize_weights = BoolProperty( + name=ms3d_str['PROP_NAME_NORMALIZE_WEIGHTS'], + description=ms3d_str['PROP_DESC_NORMALIZE_WEIGHTS'], + default=Ms3dUi.PROP_DEFAULT_NORMALIZE_WEIGHTS, + ) + + shrink_to_keys = BoolProperty( + name=ms3d_str['PROP_NAME_SHRINK_TO_KEYS'], + description=ms3d_str['PROP_DESC_SHRINK_TO_KEYS'], + default=Ms3dUi.PROP_DEFAULT_SHRINK_TO_KEYS, + ) + + bake_each_frame = BoolProperty( + name=ms3d_str['PROP_NAME_BAKE_EACH_FRAME'], + description=ms3d_str['PROP_DESC_BAKE_EACH_FRAME'], + default=Ms3dUi.PROP_DEFAULT_BAKE_EACH_FRAME, + ) + + check_existing = BoolProperty( + default=False, + options={'HIDDEN', } + ) + + filename_ext = StringProperty( + default=ms3d_str['FILE_EXT'], + options={'HIDDEN', } + ) + + filter_glob = StringProperty( + default=ms3d_str['FILE_FILTER'], + options={'HIDDEN', } + ) + + + ##EXPORT_ACTIVE_ONLY: + ##limit availability to only active mesh object + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.active_object + and blender_context.active_object.type in {'MESH', } + and blender_context.active_object.data + and blender_context.active_object.data.ms3d is not None + ) + + # draw the option panel + def draw(self, blender_context): + layout = self.layout + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS) + box.prop(self, 'verbose', icon='SPEAKER') + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_PROCESSING'], + icon=Ms3dUi.ICON_PROCESSING) + row = box.row() + row.label(ms3d_str['PROP_NAME_ACTIVE'], icon='ROTACTIVE') + row.label(blender_context.active_object.name) + #box.prop(self, 'use_blender_names', icon='LINK_BLEND') + box.prop(self, 'use_blender_names') + box.prop(self, 'use_blender_materials') + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_MODIFIER'], + icon=Ms3dUi.ICON_MODIFIER) + box.prop(self, 'apply_transform') + row = box.row() + row.prop(self, 'apply_modifiers') + sub = row.row() + sub.active = self.apply_modifiers + sub.prop(self, 'apply_modifiers_mode', text="") + + box = layout.box() + box.label(ms3d_str['LABEL_NAME_ANIMATION'], + icon=Ms3dUi.ICON_ANIMATION) + box.prop(self, 'use_animation') + if (self.use_animation): + box.prop(self, 'normalize_weights') + box.prop(self, 'shrink_to_keys') + box.prop(self, 'bake_each_frame') + + # entrypoint for blender -> MS3D + def execute(self, blender_context): + """start executing""" + from io_scene_ms3d.ms3d_export import (Ms3dExporter, ) + return Ms3dExporter( + self.report, + verbose=self.verbose, + use_blender_names=self.use_blender_names, + use_blender_materials=self.use_blender_materials, + apply_transform=self.apply_transform, + apply_modifiers=self.apply_modifiers, + apply_modifiers_mode=self.apply_modifiers_mode, + use_animation=self.use_animation, + normalize_weights=self.normalize_weights, + shrink_to_keys=self.shrink_to_keys, + bake_each_frame=self.bake_each_frame, + ).write( + blender_context, + self.filepath + ) + + # + def invoke(self, blender_context, event): + blender_context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL", } + + @staticmethod + def menu_func(cls, blender_context): + cls.layout.operator( + Ms3dExportOperator.bl_idname, + text=ms3d_str['TEXT_OPERATOR'] + ) + + +############################################################################### +## +############################################################################### + + +############################################################################### +class Ms3dSetSmoothingGroupOperator(Operator): + bl_idname = Ms3dUi.OPT_SMOOTHING_GROUP_APPLY + bl_label = ms3d_str['BL_LABEL_SMOOTHING_GROUP_OPERATOR'] + bl_options = {'INTERNAL', } + + smoothing_group_index = IntProperty( + name=ms3d_str['PROP_SMOOTHING_GROUP_INDEX'], + options={'HIDDEN', 'SKIP_SAVE', }, + ) + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + and blender_context.mode == 'EDIT_MESH' + and blender_context.tool_settings.mesh_select_mode[2] + ) + + def execute(self, blender_context): + custom_data = blender_context.object.data.ms3d + blender_mesh = blender_context.object.data + bm = from_edit_mesh(blender_mesh) + layer_smoothing_group = bm.faces.layers.int.get( + ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP']) + if custom_data.apply_mode in {'SELECT', 'DESELECT', }: + if layer_smoothing_group is not None: + is_select = (custom_data.apply_mode == 'SELECT') + for bmf in bm.faces: + if (bmf[layer_smoothing_group] \ + == self.smoothing_group_index): + bmf.select_set(is_select) + elif custom_data.apply_mode == 'ASSIGN': + if layer_smoothing_group is None: + layer_smoothing_group = bm.faces.layers.int.new( + ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP']) + blender_mesh_object = blender_context.object + get_edge_split_modifier_add_if(blender_mesh_object) + blender_face_list = [] + for bmf in bm.faces: + if not bmf.smooth: + bmf.smooth = True + if bmf.select: + bmf[layer_smoothing_group] = self.smoothing_group_index + blender_face_list.append(bmf) + edge_dict = {} + for bmf in blender_face_list: + bmf.smooth = True + for bme in bmf.edges: + if edge_dict.get(bme) is None: + edge_dict[bme] = 0 + else: + edge_dict[bme] += 1 + is_border = (edge_dict[bme] == 0) + if is_border: + surround_face_smoothing_group_index \ + = self.smoothing_group_index + for bmf in bme.link_faces: + if bmf[layer_smoothing_group] \ + != surround_face_smoothing_group_index: + surround_face_smoothing_group_index \ + = bmf[layer_smoothing_group] + break; + if surround_face_smoothing_group_index \ + == self.smoothing_group_index: + is_border = False + bme.seam = is_border + bme.smooth = not is_border + bm.free() + enable_edit_mode(False, blender_context) + enable_edit_mode(True, blender_context) + return {'FINISHED', } + + +class Ms3dGroupOperator(Operator): + bl_idname = Ms3dUi.OPT_GROUP_APPLY + bl_label = ms3d_str['BL_LABEL_GROUP_OPERATOR'] + bl_options = {'INTERNAL', } + + mode = EnumProperty( + items=( ('', "", ""), + ('ADD_GROUP', + ms3d_str['ENUM_ADD_GROUP_1'], + ms3d_str['ENUM_ADD_GROUP_2']), + ('REMOVE_GROUP', + ms3d_str['ENUM_REMOVE_GROUP_1'], + ms3d_str['ENUM_REMOVE_GROUP_2']), + ('ASSIGN', + ms3d_str['ENUM_ASSIGN_1'], + ms3d_str['ENUM_ASSIGN_2_GROUP']), + ('REMOVE', + ms3d_str['ENUM_REMOVE_1'], + ms3d_str['ENUM_REMOVE_2_GROUP']), + ('SELECT', + ms3d_str['ENUM_SELECT_1'], + ms3d_str['ENUM_SELECT_2_GROUP']), + ('DESELECT', + ms3d_str['ENUM_DESELECT_1'], + ms3d_str['ENUM_DESELECT_2_GROUP']), + ), + options={'HIDDEN', 'SKIP_SAVE', }, + ) + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + and blender_context.mode == 'EDIT_MESH' + #and blender_context.object.data.ms3d.selected_group_index != -1 + ) + + def execute(self, blender_context): + custom_data = blender_context.object.data.ms3d + blender_mesh = blender_context.object.data + bm = None + bm = from_edit_mesh(blender_mesh) + + if self.mode == 'ADD_GROUP': + item = custom_data.create_group() + layer_group = bm.faces.layers.int.get( + ms3d_str['OBJECT_LAYER_GROUP']) + if layer_group is None: + bm.faces.layers.int.new(ms3d_str['OBJECT_LAYER_GROUP']) + + elif self.mode == 'REMOVE_GROUP': + custom_data.remove_group() + + elif (custom_data.selected_group_index >= 0) and ( + custom_data.selected_group_index < len(custom_data.groups)): + if self.mode in {'SELECT', 'DESELECT', }: + layer_group = bm.faces.layers.int.get( + ms3d_str['OBJECT_LAYER_GROUP']) + if layer_group is not None: + is_select = (self.mode == 'SELECT') + id = custom_data.groups[ + custom_data.selected_group_index].id + for bmf in bm.faces: + if bmf[layer_group] == id: + bmf.select_set(is_select) + + elif self.mode in {'ASSIGN', 'REMOVE', }: + layer_group = bm.faces.layers.int.get( + ms3d_str['OBJECT_LAYER_GROUP']) + if layer_group is None: + layer_group = bm.faces.layers.int.new( + ms3d_str['OBJECT_LAYER_GROUP']) + + is_assign = (self.mode == 'ASSIGN') + id = custom_data.groups[custom_data.selected_group_index].id + for bmf in bm.faces: + if bmf.select: + if is_assign: + bmf[layer_group] = id + else: + bmf[layer_group] = -1 + if bm is not None: + bm.free() + enable_edit_mode(False, blender_context) + enable_edit_mode(True, blender_context) + return {'FINISHED', } + + +class Ms3dMaterialOperator(Operator): + bl_idname = Ms3dUi.OPT_MATERIAL_APPLY + bl_label = ms3d_str['BL_LABEL_MATERIAL_OPERATOR'] + bl_options = {'INTERNAL', } + + mode = EnumProperty( + items=( ('', "", ""), + ('FROM_BLENDER', + ms3d_str['ENUM_FROM_BLENDER_1'], + ms3d_str['ENUM_FROM_BLENDER_2']), + ('TO_BLENDER', + ms3d_str['ENUM_TO_BLENDER_1'], + ms3d_str['ENUM_TO_BLENDER_2']), + ), + options={'HIDDEN', 'SKIP_SAVE', }, + ) + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + and blender_context.material + and blender_context.material.ms3d is not None + ) + + def execute(self, blender_context): + blender_material = blender_context.active_object.active_material + ms3d_material = blender_material.ms3d + + if self.mode == 'FROM_BLENDER': + Ms3dMaterialHelper.copy_from_blender(self, blender_context, + ms3d_material, blender_material) + pass + + elif self.mode == 'TO_BLENDER': + # not implemented + pass + + return {'FINISHED', } + + # entrypoint for option via UI + def invoke(self, blender_context, event): + return blender_context.window_manager.invoke_props_dialog(self) + + +############################################################################### +class Ms3dGroupProperties(PropertyGroup): + name = StringProperty( + name=ms3d_str['PROP_NAME_NAME'], + description=ms3d_str['PROP_DESC_GROUP_NAME'], + default="", + #options={'HIDDEN', }, + ) + + flags = EnumProperty( + name=ms3d_str['PROP_NAME_FLAGS'], + description=ms3d_str['PROP_DESC_FLAGS_GROUP'], + items=(#(Ms3dUi.FLAG_NONE, ms3d_str['ENUM_FLAG_NONE_1'], + # ms3d_str['ENUM_FLAG_NONE_2'], + # Ms3dSpec.FLAG_NONE), + (Ms3dUi.FLAG_SELECTED, + ms3d_str['ENUM_FLAG_SELECTED_1'], + ms3d_str['ENUM_FLAG_SELECTED_2'], + Ms3dSpec.FLAG_SELECTED), + (Ms3dUi.FLAG_HIDDEN, + ms3d_str['ENUM_FLAG_HIDDEN_1'], + ms3d_str['ENUM_FLAG_HIDDEN_2'], + Ms3dSpec.FLAG_HIDDEN), + (Ms3dUi.FLAG_SELECTED2, + ms3d_str['ENUM_FLAG_SELECTED2_1'], + ms3d_str['ENUM_FLAG_SELECTED2_2'], + Ms3dSpec.FLAG_SELECTED2), + (Ms3dUi.FLAG_DIRTY, + ms3d_str['ENUM_FLAG_DIRTY_1'], + ms3d_str['ENUM_FLAG_DIRTY_2'], + Ms3dSpec.FLAG_DIRTY), + (Ms3dUi.FLAG_ISKEY, + ms3d_str['ENUM_FLAG_ISKEY_1'], + ms3d_str['ENUM_FLAG_ISKEY_2'], + Ms3dSpec.FLAG_ISKEY), + (Ms3dUi.FLAG_NEWLYCREATED, + ms3d_str['ENUM_FLAG_NEWLYCREATED_1'], + ms3d_str['ENUM_FLAG_NEWLYCREATED_2'], + Ms3dSpec.FLAG_NEWLYCREATED), + (Ms3dUi.FLAG_MARKED, + ms3d_str['ENUM_FLAG_MARKED_1'], + ms3d_str['ENUM_FLAG_MARKED_2'], + Ms3dSpec.FLAG_MARKED), + ), + default=Ms3dUi.flags_from_ms3d(Ms3dSpec.DEFAULT_FLAGS), + options={'ENUM_FLAG', 'ANIMATABLE', }, + ) + + comment = StringProperty( + name=ms3d_str['PROP_NAME_COMMENT'], + description=ms3d_str['PROP_DESC_COMMENT_GROUP'], + default="", + #options={'HIDDEN', }, + ) + + id = IntProperty(options={'HIDDEN', },) + + +class Ms3dModelProperties(PropertyGroup): + name = StringProperty( + name=ms3d_str['PROP_NAME_NAME'], + description=ms3d_str['PROP_DESC_NAME_MODEL'], + default="", + #options={'HIDDEN', }, + ) + + joint_size = FloatProperty( + name=ms3d_str['PROP_NAME_JOINT_SIZE'], + description=ms3d_str['PROP_DESC_JOINT_SIZE'], + min=Ms3dUi.PROP_JOINT_SIZE_MIN, max=Ms3dUi.PROP_JOINT_SIZE_MAX, + precision=Ms3dUi.PROP_JOINT_SIZE_PRECISION, \ + step=Ms3dUi.PROP_JOINT_SIZE_STEP, + default=Ms3dUi.PROP_DEFAULT_JOINT_SIZE, + subtype='FACTOR', + #options={'HIDDEN', }, + ) + + transparency_mode = EnumProperty( + name=ms3d_str['PROP_NAME_TRANSPARENCY_MODE'], + description=ms3d_str['PROP_DESC_TRANSPARENCY_MODE'], + items=( (Ms3dUi.MODE_TRANSPARENCY_SIMPLE, + ms3d_str['PROP_MODE_TRANSPARENCY_SIMPLE_1'], + ms3d_str['PROP_MODE_TRANSPARENCY_SIMPLE_2'], + Ms3dSpec.MODE_TRANSPARENCY_SIMPLE), + (Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES, + ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_1'], + ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_2'], + Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES), + (Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF, + ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_1'], + ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_2'], + Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF), + ), + default=Ms3dUi.transparency_mode_from_ms3d( + Ms3dSpec.DEFAULT_MODEL_TRANSPARENCY_MODE), + #options={'HIDDEN', }, + ) + + alpha_ref = FloatProperty( + name=ms3d_str['PROP_NAME_ALPHA_REF'], + description=ms3d_str['PROP_DESC_ALPHA_REF'], + min=0, max=1, precision=3, step=0.1, + default=0.5, + subtype='FACTOR', + #options={'HIDDEN', }, + ) + + comment = StringProperty( + name=ms3d_str['PROP_NAME_COMMENT'], + description=ms3d_str['PROP_DESC_COMMENT_MODEL'], + default="", + #options={'HIDDEN', }, + ) + + ########################## + # ms3d group handling + # + apply_mode = EnumProperty( + items=( ('ASSIGN', + ms3d_str['ENUM_ASSIGN_1'], + ms3d_str['ENUM_ASSIGN_2_SMOOTHING_GROUP']), + ('SELECT', + ms3d_str['ENUM_SELECT_1'], + ms3d_str['ENUM_SELECT_2_SMOOTHING_GROUP']), + ('DESELECT', + ms3d_str['ENUM_DESELECT_1'], + ms3d_str['ENUM_DESELECT_2_SMOOTHING_GROUP']), + ), + default='SELECT', + options={'HIDDEN', 'SKIP_SAVE', }, + ) + + selected_group_index = IntProperty( + default=-1, + min=-1, + options={'HIDDEN', 'SKIP_SAVE', }, + ) + # + # ms3d group handling + ########################## + + groups = CollectionProperty( + type=Ms3dGroupProperties, + #options={'HIDDEN', }, + ) + + + def generate_unique_id(self): + return randrange(1, 0x7FFFFFFF) # pseudo unique id + + def create_group(self): + item = self.groups.add() + item.id = self.generate_unique_id() + length = len(self.groups) + self.selected_group_index = length - 1 + + item.name = ms3d_str['STRING_FORMAT_GROUP'].format(length) + return item + + def remove_group(self): + index = self.selected_group_index + length = len(self.groups) + if (index >= 0) and (index < length): + if index > 0 or length == 1: + self.selected_group_index = index - 1 + self.groups.remove(index) + + +class Ms3dArmatureProperties(PropertyGroup): + name = StringProperty( + name=ms3d_str['PROP_NAME_NAME'], + description=ms3d_str['PROP_DESC_NAME_ARMATURE'], + default="", + #options={'HIDDEN', }, + ) + + +class Ms3dJointProperties(PropertyGroup): + name = StringProperty( + name=ms3d_str['PROP_NAME_NAME'], + description=ms3d_str['PROP_DESC_NAME_JOINT'], + default="", + #options={'HIDDEN', }, + ) + + flags = EnumProperty( + name=ms3d_str['PROP_NAME_FLAGS'], + description=ms3d_str['PROP_DESC_FLAGS_JOINT'], + items=(#(Ms3dUi.FLAG_NONE, + # ms3d_str['ENUM_FLAG_NONE_1'], + # ms3d_str['ENUM_FLAG_NONE_2'], + # Ms3dSpec.FLAG_NONE), + (Ms3dUi.FLAG_SELECTED, + ms3d_str['ENUM_FLAG_SELECTED_1'], + ms3d_str['ENUM_FLAG_SELECTED_2'], + Ms3dSpec.FLAG_SELECTED), + (Ms3dUi.FLAG_HIDDEN, + ms3d_str['ENUM_FLAG_HIDDEN_1'], + ms3d_str['ENUM_FLAG_HIDDEN_2'], + Ms3dSpec.FLAG_HIDDEN), + (Ms3dUi.FLAG_SELECTED2, + ms3d_str['ENUM_FLAG_SELECTED2_1'], + ms3d_str['ENUM_FLAG_SELECTED2_2'], + Ms3dSpec.FLAG_SELECTED2), + (Ms3dUi.FLAG_DIRTY, + ms3d_str['ENUM_FLAG_DIRTY_1'], + ms3d_str['ENUM_FLAG_DIRTY_2'], + Ms3dSpec.FLAG_DIRTY), + (Ms3dUi.FLAG_ISKEY, + ms3d_str['ENUM_FLAG_ISKEY_1'], + ms3d_str['ENUM_FLAG_ISKEY_2'], + Ms3dSpec.FLAG_ISKEY), + (Ms3dUi.FLAG_NEWLYCREATED, + ms3d_str['ENUM_FLAG_NEWLYCREATED_1'], + ms3d_str['ENUM_FLAG_NEWLYCREATED_2'], + Ms3dSpec.FLAG_NEWLYCREATED), + (Ms3dUi.FLAG_MARKED, + ms3d_str['ENUM_FLAG_MARKED_1'], + ms3d_str['ENUM_FLAG_MARKED_2'], + Ms3dSpec.FLAG_MARKED), + ), + default=Ms3dUi.flags_from_ms3d(Ms3dSpec.DEFAULT_FLAGS), + options={'ENUM_FLAG', 'ANIMATABLE', }, + ) + + color = FloatVectorProperty( + name=ms3d_str['PROP_NAME_COLOR'], + description=ms3d_str['PROP_DESC_COLOR_JOINT'], + subtype='COLOR', size=3, min=0, max=1, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_JOINT_COLOR, + #options={'HIDDEN', }, + ) + + comment = StringProperty( + name=ms3d_str['PROP_NAME_COMMENT'], + description=ms3d_str['PROP_DESC_COMMENT_JOINT'], + default="", + #options={'HIDDEN', }, + ) + + +class Ms3dMaterialHelper: + @staticmethod + def copy_to_blender_ambient(cls, blender_context): + pass + + @staticmethod + def copy_to_blender_diffuse(cls, blender_context): + cls.id_data.diffuse_color = cls.diffuse[0:3] + #cls.id_data.diffuse_intensity = cls.diffuse[3] + pass + + @staticmethod + def copy_to_blender_specular(cls, blender_context): + cls.id_data.specular_color = cls.specular[0:3] + #cls.id_data.specular_intensity = cls.specular[3] + pass + + @staticmethod + def copy_to_blender_emissive(cls, blender_context): + cls.id_data.emit = (cls.emissive[0] + cls.emissive[1] \ + + cls.emissive[2]) / 3.0 + pass + + @staticmethod + def copy_to_blender_shininess(cls, blender_context): + cls.id_data.specular_hardness = cls.shininess * 4.0 + pass + + @staticmethod + def copy_to_blender_transparency(cls, blender_context): + cls.id_data.alpha = 1.0 - cls.transparency + pass + + + @staticmethod + def copy_from_blender(cls, blender_context, ms3d_material, blender_material): + # copy, bacause of auto update, it would distord original values + blender_material_diffuse_color = blender_material.diffuse_color.copy() + blender_material_diffuse_intensity = blender_material.diffuse_intensity + blender_material_specular_color = blender_material.specular_color.copy() + blender_material_specular_intensity = \ + blender_material.specular_intensity + blender_material_emit = blender_material.emit + blender_material_specular_hardness = \ + blender_material.specular_hardness + blender_material_alpha = blender_material.alpha + + blender_material_texture = None + for slot in blender_material.texture_slots: + if slot and slot.use_map_color_diffuse \ + and slot.texture.type == 'IMAGE': + blender_material_texture = slot.texture.image.filepath + break + + blender_material_alphamap = None + for slot in blender_material.texture_slots: + if slot and not slot.use_map_color_diffuse \ + and slot.use_map_alpha and slot.texture.type == 'IMAGE': + blender_material_alphamap = slot.texture.image.filepath + break + + ms3d_material.diffuse[0] = blender_material_diffuse_color[0] + ms3d_material.diffuse[1] = blender_material_diffuse_color[1] + ms3d_material.diffuse[2] = blender_material_diffuse_color[2] + ms3d_material.diffuse[3] = 1.0 + ms3d_material.specular[0] = blender_material_specular_color[0] + ms3d_material.specular[1] = blender_material_specular_color[1] + ms3d_material.specular[2] = blender_material_specular_color[2] + ms3d_material.specular[3] = 1.0 + ms3d_material.emissive[0] = blender_material_emit + ms3d_material.emissive[1] = blender_material_emit + ms3d_material.emissive[2] = blender_material_emit + ms3d_material.emissive[3] = 1.0 + ms3d_material.shininess = blender_material_specular_hardness / 4.0 + ms3d_material.transparency = 1.0 - blender_material_alpha + + if blender_material_texture: + ms3d_material.texture = blender_material_texture + else: + ms3d_material.texture = "" + + if blender_material_alphamap: + ms3d_material.alphamap = blender_material_alphamap + else: + ms3d_material.alphamap = "" + + +class Ms3dMaterialProperties(PropertyGroup): + name = StringProperty( + name=ms3d_str['PROP_NAME_NAME'], + description=ms3d_str['PROP_DESC_NAME_MATERIAL'], + default="", + #options={'HIDDEN', }, + ) + + ambient = FloatVectorProperty( + name=ms3d_str['PROP_NAME_AMBIENT'], + description=ms3d_str['PROP_DESC_AMBIENT'], + subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_MATERIAL_AMBIENT, + update=Ms3dMaterialHelper.copy_to_blender_ambient, + #options={'HIDDEN', }, + ) + + diffuse = FloatVectorProperty( + name=ms3d_str['PROP_NAME_DIFFUSE'], + description=ms3d_str['PROP_DESC_DIFFUSE'], + subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_MATERIAL_DIFFUSE, + update=Ms3dMaterialHelper.copy_to_blender_diffuse, + #options={'HIDDEN', }, + ) + + specular = FloatVectorProperty( + name=ms3d_str['PROP_NAME_SPECULAR'], + description=ms3d_str['PROP_DESC_SPECULAR'], + subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_MATERIAL_SPECULAR, + update=Ms3dMaterialHelper.copy_to_blender_specular, + #options={'HIDDEN', }, + ) + + emissive = FloatVectorProperty( + name=ms3d_str['PROP_NAME_EMISSIVE'], + description=ms3d_str['PROP_DESC_EMISSIVE'], + subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_MATERIAL_EMISSIVE, + update=Ms3dMaterialHelper.copy_to_blender_emissive, + #options={'HIDDEN', }, + ) + + shininess = FloatProperty( + name=ms3d_str['PROP_NAME_SHININESS'], + description=ms3d_str['PROP_DESC_SHININESS'], + min=0, max=Ms3dSpec.MAX_MATERIAL_SHININESS, precision=3, step=0.1, + default=Ms3dSpec.DEFAULT_MATERIAL_SHININESS, + subtype='FACTOR', + update=Ms3dMaterialHelper.copy_to_blender_shininess, + #options={'HIDDEN', }, + ) + + transparency = FloatProperty( + name=ms3d_str['PROP_NAME_TRANSPARENCY'], + description=ms3d_str['PROP_DESC_TRANSPARENCY'], + min=0, max=1, precision=3, step=0.1, + default=0, + subtype='FACTOR', + update=Ms3dMaterialHelper.copy_to_blender_transparency, + #options={'HIDDEN', }, + ) + + mode = EnumProperty( + name=ms3d_str['PROP_NAME_MODE'], + description=ms3d_str['PROP_DESC_MODE_TEXTURE'], + items=( (Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA, + ms3d_str['PROP_FLAG_TEXTURE_COMBINE_ALPHA_1'], + ms3d_str['PROP_FLAG_TEXTURE_COMBINE_ALPHA_2'], + Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA), + (Ms3dUi.FLAG_TEXTURE_HAS_ALPHA, + ms3d_str['PROP_FLAG_TEXTURE_HAS_ALPHA_1'], + ms3d_str['PROP_FLAG_TEXTURE_HAS_ALPHA_2'], + Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA), + (Ms3dUi.FLAG_TEXTURE_SPHERE_MAP, + ms3d_str['PROP_FLAG_TEXTURE_SPHERE_MAP_1'], + ms3d_str['PROP_FLAG_TEXTURE_SPHERE_MAP_2'], + Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP), + ), + default=Ms3dUi.texture_mode_from_ms3d( + Ms3dSpec.DEFAULT_MATERIAL_MODE), + options={'ANIMATABLE', 'ENUM_FLAG', }, + ) + + texture = StringProperty( + name=ms3d_str['PROP_NAME_TEXTURE'], + description=ms3d_str['PROP_DESC_TEXTURE'], + default="", + subtype = 'FILE_PATH' + #options={'HIDDEN', }, + ) + + alphamap = StringProperty( + name=ms3d_str['PROP_NAME_ALPHAMAP'], + description=ms3d_str['PROP_DESC_ALPHAMAP'], + default="", + subtype = 'FILE_PATH' + #options={'HIDDEN', }, + ) + + comment = StringProperty( + name=ms3d_str['PROP_NAME_COMMENT'], + description=ms3d_str['PROP_DESC_COMMENT_MATERIAL'], + default="", + #options={'HIDDEN', }, + ) + + +############################################################################### +# http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53355 +class Ms3dGroupUILise(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + layout.label(item.name, icon_value=icon) + + +############################################################################### +class Ms3dMeshPanel(Panel): + bl_label = ms3d_str['LABEL_PANEL_MODEL'] + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'object' + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + ) + + def draw_header(self, blender_context): + layout = self.layout + layout.label(icon='PLUGIN') + + def draw(self, blender_context): + layout = self.layout + custom_data = blender_context.object.data.ms3d + + row = layout.row() + row.prop(custom_data, 'name') + + col = layout.column() + row = col.row() + row.prop(custom_data, 'joint_size') + row = col.row() + row.prop(custom_data, 'transparency_mode') + row = col.row() + row.prop(custom_data, 'alpha_ref', ) + + row = layout.row() + row.prop(custom_data, 'comment') + + +class Ms3dMaterialPanel(Panel): + bl_label = ms3d_str['LABEL_PANEL_MATERIALS'] + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'material' + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + and blender_context.material + and blender_context.material.ms3d is not None + ) + + def draw_header(self, blender_context): + layout = self.layout + layout.label(icon='PLUGIN') + + def draw(self, blender_context): + layout = self.layout + custom_data = blender_context.material.ms3d + + row = layout.row() + row.prop(custom_data, 'name') + + col = layout.column() + row = col.row() + row.prop(custom_data, 'diffuse') + row.prop(custom_data, 'ambient') + row = col.row() + row.prop(custom_data, 'specular') + row.prop(custom_data, 'emissive') + row = col.row() + row.prop(custom_data, 'shininess') + row.prop(custom_data, 'transparency') + + col = layout.column() + row = col.row() + row.prop(custom_data, 'texture') + row = col.row() + row.prop(custom_data, 'alphamap') + row = col.row() + row.prop(custom_data, 'mode', expand=True) + + row = layout.row() + row.prop(custom_data, 'comment') + + layout.row().operator( + Ms3dUi.OPT_MATERIAL_APPLY, + text=ms3d_str['ENUM_FROM_BLENDER_1'], + icon='APPEND_BLEND').mode = 'FROM_BLENDER' + pass + + +class Ms3dBonePanel(Panel): + bl_label = ms3d_str['LABEL_PANEL_JOINTS'] + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'bone' + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object.type in {'ARMATURE', } + and blender_context.active_bone + and isinstance(blender_context.active_bone, Bone) + and blender_context.active_bone.ms3d is not None + ) + + def draw_header(self, blender_context): + layout = self.layout + layout.label(icon='PLUGIN') + + def draw(self, blender_context): + import bpy + layout = self.layout + custom_data = blender_context.active_bone.ms3d + + row = layout.row() + row.prop(custom_data, 'name') + row = layout.row() + row.prop(custom_data, 'flags', expand=True) + row = layout.row() + row.prop(custom_data, 'color') + row = layout.row() + row.prop(custom_data, 'comment') + + +class Ms3dGroupPanel(Panel): + bl_label = ms3d_str['LABEL_PANEL_GROUPS'] + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'data' + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + ) + + def draw_header(self, blender_context): + layout = self.layout + layout.label(icon='PLUGIN') + + def draw(self, blender_context): + layout = self.layout + custom_data = blender_context.object.data.ms3d + layout.enabled = (blender_context.mode == 'EDIT_MESH') and ( + blender_context.tool_settings.mesh_select_mode[2]) + + row = layout.row() + + # http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53355 + row.template_list( + listtype_name='Ms3dGroupUILise', + dataptr=custom_data, + propname='groups', + active_dataptr=custom_data, + active_propname='selected_group_index', + rows=2, + type='DEFAULT', + ) + + col = row.column(align=True) + col.operator( + Ms3dUi.OPT_GROUP_APPLY, + text="", icon='ZOOMIN').mode = 'ADD_GROUP' + col.operator( + Ms3dUi.OPT_GROUP_APPLY, + text="", icon='ZOOMOUT').mode = 'REMOVE_GROUP' + + index = custom_data.selected_group_index + collection = custom_data.groups + if (index >= 0 and index < len(collection)): + row = layout.row() + row.prop(collection[index], 'name') + + row = layout.row() + subrow = row.row(align=True) + subrow.operator( + Ms3dUi.OPT_GROUP_APPLY, + text=ms3d_str['ENUM_ASSIGN_1']).mode = 'ASSIGN' + subrow.operator( + Ms3dUi.OPT_GROUP_APPLY, + text=ms3d_str['ENUM_REMOVE_1']).mode = 'REMOVE' + subrow = row.row(align=True) + subrow.operator( + Ms3dUi.OPT_GROUP_APPLY, + text=ms3d_str['ENUM_SELECT_1']).mode = 'SELECT' + subrow.operator( + Ms3dUi.OPT_GROUP_APPLY, + text=ms3d_str['ENUM_DESELECT_1']).mode = 'DESELECT' + + row = layout.row() + row.prop(collection[index], 'flags', expand=True) + + row = layout.row() + row.prop(collection[index], 'comment') + + +class Ms3dSmoothingGroupPanel(Panel): + bl_label = ms3d_str['BL_LABEL_PANEL_SMOOTHING_GROUP'] + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'data' + + def preview(self, dict, id, text): + item = dict.get(id) + if item is None: + return "{}".format(text) + elif item: + return "{}:".format(text) + + return "{}.".format(text) + + def build_preview(self, blender_context): + dict = {} + if (blender_context.mode != 'EDIT_MESH') or ( + not blender_context.tool_settings.mesh_select_mode[2]): + return dict + + custom_data = blender_context.object.data.ms3d + blender_mesh = blender_context.object.data + bm = from_edit_mesh(blender_mesh) + layer_smoothing_group = bm.faces.layers.int.get( + ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP']) + if layer_smoothing_group is not None: + for bmf in bm.faces: + item = dict.get(bmf[layer_smoothing_group]) + if item is None: + dict[bmf[layer_smoothing_group]] = bmf.select + else: + if not item: + dict[bmf[layer_smoothing_group]] = bmf.select + return dict + + @classmethod + def poll(cls, blender_context): + return (blender_context + and blender_context.object + and blender_context.object.type in {'MESH', } + and blender_context.object.data + and blender_context.object.data.ms3d is not None + ) + + def draw_header(self, blender_context): + layout = self.layout + layout.label(icon='PLUGIN') + + def draw(self, blender_context): + dict = self.build_preview(blender_context) + + custom_data = blender_context.object.data.ms3d + layout = self.layout + layout.enabled = (blender_context.mode == 'EDIT_MESH') and ( + blender_context.tool_settings.mesh_select_mode[2]) + + row = layout.row() + subrow = row.row() + subrow.prop(custom_data, 'apply_mode', expand=True) + + col = layout.column(align=True) + subrow = col.row(align=True) + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 1, "1") + ).smoothing_group_index = 1 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 2, "2") + ).smoothing_group_index = 2 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 3, "3") + ).smoothing_group_index = 3 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 4, "4") + ).smoothing_group_index = 4 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 5, "5") + ).smoothing_group_index = 5 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 6, "6") + ).smoothing_group_index = 6 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 7, "7") + ).smoothing_group_index = 7 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 8, "8") + ).smoothing_group_index = 8 + subrow = col.row(align=True) + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 9, "9") + ).smoothing_group_index = 9 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 10, "10") + ).smoothing_group_index = 10 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 11, "11") + ).smoothing_group_index = 11 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 12, "12") + ).smoothing_group_index = 12 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 13, "13") + ).smoothing_group_index = 13 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 14, "14") + ).smoothing_group_index = 14 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 15, "15") + ).smoothing_group_index = 15 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 16, "16") + ).smoothing_group_index = 16 + subrow = col.row(align=True) + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 17, "17") + ).smoothing_group_index = 17 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 18, "18") + ).smoothing_group_index = 18 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 19, "19") + ).smoothing_group_index = 19 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 20, "20") + ).smoothing_group_index = 20 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 21, "21") + ).smoothing_group_index = 21 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 22, "22") + ).smoothing_group_index = 22 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 23, "23") + ).smoothing_group_index = 23 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 24, "24") + ).smoothing_group_index = 24 + subrow = col.row(align=True) + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 25, "25") + ).smoothing_group_index = 25 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 26, "26") + ).smoothing_group_index = 26 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 27, "27") + ).smoothing_group_index = 27 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 28, "28") + ).smoothing_group_index = 28 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 29, "29") + ).smoothing_group_index = 29 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 30, "30") + ).smoothing_group_index = 30 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 31, "31") + ).smoothing_group_index = 31 + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 32, "32") + ).smoothing_group_index = 32 + subrow = col.row() + subrow.operator( + Ms3dUi.OPT_SMOOTHING_GROUP_APPLY, + text=self.preview(dict, 0, ms3d_str['LABEL_PANEL_BUTTON_NONE']) + ).smoothing_group_index = 0 + + +############################################################################### +class Ms3dSetSceneToMetricOperator(Operator): + """ . """ + bl_idname = 'io_scene_ms3d.set_sence_to_metric' + bl_label = ms3d_str['BL_LABEL_SET_SCENE_TO_METRIC'] + bl_description = ms3d_str['BL_DESC_SET_SCENE_TO_METRIC'] + + + # + @classmethod + def poll(cls, blender_context): + return True + + # entrypoint for option + def execute(self, blender_context): + return self.set_sence_to_metric(blender_context) + + # entrypoint for option via UI + def invoke(self, blender_context, event): + return blender_context.window_manager.invoke_props_dialog(self) + + + ########################################################################### + def set_sence_to_metric(self, blender_context): + set_sence_to_metric(blender_context) + return {"FINISHED"} + + +############################################################################### +def register(): + register_class(Ms3dSetSceneToMetricOperator) + register_class(Ms3dGroupProperties) + register_class(Ms3dModelProperties) + register_class(Ms3dArmatureProperties) + register_class(Ms3dJointProperties) + register_class(Ms3dMaterialProperties) + inject_properties() + register_class(Ms3dSetSmoothingGroupOperator) + register_class(Ms3dGroupOperator) + +def unregister(): + unregister_class(Ms3dGroupOperator) + unregister_class(Ms3dSetSmoothingGroupOperator) + delete_properties() + unregister_class(Ms3dMaterialProperties) + unregister_class(Ms3dJointProperties) + unregister_class(Ms3dArmatureProperties) + unregister_class(Ms3dModelProperties) + unregister_class(Ms3dGroupProperties) + unregister_class(Ms3dSetSceneToMetricOperator) + +def inject_properties(): + Mesh.ms3d = PointerProperty(type=Ms3dModelProperties) + Armature.ms3d = PointerProperty(type=Ms3dArmatureProperties) + Bone.ms3d = PointerProperty(type=Ms3dJointProperties) + Material.ms3d = PointerProperty(type=Ms3dMaterialProperties) + Action.ms3d = PointerProperty(type=Ms3dArmatureProperties) + Group.ms3d = PointerProperty(type=Ms3dGroupProperties) + +def delete_properties(): + del Mesh.ms3d + del Armature.ms3d + del Bone.ms3d + del Material.ms3d + del Action.ms3d + del Group.ms3d + +############################################################################### + + +############################################################################### +#234567890123456789012345678901234567890123456789012345678901234567890123456789 +#--------1---------2---------3---------4---------5---------6---------7--------- +# ##### END OF FILE ##### |