OSDN Git Service

refactoring.
authorousttrue <ousttrue@gmail.com>
Thu, 27 May 2010 11:59:51 +0000 (20:59 +0900)
committerousttrue <ousttrue@gmail.com>
Thu, 27 May 2010 11:59:51 +0000 (20:59 +0900)
swig/blender24/pmd_export.py

index 68fbc7c..36f37e9 100644 (file)
@@ -165,13 +165,18 @@ class VertexArray(object):
 
 
 class Morph(object):
-    __slots__=['name', 'type', 'indices', 'offsets']
+    __slots__=['name', 'type', 'offsets']
     def __init__(self, name, type):
         self.name=name
         self.type=type
-        self.indices=[]
         self.offsets=[]
 
+    def add(self, index, offset):
+        self.offsets.append((index, offset))
+
+    def sort(self):
+        self.offsets.sort(lambda l, r: l[0]-r[0])
+
 
 class IKSolver(object):
     __slots__=['target', 'effector', 'length', 'iterations', 'weight']
@@ -184,27 +189,17 @@ class IKSolver(object):
 
 
 class OneSkinMesh(object):
-    __slots__=['armatureObj', 'vertexArray', 'morphList']
-    def __init__(self, root):
-        self.armatureObj=None
+    __slots__=['vertexArray', 'morphList']
+    def __init__(self):
         self.vertexArray=VertexArray()
         self.morphList=[]
-        self.__create(root)
 
     def __str__(self):
-        return "<OneSkinMesh armature:%s, %s, morph:%d>" % (
-                self.armatureObj.name if self.armatureObj else None, 
+        return "<OneSkinMesh %s, morph:%d>" % (
                 self.vertexArray,
                 len(self.morphList))
 
-    def __create(self, node):
-        if node.o.getType()=='Mesh':
-            self.__addMesh(node.o)
-
-        for child in node.children:
-            self.__create(child)
-
-    def __addMesh(self, obj):
+    def addMesh(self, obj):
         if obj.restrictDisplay:
             # 非表示
             return
@@ -212,17 +207,6 @@ class OneSkinMesh(object):
         print("export", obj.name)
 
         ############################################################
-        # search armature modifier
-        ############################################################
-        for m in obj.modifiers:
-            if m.name=="Armature":
-                armatureObj=m[Blender.Modifier.Settings.OBJECT]
-                if not self.armatureObj:
-                    self.armatureObj=armatureObj
-                elif self.armatureObj!=armatureObj:
-                    print "warning! found multiple armature. ignored.", armatureObj.name
-
-        ############################################################
         # bone weight
         ############################################################
         mesh=obj.getData(mesh=True)
@@ -351,11 +335,12 @@ class OneSkinMesh(object):
         # base
         indexRelativeMap={}
         blenderMesh=obj.getData(mesh=True)
+        baseMorph=None
         if blenderMesh.key:
             for b in blenderMesh.key.blocks:
                 if b.name=='Basis':
                     print(b.name)
-                    morph=self.__getOrCreateMorph('base', 0)
+                    baseMorph=self.__getOrCreateMorph('base', 0)
                     relativeIndex=0
                     basis=b
                     for index in blenderMesh.getVertsFromGroup(
@@ -364,32 +349,33 @@ class OneSkinMesh(object):
                         pos=[v[0], v[1], v[2]]
                         indices=self.vertexArray.getMappedIndices(index)
                         for i in indices:
-                            morph.indices.append(i)
-                            morph.offsets.append(pos)
+                            baseMorph.add(i, pos)
                             indexRelativeMap[i]=relativeIndex
                             relativeIndex+=1
                     break
-
+            print(len(baseMorph.offsets))
+            baseMorph.sort()
             assert(basis)
 
             # shape keys
+            vg=obj.getData(mesh=True).getVertsFromGroup(
+                        MMD_SHAPE_GROUP_NAME)
             for b in obj.getData(mesh=True).key.blocks:
                 if b.name=='Basis':
                     continue
 
                 print(b.name)
                 morph=self.__getOrCreateMorph(b.name, 4)
-                for index in obj.getData(mesh=True).getVertsFromGroup(
-                        MMD_SHAPE_GROUP_NAME):
-                    #offset=[d-s for d, s in zip(
-                    #    b.data[index], basis.data[index])]
-                    src=basis.data[index]
-                    dst=b.data[index]
+                for index, src, dst in zip(
+                        xrange(len(blenderMesh.verts)),
+                        basis.data,
+                        b.data):
                     offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]]
-                    indices=self.vertexArray.getMappedIndices(index)
-                    for i in indices:
-                        morph.indices.append(indexRelativeMap[i])
-                        morph.offsets.append(offset)
+                    if index in vg:
+                        indices=self.vertexArray.getMappedIndices(index)
+                        for i in indices:
+                            morph.add(indexRelativeMap[i], offset)
+                assert(len(morph.offsets)==len(baseMorph.offsets))
 
     def __getOrCreateMorph(self, name, type):
         for m in self.morphList:
@@ -526,6 +512,9 @@ class BoneBuilder(object):
 
 class PmdExporter(object):
 
+    def __init__(self):
+        self.armatureObj=None
+
     def setup(self, scene):
         # 木構造を構築する
         object_node_map={}
@@ -538,10 +527,29 @@ class PmdExporter(object):
         root=object_node_map[scene.objects.active]
 
         # ワンスキンメッシュを作る
-        self.oneSkinMesh=OneSkinMesh(root)
+        self.oneSkinMesh=OneSkinMesh()
+        self.__createOneSkinMesh(root)
         print(self.oneSkinMesh)
         self.name=root.o.name
 
+    def __createOneSkinMesh(self, node):
+        ############################################################
+        # search armature modifier
+        ############################################################
+        for m in node.o.modifiers:
+            if m.name=="Armature":
+                armatureObj=m[Blender.Modifier.Settings.OBJECT]
+                if not self.armatureObj:
+                    self.armatureObj=armatureObj
+                elif self.armatureObj!=armatureObj:
+                    print "warning! found multiple armature. ignored.", armatureObj.name
+
+        if node.o.getType()=='Mesh':
+            self.oneSkinMesh.addMesh(node.o)
+
+        for child in node.children:
+            self.__createOneSkinMesh(child)
+
     def write(self, path):
         io=pmd.IO()
         io.name=self.name
@@ -550,7 +558,7 @@ class PmdExporter(object):
 
         # skeleton
         builder=BoneBuilder()
-        builder.build(self.oneSkinMesh.armatureObj)
+        builder.build(self.armatureObj)
 
         # 頂点
         for pos, normal, uv, b0, b1, weight in self.oneSkinMesh.vertexArray.zip():
@@ -658,10 +666,10 @@ class PmdExporter(object):
 
             morph.english_name="%s\n" % m.name
             morph.type=m.type
-            for index, offset in zip(m.indices, m.offsets):
+            for index, offset in m.offsets:
                 # convert right-handed z-up to left-handed y-up
                 morph.append(index, offset[0], offset[2], offset[1])
-            morph.vertex_count=len(m.indices)
+            morph.vertex_count=len(m.offsets)
 
             # 表情枠
             if i>0: