OSDN Git Service

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