OSDN Git Service

fix shape key.
authorousttrue <ousttrue@gmail.com>
Mon, 14 Jun 2010 13:40:56 +0000 (22:40 +0900)
committerousttrue <ousttrue@gmail.com>
Mon, 14 Jun 2010 13:40:56 +0000 (22:40 +0900)
swig/blender/pmd_export.py

index 2e8703d..d68f53a 100644 (file)
@@ -78,12 +78,14 @@ class VertexKey(object):
     重複頂点の検索キー
     """
     __slots__=[
+            'index',
             'x', 'y', 'z', # 位置
             'nx', 'ny', 'nz', # 法線
             'u', 'v', # uv
             ]
 
-    def __init__(self, x, y, z, nx, ny, nz, u, v):
+    def __init__(self, index, x, y, z, nx, ny, nz, u, v):
+        self.index=index
         self.x=x
         self.y=y
         self.z=z
@@ -104,7 +106,8 @@ class VertexKey(object):
     def __eq__(self, rhs):
         #return near(self.x, rhs.x) and near(self.y, rhs.y) and near(self.z, rhs.z) and near(self.nx, rhs.nx) and near(self.ny, rhs.ny) and near(self.nz, rhs.nz) and near(self.u, rhs.u) and near(self.v, rhs.v)
         #return near(self.x, rhs.x) and near(self.y, rhs.y) and near(self.z, rhs.z)
-        return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z
+        #return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z
+        return self.index==rhs.index
 
 
 class VertexArray(object):
@@ -140,6 +143,7 @@ class VertexArray(object):
         頂点属性からその頂点のインデックスを得る
         """
         key=VertexKey(
+                base_index,
                 pos[0], pos[1], pos[2],
                 normal[0], normal[1], normal[2],
                 uv[0], uv[1])
@@ -237,9 +241,13 @@ class OneSkinMesh(object):
 
         print("export", obj.name)
 
-        ############################################################
         # bone weight
-        ############################################################
+        weightMap=self.__mesh(obj)
+
+        # skin
+        self.__skin(obj)
+
+    def __mesh(self, obj):
         mesh=bl.objectGetData(obj)
         weightMap={}
         secondWeightMap={}
@@ -287,10 +295,8 @@ class OneSkinMesh(object):
                 print("no weight vertex")
                 weightMap[i]=("", 0)
                 secondWeightMap[i]=("", 0)
-                
-        ############################################################
+
         # メッシュのコピーを生成してオブジェクトの行列を適用する
-        ############################################################
         copyMesh, copyObj=bl.objectDuplicate(self.scene, obj)
         if len(copyMesh.verts)==0:
             return
@@ -364,67 +370,79 @@ class OneSkinMesh(object):
                         )
         bl.objectDelete(self.scene, copyObj)
 
-        ############################################################
-        # skin
-        ############################################################
+    def __skin(self, obj):
+        if not bl.objectHasShapeKey(obj):
+            return
+
         indexRelativeMap={}
         blenderMesh=bl.objectGetData(obj)
         baseMorph=None
-        if bl.objectHasShapeKey(obj):
-            # base
-            for b in bl.objectShapeKeys(obj):
-                if b.name==BASE_SHAPE_NAME:
-                    baseMorph=self.__getOrCreateMorph('base', 0)
-                    relativeIndex=0
-                    basis=b
-
-                    for index in bl.meshVertexGroup(obj, MMD_SHAPE_GROUP_NAME):
-                        v=bl.shapeKeyGet(b, index)
-                        pos=[v[0], v[1], v[2]]
-                        indices=self.vertexArray.getMappedIndices(index)
-                        for i in indices:
-                            baseMorph.add(i, pos)
-                            indexRelativeMap[i]=relativeIndex
-                            relativeIndex+=1
-
-                    break
-            assert(basis)
-            print(basis.name, len(baseMorph.offsets))
-
-            if(len(baseMorph.offsets)>0):
-                baseMorph.sort()
-
-                # shape keys
-                vg=bl.meshVertexGroup(obj, MMD_SHAPE_GROUP_NAME)
-                for b in bl.objectShapeKeys(obj):
-                    if b.name==BASE_SHAPE_NAME:
-                        continue
-
-                    print(b.name)
-                    morph=self.__getOrCreateMorph(b.name, 4)
-                    for index, src, dst in zip(
-                            xrange(len(blenderMesh.verts)),
-                            bl.shapeKeys(basis),
-                            bl.shapeKeys(b)):
-                        offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]]
-                        if offset[0]==0 and offset[1]==0 and offset[2]==0:
+
+        # shape keys
+        vg=bl.meshVertexGroup(obj, MMD_SHAPE_GROUP_NAME)
+
+        # base
+        used=set()
+        for b in bl.objectShapeKeys(obj):
+            if b.name==BASE_SHAPE_NAME:
+                baseMorph=self.__getOrCreateMorph('base', 0)
+                basis=b
+
+                relativeIndex=0
+                for index in vg:
+                    v=bl.shapeKeyGet(b, index)
+                    pos=[v[0], v[1], v[2]]
+                    indices=self.vertexArray.getMappedIndices(index)
+                    for i in indices:
+                        if i in used:
                             continue
-                        if index in vg:
-                            indices=self.vertexArray.getMappedIndices(index)
-                            for i in indices:
-                                morph.add(indexRelativeMap[i], offset)
-
-                # sort skinmap
-                original=self.morphList[:]
-                def getIndex(morph):
-                    for i, v in enumerate(englishmap.skinMap):
-                        if v[0]==morph.name:
-                            return i
-                    print(morph)
-                if isBlender24():
-                    self.morphList.sort(lambda l, r: getIndex(l)-getIndex(r))
-                else:
-                    self.morphList.sort(key=getIndex)
+                        used.add(i)
+
+                        baseMorph.add(i, pos)
+                        indexRelativeMap[i]=relativeIndex
+                        relativeIndex+=1
+
+                break
+        assert(basis)
+        print(basis.name, len(baseMorph.offsets))
+
+        if len(baseMorph.offsets)==0:
+            return
+
+        # shape keys
+        for b in bl.objectShapeKeys(obj):
+            if b.name==BASE_SHAPE_NAME:
+                continue
+
+            print(b.name)
+            morph=self.__getOrCreateMorph(b.name, 4)
+            used=set()
+            for index, src, dst in zip(
+                    xrange(len(blenderMesh.verts)),
+                    bl.shapeKeys(basis),
+                    bl.shapeKeys(b)):
+                offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]]
+                if offset[0]==0 and offset[1]==0 and offset[2]==0:
+                    continue
+                if index in vg:
+                    indices=self.vertexArray.getMappedIndices(index)
+                    for i in indices:
+                        if i in used:
+                            continue
+                        used.add(i) 
+                        morph.add(indexRelativeMap[i], offset)
+
+        # sort skinmap
+        original=self.morphList[:]
+        def getIndex(morph):
+            for i, v in enumerate(englishmap.skinMap):
+                if v[0]==morph.name:
+                    return i
+            print(morph)
+        if isBlender24():
+            self.morphList.sort(lambda l, r: getIndex(l)-getIndex(r))
+        else:
+            self.morphList.sort(key=getIndex)
 
     def __getOrCreateMorph(self, name, type):
         for m in self.morphList: