OSDN Git Service

8d396f00ef763606cad0bb63a1f1484bbc4ce8c0
[meshio/pymeshio.git] / blender25-meshio / import_pmd.py
1 #!BPY
2 # coding:utf-8
3 """
4  Name: 'MikuMikuDance model (.pmd)...'
5  Blender: 248
6  Group: 'Import'
7  Tooltip: 'Import PMD file for MikuMikuDance.'
8 """
9 __author__= ["ousttrue"]
10 __version__= "2.4"
11 __url__=()
12 __bpydoc__="""
13 pmd Importer
14
15 This script imports a pmd into Blender for editing.
16
17 0.1 20091126: first implement.
18 0.2 20091209: implement IK.
19 0.3 20091210: implement morph target.
20 0.4 20100305: use english name.
21 0.5 20100408: cleanup not used vertices.
22 0.6 20100416: fix fornt face. texture load fail safe. add progress.
23 0.7 20100506: C extension.
24 0.8 20100521: add shape_key group.
25 1.0 20100530: add invisilbe bone tail(armature layer 2).
26 1.1 20100608: integrate 2.4 and 2.5.
27 1.2 20100616: implement rigid body.
28 1.3 20100619: fix for various models.
29 1.4 20100623: fix constraint name.
30 1.5 20100626: refactoring.
31 1.6 20100629: sphere map.
32 1.7 20100703: implement bone group.
33 1.8 20100710: implement toon texture.
34 1.9 20100718: keep model name, comment.
35 2.0 20100724: update for Blender2.53.
36 2.1 20100731: add full python module.
37 2.2 20101005: update for Blender2.54.
38 2.3 20101228: update for Blender2.55.
39 2.4 20110429: update for Blender2.57b.
40 """
41 bl_addon_info = {
42         'category': 'Import/Export',
43         'name': 'Import: MikuMikuDance Model Format (.pmd)',
44         'author': 'ousttrue',
45         'version': (2, 2),
46         'blender': (2, 5, 3),
47         'location': 'File > Import',
48         'description': 'Import from the MikuMikuDance Model Format (.pmd)',
49         'warning': '', # used for warning icon and text in addons panel
50         'wiki_url': 'http://sourceforge.jp/projects/meshio/wiki/FrontPage',
51         'tracker_url': 'http://sourceforge.jp/ticket/newticket.php?group_id=5081',
52         }
53
54 MMD_SHAPE_GROUP_NAME='_MMD_SHAPE'
55 MMD_MB_NAME='mb_name'
56 MMD_MB_COMMENT='mb_comment'
57 MMD_COMMENT='comment'
58 BASE_SHAPE_NAME='Basis'
59 RIGID_NAME='rigid_name'
60 RIGID_SHAPE_TYPE='rigid_shape_type'
61 RIGID_PROCESS_TYPE='rigid_process_type'
62 RIGID_BONE_NAME='rigid_bone_name'
63 #RIGID_LOCATION='rigid_loation'
64 RIGID_GROUP='ribid_group'
65 RIGID_INTERSECTION_GROUP='rigid_intersection_group'
66 RIGID_WEIGHT='rigid_weight'
67 RIGID_LINEAR_DAMPING='rigid_linear_damping'
68 RIGID_ANGULAR_DAMPING='rigid_angular_damping'
69 RIGID_RESTITUTION='rigid_restitution'
70 RIGID_FRICTION='rigid_friction'
71 CONSTRAINT_NAME='constraint_name'
72 CONSTRAINT_A='const_a'
73 CONSTRAINT_B='const_b'
74 CONSTRAINT_POS_MIN='const_pos_min'
75 CONSTRAINT_POS_MAX='const_pos_max'
76 CONSTRAINT_ROT_MIN='const_rot_min'
77 CONSTRAINT_ROT_MAX='const_rot_max'
78 CONSTRAINT_SPRING_POS='const_spring_pos'
79 CONSTRAINT_SPRING_ROT='const_spring_rot'
80 TOON_TEXTURE_OBJECT='ToonTextures'
81
82
83 ###############################################################################
84 # import
85 ###############################################################################
86 import os
87 import sys
88 import math
89
90 try:
91     # C extension
92     from meshio import pmd, englishmap
93     print('use meshio C module')
94 except ImportError:
95     # full python
96     from .pymeshio import englishmap
97     from .pymeshio import mmd as pmd
98     pmd.IO=pmd.PMDLoader
99
100 # for 2.5
101 import bpy
102 import mathutils
103
104 # wrapper
105 from . import bl25 as bl
106
107 xrange=range
108
109 def createPmdMaterial(m, index):
110     material = bpy.data.materials.new("Material")
111     # diffuse
112     material.diffuse_shader='FRESNEL'
113     material.diffuse_color=([m.diffuse.r, m.diffuse.g, m.diffuse.b])
114     material.alpha=m.diffuse.a
115     # specular
116     material.specular_shader='TOON'
117     material.specular_color=([m.specular.r, m.specular.g, m.specular.b])
118     material.specular_toon_size=int(m.shinness)
119     # ambient
120     material.mirror_color=([m.ambient.r, m.ambient.g, m.ambient.b])
121     # flag
122     material.subsurface_scattering.use=True if m.flag==1 else False
123     # other
124     material.name="m_%02d" % index
125     material.preview_render_type='FLAT'
126     material.use_transparency=True
127     return material
128
129 def poseBoneLimit(n, b):
130     if n.endswith("_t"):
131         return
132     if n.startswith("knee_"):
133         b.lock_ik_y=True
134         b.lock_ik_z=True
135         b.lock_ik_x=False
136         # IK limit
137         b.use_ik_limit_x=True
138         b.ik_min_x=0
139         b.ik_max_x=180
140     elif n.startswith("ankle_"):
141         #b.ik_dof_y=False
142         pass
143
144 def setSphereMap(material, index, blend_type='MULTIPLY'):
145     slot=material.texture_slots[index]
146     slot.texture_coords='NORMAL'
147     slot.mapping='SPHERE'
148     slot.blend_type=blend_type
149
150
151 ###############################################################################
152 def VtoV(v):
153     return bl.createVector(v.x, v.y, v.z)
154
155
156 def convert_coord(pos):
157     """
158     Left handed y-up to Right handed z-up
159     """
160     return (pos.x, pos.z, pos.y)
161
162
163 def to_radian(degree):
164     return math.pi * degree / 180
165
166
167 def get_bone_name(l, index):
168     if index==0xFFFF:
169         return l.bones[0].getName()
170
171     if index < len(l.bones):
172         name=englishmap.getEnglishBoneName(l.bones[index].getName())
173         if name:
174             return name
175         return l.bones[index].getName()
176     print('invalid bone index', index)
177     return l.bones[0].getName()
178
179
180 def get_group_name(g):
181     group_name=englishmap.getEnglishBoneGroupName(g.getName().strip())
182     if not group_name:
183         group_name=g.getName().strip()
184     return group_name
185
186
187 def __importToonTextures(io, tex_dir):
188     mesh, meshObject=bl.mesh.create(TOON_TEXTURE_OBJECT)
189     material=bl.material.create(TOON_TEXTURE_OBJECT)
190     bl.mesh.addMaterial(mesh, material)
191     for i in range(10):
192         t=io.getToonTexture(i)
193         path=os.path.join(tex_dir, t.getName())
194         texture, image=bl.texture.create(path)
195         bl.material.addTexture(material, texture, False)
196     return meshObject, material
197
198
199 def __importShape(obj, l, vertex_map):
200     if len(l.morph_list)==0:
201         return
202
203     # set shape_key pin
204     bl.object.pinShape(obj, True)
205
206     # find base
207     base=None
208     for s in l.morph_list:
209         if s.type==0:
210             base=s
211
212             # create vertex group
213             bl.object.addVertexGroup(obj, MMD_SHAPE_GROUP_NAME)
214             hasShape=False
215             for i in s.indices:
216                 if i in vertex_map:
217                     hasShape=True
218                     bl.object.assignVertexGroup(
219                             obj, MMD_SHAPE_GROUP_NAME, vertex_map[i], 0)
220             if not hasShape:
221                 return
222     assert(base)
223
224     # create base key
225     baseShapeBlock=bl.object.addShapeKey(obj, BASE_SHAPE_NAME)
226     # mesh
227     mesh=bl.object.getData(obj)
228     mesh.update()
229
230     # each skin
231     for s in l.morph_list:
232         if s.type==0:
233             continue
234
235         # name
236         name=englishmap.getEnglishSkinName(s.getName())
237         if not name:
238             name=s.getName()
239
240         # 25
241         new_shape_key=bl.object.addShapeKey(obj, name)
242
243         for index, offset in zip(s.indices, s.pos_list):
244             try:
245                 vertex_index=vertex_map[base.indices[index]]
246                 bl.shapekey.assign(new_shape_key, vertex_index,
247                         mesh.vertices[vertex_index].co+
248                         bl.createVector(*convert_coord(offset)))
249             except IndexError as msg:
250                 print(msg)
251                 print(index, len(base.indices), len(vertex_map))
252                 print(len(mesh.vertices))
253                 print(base.indices[index])
254                 print(vertex_index)
255                 break
256             except KeyError:
257                 #print 'this mesh not has shape vertices'
258                 break
259
260     # select base shape
261     bl.object.setActivateShapeKey(obj, 0)
262
263
264 def __build(armature, b, p, parent):
265     name=englishmap.getEnglishBoneName(b.getName())
266     if not name:
267         name=b.getName()
268
269     bone=bl.armature.createBone(armature, name)
270
271     if parent and (b.tail_index==0 or b.type==6 or b.type==7 or b.type==9):
272         # 先端ボーン
273         bone.head = bl.createVector(*convert_coord(b.pos))
274         bone.tail=bone.head+bl.createVector(0, 1, 0)
275         bone.parent=parent
276         if bone.name=="center_t":
277             # センターボーンは(0, 1, 0)の方向を向いていないと具合が悪い
278             parent.tail=parent.head+bl.createVector(0, 1, 0)
279             bone.head=parent.tail
280             bone.tail=bone.head+bl.createVector(0, 1, 0)
281         else:
282             if parent.tail==bone.head:
283                 pass
284             else:
285                 print('diffurence with parent.tail and head', name)
286
287         if b.type!=9:
288             bl.bone.setConnected(bone)
289         # armature layer 2
290         bl.bone.setLayerMask(bone, [0, 1])
291     else:
292         # 通常ボーン
293         bone.head = bl.createVector(*convert_coord(b.pos))
294         bone.tail = bl.createVector(*convert_coord(b.tail))
295         if parent:
296             bone.parent=parent
297             if parent.tail==bone.head:
298                 bl.bone.setConnected(bone)
299
300     if bone.head==bone.tail:
301         bone.tail=bone.head+bl.createVector(0, 1, 0)
302
303     for c in b.children:
304         __build(armature, c, b, bone)
305
306
307 def __importArmature(l):
308     armature, armature_object=bl.armature.create()
309
310     # build bone
311     bl.armature.makeEditable(armature_object)
312     for b in l.bones:
313         if not b.parent:
314             __build(armature, b, None, None)
315     bl.armature.update(armature)
316     bl.enterObjectMode()
317
318     # IK constraint
319     pose = bl.object.getPose(armature_object)
320     for ik in l.ik_list:
321         target=l.bones[ik.target]
322         name = englishmap.getEnglishBoneName(target.getName())
323         if not name:
324             name=target.getName()
325         p_bone = pose.bones[name]
326         if not p_bone:
327             print('not found', name)
328             continue
329         if len(ik.children) >= 16:
330             print('over MAX_CHAINLEN', ik, len(ik.children))
331             continue
332         effector_name=englishmap.getEnglishBoneName(
333                 l.bones[ik.index].getName())
334         if not effector_name:
335             effector_name=l.bones[ik.index].getName()
336
337         constraint=bl.armature.createIkConstraint(armature_object,
338                 p_bone, effector_name, ik)
339
340     bl.armature.makeEditable(armature_object)
341     bl.armature.update(armature)
342     bl.enterObjectMode()
343
344     # create bone group
345     for i, g in enumerate(l.bone_group_list):
346         name=get_group_name(g)
347         bl.object.createBoneGroup(armature_object, name, "THEME%02d" % (i+1))
348
349     # assign bone to group
350     for b_index, g_index in l.bone_display_list:
351         # bone
352         b=l.bones[b_index]
353         bone_name=englishmap.getEnglishBoneName(b.getName())
354         if not bone_name:
355             bone_name=b.getName()
356         # group
357         g=l.bone_group_list[g_index-1]
358         group_name=get_group_name(g)
359
360         # assign
361         pose.bones[bone_name].bone_group=pose.bone_groups[group_name]
362
363     bl.enterObjectMode()
364
365     return armature_object
366
367
368 def __import16MaerialAndMesh(meshObject, l,
369         material_order, face_map, tex_dir, toon_material):
370
371     mesh=bl.object.getData(meshObject)
372     ############################################################
373     # material
374     ############################################################
375     bl.progress_print('create materials')
376     mesh_material_map={}
377     textureMap={}
378     imageMap={}
379     index=0
380
381     for material_index in material_order:
382         try:
383             m=l.materials[material_index]
384             mesh_material_map[material_index]=index
385         except KeyError:
386             break
387
388         material=createPmdMaterial(m, material_index)
389
390         # main texture
391         texture_name=m.getTexture()
392         if texture_name!='':
393             for i, t in enumerate(texture_name.split('*')):
394                 if t in textureMap:
395                     texture=textureMap[t]
396                 else:
397                     path=os.path.join(tex_dir, t)
398                     texture, image=bl.texture.create(path)
399                     textureMap[texture_name]=texture
400                     imageMap[material_index]=image
401                 texture_index=bl.material.addTexture(material, texture)
402                 if t.endswith('sph'):
403                     # sphere map
404                     setSphereMap(material, texture_index)
405                 elif t.endswith('spa'):
406                     # sphere map
407                     setSphereMap(material, texture_index, 'ADD')
408
409         # toon texture
410         toon_index=bl.material.addTexture(
411                 material,
412                 bl.material.getTexture(
413                     toon_material,
414                     0 if m.toon_index==0xFF else m.toon_index
415                     ),
416                 False)
417
418         bl.mesh.addMaterial(mesh, material)
419
420         index+=1
421
422     ############################################################
423     # vertex
424     ############################################################
425     bl.progress_print('create vertices')
426     # create vertices
427     vertices=[]
428     for v in l.each_vertex():
429         vertices.append(convert_coord(v.pos))
430
431     ############################################################
432     # face
433     ############################################################
434     bl.progress_print('create faces')
435     # create faces
436     mesh_face_indices=[]
437     mesh_face_materials=[]
438     used_vertices=set()
439
440     for material_index in material_order:
441         face_offset=face_map[material_index]
442         m=l.materials[material_index]
443         material_faces=l.indices[face_offset:face_offset+m.vertex_count]
444
445         def degenerate(i0, i1, i2):
446             """
447             縮退しているか?
448             """
449             return i0==i1 or i1==i2 or i2==i0
450
451         for j in xrange(0, len(material_faces), 3):
452             i0=material_faces[j]
453             i1=material_faces[j+1]
454             i2=material_faces[j+2]
455             # flip
456             triangle=[i2, i1, i0]
457             if degenerate(*triangle):
458                 continue
459             mesh_face_indices.append(triangle[0:3])
460             mesh_face_materials.append(material_index)
461             used_vertices.add(i0)
462             used_vertices.add(i1)
463             used_vertices.add(i2)
464
465     ############################################################
466     # create vertices & faces
467     ############################################################
468     bl.mesh.addGeometry(mesh, vertices, mesh_face_indices)
469
470     ############################################################
471     # vertex bone weight
472     ############################################################
473     # create vertex group
474     vertex_groups={}
475     for v in l.each_vertex():
476         vertex_groups[v.bone0]=True
477         vertex_groups[v.bone1]=True
478     for i in vertex_groups.keys():
479         bl.object.addVertexGroup(meshObject, get_bone_name(l, i))
480
481     # vertex params
482     bl.mesh.useVertexUV(mesh)
483     for i, v, mvert in zip(xrange(len(l.vertices)),
484         l.each_vertex(), mesh.vertices):
485         # normal, uv
486         bl.vertex.setNormal(mvert, convert_coord(v.normal))
487         # bone weight
488         w1=float(v.weight0)/100.0
489         w2=1.0-w1
490         bl.object.assignVertexGroup(meshObject, get_bone_name(l, v.bone0),
491             i,  w1)
492         bl.object.assignVertexGroup(meshObject, get_bone_name(l, v.bone1),
493             i,  w2)
494
495     ############################################################
496     # face params
497     ############################################################
498     used_map={}
499     bl.mesh.addUV(mesh)
500     for i, (face, material_index) in enumerate(
501             zip(mesh.faces, mesh_face_materials)):
502         try:
503             index=mesh_material_map[material_index]
504         except KeyError as message:
505             print(message, mesh_material_map, m)
506             assert(False)
507         bl.face.setMaterial(face, index)
508         material=mesh.materials[index]
509         used_map[index]=True
510         if bl.material.hasTexture(material):
511             uv_array=[l.getUV(i) for i in bl.face.getIndices(face)]
512             bl.mesh.setFaceUV(mesh, i, face,
513                     # fix uv
514                     [(uv.x, 1.0-uv.y) for uv in uv_array],
515                     imageMap.get(index, None))
516
517         # set smooth
518         bl.face.setSmooth(face, True)
519
520     mesh.update()
521
522     ############################################################
523     # clean up not used vertices
524     ############################################################
525     bl.progress_print('clean up vertices not used')
526     remove_vertices=[]
527     vertex_map={}
528     for i, v in enumerate(l.each_vertex()):
529         if i in used_vertices:
530             vertex_map[i]=len(vertex_map)
531         else:
532             remove_vertices.append(i)
533
534     bl.mesh.vertsDelete(mesh, remove_vertices)
535
536     bl.progress_print('%s created' % mesh.name)
537     return vertex_map
538
539
540 def __importMaterialAndMesh(io, tex_dir, toon_material):
541     """
542     @param l[in] mmd.PMDLoader
543     @param filename[in]
544     """
545     ############################################################
546     # shpaeキーで使われるマテリアル優先的に前に並べる
547     ############################################################
548     # shapeキーで使われる頂点インデックスを集める
549     shape_key_used_vertices=set()
550     if len(io.morph_list)>0:
551         # base
552         base=None
553         for s in io.morph_list:
554             if s.type!=0:
555                 continue
556             base=s
557             break
558         assert(base)
559
560         for index in base.indices:
561             shape_key_used_vertices.add(index)
562
563     # マテリアルに含まれる頂点がshape_keyに含まれるか否か?
564     def isMaterialUsedInShape(offset, m):
565         for i in xrange(offset, offset+m.vertex_count):
566             if io.indices[i] in shape_key_used_vertices:
567                 return True
568
569     material_with_shape=set()
570
571     # 各マテリアルの開始頂点インデックスを記録する
572     face_map={}
573     face_count=0
574     for i, m in enumerate(io.materials):
575         face_map[i]=face_count
576         if isMaterialUsedInShape(face_count, m):
577             material_with_shape.add(i)
578         face_count+=m.vertex_count
579
580     # shapeキーで使われる頂点のあるマテリアル
581     material_with_shape=list(material_with_shape)
582     material_with_shape.sort()
583
584     # shapeキーに使われていないマテリアル
585     material_without_shape=[]
586     for i in range(len(io.materials)):
587         if not i in material_with_shape:
588             material_without_shape.append(i)
589
590     # メッシュの生成
591     def __splitList(l, length):
592         for i in range(0, len(l), length):
593             yield l[i:i+length]
594
595     def __importMeshAndShape(material16, name):
596         mesh, meshObject=bl.mesh.create(name)
597
598         # activate object
599         bl.object.deselectAll()
600         bl.object.activate(meshObject)
601
602         # shapeキーで使われる順に並べなおしたマテリアル16個分の
603         # メッシュを作成する
604         vertex_map=__import16MaerialAndMesh(
605                 meshObject, io, material16, face_map, tex_dir, toon_material)
606
607         # crete shape key
608         __importShape(meshObject, io, vertex_map)
609
610         mesh.update()
611         return meshObject
612
613     mesh_objects=[__importMeshAndShape(material16, 'with_shape')
614         for material16 in __splitList(material_with_shape, 16)]
615
616     mesh_objects+=[__importMeshAndShape(material16, 'mesh')
617         for material16 in __splitList(material_without_shape, 16)]
618
619     return mesh_objects
620
621
622 def __importConstraints(io):
623     print("create constraint")
624     container=bl.object.createEmpty('Constraints')
625     layer=[
626         True, False, False, False, False, False, False, False, False, False,
627         False, False, False, False, False, False, False, False, False, False,
628             ]
629     material=bl.material.create('constraint')
630     material.diffuse_color=(1, 0, 0)
631     constraintMeshes=[]
632     for i, c in enumerate(io.constraints):
633         bpy.ops.mesh.primitive_uv_sphere_add(
634                 segments=8,
635                 rings=4,
636                 size=0.1,
637                 location=(c.pos.x, c.pos.z, c.pos.y),
638                 layer=layer
639                 )
640         meshObject=bl.object.getActive()
641         constraintMeshes.append(meshObject)
642         mesh=bl.object.getData(meshObject)
643         bl.mesh.addMaterial(mesh, material)
644         meshObject.name='c_%d' % i
645         #meshObject.draw_transparent=True
646         #meshObject.draw_wire=True
647         meshObject.max_draw_type='SOLID'
648         rot=c.rot
649         meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
650
651         meshObject[CONSTRAINT_NAME]=c.getName()
652         meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].getName()
653         meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].getName()
654         meshObject[CONSTRAINT_POS_MIN]=VtoV(c.constraintPosMin)
655         meshObject[CONSTRAINT_POS_MAX]=VtoV(c.constraintPosMax)
656         meshObject[CONSTRAINT_ROT_MIN]=VtoV(c.constraintRotMin)
657         meshObject[CONSTRAINT_ROT_MAX]=VtoV(c.constraintRotMax)
658         meshObject[CONSTRAINT_SPRING_POS]=VtoV(c.springPos)
659         meshObject[CONSTRAINT_SPRING_ROT]=VtoV(c.springRot)
660
661     for meshObject in reversed(constraintMeshes):
662         bl.object.makeParent(container, meshObject)
663
664     return container
665
666
667 def __importRigidBodies(io):
668     print("create rigid bodies")
669
670     container=bl.object.createEmpty('RigidBodies')
671     layer=[
672         True, False, False, False, False, False, False, False, False, False,
673         False, False, False, False, False, False, False, False, False, False,
674             ]
675     material=bl.material.create('rigidBody')
676     rigidMeshes=[]
677     for i, rigid in enumerate(io.rigidbodies):
678         if rigid.boneIndex==0xFFFF:
679             # no reference bone
680             bone=io.bones[0]
681         else:
682             bone=io.bones[rigid.boneIndex]
683         pos=bone.pos+rigid.position
684
685         if rigid.shapeType==pmd.SHAPE_SPHERE:
686             bpy.ops.mesh.primitive_ico_sphere_add(
687                     location=(pos.x, pos.z, pos.y),
688                     layer=layer
689                     )
690             bpy.ops.transform.resize(
691                     value=(rigid.w, rigid.w, rigid.w))
692         elif rigid.shapeType==pmd.SHAPE_BOX:
693             bpy.ops.mesh.primitive_cube_add(
694                     location=(pos.x, pos.z, pos.y),
695                     layer=layer
696                     )
697             bpy.ops.transform.resize(
698                     value=(rigid.w, rigid.d, rigid.h))
699         elif rigid.shapeType==pmd.SHAPE_CAPSULE:
700             bpy.ops.mesh.primitive_tube_add(
701                     location=(pos.x, pos.z, pos.y),
702                     layer=layer
703                     )
704             bpy.ops.transform.resize(
705                     value=(rigid.w, rigid.w, rigid.h))
706         else:
707             assert(False)
708
709         meshObject=bl.object.getActive()
710         mesh=bl.object.getData(meshObject)
711         rigidMeshes.append(meshObject)
712         bl.mesh.addMaterial(mesh, material)
713         meshObject.name='r_%d' % i
714         meshObject[RIGID_NAME]=rigid.getName()
715         #meshObject.draw_transparent=True
716         #meshObject.draw_wire=True
717         meshObject.max_draw_type='WIRE'
718         rot=rigid.rotation
719         meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
720
721         # custom properties
722         meshObject[RIGID_SHAPE_TYPE]=rigid.shapeType
723         meshObject[RIGID_PROCESS_TYPE]=rigid.processType
724
725         bone_name = englishmap.getEnglishBoneName(bone.getName())
726         if not bone_name:
727             bone_name=bone.getName()
728         meshObject[RIGID_BONE_NAME]=bone_name
729
730         meshObject[RIGID_GROUP]=rigid.group
731         meshObject[RIGID_INTERSECTION_GROUP]=rigid.target
732         meshObject[RIGID_WEIGHT]=rigid.weight
733         meshObject[RIGID_LINEAR_DAMPING]=rigid.linearDamping
734         meshObject[RIGID_ANGULAR_DAMPING]=rigid.angularDamping
735         meshObject[RIGID_RESTITUTION]=rigid.restitution
736         meshObject[RIGID_FRICTION]=rigid.friction
737
738     for meshObject in reversed(rigidMeshes):
739         bl.object.makeParent(container, meshObject)
740
741     return container
742
743
744 def _execute(filepath=""):
745     """
746     load pmd file to context.
747     """
748
749     # load pmd
750     bl.progress_set('load %s' % filepath, 0.0)
751
752     io=pmd.IO()
753     if not io.read(filepath):
754         bl.message("fail to load %s" % filepath)
755         return
756     bl.progress_set('loaded', 0.1)
757
758     # create root object
759     model_name=io.getEnglishName()
760     if len(model_name)==0:
761         model_name=io.getName()
762     root=bl.object.createEmpty(model_name)
763     root[MMD_MB_NAME]=io.getName()
764     root[MMD_MB_COMMENT]=io.getComment()
765     root[MMD_COMMENT]=io.getEnglishComment()
766
767     # toon textures
768     tex_dir=os.path.dirname(filepath)
769     toonTextures, toonMaterial=__importToonTextures(io, tex_dir)
770     bl.object.makeParent(root, toonTextures)
771
772     # import mesh
773     mesh_objects=__importMaterialAndMesh(io, tex_dir, toonMaterial)
774     for o in mesh_objects:
775         bl.object.makeParent(root, o)
776
777     # import armature
778     armature_object=__importArmature(io)
779     if armature_object:
780         bl.object.makeParent(root, armature_object)
781         armature = bl.object.getData(armature_object)
782
783         # add armature modifier
784         for o in mesh_objects:
785             bl.modifier.addArmature(o, armature_object)
786
787         # Limitation
788         for n, b in bl.object.getPose(armature_object).bones.items():
789             poseBoneLimit(n, b)
790
791     # import rigid bodies
792     rigidBodies=__importRigidBodies(io)
793     if rigidBodies:
794         bl.object.makeParent(root, rigidBodies)
795
796     # import constraints
797     constraints=__importConstraints(io)
798     if constraints:
799         bl.object.makeParent(root, constraints)
800
801     bl.object.activate(root)
802