OSDN Git Service

implement clean up.
[meshio/pymeshio.git] / blender26-meshio / import_pmx.py
index 8b13d9e..3641050 100644 (file)
@@ -47,7 +47,8 @@ def __create_a_material(m, name, textures_and_images):
     material.preview_render_type='FLAT'
     material.use_transparency=True
     # texture
-    texture_index=bl.material.addTexture(material, textures_and_images[m.texture_index][0])
+    if m.texture_index!=-1:
+        bl.material.addTexture(material, textures_and_images[m.texture_index][0])
     return material
 
 def __create_armature(bones, display_slots):
@@ -156,55 +157,123 @@ def _execute(filepath):
             for t in model.textures]
     print(textures_and_images)
 
-    def get_name(name, fmt, *args):
-        if len(name.encode("utf-8"))<16:
-            return name
-        else:
-            return fmt.format(*args)
     index_generator=(i for i in model.indices)
     # 頂点配列。(Left handed y-up) to (Right handed z-up)
     vertices=[convert_coord(pos)
             for pos in (v.position for v in model.vertices)]
+
+    # マテリアル毎にメッシュを作成する
+    def get_object_name(index, name):
+        """
+        object名を作る。最大21バイト
+        """
+        len_list=[len(name[:i].encode('utf-8')) for i in range(1, len(name)+1, 1)]
+        letter_count=0
+        for str_len in len_list:
+            if str_len<18: # 21-3
+                letter_count+=1
+            else:
+                break
+        name="{0:02}:{1}".format(index, name[:letter_count])
+        print("%s(%d)" % (name, letter_count))
+        return name
     for i, m in enumerate(model.materials):
-        # マテリアル毎にメッシュを作成する
-        print(m.name)
-        #material=__create_a_material(m, get_name(m.name, "material:{0:02}", i), textures_and_images)
+        ####################
+        # material
+        ####################
         material=__create_a_material(m, m.name, textures_and_images)
-        mesh, mesh_object=bl.mesh.create("object:{0:02}".format(i))
+
+        ####################
+        # mesh object
+        ####################
+        # object名はutf-8で21byteまで
+        mesh, mesh_object=bl.mesh.create(get_object_name(i, m.name))
         bl.mesh.addMaterial(mesh, material)
         # activate object
         bl.object.deselectAll()
         bl.object.activate(mesh_object)
         bl.object.makeParent(root_object, mesh_object)
+
+        ####################
         # vertices & faces
+        ####################
         indices=[next(index_generator)
                     for _ in range(m.vertex_count)]
+        used_indices=set(indices)
         bl.mesh.addGeometry(mesh, vertices,
                 [(indices[i], indices[i+1], indices[i+2])
                     for i in range(0, len(indices), 3)])
         assert(len(model.vertices), len(mesh.vertices))
-        # set vertex attributes(normal, bone weights)
-        bl.mesh.useVertexUV(mesh)
-        for i, (v,  mvert) in enumerate(zip(model.vertices, mesh.vertices)):
-            bl.vertex.setNormal(mvert, convert_coord(v.normal))
-            if isinstance(v.deform, pmx.Bdef1):
-                bl.object.assignVertexGroup(mesh_object,
-                        model.bones[v.deform.index0].name, i, 1.0)
-            elif isinstance(v.deform, pmx.Bdef2):
-                bl.object.assignVertexGroup(mesh_object,
-                        model.bones[v.deform.index0].name, i, v.deform.weight0)
-                bl.object.assignVertexGroup(mesh_object,
-                        model.bones[v.deform.index1].name, i, 1.0-v.deform.weight0)
-            else:
-                raise Exception("unknown deform: %s" % v.deform)
 
+        # assign material
+        bl.mesh.addUV(mesh)
+        hasTexture=bl.material.hasTexture(material)
+        if hasTexture:
+            index_gen=(i for i in indices)
+            image=(textures_and_images.get[m.texture_index] 
+                    if m.texture_index in textures_and_images
+                    else None)
+        for i, face in enumerate(mesh.faces):
+            bl.face.setMaterial(face, 0)
+            if hasTexture:
+                uv0=model.vertices[next(index_gen)].uv
+                uv1=model.vertices[next(index_gen)].uv
+                uv2=model.vertices[next(index_gen)].uv
+                bl.mesh.setFaceUV(mesh, i, face, [# fix uv
+                    (uv0.x, 1.0-uv0.y),
+                    (uv1.x, 1.0-uv1.y),
+                    (uv2.x, 1.0-uv2.y)
+                    ],
+                    image)
 
+        ####################
+        # armature
+        ####################
         if armature_object:
             # armature modifirer
             bl.modifier.addArmature(mesh_object, armature_object)
+            # set vertex attributes(normal, bone weights)
+            bl.mesh.useVertexUV(mesh)
+            for i, (v,  mvert) in enumerate(zip(model.vertices, mesh.vertices)):
+                bl.vertex.setNormal(mvert, convert_coord(v.normal))
+                if isinstance(v.deform, pmx.Bdef1):
+                    bl.object.assignVertexGroup(mesh_object,
+                            model.bones[v.deform.index0].name, i, 1.0)
+                elif isinstance(v.deform, pmx.Bdef2):
+                    bl.object.assignVertexGroup(mesh_object,
+                            model.bones[v.deform.index0].name, i, v.deform.weight0)
+                    bl.object.assignVertexGroup(mesh_object,
+                            model.bones[v.deform.index1].name, i, 1.0-v.deform.weight0)
+                else:
+                    raise Exception("unknown deform: %s" % v.deform)
 
-        # shape
+        ####################
+        # shape keys
+        ####################
+        # set shape_key pin
+        bl.object.pinShape(mesh_object, True)
+        # create base key
+        baseShapeBlock=bl.object.addShapeKey(mesh_object, bl.BASE_SHAPE_NAME)
+        mesh.update()
+        for m in model.morphs:
+            new_shape_key=bl.object.addShapeKey(mesh_object, m.name)
+            for o in m.offsets:
+                if isinstance(o, pmx.VertexMorphOffset):
+                    bl.shapekey.assign(new_shape_key, 
+                            o.vertex_index, 
+                            mesh.vertices[o.vertex_index].co+
+                            bl.createVector(*convert_coord(o.position_offset)))
+                else:
+                    raise Exception("unknown morph type: %s" % o)
+        # select base shape
+        bl.object.setActivateShapeKey(mesh_object, 0)
 
+        #############################
+        # clean up not used vertices
+        # in the material.
+        #############################
+        bl.mesh.vertsDelete(mesh, [i for i in range(len(mesh.vertices))
+            if i not in used_indices])
 
     return {'FINISHED'}