OSDN Git Service

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