Package pymeshio :: Package pmd
[hide private]
[frames] | no frames]

Source Code for Package pymeshio.pmd

  1  # coding: utf-8 
  2  """ 
  3  ======================== 
  4  MikuMikuDance PMD format 
  5  ======================== 
  6   
  7  file format 
  8  ~~~~~~~~~~~ 
  9  * http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4  
 10   
 11  specs 
 12  ~~~~~ 
 13  * textencoding: bytes(cp932) 
 14  * coordinate: left handed y-up(DirectX) 
 15  * uv origin:  
 16  * face: only triangle 
 17  * backculling:  
 18   
 19  """ 
 20  import os 
 21  import sys 
 22  import struct 
 23  import warnings 
 24  from .. import common 
 25   
 26   
27 -class Vertex(object):
28 """ 29 ========== 30 pmd vertex 31 ========== 32 two bone weighted vertex with normal and uv. 33 34 format 35 ~~~~~~ 36 * http://blog.goo.ne.jp/torisu_tetosuki/e/5a1b16e2f61067838dfc66d010389707 37 38 :IVariables: 39 pos 40 Vector3 41 normal 42 Vector3 43 uv 44 Vector2 45 bone0 46 bone index 47 bone1 48 bone index 49 weight0 50 bone0 influence. min: 0, max: 100 51 edge_flag 52 int flag. 0: edge on, 1: edge off 53 """ 54 __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
55 - def __init__(self, pos, normal, uv, 56 bone0, bone1, weight0, edge_flag):
57 self.pos=pos 58 self.normal=normal 59 self.uv=uv 60 self.bone0=bone0 61 self.bone1=bone1 62 self.weight0=weight0 63 self.edge_flag=edge_flag
64
65 - def __str__(self):
66 return "<%s %s %s, (%d, %d, %d)>" % ( 67 str(self.pos), 68 str(self.normal), 69 str(self.uv), 70 self.bone0, self.bone1, self.weight0)
71
72 - def __eq__(self, rhs):
73 return ( 74 self.pos==rhs.pos 75 and self.normal==rhs.normal 76 and self.uv==rhs.uv 77 and self.bone0==rhs.bone0 78 and self.bone1==rhs.bone1 79 and self.weight0==rhs.weight0 80 and self.edge_flag==rhs.edge_flag 81 )
82
83 - def __getitem__(self, key):
84 if key==0: 85 return self.pos.x 86 elif key==1: 87 return self.pos.y 88 elif key==2: 89 return self.pos.z 90 else: 91 assert(False)
92 93
94 -class Material(object):
95 """ 96 ============ 97 pmd material 98 ============ 99 100 format 101 ~~~~~~ 102 * http://blog.goo.ne.jp/torisu_tetosuki/e/ea0bb1b1d4c6ad98a93edbfe359dac32 103 104 :IVariables: 105 diffuse_color 106 RGB 107 alpha 108 float 109 specular_factor 110 float 111 specular_color 112 RGB 113 ambient_color 114 RGB 115 toon_index 116 int 117 edge_flag 118 int 119 vertex_count 120 indices length 121 texture_file 122 texture file path 123 """ 124 __slots__=[ 125 'diffuse_color', 'alpha', 126 'specular_factor', 'specular_color', 'ambient_color', 127 'toon_index', 'edge_flag', 128 'vertex_count', 'texture_file', 129 ]
130 - def __init__(self, diffuse_color, alpha, 131 specular_factor, specular_color, ambient_color, 132 toon_index, edge_flag, vertex_count, texture_file):
142
143 - def __str__(self):
144 return "<Material [%f, %f, %f, %f]>" % ( 145 self.diffuse[0], self.diffuse[1], 146 self.diffuse[2], self.diffuse[3], 147 )
148
149 - def __eq__(self, rhs):
150 return ( 151 self.diffuse_color==rhs.diffuse_color 152 and self.alpha==rhs.alpha 153 and self.specular_factor==rhs.specular_factor 154 and self.specular_color==rhs.specular_color 155 and self.ambient_color==rhs.ambient_color 156 and self.toon_index==rhs.toon_index 157 and self.edge_flag==rhs.edge_flag 158 and self.vertex_count==rhs.vertex_count 159 and self.texture_file==rhs.texture_file 160 )
161 162
163 -class Bone(object):
164 """ 165 ========== 166 pmd bone 167 ========== 168 169 format 170 ~~~~~~ 171 * http://blog.goo.ne.jp/torisu_tetosuki/e/638463f52d0ad6ca1c46fd315a9b17d0 172 173 :IVariables: 174 name 175 bone name 176 english_name 177 bone english_name 178 index 179 boen index(append for internal use) 180 type 181 bone type 182 ik 183 ik(append for internal use) 184 pos 185 bone head position 186 ik_index 187 ik target bone index 188 parent_index 189 parent bone index 190 tail_index 191 tail bone index 192 parent 193 parent bone(append for internal use) 194 tail 195 tail bone(append for internal use) 196 children 197 children bone(append for internal use) 198 """ 199 # kinds 200 ROTATE = 0 201 ROTATE_MOVE = 1 202 IK = 2 203 IK_ROTATE_INFL = 4 204 ROTATE_INFL = 5 205 IK_TARGET = 6 206 UNVISIBLE = 7 207 # since v4.0 208 ROLLING=8 # ? 209 TWEAK=9 210 __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos', 211 'children', 'english_name', 'ik_index', 212 'parent_index', 'tail_index', 'tail', 213 ]
214 - def __init__(self, name=b'bone', type=0):
215 self.name=name 216 self.index=0 217 self.type=type 218 self.parent_index=0xFFFF 219 self.tail_index=0 220 self.tail=common.Vector3(0, 0, 0) 221 self.parent=None 222 self.ik_index=0xFFFF 223 self.pos=common.Vector3(0, 0, 0) 224 self.children=[] 225 self.english_name=b''
226
227 - def __eq__(self, rhs):
228 return ( 229 self.name==rhs.name 230 and self.index==rhs.index 231 and self.type==rhs.type 232 and self.parent_index==rhs.parent_index 233 and self.tail_index==rhs.tail_index 234 and self.tail==rhs.tail 235 and self.ik_index==rhs.ik_index 236 and self.pos==rhs.pos 237 and self.children==rhs.children 238 and self.english_name==rhs.english_name 239 )
240
241 - def hasParent(self):
242 return self.parent_index!=0xFFFF
243
244 - def hasChild(self):
245 return self.tail_index!=0
246
247 - def display(self, indent=None):
248 indent=indent or [] 249 if len(indent)>0: 250 prefix='' 251 for i, is_end in enumerate(indent): 252 if i==len(indent)-1: 253 break 254 else: 255 prefix+=' ' if is_end else ' |' 256 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name) 257 print(uni.encode(ENCODING)) 258 else: 259 uni='%s(%s)' % (unicode(self), self.english_name) 260 print(uni.encode(ENCODING)) 261 262 child_count=len(self.children) 263 for i in range(child_count): 264 child=self.children[i] 265 if i<child_count-1: 266 child.display(indent+[False]) 267 else: 268 # last 269 child.display(indent+[True])
270 271 # 0
272 -class Bone_Rotate(Bone):
273 __slots__=[]
274 - def __init__(self, name):
275 super(Bone_Rotate, self).__init__(name, 0)
276 - def __str__(self):
277 return '<ROTATE %s>' % (self.name)
278 # 1
279 -class Bone_RotateMove(Bone):
280 __slots__=[]
281 - def __init__(self, name):
282 super(Bone_RotateMove, self).__init__(name, 1)
283 - def __str__(self):
284 return '<ROTATE_MOVE %s>' % (self.name)
285 # 2
286 -class Bone_IK(Bone):
287 __slots__=[]
288 - def __init__(self, name):
289 super(Bone_IK, self).__init__(name, 2)
290 - def __str__(self):
291 return '<IK %s>' % (self.name)
292 # 4
293 -class Bone_IKRotateInfl(Bone):
294 __slots__=[]
295 - def __init__(self, name):
296 super(Bone_IKRotateInfl, self).__init__(name, 4)
297 - def __str__(self):
298 return '<IK_ROTATE_INFL %s>' % (self.name)
299 # 5
300 -class Bone_RotateInfl(Bone):
301 __slots__=[]
302 - def __init__(self, name):
303 super(Bone_RotateInfl, self).__init__(name, 5)
304 - def __str__(self):
305 return '<ROTATE_INFL %s>' % (self.name)
306 # 6
307 -class Bone_IKTarget(Bone):
308 __slots__=[]
309 - def __init__(self, name):
310 super(Bone_IKTarget, self).__init__(name, 6)
311 - def __str__(self):
312 return '<IK_TARGET %s>' % (self.name)
313 # 7
314 -class Bone_Unvisible(Bone):
315 __slots__=[]
316 - def __init__(self, name):
317 super(Bone_Unvisible, self).__init__(name, 7)
318 - def __str__(self):
319 return '<UNVISIBLE %s>' % (self.name)
320 # 8
321 -class Bone_Rolling(Bone):
322 __slots__=[]
323 - def __init__(self, name):
324 super(Bone_Rolling, self).__init__(name, 8)
325 - def __str__(self):
326 return '<ROLLING %s>' % (self.name)
327 # 9
328 -class Bone_Tweak(Bone):
329 __slots__=[]
330 - def __init__(self, name):
331 super(Bone_Tweak, self).__init__(name, 9)
332 - def __str__(self):
333 return '<TWEAK %s>' % (self.name)
334 335
336 -def createBone(name, type):
337 if type==0: 338 return Bone_Rotate(name) 339 elif type==1: 340 return Bone_RotateMove(name) 341 elif type==2: 342 return Bone_IK(name) 343 elif type==3: 344 raise Exception("no used bone type: 3(%s)" % name) 345 elif type==4: 346 return Bone_IKRotateInfl(name) 347 elif type==5: 348 return Bone_RotateInfl(name) 349 elif type==6: 350 return Bone_IKTarget(name) 351 elif type==7: 352 return Bone_Unvisible(name) 353 elif type==8: 354 return Bone_Rolling(name) 355 elif type==9: 356 return Bone_Tweak(name) 357 else: 358 raise Exception("unknown bone type: %d(%s)", type, name)
359 360
361 -class IK(object):
362 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
363 - def __init__(self, index=0, target=0):
364 self.index=index 365 self.target=target 366 self.iterations=None 367 self.weight=None 368 self.children=[]
369
370 - def __str__(self):
371 return "<IK index: %d, target: %d, iterations: %d, weight: %f, children: %s(%d)>" %(self.index, self.target, self.iterations, self.weight, '-'.join([str(i) for i in self.children]), len(self.children))
372
373 - def __eq__(self, rhs):
374 return ( 375 self.index==rhs.index 376 and self.target==rhs.target 377 and self.iterations==rhs.iterations 378 and self.weight==rhs.weight 379 and self.children==rhs.children 380 )
381 382
383 -class Morph(object):
384 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name', 385 'vertex_count']
386 - def __init__(self, name):
387 self.name=name 388 self.type=None 389 self.indices=[] 390 self.pos_list=[] 391 self.english_name=b'' 392 self.vertex_count=0
393
394 - def append(self, index, x, y, z):
395 self.indices.append(index) 396 self.pos_list.append(common.Vector3(x, y, z))
397
398 - def __str__(self):
399 return '<Skin name: "%s", type: %d, vertex: %d>' % ( 400 self.name, self.type, len(self.indices))
401
402 - def __eq__(self, rhs):
403 return ( 404 self.name==rhs.name 405 and self.type==rhs.type 406 and self.indices==rhs.indices 407 and self.pos_list==rhs.pos_list 408 and self.english_name==rhs.english_name 409 and self.vertex_count==rhs.vertex_count 410 )
411 412
413 -class BoneGroup(object):
414 __slots__=['name', 'english_name']
415 - def __init__(self, name=b'group', english_name=b'center'):
416 self.name=name 417 self.english_name=english_name
418
419 - def __eq__(self, rhs):
420 return self.name==rhs.name and self.english_name==rhs.english_name
421 422 423 SHAPE_SPHERE=0 424 SHAPE_BOX=1 425 SHAPE_CAPSULE=2 426 427 RIGIDBODY_KINEMATICS=0 428 RIGIDBODY_PHYSICS=1 429 RIGIDBODY_PHYSICS_WITH_BONE=2 430 431
432 -class RigidBody(object):
433 __slots__=['name', 434 'bone_index', 435 'collision_group', 436 'no_collision_group', 437 'shape_type', 438 'shape_size', 439 'shape_position', 440 'shape_rotation', 441 'mass', 442 'linear_damping', 443 'angular_damping', 444 'restitution', 445 'friction', 446 'mode' 447 ]
448 - def __init__(self, name, 449 bone_index, 450 collision_group, 451 no_collision_group, 452 shape_type, 453 shape_size, 454 shape_position, 455 shape_rotation, 456 mass, 457 linear_damping, 458 angular_damping, 459 restitution, 460 friction, 461 mode 462 ):
477
478 - def __eq__(self, rhs):
479 return ( 480 self.name==rhs.name 481 and self.bone_index==rhs.bone_index 482 and self.collision_group==rhs.collision_group 483 and self.no_collision_group==rhs.no_collision_group 484 and self.shape_type==rhs.shape_type 485 and self.shape_size==rhs.shape_size 486 and self.shape_position==rhs.shape_position 487 and self.shape_rotation==rhs.shape_rotation 488 and self.mass==rhs.mass 489 and self.linear_damping==rhs.linear_damping 490 and self.angular_damping==rhs.angular_damping 491 and self.restitution==rhs.restitution 492 and self.friction==rhs.friction 493 and self.mode==rhs.mode 494 )
495 496
497 -class Joint(object):
498 __slots__=[ 'name', 'rigidbody_index_a', 'rigidbody_index_b', 499 'position', 'rotation', 500 'translation_limit_max', 'translation_limit_min', 501 'rotation_limit_max', 'rotation_limit_min', 502 'spring_constant_translation', 'spring_constant_rotation', 503 ]
504 - def __init__(self, name, 505 rigidbody_index_a, rigidbody_index_b, 506 position, rotation, 507 translation_limit_max, translation_limit_min, 508 rotation_limit_max, rotation_limit_min, 509 spring_constant_translation, spring_constant_rotation 510 ):
522
523 - def __eq__(self, rhs):
537 538
539 -class Model(object):
540 """pmd loader class. 541 542 Attributes: 543 io: internal use. 544 end: internal use. 545 pos: internal user. 546 547 version: pmd version number 548 _name: internal 549 """ 550 __slots__=[ 551 'path', 552 'version', 'name', 'comment', 553 'english_name', 'english_comment', 554 'vertices', 'indices', 'materials', 'bones', 555 'ik_list', 'morphs', 556 'morph_indices', 'bone_group_list', 'bone_display_list', 557 'toon_textures', 558 'rigidbodies', 'joints', 559 560 'no_parent_bones', 561 ]
562 - def __init__(self, version=1.0):
563 self.path=b'' 564 self.version=version 565 self.name=b'' 566 self.comment=b'' 567 self.english_name=b'' 568 self.english_comment=b'' 569 self.vertices=[] 570 self.indices=[] 571 self.materials=[] 572 self.bones=[] 573 self.ik_list=[] 574 self.morphs=[] 575 self.morph_indices=[] 576 self.bone_group_list=[] 577 self.bone_display_list=[] 578 # extend 579 self.toon_textures=[b'']*10 580 self.rigidbodies=[] 581 self.joints=[] 582 # innner use 583 self.no_parent_bones=[]
584
585 - def each_vertex(self): return self.vertices
586 - def getUV(self, i): return self.vertices[i].uv
587
588 - def __str__(self):
589 return '<pmd-%g, "%s" vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % ( 590 self.version, self.name, len(self.vertices), len(self.indices), 591 len(self.materials), len(self.bones), len(self.ik_list), len(self.morphs))
592
593 - def __eq__(self, rhs):
594 return ( 595 self.name==rhs.name 596 and self.comment==rhs.comment 597 and self.english_name==rhs.english_name 598 and self.english_comment==rhs.english_comment 599 and self.vertices==rhs.vertices 600 and self.indices==rhs.indices 601 and self.materials==rhs.materials 602 and self.bones==rhs.bones 603 and self.ik_list==rhs.ik_list 604 and self.morphs==rhs.morphs 605 and self.morph_indices==rhs.morph_indices 606 and self.bone_group_list==rhs.bone_group_list 607 and self.bone_display_list==rhs.bone_display_list 608 and self.toon_textures==rhs.toon_textures 609 and self.rigidbodies==rhs.rigidbodies 610 and self.joints==rhs.joints 611 )
612
613 - def diff(self, rhs):
614 if self.name!=rhs.name: 615 print(self.name, rhs.name) 616 return 617 if self.comment!=rhs.comment: 618 print(self.comment, rhs.comment) 619 return 620 if self.english_name!=rhs.english_name: 621 print(self.english_name, rhs.english_name) 622 return 623 if self.english_comment!=rhs.english_comment: 624 print(self.english_comment, rhs.english_comment) 625 return 626 if self.vertices!=rhs.vertices: 627 print(self.vertices, rhs.vertices) 628 return 629 if self.indices!=rhs.indices: 630 print(self.indices, rhs.indices) 631 return 632 if self.materials!=rhs.materials: 633 print(self.materials, rhs.materials) 634 return 635 if self.bones!=rhs.bones: 636 print(self.bones, rhs.bones) 637 return 638 if self.ik_list!=rhs.ik_list: 639 print(self.ik_list, rhs.ik_list) 640 return 641 if self.morphs!=rhs.morphs: 642 print(self.morphs, rhs.morphs) 643 return 644 if self.morph_indices!=rhs.morph_indices: 645 print(self.morph_indices, rhs.morph_indices) 646 return 647 if self.bone_group_list!=rhs.bone_group_list: 648 print(self.bone_group_list, rhs.bone_group_list) 649 return 650 if self.bone_display_list!=rhs.bone_display_list: 651 print(self.bone_display_list, rhs.bone_display_list) 652 return 653 if self.toon_textures!=rhs.toon_textures: 654 print(self.toon_textures, rhs.toon_textures) 655 return 656 if self.rigidbodies!=rhs.rigidbodies: 657 print(self.rigidbodies, rhs.rigidbodies) 658 return 659 if self.joints!=rhs.joints: 660 print(self.joints, rhs.joints) 661 return
662