OSDN Git Service

fix bone group name.
[meshio/meshio.git] / swig / blender / pmd_import.py
index eb6506a..9590d7e 100755 (executable)
@@ -7,7 +7,7 @@
  Tooltip: 'Import PMD file for MikuMikuDance.'
 """
 __author__= ["ousttrue"]
-__version__= "1.2"
+__version__= "1.8"
 __url__=()
 __bpydoc__="""
 pmd Importer
@@ -30,6 +30,7 @@ This script imports a pmd into Blender for editing.
 1.5 20100626: refactoring.
 1.6 20100629: sphere map.
 1.7 20100703: implement bone group.
+1.8 20100710: implement toon texture.
 """
 
 MMD_SHAPE_GROUP_NAME='_MMD_SHAPE'
@@ -162,18 +163,18 @@ else:
             #b.ik_dof_y=False
             pass
 
-    def setSphereMap(material, index, blend_type=None):
+    def setSphereMap(material, index, blend_type='MULTIPLY'):
         slot=material.texture_slots[index]
-        slot.texture_coordinates='REFLECTION'
+        slot.texture_coordinates='NORMAL'
         slot.mapping='SPHERE'
-        if blend_type:
-            slot.blend_type=blend_type
+        slot.blend_type=blend_type
 
 
 ###############################################################################
 def VtoV(v):
     return bl.createVector(v.x, v.y, v.z)
 
+
 def convert_coord(pos):
     """
     Left handed y-up to Right handed z-up
@@ -197,6 +198,26 @@ def get_bone_name(l, index):
     print('invalid bone index', index)
     return l.bones[0].getName()
 
+
+def get_group_name(g):
+    group_name=englishmap.getEnglishBoneGroupName(g.getName().strip())
+    if not group_name:
+        group_name=g.getName().strip()
+    return group_name
+
+
+def __importToonTextures(io, tex_dir):
+    mesh, meshObject=bl.mesh.create('ToonTextures')
+    material=bl.material.create('ToonTextures')
+    bl.mesh.addMaterial(mesh, material)
+    for i in range(10):
+        t=io.getToonTexture(i)
+        path=os.path.join(tex_dir, t.getName())
+        texture, image=bl.texture.create(path)
+        bl.material.addTexture(material, texture, False)
+    return meshObject, material
+
+
 def __importShape(obj, l, vertex_map):
     if len(l.morph_list)==0:
         return
@@ -319,7 +340,8 @@ def __build(armature, b, p, parent):
             else:
                 print('diffurence with parent.tail and head', name)
 
-        bl.bone.setConnected(bone)
+        if b.type!=9:
+            bl.bone.setConnected(bone)
         # armature layer 2
         bl.bone.setLayerMask(bone, [0, 1])
     else:
@@ -338,7 +360,7 @@ def __build(armature, b, p, parent):
         __build(armature, c, b, bone)
 
 
-def __importArmature(scene, l):
+def __importArmature(l):
     armature, armature_object=bl.armature.create()
 
     # build bone
@@ -380,9 +402,7 @@ def __importArmature(scene, l):
     else:
         # create bone group
         for i, g in enumerate(l.bone_group_list):
-            name=englishmap.getEnglishBoneGroupName(g.getName().strip())
-            if not name:
-                name=g.getName()
+            name=get_group_name(g)
             bl.object.createBoneGroup(armature_object, name, "THEME%02d" % (i+1))
 
         # assign bone to group
@@ -394,9 +414,7 @@ def __importArmature(scene, l):
                 bone_name=b.getName()
             # group
             g=l.bone_group_list[g_index-1]
-            group_name=englishmap.getEnglishBoneGroupName(g.getName().strip())
-            if not group_name:
-                group_name=g.getName()
+            group_name=get_group_name(g)
 
             # assign
             pose.bones[bone_name].bone_group=pose.bone_groups[group_name]
@@ -407,7 +425,7 @@ def __importArmature(scene, l):
         
 
 def __import16MaerialAndMesh(meshObject, l, 
-        material_order, face_map, tex_dir):
+        material_order, face_map, tex_dir, toon_material):
 
     mesh=bl.object.getData(meshObject)
     ############################################################
@@ -427,6 +445,13 @@ def __import16MaerialAndMesh(meshObject, l,
             break
 
         material=createPmdMaterial(m, material_index)
+        toon_index=bl.material.addTexture(
+                material, 
+                bl.material.getTexture(
+                    toon_material, 
+                    0 if m.toon_index==0xFF else m.toon_index
+                    ).texture,
+                False)
 
         texture_name=m.getTexture()
         if texture_name!='':
@@ -438,13 +463,13 @@ def __import16MaerialAndMesh(meshObject, l,
                     texture, image=bl.texture.create(path)
                     textureMap[texture_name]=texture
                     imageMap[material_index]=image
-                bl.material.addTexture(material, texture)
+                texture_index=bl.material.addTexture(material, texture)
                 if t.endswith('sph'):
                     # sphere map
-                    setSphereMap(material, i)
+                    setSphereMap(material, texture_index)
                 elif t.endswith('spa'):
                     # sphere map
-                    setSphereMap(material, i, 'ADD')
+                    setSphereMap(material, texture_index, 'ADD')
 
         bl.mesh.addMaterial(mesh, material)
         index+=1
@@ -567,7 +592,7 @@ def __import16MaerialAndMesh(meshObject, l,
     return vertex_map
 
 
-def __importMesh(scene, io, tex_dir):
+def __importMaterialAndMesh(io, tex_dir, toon_material):
     """
     @param l[in] mmd.PMDLoader
     @param filename[in]
@@ -632,7 +657,7 @@ def __importMesh(scene, io, tex_dir):
         # shapeキーで使われる順に並べなおしたマテリアル16個分の
         # メッシュを作成する
         vertex_map=__import16MaerialAndMesh(
-                meshObject, io, material16, face_map, tex_dir)
+                meshObject, io, material16, face_map, tex_dir, toon_material)
 
         # crete shape key
         __importShape(meshObject, io, vertex_map)
@@ -649,7 +674,7 @@ def __importMesh(scene, io, tex_dir):
     return mesh_objects
 
 
-def __importConstraints(scene, io):
+def __importConstraints(io):
     if isBlender24():
         return
     print("create constraint")
@@ -671,7 +696,7 @@ def __importConstraints(scene, io):
                 location=(c.pos.x, c.pos.z, c.pos.y),
                 layer=layer
                 )
-        meshObject=scene.objects.active
+        meshObject=bl.object.getActive()
         constraintMeshes.append(meshObject)
         mesh=bl.object.getData(meshObject)
         bl.mesh.addMaterial(mesh, material)
@@ -698,7 +723,7 @@ def __importConstraints(scene, io):
     return container
 
 
-def __importRigidBodies(scene, io):
+def __importRigidBodies(io):
     if isBlender24():
         return
     print("create rigid bodies")
@@ -744,7 +769,7 @@ def __importRigidBodies(scene, io):
         else:
             assert(False)
 
-        meshObject=scene.objects.active
+        meshObject=bl.object.getActive()
         mesh=bl.object.getData(meshObject)
         rigidMeshes.append(meshObject)
         bl.mesh.addMaterial(mesh, material)
@@ -778,7 +803,7 @@ def __importRigidBodies(scene, io):
     return container
 
 
-def __execute(filename, scene):
+def _execute(filename):
     """
     load pmd file to context.
     """
@@ -798,13 +823,18 @@ def __execute(filename, scene):
         model_name=io.getName()
     root=bl.object.createEmpty(model_name)
 
+    # toon textures
+    tex_dir=os.path.dirname(filename)
+    toonTextures, toonMaterial=__importToonTextures(io, tex_dir)
+    bl.object.makeParent(root, toonTextures)
+
     # import mesh
-    mesh_objects=__importMesh(scene, io, os.path.dirname(filename))
+    mesh_objects=__importMaterialAndMesh(io, tex_dir, toonMaterial)
     for o in mesh_objects:
         bl.object.makeParent(root, o)
 
     # import armature
-    armature_object=__importArmature(scene, io)
+    armature_object=__importArmature(io)
     if armature_object:
         bl.object.makeParent(root, armature_object)
         armature = bl.object.getData(armature_object) 
@@ -818,12 +848,12 @@ def __execute(filename, scene):
             poseBoneLimit(n, b)
 
     # import rigid bodies
-    rigidBodies=__importRigidBodies(scene, io)
+    rigidBodies=__importRigidBodies(io)
     if rigidBodies:
         bl.object.makeParent(root, rigidBodies)
 
     # import constraints
-    constraints=__importConstraints(scene, io)
+    constraints=__importConstraints(io)
     if constraints:
         bl.object.makeParent(root, constraints)
 
@@ -833,11 +863,8 @@ def __execute(filename, scene):
 if isBlender24():
     # for 2.4
     def execute_24(filename):
-        scene=bpy.data.scenes.active
-        bl.initialize('pmd_import', scene)
-        __execute(
-                filename.decode(bl.INTERNAL_ENCODING), 
-                scene)
+        bl.initialize('pmd_import', bpy.data.scenes.active)
+        _execute(filename.decode(bl.INTERNAL_ENCODING))
         bl.finalize()
 
     Blender.Window.FileSelector(
@@ -846,12 +873,6 @@ if isBlender24():
             Blender.sys.makename(ext='.pmd'))
 
 else:
-    # for 2.5
-    def execute_25(filename, scene):
-        bl.initialize('pmd_import', scene)
-        __execute(filename, scene)
-        bl.finalize()
-
     # import operator
     class IMPORT_OT_pmd(bpy.types.Operator):
         bl_idname = "import_scene.pmd"
@@ -872,7 +893,9 @@ else:
                 description="Directory of the file.")
 
         def execute(self, context):
-            execute_25(self.properties.path, context.scene)
+            bl.initialize('pmd_import', context.scene)
+            _execute(self.properties.path)
+            bl.finalize()
             return 'FINISHED'
 
         def invoke(self, context, event):