OSDN Git Service

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