diff --git a/io_scene_ms3d/__init__.py b/io_scene_ms3d/__init__.py index c8651ce7422bb4b8f3c0053019a973c4bfbc1b4d..1d231a113082a2e30a2ff0ed249febf71a1150bf 100644 --- a/io_scene_ms3d/__init__.py +++ b/io_scene_ms3d/__init__.py @@ -23,7 +23,7 @@ bl_info = { 'description': "Import / Export MilkShape3D MS3D files"\ " (conform with MilkShape3D v1.8.4)", 'author': "Alexander Nussbaumer", - 'version': (0, 93, 1), + 'version': (0, 94, 0), 'blender': (2, 65, 3), 'location': "File > Import & File > Export", 'warning': "", diff --git a/io_scene_ms3d/ms3d_export.py b/io_scene_ms3d/ms3d_export.py index bc6425a19af1034cb5140809ec22f5f8e0146e40..b377e3222163d0780e92f9eff67cae109554dade 100644 --- a/io_scene_ms3d/ms3d_export.py +++ b/io_scene_ms3d/ms3d_export.py @@ -342,70 +342,77 @@ class Ms3dExporter(): if self.options_use_animation and layer_deform: blender_vertex_group_ids = bmv[layer_deform] if blender_vertex_group_ids: - count = 0 - bone_ids = [] - weights = [] + bone_weights = {} for blender_index, blender_weight \ in blender_vertex_group_ids.items(): ms3d_joint = blender_to_ms3d_bones.get( blender_mesh_object_temp.vertex_groups[\ blender_index].name) if ms3d_joint: - if count == 0: - ms3d_vertex.bone_id = ms3d_joint.__index - weights.append( - int(blender_weight * 100.0)) - elif count == 1: - bone_ids.append(ms3d_joint.__index) - weights.append( - int(blender_weight * 100.0)) - elif count == 2: - bone_ids.append(ms3d_joint.__index) - weights.append( - int(blender_weight * 100.0)) - elif count == 3: - bone_ids.append(ms3d_joint.__index) - self.report( - {'WARNING', 'INFO'}, - ms3d_str['WARNING_EXPORT_SKIP_WEIGHT']) - else: - # only first three weights will be supported / four bones - self.report( - {'WARNING', 'INFO'}, - ms3d_str['WARNING_EXPORT_SKIP_WEIGHT_EX']) - break - count+= 1 + weight = bone_weights.get(ms3d_joint.__index) + if not weight: + weight = 0 + bone_weights[ms3d_joint.__index] = weight + blender_weight - while len(bone_ids) < 3: - bone_ids.append(Ms3dSpec.DEFAULT_VERTEX_BONE_ID) - while len(weights) < 3: - weights.append(0) + # sort (bone_id: weight) according its weights + # to skip only less important weights in the next pass + bone_weights_sorted = sorted(bone_weights.items(), key=lambda item: item[1], reverse=True) - # normalize weights to 100 + count = 0 + bone_ids = [] + weights = [] + for ms3d_index, blender_weight \ + in bone_weights_sorted: + + if count == 0: + ms3d_vertex.bone_id = ms3d_index + weights.append(blender_weight) + elif count == 1: + bone_ids.append(ms3d_index) + weights.append(blender_weight) + elif count == 2: + bone_ids.append(ms3d_index) + weights.append(blender_weight) + elif count == 3: + bone_ids.append(ms3d_index) + self.report( + {'WARNING', 'INFO'}, + ms3d_str['WARNING_EXPORT_SKIP_WEIGHT']) + else: + # only first three weights will be supported / four bones + self.report( + {'WARNING', 'INFO'}, + ms3d_str['WARNING_EXPORT_SKIP_WEIGHT_EX']) + break + count += 1 + + # normalize weights to 100% if self.options_normalize_weights: - weight_sum = 0 + weight_sum = 0.0 for weight in weights: weight_sum += weight - if weight_sum > 100: - weight_normalize = 100 / weight_sum - else: - weight_normalize = 1 + weight_normalize = 1.0 / weight_sum - weight_sum = 100 + weight_sum = 1.0 for index, weight in enumerate(weights): if index >= count-1: - weights[index] = weight_sum + weights[index] = weight_sum + 0.009 break - normalized_weight = int( - weight * weight_normalize) + normalized_weight = weight * weight_normalize weight_sum -= normalized_weight weights[index] = normalized_weight + # fill up missing values + while len(bone_ids) < 3: + bone_ids.append(Ms3dSpec.DEFAULT_VERTEX_BONE_ID) + while len(weights) < 3: + weights.append(0.0) + ms3d_vertex._vertex_ex_object._bone_ids = \ tuple(bone_ids) ms3d_vertex._vertex_ex_object._weights = \ - tuple(weights) + tuple([int(value * 100) for value in weights]) if layer_extra: #ms3d_vertex._vertex_ex_object.extra = bmv[layer_extra] diff --git a/io_scene_ms3d/ms3d_ui.py b/io_scene_ms3d/ms3d_ui.py index b3e52b1e8aa07153a198f7acd58ba176b69bbc3a..31369429634e4db4367f8cf03b9ebd604d2e7738 100644 --- a/io_scene_ms3d/ms3d_ui.py +++ b/io_scene_ms3d/ms3d_ui.py @@ -492,7 +492,15 @@ class Ms3dExportOperator(Operator, ExportHelper): default=ms3d_str['FILE_FILTER'], options={'HIDDEN', } ) - + + ##def object_items(self, blender_context): + ## return[(item.name, item.name, "") for item in blender_context.selected_objects if item.type in {'MESH', }] + ## + ##object_name = EnumProperty( + ## name="Object", + ## description="select an object to export", + ## items=object_items, + ## ) ##EXPORT_ACTIVE_ONLY: ##limit availability to only active mesh object @@ -510,37 +518,41 @@ class Ms3dExportOperator(Operator, ExportHelper): layout = self.layout box = layout.box() - box.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS) - box.prop(self, 'verbose', icon='SPEAKER') + flow = box.column_flow() + flow.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS) + flow.prop(self, 'verbose', icon='SPEAKER') box = layout.box() - box.label(ms3d_str['LABEL_NAME_PROCESSING'], + flow = box.column_flow() + flow.label(ms3d_str['LABEL_NAME_PROCESSING'], icon=Ms3dUi.ICON_PROCESSING) - row = box.row() + row = flow.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') + ##flow.prop(self, 'object_name') + flow.prop(self, 'use_blender_names') + flow.prop(self, 'use_blender_materials') box = layout.box() - box.label(ms3d_str['LABEL_NAME_MODIFIER'], + flow = box.column_flow() + flow.label(ms3d_str['LABEL_NAME_MODIFIER'], icon=Ms3dUi.ICON_MODIFIER) - box.prop(self, 'apply_transform') - row = box.row() + flow.prop(self, 'apply_transform') + row = flow.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'], + flow = box.column_flow() + flow.label(ms3d_str['LABEL_NAME_ANIMATION'], icon=Ms3dUi.ICON_ANIMATION) - box.prop(self, 'use_animation') + flow.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') + flow.prop(self, 'normalize_weights') + flow.prop(self, 'shrink_to_keys') + flow.prop(self, 'bake_each_frame') # entrypoint for blender -> MS3D def execute(self, blender_context):