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

Source Code for Package pymeshio.pmx

  1  #!/usr/bin/env python
 
  2  # coding: utf-8
 
  3  """
 
  4  ========================
 
  5  MikuMikuDance PMX format
 
  6  ========================
 
  7  
 
  8  file format
 
  9  ~~~~~~~~~~~
 
 10  * PMDEditor's Lib/PMX仕様/PMX仕様.txt
 
 11  
 
 12  specs
 
 13  ~~~~~
 
 14  * textencoding: unicode
 
 15  * coordinate: left handed y-up(DirectX)
 
 16  * uv origin: 
 
 17  * face: only triangle
 
 18  * backculling: 
 
 19  
 
 20  """ 
 21  __author__="ousttrue" 
 22  __license__="zlib" 
 23  __versioon__="1.0.0" 
 24  
 
 25  
 
 26  import io 
 27  import os 
 28  import struct 
 29  from .. import common 
 30  
 
 31  
 
 32  
 
33 -class DifferenceException(Exception):
34 pass
35 36
37 -class Diff(object):
38 - def _diff(self, rhs, key):
39 l=getattr(self, key) 40 r=getattr(rhs, key) 41 if l!=r: 42 print(l) 43 print(r) 44 raise DifferenceException(key)
45
46 - def _diff_array(self, rhs, key):
47 la=getattr(self, key) 48 ra=getattr(rhs, key) 49 if len(la)!=len(ra): 50 raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra))) 51 for i, (l, r) in enumerate(zip(la, ra)): 52 if isinstance(l, Diff): 53 try: 54 l.diff(r) 55 except DifferenceException as e: 56 print(i) 57 print(l) 58 print(r) 59 raise DifferenceException("{0}: {1}".format(key, e.message)) 60 else: 61 if l!=r: 62 print(i) 63 print(l) 64 print(r) 65 raise DifferenceException("{0}".format(key))
66 67
68 -class Ik(Diff):
69 """ik info 70 """ 71 __slots__=[ 72 'target_index', 73 'loop', 74 'limit_radian', 75 'link', 76 ]
77 - def __init__(self, target_index, loop, limit_radian, link=None):
78 self.target_index=target_index 79 self.loop=loop 80 self.limit_radian=limit_radian 81 self.link=link or []
82
83 - def __eq__(self, rhs):
84 return ( 85 self.target_index==rhs.target_index 86 and self.loop==rhs.loop 87 and self.limit_radian==rhs.limit_radian 88 and self.link==rhs.link 89 )
90
91 - def diff(self, rhs):
92 self._diff(rhs, 'target_index') 93 self._diff(rhs, 'loop') 94 self._diff(rhs, 'limit_radian') 95 self._diff_array(rhs, 'link')
96 97 126 127
128 -class Bone(Diff):
129 """material 130 131 Bone: see __init__ 132 """ 133 __slots__=[ 134 'name', 135 'english_name', 136 'position', 137 'parent_index', 138 'layer', 139 'flag', 140 141 'tail_position', 142 'tail_index', 143 'effect_index', 144 'effect_factor', 145 'fixed_axis', 146 'local_x_vector', 147 'local_z_vector', 148 'external_key', 149 'ik', 150 ]
151 - def __init__(self, 152 name, 153 english_name, 154 position, 155 parent_index, 156 layer, 157 flag, 158 tail_position=None, 159 tail_index=-1, 160 effect_index=-1, 161 effect_factor=0.0, 162 fixed_axis=None, 163 local_x_vector=None, 164 local_z_vector=None, 165 external_key=-1, 166 ik=None 167 ):
183
184 - def __eq__(self, rhs):
185 return ( 186 self.name==rhs.name 187 and self.english_name==rhs.english_name 188 and self.position==rhs.position 189 and self.parent_index==rhs.parent_index 190 and self.layer==rhs.layer 191 and self.flag==rhs.flag 192 )
193
194 - def __ne__(self, rhs):
195 return not self.__eq__(rhs)
196
197 - def diff(self, rhs):
198 self._diff(rhs, 'name') 199 self._diff(rhs, 'english_name') 200 self._diff(rhs, 'position') 201 self._diff(rhs, 'parent_index') 202 #self._diff(rhs, 'layer') 203 self._diff(rhs, 'flag') 204 self._diff(rhs, 'tail_position') 205 self._diff(rhs, 'tail_index') 206 #self._diff(rhs, 'effect_index') 207 #self._diff(rhs, 'effect_factor') 208 #self._diff(rhs, 'fixed_axis') 209 self._diff(rhs, 'local_x_vector') 210 self._diff(rhs, 'local_z_vector') 211 self._diff(rhs, 'external_key') 212 if self.ik and rhs.ik: 213 self.ik.diff(rhs.ik) 214 else: 215 self._diff(rhs, 'ik')
216
217 - def getConnectionFlag(self):
218 return (self.flag & 0x0001)!=0
219
220 - def getVisibleFlag(self):
221 return (self.flag & 0x0008)!=0
222
223 - def getIkFlag(self):
224 return (self.flag & 0x0020)!=0
225
226 - def getRotationFlag(self):
227 return (self.flag & 0x0100)!=0
228
229 - def getTranslationFlag(self):
230 return (self.flag & 0x0200)!=0
231
232 - def getFixedAxisFlag(self):
233 return (self.flag & 0x0400)!=0
234
235 - def getLocalCoordinateFlag(self):
236 return (self.flag & 0x0800)!=0
237
239 return (self.flag & 0x2000)!=0
240 241
242 -class Material(Diff):
243 """material 244 245 Attributes: see __init__ 246 """ 247 __slots__=[ 248 'name', 249 'english_name', 250 'diffuse_color', 251 'alpha', 252 'specular_color', 253 'specular_factor', 254 'ambient_color', 255 'flag', 256 'edge_color', 257 'edge_size', 258 'texture_index', 259 'sphere_texture_index', 260 'sphere_mode', 261 'toon_sharing_flag', 262 'toon_texture_index', 263 'comment', 264 'vertex_count', 265 ]
266 - def __init__(self, 267 name, 268 english_name, 269 diffuse_color, 270 alpha, 271 specular_factor, 272 specular_color, 273 ambient_color, 274 flag, 275 edge_color, 276 edge_size, 277 texture_index, 278 sphere_texture_index, 279 sphere_mode, 280 toon_sharing_flag, 281 toon_texture_index=0, 282 comment=common.unicode(""), 283 vertex_count=0, 284 ):
302
303 - def __eq__(self, rhs):
304 return ( 305 self.name==rhs.name 306 and self.english_name==rhs.english_name 307 and self.diffuse_color==rhs.diffuse_color 308 and self.alpha==rhs.alpha 309 and self.specular_color==rhs.specular_color 310 and self.specular_factor==rhs.specular_factor 311 and self.ambient_color==rhs.ambient_color 312 and self.flag==rhs.flag 313 and self.edge_color==rhs.edge_color 314 and self.edge_size==rhs.edge_size 315 and self.texture_index==rhs.texture_index 316 and self.sphere_texture_index==rhs.sphere_texture_index 317 and self.sphere_mode==rhs.sphere_mode 318 and self.toon_sharing_flag==rhs.toon_sharing_flag 319 and self.toon_texture_index==rhs.toon_texture_index 320 and self.comment==rhs.comment 321 and self.vertex_count==rhs.vertex_count 322 )
323
324 - def diff(self, rhs):
325 #self._diff(rhs, "name") 326 self._diff(rhs, "english_name") 327 self._diff(rhs, "diffuse_color") 328 self._diff(rhs, "alpha") 329 self._diff(rhs, "specular_color") 330 self._diff(rhs, "specular_factor") 331 self._diff(rhs, "ambient_color") 332 self._diff(rhs, "flag") 333 self._diff(rhs, "edge_color") 334 self._diff(rhs, "edge_size") 335 self._diff(rhs, "texture_index") 336 self._diff(rhs, "sphere_texture_index") 337 self._diff(rhs, "sphere_mode") 338 self._diff(rhs, "toon_sharing_flag") 339 self._diff(rhs, "toon_texture_index") 340 self._diff(rhs, "comment") 341 self._diff(rhs, "vertex_count")
342
343 - def __ne__(self, rhs):
344 return not self.__eq__(rhs)
345
346 - def __str__(self):
347 return ("<pmx.Material {name}>".format( 348 name=self.english_name 349 ))
350 351
352 -class Bdef1(Diff):
353 """bone deform. use a weight 354 355 Attributes: see __init__ 356 """ 357 __slots__=[ 'index0']
358 - def __init__(self, index0):
359 self.index0=index0
360
361 - def __str__(self):
362 return "<Bdef1 {0}>".format(self.index0)
363
364 - def __eq__(self, rhs):
365 return self.index0==rhs.index0
366
367 - def __ne__(self, rhs):
368 return not self.__eq__(rhs)
369 370
371 -class Bdef2(Diff):
372 """bone deform. use two weights 373 374 Attributes: see __init__ 375 """ 376 __slots__=[ 'index0', 'index1', 'weight0']
377 - def __init__(self, 378 index0, 379 index1, 380 weight0):
381 self.index0=index0 382 self.index1=index1 383 self.weight0=weight0
384
385 - def __str__(self):
386 return "<Bdef2 {0}, {1}, {2}>".format(self.index0, self.index1, self.weight0)
387
388 - def __eq__(self, rhs):
389 return ( 390 self.index0==rhs.index0 391 and self.index1==rhs.index1 392 #and self.weight0==rhs.weight0 393 and abs(self.weight0-rhs.weight0)<1e-5 394 )
395
396 - def __ne__(self, rhs):
397 return not self.__eq__(rhs)
398 399
400 -class Vertex(Diff):
401 """ 402 ========== 403 pmx vertex 404 ========== 405 406 :IVariables: 407 position 408 Vector3 409 normal 410 Vector3 411 uv 412 Vector2 413 deform 414 Bdef1, Bdef2 or Bdef4 415 edge_factor 416 float 417 """ 418 __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]
419 - def __init__(self, 420 position, 421 normal, 422 uv, 423 deform, 424 edge_factor):
425 self.position=position 426 self.normal=normal 427 self.uv=uv 428 self.deform=deform 429 self.edge_factor=edge_factor
430
431 - def __str__(self):
432 return "<Vertex position:{0}, normal:{1}, uv:{2}, deform:{3}, edge:{4}".format( 433 self.position, self.normal, self.uv, self.deform, self.edge_factor 434 )
435
436 - def __eq__(self, rhs):
437 return ( 438 self.position==rhs.position 439 and self.normal==rhs.normal 440 and self.uv==rhs.uv 441 and self.deform==rhs.deform 442 and self.edge_factor==rhs.edge_factor 443 )
444
445 - def __ne__(self, rhs):
446 return not self.__eq__(rhs)
447
448 - def diff(self, rhs):
449 self._diff(rhs, "position") 450 self._diff(rhs, "normal") 451 self._diff(rhs, "uv") 452 self._diff(rhs, "deform") 453 self._diff(rhs, "edge_factor")
454 455
456 -class Morph(Diff):
457 """pmx morph 458 459 Attributes: 460 name: 461 english_name: 462 panel: 463 morph_type: 464 offsets: 465 """ 466 __slots__=[ 467 'name', 468 'english_name', 469 'panel', 470 'morph_type', 471 'offsets', 472 ]
473 - def __init__(self, name, english_name, panel, morph_type, offsets=None):
474 self.name=name 475 self.english_name=english_name 476 self.panel=panel 477 self.morph_type=morph_type 478 self.offsets=offsets or []
479
480 - def __eq__(self, rhs):
481 return ( 482 self.name==rhs.name 483 and self.english_name==rhs.english_name 484 and self.panel==rhs.panel 485 and self.morph_type==rhs.morph_type 486 and self.offsets==rhs.offsets 487 )
488
489 - def __ne__(self, rhs):
490 return not self.__eq__(rhs)
491
492 - def diff(self, rhs):
493 self._diff(rhs, 'name') 494 self._diff(rhs, 'english_name') 495 #self._diff(rhs, 'panel') 496 self._diff(rhs, 'morph_type') 497 self._diff_array(rhs, 'offsets')
498 499
500 -class VertexMorphOffset(Diff):
501 """pmx vertex morph offset 502 503 Attributes: 504 vertex_index: 505 position_offset: Vector3 506 """ 507 __slots__=[ 508 'vertex_index', 509 'position_offset', 510 ]
511 - def __init__(self, vertex_index, position_offset):
514
515 - def __eq__(self, rhs):
516 return ( 517 self.vertex_index==rhs.vertex_index 518 and self.position_offset==rhs.position_offset 519 )
520
521 - def __ne__(self, rhs):
522 return not self.__eq__(rhs)
523
524 - def diff(self, rhs):
525 self._diff(rhs, 'vertex_index') 526 self._diff(rhs, 'position_offset')
527 528
529 -class DisplaySlot(Diff):
530 """pmx display slot 531 532 Attributes: 533 name: 534 english_name: 535 special_flag: 536 references: list of (ref_type, ref_index) 537 """ 538 __slots__=[ 539 'name', 540 'english_name', 541 'special_flag', 542 'references', 543 ]
544 - def __init__(self, name, english_name, special_flag, references=None):
549
550 - def __str__(self):
551 return "<DisplaySlots %s(%d)>" % (self.name, len(self.references))
552
553 - def __eq__(self, rhs):
554 return ( 555 self.name==rhs.name 556 and self.english_name==rhs.english_name 557 and self.special_flag==rhs.special_flag 558 and self.references==rhs.references 559 )
560
561 - def __ne__(self, rhs):
562 return not self.__eq__(rhs)
563
564 - def diff(self, rhs):
565 self._diff(rhs, 'name') 566 self._diff(rhs, 'english_name') 567 self._diff(rhs, 'special_flag')
568 #self._diff_array(rhs, 'references') 569 570
571 -class RigidBodyParam(Diff):
572 """pmx rigidbody param(for bullet) 573 574 Attributes: 575 mass: 576 linear_damping: 577 angular_damping: 578 restitution: 579 friction: 580 """ 581 __slots__=[ 582 'mass', 583 'linear_damping', 584 'angular_damping', 585 'restitution', 586 'friction', 587 ]
588 - def __init__(self, mass, 589 linear_damping, angular_damping, restitution, friction):
595
596 - def __eq__(self, rhs):
597 return ( 598 self.mass==rhs.mass 599 and self.linear_damping==rhs.linear_damping 600 and self.angular_damping==rhs.angular_damping 601 and self.restitution==rhs.restitution 602 and self.friction==rhs.friction 603 )
604
605 - def __ne__(self, rhs):
606 return not self.__eq__(rhs)
607
608 - def diff(self, rhs):
609 self._diff(rhs, 'mass') 610 self._diff(rhs, 'linear_damping') 611 self._diff(rhs, 'angular_damping') 612 self._diff_array(rhs, 'restitution') 613 self._diff_array(rhs, 'friction')
614 615
616 -class RigidBody(Diff):
617 """pmx rigidbody 618 619 Attributes: 620 name: 621 english_name: 622 bone_index: 623 collision_group: 624 no_collision_group: 625 shape: 626 param: 627 mode: 628 """ 629 __slots__=[ 630 'name', 631 'english_name', 632 'bone_index', 633 'collision_group', 634 'no_collision_group', 635 'shape_type', 636 'shape_size', 637 'shape_position', 638 'shape_rotation', 639 'param', 640 'mode', 641 ]
642 - def __init__(self, 643 name, 644 english_name, 645 bone_index, 646 collision_group, 647 no_collision_group, 648 shape_type, 649 shape_size, 650 shape_position, 651 shape_rotation, 652 mass, 653 linear_damping, 654 angular_damping, 655 restitution, 656 friction, 657 mode 658 ):
672
673 - def __eq__(self, rhs):
674 return ( 675 self.name==rhs.name 676 and self.english_name==rhs.english_name 677 and self.bone_index==rhs.bone_index 678 and self.collision_group==rhs.collision_group 679 and self.no_collision_group==rhs.no_collision_group 680 and self.shape_type==rhs.shape_type 681 and self.shape_size==rhs.shape_size 682 and self.param==rhs.param 683 and self.mode==rhs.mode 684 )
685
686 - def __ne__(self, rhs):
687 return not self.__eq__(rhs)
688
689 - def diff(self, rhs):
690 self._diff(rhs, 'name') 691 self._diff(rhs, 'english_name') 692 self._diff(rhs, 'bone_index') 693 self._diff(rhs, 'collision_group') 694 self._diff(rhs, 'no_collision_group') 695 self._diff(rhs, 'shape_type') 696 self._diff(rhs, 'shape_size') 697 self._diff(rhs, 'shape_position') 698 self._diff(rhs, 'shape_rotation') 699 self._diff(rhs, 'param') 700 self._diff(rhs, 'mode')
701 702
703 -class Joint(Diff):
704 """pmx joint 705 706 Attributes: 707 name: 708 english_name: 709 joint_type: 710 rigidbody_index_a: 711 rigidbody_index_b: 712 position: Vector3 713 rotation: Vector3 714 translation_limit_min: Vector3 715 translation_limit_max: Vector3 716 rotation_limit_min: Vector3 717 rotation_limit_max: Vector3 718 spring_constant_translation: Vector3 719 spring_constant_rotation: Vector3 720 """ 721 __slots__=[ 722 'name', 723 'english_name', 724 'joint_type', 725 'rigidbody_index_a', 726 'rigidbody_index_b', 727 'position', 728 'rotation', 729 'translation_limit_min', 730 'translation_limit_max', 731 'rotation_limit_min', 732 'rotation_limit_max', 733 'spring_constant_translation', 734 'spring_constant_rotation', 735 ]
736 - def __init__(self, name, english_name, 737 joint_type, 738 rigidbody_index_a, 739 rigidbody_index_b, 740 position, 741 rotation, 742 translation_limit_min, 743 translation_limit_max, 744 rotation_limit_min, 745 rotation_limit_max, 746 spring_constant_translation, 747 spring_constant_rotation 748 ):
762
763 - def __eq__(self, rhs):
764 return ( 765 self.name==rhs.name 766 and self.english_name==rhs.english_name 767 and self.joint_type==rhs.joint_type 768 and self.rigidbody_index_a==rhs.rigidbody_index_a 769 and self.rigidbody_index_b==rhs.rigidbody_index_b 770 and self.position==rhs.position 771 and self.rotation==rhs.rotation 772 and self.translation_limit_min==rhs.translation_limit_min 773 and self.translation_limit_max==rhs.translation_limit_max 774 and self.rotation_limit_min==rhs.rotation_limit_min 775 and self.rotation_limit_max==rhs.rotation_limit_max 776 and self.spring_constant_translation==rhs.spring_constant_translation 777 and self.spring_constant_rotation==rhs.spring_constant_rotation 778 )
779
780 - def __ne__(self, rhs):
781 return not self.__eq__(rhs)
782
783 - def diff(self, rhs):
784 self._diff(rhs, 'name') 785 self._diff(rhs, 'joint_type') 786 self._diff(rhs, 'rigidbody_index_a') 787 self._diff(rhs, 'rigidbody_index_b') 788 self._diff(rhs, 'position') 789 self._diff(rhs, 'rotation') 790 self._diff(rhs, 'translation_limit_min') 791 self._diff(rhs, 'translation_limit_max') 792 self._diff(rhs, 'rotation_limit_min') 793 self._diff(rhs, 'rotation_limit_max') 794 self._diff(rhs, 'spring_constant_translation') 795 self._diff(rhs, 'spring_constant_rotation')
796 797
798 -class Model(Diff):
799 """ 800 ========== 801 pmx model 802 ========== 803 804 :IVariables: 805 version 806 pmx version(expected 2.0) 807 name 808 model name 809 english_name 810 model name 811 comment 812 comment 813 english_comment 814 comment 815 vertices 816 vertex list 817 textures 818 texture list 819 materials 820 material list 821 bones 822 bone list 823 morph 824 morph list 825 display_slots 826 display list for bone/morph grouping 827 rigidbodies 828 bullet physics rigidbody list 829 joints 830 bullet physics joint list 831 """ 832 __slots__=[ 833 'path', 834 'version', 835 'name', 836 'english_name', 837 'comment', 838 'english_comment', 839 'vertices', 840 'indices', 841 'textures', 842 'materials', 843 'bones', 844 'morphs', 845 'display_slots', 846 'rigidbodies', 847 'joints', 848 ]
849 - def __init__(self, version=2.0):
850 self.path='' 851 self.version=version 852 self.name='' 853 self.english_name='' 854 self.comment='' 855 self.english_comment='' 856 self.vertices=[] 857 self.indices=[] 858 self.textures=[] 859 self.materials=[] 860 self.bones=[] 861 self.morphs=[] 862 self.display_slots=[] 863 self.rigidbodies=[] 864 self.joints=[]
865
866 - def __str__(self):
867 return ('<pmx-{version} "{name}" {vertices}vertices>'.format( 868 version=self.version, 869 name=self.english_name, 870 vertices=len(self.vertices) 871 ))
872
873 - def __eq__(self, rhs):
874 return ( 875 self.version==rhs.version 876 and self.name==rhs.name 877 and self.english_name==rhs.english_name 878 and self.comment==rhs.comment 879 and self.english_comment==rhs.english_comment 880 and self.vertices==rhs.vertices 881 and self.indices==rhs.indices 882 and self.textures==rhs.textures 883 and self.materials==rhs.materials 884 and self.bones==rhs.bones 885 and self.morphs==rhs.morphs 886 and self.display_slots==rhs.display_slots 887 and self.rigidbodies==rhs.rigidbodies 888 and self.joints==rhs.joints 889 )
890
891 - def __ne__(self, rhs):
892 return not self.__eq__(rhs)
893
894 - def diff(self, rhs):
895 self._diff(rhs, "version") 896 self._diff(rhs, "name") 897 self._diff(rhs, "english_name") 898 self._diff(rhs, "comment") 899 self._diff(rhs, "english_comment") 900 self._diff_array(rhs, "vertices") 901 self._diff_array(rhs, "indices") 902 self._diff_array(rhs, "textures") 903 self._diff_array(rhs, "materials") 904 self._diff_array(rhs, "bones") 905 self._diff_array(rhs, "morphs") 906 self._diff_array(rhs, "display_slots") 907 self._diff_array(rhs, "rigidbodies") 908 self._diff_array(rhs, "joints")
909