[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [4815] trunk/py/scripts/addons/ io_import_scene_mhx.py: MHX importer: Improved mhp (posing) format where the full pose matrix is stored.

Thomas Larsson thomas_larsson_01 at hotmail.com
Sun Oct 27 06:35:06 CET 2013


Revision: 4815
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=4815
Author:   thomasl
Date:     2013-10-27 05:35:06 +0000 (Sun, 27 Oct 2013)
Log Message:
-----------
MHX importer: Improved mhp (posing) format where the full pose matrix is stored.

Modified Paths:
--------------
    trunk/py/scripts/addons/io_import_scene_mhx.py

Modified: trunk/py/scripts/addons/io_import_scene_mhx.py
===================================================================
--- trunk/py/scripts/addons/io_import_scene_mhx.py	2013-10-24 22:49:08 UTC (rev 4814)
+++ trunk/py/scripts/addons/io_import_scene_mhx.py	2013-10-27 05:35:06 UTC (rev 4815)
@@ -38,7 +38,7 @@
 bl_info = {
     'name': 'Import: MakeHuman (.mhx)',
     'author': 'Thomas Larsson',
-    'version': "1.16.10",
+    'version': "1.16.11",
     "blender": (2, 68, 0),
     'location': "File > Import > MakeHuman (.mhx)",
     'description': 'Import files in the MakeHuman eXchange format (.mhx)',
@@ -392,19 +392,42 @@
 
 ifResult = False
 
+def printMHXVersionInfo(versionStr, performVersionCheck = False):
+    versionInfo = dict()
+    val = versionStr.split()
+
+    majorVersion = int(val[0])
+    minorVersion = int(val[1])
+
+    for debugVal in val[2:]:
+        debugVal = debugVal.replace("_"," ")
+        dKey, dVal = debugVal.split(':')
+        versionInfo[ dKey.strip() ] = dVal.strip()
+
+    if 'MHXImporter' in versionInfo:
+        print("MHX importer version: ", versionInfo["MHXImporter"])
+    if performVersionCheck:
+        checkMhxVersion(majorVersion, minorVersion)
+    else:
+        print("MHX: %s.%s" % (majorVersion, minorVersion))
+
+    for (key, value) in versionInfo.items():
+        if key == "MHXImporter":
+            continue
+        print("%s: %s" % (key, value))
+
 def parse(tokens):
     global MHX249, ifResult, theScale, defaultScale, One
     global majorVersion, minorVersion
+    versionInfoStr = ""
 
     for (key, val, sub) in tokens:
         data = None
         if key == 'MHX':
-            print("MHX importer version: ", bl_info["version"])
-            majorVersion = int(val[0])
-            minorVersion = int(val[1])
-            checkMhxVersion(majorVersion, minorVersion)
-            for string in val[2:]:
-                print(string.replace("_"," "))
+            importerVerStr = "MHXImporter:_%s" % (bl_info["version"])
+            versionInfoStr = " ".join(val + [importerVerStr])
+
+            printMHXVersionInfo(versionInfoStr, performVersionCheck = True)
         elif key == 'MHX249':
             MHX249 = mhxEval(val[0])
             print("Blender 2.49 compatibility mode is %s\n" % MHX249)
@@ -426,7 +449,7 @@
                 theScale = defaultScale
             One = 1.0/theScale
         elif key == "Object":
-            parseObject(val, sub)
+            parseObject(val, sub, versionInfoStr)
         elif key == "Mesh":
             reinitGlobalData()
             data = parseMesh(val, sub)
@@ -496,6 +519,7 @@
         else:
             data = parseDefaultType(key, val, sub)
 
+
 #
 #    parseDefaultType(typ, args, tokens):
 #
@@ -969,7 +993,7 @@
 #    setObjectAndData(args, typ):
 #
 
-def parseObject(args, tokens):
+def parseObject(args, tokens, versionInfoStr=""):
     if verbosity > 2:
         print( "Parsing object %s" % args )
     name = args[0]
@@ -1012,6 +1036,12 @@
         else:
             defaultKey(key, val, sub, ob, ['type', 'data'])
 
+    if versionInfoStr:
+        print('============= updating version string %s' % versionInfoStr)
+        ob.MhxVersionStr = versionInfoStr
+    else:
+        print('============= not updating version str')
+
     if bpy.context.object == ob:
         if ob.type == 'MESH':
             bpy.ops.object.shade_smooth()
@@ -3119,21 +3149,28 @@
     if not isMuscleBone(pb):
         b = pb.bone
         if pb.parent:
-            string = "quat"
             mat = b.matrix_local.inverted() * b.parent.matrix_local * pb.parent.matrix.inverted() * pb.matrix
         else:
-            string = "gquat"
             mat = pb.matrix.copy()
             maty = mat[1].copy()
             matz = mat[2].copy()
             mat[1] = matz
             mat[2] = -maty
 
-        t,q,s = mat.decompose()
-        magn = math.sqrt(q.x*q.x + q.y*q.y + q.z*q.z)
-        if magn > 1e-5:
-            fp.write("%s\t%s\t%.5f\t%.5f\t%.5f\t%.5f\n" % (pb.name, string, q.w, q.x, q.y, q.z))
+        diff = mat - Matrix()
+        nonzero = False
+        for i in range(4):
+            if abs(diff[i].length) > 5e-3:
+                nonzero = True
+                break
 
+        if nonzero:
+            fp.write("%s\tmatrix" % pb.name)
+            for i in range(4):
+                row = mat[i]
+                fp.write("\t%.4f\t%.4f\t%.4f\t%.4f" % (row[0], row[1], row[2], row[3]))
+            fp.write("\n")
+
     for child in pb.children:
         writeMhpBones(fp, child, log)
 
@@ -3153,6 +3190,10 @@
 
 
 def loadMhpFile(rig, scn, filepath):
+    unit = Matrix()
+    for pb in rig.pose.bones:
+        pb.matrix_basis = unit
+
     (pname, ext) = os.path.splitext(filepath)
     mhppath = pname + ".mhp"
 
@@ -3161,22 +3202,20 @@
         words = line.split()
         if len(words) < 4:
             continue
+
+        try:
+            pb = rig.pose.bones[words[0]]
+        except KeyError:
+            print("Warning: Did not find bone %s" % words[0])
+            continue
+
+        if isMuscleBone(pb):
+            pass
         elif words[1] == "quat":
-            try:
-                pb = rig.pose.bones[words[0]]
-            except KeyError:
-                print("Warning: Did not find bone %s" % words[0])
-                continue
-            if not isMuscleBone(pb):
-                q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
-                mat = q.to_matrix().to_4x4()
-                pb.matrix_basis = mat
+            q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
+            mat = q.to_matrix().to_4x4()
+            pb.matrix_basis = mat
         elif words[1] == "gquat":
-            try:
-                pb = rig.pose.bones[words[0]]
-            except KeyError:
-                print("Warning: Did not find bone %s" % words[0])
-                continue
             q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
             mat = q.to_matrix().to_4x4()
             maty = mat[1].copy()
@@ -3184,6 +3223,21 @@
             mat[1] = -matz
             mat[2] = maty
             pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
+        elif words[1] == "matrix":
+            rows = []
+            n = 2
+            for i in range(4):
+                rows.append((float(words[n]), float(words[n+1]), float(words[n+2]), float(words[n+3])))
+                n += 4
+            mat = Matrix(rows)
+            if pb.parent:
+                pb.matrix_basis = mat
+            else:
+                maty = mat[1].copy()
+                matz = mat[2].copy()
+                mat[1] = -matz
+                mat[2] = maty
+                pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
         elif words[1] == "scale":
             pass
         else:
@@ -4749,6 +4803,7 @@
     self.layout.operator(ImportMhx.bl_idname, text="MakeHuman (.mhx)...")
 
 def register():
+    bpy.types.Object.MhxVersionStr = StringProperty(name="Version", default="", maxlen=128)
     bpy.types.Object.MhAlpha8 = BoolProperty(default=True)
     bpy.types.Object.MhxMesh = BoolProperty(default=False)
     bpy.types.Object.MhxRig = StringProperty(default="")



More information about the Bf-extensions-cvs mailing list