[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [4248] trunk/py/scripts/addons/ io_scene_ms3d: fixed vertex weight handling of more than 3 bone weights, that milkshape cannot support.

Alexander Nussbaumer alpha-beta-release at gmx.net
Sat Feb 9 14:12:41 CET 2013


Revision: 4248
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=4248
Author:   beta-tester
Date:     2013-02-09 13:12:41 +0000 (Sat, 09 Feb 2013)
Log Message:
-----------
fixed vertex weight handling of more than 3 bone weights, that milkshape cannot support.

indirect part of the reported issue:
http://www.blender.org/forum/viewtopic.php?t=26251

now, vertex weights will sorted according the weight. in case of more than 3 weights, less important ones will be skipped on export.

Modified Paths:
--------------
    trunk/py/scripts/addons/io_scene_ms3d/__init__.py
    trunk/py/scripts/addons/io_scene_ms3d/ms3d_export.py
    trunk/py/scripts/addons/io_scene_ms3d/ms3d_ui.py

Modified: trunk/py/scripts/addons/io_scene_ms3d/__init__.py
===================================================================
--- trunk/py/scripts/addons/io_scene_ms3d/__init__.py	2013-02-09 01:41:54 UTC (rev 4247)
+++ trunk/py/scripts/addons/io_scene_ms3d/__init__.py	2013-02-09 13:12:41 UTC (rev 4248)
@@ -23,7 +23,7 @@
     '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': "",

Modified: trunk/py/scripts/addons/io_scene_ms3d/ms3d_export.py
===================================================================
--- trunk/py/scripts/addons/io_scene_ms3d/ms3d_export.py	2013-02-09 01:41:54 UTC (rev 4247)
+++ trunk/py/scripts/addons/io_scene_ms3d/ms3d_export.py	2013-02-09 13:12:41 UTC (rev 4248)
@@ -342,70 +342,77 @@
                     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]

Modified: trunk/py/scripts/addons/io_scene_ms3d/ms3d_ui.py
===================================================================
--- trunk/py/scripts/addons/io_scene_ms3d/ms3d_ui.py	2013-02-09 01:41:54 UTC (rev 4247)
+++ trunk/py/scripts/addons/io_scene_ms3d/ms3d_ui.py	2013-02-09 13:12:41 UTC (rev 4248)
@@ -492,8 +492,16 @@
             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
     @classmethod
@@ -510,37 +518,41 @@
         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()

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list