X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=pymeshio%2Fpmx%2F__init__.py;h=4db73d17a79d6dff8fd7c8b2c1da7f73298e6f84;hb=274167c4b811b059f7c5fdca47c2113ca185399c;hp=42b15f6a8685d2dafff36200b3ecf0fbda84394e;hpb=cf6ec3e04ee67bbe635510486475961ed32e46f2;p=meshio%2Fpymeshio.git diff --git a/pymeshio/pmx/__init__.py b/pymeshio/pmx/__init__.py index 42b15f6..4db73d1 100644 --- a/pymeshio/pmx/__init__.py +++ b/pymeshio/pmx/__init__.py @@ -1,10 +1,22 @@ #!/usr/bin/env python # coding: utf-8 """ -pmx file io library. +======================== +MikuMikuDance PMX format +======================== + +file format +~~~~~~~~~~~ +* PMDEditor's Lib/PMX仕様/PMX仕様.txt + +specs +~~~~~ +* textencoding: unicode +* coordinate: left handed y-up(DirectX) +* uv origin: +* face: only triangle +* backculling: -pmx file format: - PMDEditor's Lib/PMX仕様/PMX仕様.txt """ __author__="ousttrue" __license__="zlib" @@ -18,7 +30,42 @@ from pymeshio import common -class Ik(object): +class DifferenceException(Exception): + pass + + +class Diff(object): + def _diff(self, rhs, key): + l=getattr(self, key) + r=getattr(rhs, key) + if l!=r: + print(l) + print(r) + raise DifferenceException(key) + + def _diff_array(self, rhs, key): + la=getattr(self, key) + ra=getattr(rhs, key) + if len(la)!=len(ra): + raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra))) + for i, (l, r) in enumerate(zip(la, ra)): + if isinstance(l, Diff): + try: + l.diff(r) + except DifferenceException as e: + print(i) + print(l) + print(r) + raise DifferenceException("{0}: {1}".format(key, e.message)) + else: + if l!=r: + print(i) + print(l) + print(r) + raise DifferenceException("{0}".format(key)) + + +class Ik(Diff): """ik info """ __slots__=[ @@ -27,14 +74,28 @@ class Ik(object): 'limit_radian', 'link', ] - def __init__(self, target_index, loop, limit_radian): + def __init__(self, target_index, loop, limit_radian, link=[]): self.target_index=target_index self.loop=loop self.limit_radian=limit_radian - self.link=[] + self.link=link + + def __eq__(self, rhs): + return ( + self.target_index==rhs.target_index + and self.loop==rhs.loop + and self.limit_radian==rhs.limit_radian + and self.link==rhs.link + ) + def diff(self, rhs): + self._diff(rhs, 'target_index') + self._diff(rhs, 'loop') + self._diff(rhs, 'limit_radian') + self._diff_array(rhs, 'link') -class IkLink(object): + +class IkLink(Diff): """ik link info """ __slots__=[ @@ -43,14 +104,28 @@ class IkLink(object): 'limit_min', 'limit_max', ] - def __init__(self, bone_index, limit_angle): + def __init__(self, bone_index, limit_angle, limit_min=common.Vector3(), limit_max=common.Vector3()): self.bone_index=bone_index self.limit_angle=limit_angle - self.limit_min=None - self.limit_max=None + self.limit_min=limit_min + self.limit_max=limit_max + def __eq__(self, rhs): + return ( + self.bone_index==rhs.bone_index + and self.limit_angle==rhs.limit_angle + and self.limit_min==rhs.limit_min + and self.limit_max==rhs.limit_max + ) -class Bone(object): + def diff(self, rhs): + self._diff(rhs, 'bone_index') + self._diff(rhs, 'limit_angle') + self._diff(rhs, 'limit_min') + self._diff(rhs, 'limit_max') + + +class Bone(Diff): """material Bone: see __init__ @@ -63,7 +138,7 @@ class Bone(object): 'layer', 'flag', - 'tail_positoin', + 'tail_position', 'tail_index', 'effect_index', 'effect_factor', @@ -79,7 +154,16 @@ class Bone(object): position, parent_index, layer, - flag + flag, + tail_position=common.Vector3(), + tail_index=-1, + effect_index=-1, + effect_factor=0.0, + fixed_axis=common.Vector3(), + local_x_vector=common.Vector3(), + local_z_vector=common.Vector3(), + external_key=-1, + ik=None ): self.name=name self.english_name=english_name @@ -87,6 +171,15 @@ class Bone(object): self.parent_index=parent_index self.layer=layer self.flag=flag + self.tail_position=tail_position + self.tail_index=tail_index + self.effect_index=effect_index + self.effect_factor=effect_factor + self.fixed_axis=fixed_axis + self.local_x_vector=local_x_vector + self.local_z_vector=local_z_vector + self.external_key=external_key + self.ik=ik def __eq__(self, rhs): return ( @@ -98,6 +191,29 @@ class Bone(object): and self.flag==rhs.flag ) + def __ne__(self, rhs): + return not self.__eq__(rhs) + + def diff(self, rhs): + self._diff(rhs, 'name') + self._diff(rhs, 'english_name') + self._diff(rhs, 'position') + self._diff(rhs, 'parent_index') + #self._diff(rhs, 'layer') + self._diff(rhs, 'flag') + self._diff(rhs, 'tail_position') + self._diff(rhs, 'tail_index') + #self._diff(rhs, 'effect_index') + #self._diff(rhs, 'effect_factor') + #self._diff(rhs, 'fixed_axis') + self._diff(rhs, 'local_x_vector') + self._diff(rhs, 'local_z_vector') + self._diff(rhs, 'external_key') + if self.ik and rhs.ik: + self.ik.diff(rhs.ik) + else: + self._diff(rhs, 'ik') + def getConnectionFlag(self): return self.flag & 0x0001 @@ -120,7 +236,7 @@ class Bone(object): return (self.flag & 0x2000) >> 13 -class Material(object): +class Material(Diff): """material Attributes: see __init__ @@ -149,8 +265,8 @@ class Material(object): english_name, diffuse_color, alpha, - specular_color, specular_factor, + specular_color, ambient_color, flag, edge_color, @@ -158,7 +274,10 @@ class Material(object): texture_index, sphere_texture_index, sphere_mode, - toon_sharing_flag + toon_sharing_flag, + toon_texture_index=0, + comment=common.unicode(""), + vertex_count=0, ): self.name=name self.english_name=english_name @@ -174,10 +293,9 @@ class Material(object): self.sphere_texture_index=sphere_texture_index self.sphere_mode=sphere_mode self.toon_sharing_flag=toon_sharing_flag - # - self.toon_texture_index=None - self.comment=name.__class__() # unicode - self.vertex_count=0 + self.toon_texture_index=toon_texture_index + self.comment=comment + self.vertex_count=vertex_count def __eq__(self, rhs): return ( @@ -200,17 +318,35 @@ class Material(object): and self.vertex_count==rhs.vertex_count ) + def diff(self, rhs): + #self._diff(rhs, "name") + self._diff(rhs, "english_name") + self._diff(rhs, "diffuse_color") + self._diff(rhs, "alpha") + self._diff(rhs, "specular_color") + self._diff(rhs, "specular_factor") + self._diff(rhs, "ambient_color") + self._diff(rhs, "flag") + self._diff(rhs, "edge_color") + self._diff(rhs, "edge_size") + self._diff(rhs, "texture_index") + self._diff(rhs, "sphere_texture_index") + self._diff(rhs, "sphere_mode") + self._diff(rhs, "toon_sharing_flag") + self._diff(rhs, "toon_texture_index") + self._diff(rhs, "comment") + self._diff(rhs, "vertex_count") + + def __ne__(self, rhs): + return not self.__eq__(rhs) + def __str__(self): return ("".format( name=self.english_name )) -class Deform(object): - pass - - -class Bdef1(object): +class Bdef1(Diff): """bone deform. use a weight Attributes: see __init__ @@ -219,11 +355,17 @@ class Bdef1(object): def __init__(self, index0): self.index0=index0 + def __str__(self): + return "".format(self.index0) + def __eq__(self, rhs): return self.index0==rhs.index0 + def __ne__(self, rhs): + return not self.__eq__(rhs) + -class Bdef2(object): +class Bdef2(Diff): """bone deform. use two weights Attributes: see __init__ @@ -237,18 +379,38 @@ class Bdef2(object): self.index1=index1 self.weight0=weight0 + def __str__(self): + return "".format(self.index0, self.index1, self.weight0) + def __eq__(self, rhs): return ( self.index0==rhs.index0 and self.index1==rhs.index1 - and self.weight0==rhs.weight0 + #and self.weight0==rhs.weight0 + and abs(self.weight0-rhs.weight0)<1e-5 ) + def __ne__(self, rhs): + return not self.__eq__(rhs) -class Vertex(object): - """pmx vertex - Attributes: see __init__ +class Vertex(Diff): + """ + ========== + pmx vertex + ========== + + :IVariables: + position + Vector3 + normal + Vector3 + uv + Vector2 + deform + Bdef1, Bdef2 or Bdef4 + edge_factor + float """ __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ] def __init__(self, @@ -263,6 +425,11 @@ class Vertex(object): self.deform=deform self.edge_factor=edge_factor + def __str__(self): + return "