OSDN Git Service

implement converter
authorousttrue <ousttrue@gmail.com>
Thu, 6 Oct 2011 20:39:27 +0000 (05:39 +0900)
committerousttrue <ousttrue@gmail.com>
Thu, 6 Oct 2011 20:39:27 +0000 (05:39 +0900)
examples/pmxbuilder.py
pymeshio/__init__.py
pymeshio/common.py
pymeshio/converter.py [new file with mode: 0644]
pymeshio/pmd/__init__.py
pymeshio/pmd/reader.py
pymeshio/pmx/__init__.py
pymeshio/pmx/reader.py
pymeshio/pmx/writer.py
test/pmd_test.py
test/pmx_test.py

index 44a6907..b2b75c2 100644 (file)
@@ -51,7 +51,7 @@ def build(path):
                 m.diffuse_color[0], \r
                 m.diffuse_color[1], \r
                 m.diffuse_color[2], \r
-                m.diffuse_alpha)\r
+                m.alpha)\r
         if m.texture_index!=255:\r
             texturepath=os.path.join(basedir, model.textures[m.texture_index])\r
             if os.path.isfile(texturepath):\r
index 7921d15..5e4771a 100644 (file)
@@ -1,8 +1,9 @@
+# coding: utf-8\r
+"""\r
+========================\r
+pymeshio\r
+========================\r
 \r
-def unicode(src):\r
-    import sys\r
-    if sys.version_info[0]<3:\r
-        return src.decode('utf-8')\r
-    else:\r
-        return src\r
+3d mesh io library.\r
+"""\r
 \r
index 7177506..950e2d0 100644 (file)
@@ -4,8 +4,21 @@ common utilities.
 """\r
 import math\r
 import struct\r
+import sys\r
 \r
 \r
+def unicode(src):\r
+    """\r
+    literal to unicode for python2 and python3 compatiblity.\r
+\r
+    in python2 str to unicode.\r
+    in python3 str(as unicode) to str.\r
+    """\r
+    if sys.version_info[0]<3:\r
+        return src.decode('utf-8')\r
+    else:\r
+        return src\r
+\r
 """\r
 common structures.\r
 """\r
@@ -24,6 +37,9 @@ class Vector2(object):
     def __eq__(self, rhs):\r
         return self.x==rhs.x and self.y==rhs.y\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
     def __getitem__(self, key):\r
         if key==0:\r
             return self.x\r
@@ -56,6 +72,9 @@ class Vector3(object):
     def __eq__(self, rhs):\r
         return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
     def __getitem__(self, key):\r
         if key==0:\r
             return self.x\r
@@ -221,6 +240,9 @@ class RGB(object):
     def __eq__(self, rhs):\r
         return self.r==rhs.r and self.g==rhs.g and self.b==rhs.b\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
     def __getitem__(self, key):\r
         if key==0:\r
             return self.r\r
@@ -246,6 +268,9 @@ class RGBA(object):
     def __eq__(self, rhs):\r
         return self.r==rhs.r and self.g==rhs.g and self.b==rhs.b and self.a==rhs.a\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
     def __getitem__(self, key):\r
         if key==0:\r
             return self.r\r
@@ -269,6 +294,9 @@ def radian_to_degree(x):
 \r
 \r
 class ParseException(Exception):\r
+    """\r
+    Exception in reader\r
+    """\r
     pass\r
 \r
 \r
@@ -292,6 +320,16 @@ class BinaryReader(object):
         result=struct.unpack(fmt, self.ios.read(size))\r
         return result[0]\r
 \r
+    def read_int(self, size):\r
+        if size==1:\r
+            return self.unpack("b", size)\r
+        if size==2:\r
+            return self.unpack("h", size)\r
+        if size==4:\r
+            return self.unpack("i", size)\r
+        print("not reach here")\r
+        raise ParseException("invalid int size: "+size)\r
+\r
     def read_uint(self, size):\r
         if size==1:\r
             return self.unpack("B", size)\r
@@ -335,6 +373,9 @@ class BinaryReader(object):
 \r
 \r
 class WriteException(Exception):\r
+    """\r
+    Exception in writer\r
+    """\r
     pass\r
 \r
 \r
@@ -351,6 +392,16 @@ class BinaryWriter(object):
     def write_float(self, v):\r
         self.ios.write(struct.pack("f", v))\r
 \r
+    def write_int(self, v, size):\r
+        if size==1:\r
+            self.ios.write(struct.pack("b", v))\r
+        elif size==2:\r
+            self.ios.write(struct.pack("h", v))\r
+        elif size==4:\r
+            self.ios.write(struct.pack("i", v))\r
+        else:\r
+            raise WriteError("invalid int uint size")\r
+\r
     def write_uint(self, v, size):\r
         if size==1:\r
             self.ios.write(struct.pack("B", v))\r
diff --git a/pymeshio/converter.py b/pymeshio/converter.py
new file mode 100644 (file)
index 0000000..a78f322
--- /dev/null
@@ -0,0 +1,328 @@
+# coding: utf-8
+"""
+convert model
+"""
+
+import math
+from . import common
+from . import pmx
+from . import pmd
+
+class ConvertException(Exception):
+    """
+    Exception in writer
+    """
+    pass
+
+def pmd_to_pmx(src):
+    """
+    convert pmd model to pmx model.
+    """
+    dst=pmx.Model()
+    dst.name=src.name.decode("cp932")
+    dst.english_name=src.english_name.decode("cp932")
+    dst.comment=src.comment.replace(
+            b"\n", b"\r\n").decode("cp932")
+    dst.english_comment=src.english_comment.replace(
+            b"\n", b"\r\n").decode("cp932")
+    def createDeform(bone0, bone1, weight0):
+        if weight0==0:
+            return pmx.Bdef1(bone1)
+        elif weight0==100:
+            return pmx.Bdef1(bone0)
+        else:
+            return pmx.Bdef2(bone0, bone1, weight0*0.01)
+    dst.vertices=[
+            pmx.Vertex(
+                v.pos, 
+                v.normal, 
+                v.uv, 
+                createDeform(v.bone0, v.bone1, v.weight0), 
+                1.0 if v.edge_flag==0 else 0.0
+                )
+            for v in src.vertices]
+    dst.indices=[i for i in src.indices]
+
+    texture_map={}
+    def get_flag(m):
+        return (
+                (1 if False  else 0)+
+                (2 if (m.edge_flag & 1!=0) else 0)+
+                (4 if True else 0)+
+                (8 if True else 0)+
+                (16 if (m.edge_flag & 1!=0) else 0)
+                )
+    def get_texture_file(path):
+        if len(path)==0:
+            return None
+        elif path.find(b'*')==-1:
+            return path
+        else:
+            return b'*'.split(path)[0]
+    def get_sphere_texture_file(path):
+        if len(path)==0:
+            return None
+        elif path.find(b'*')==-1:
+            return None
+        else:
+            return b'*'.split(path)[1]
+    def get_texture_index(path):
+        try:
+            return texture_map[get_texture_file(path)]
+        except KeyError:
+            return -1
+    def get_sphere_texture_index(path):
+        try:
+            return texture_map[get_sphere_texture_file(path)]
+        except KeyError:
+            return -1
+    def get_sphere_texture_flag(path):
+        sphere_texture=get_sphere_texture_file(path)
+        if sphere_texture:
+            if sphere_texture.endswith('.sph'):
+                return 1
+            elif sphere_texture.endswith('.spa'):
+                return 2
+            else:
+                raise ConvertException(
+                        "invalid sphere texture: {0}".format(sphere_texture))
+        return 0
+    for m in src.materials:
+        texture=get_texture_file(m.texture_file)
+        if texture and not texture in texture_map:
+            texture_map[texture]=len(texture_map)
+            dst.textures.append(texture.decode("cp932"))
+        sphere_texture=get_sphere_texture_file(m.texture_file)
+        if sphere_texture and not sphere_texture in texture_map:
+            texture_map[sphere_texture]=len(texture_map)
+            dst.textures.append(sphere_texture.decode("cp932"))
+    dst.materials=[
+            pmx.Material(
+                name=common.unicode(""),
+                english_name=common.unicode(""),
+                diffuse_color=m.diffuse_color,
+                alpha=m.alpha,
+                specular_factor=m.specular_factor,
+                specular_color=m.specular_color,
+                ambient_color=m.ambient_color,
+                flag=get_flag(m),
+                edge_color=common.RGBA(0.0, 0.0, 0.0, 1.0),
+                edge_size=1.0,
+                texture_index=get_texture_index(m.texture_file),
+                sphere_texture_index=get_sphere_texture_index(m.texture_file),
+                sphere_mode=get_sphere_texture_flag(m.texture_file),
+                toon_sharing_flag=1,
+                toon_texture_index=m.toon_index,
+                comment=common.unicode(""),
+                vertex_count=m.vertex_count
+                )
+            for i, m in enumerate(src.materials)]
+
+    ik_map={}
+    for ik in src.ik_list:
+        ik_map[ik.index]=ik
+
+    def is_connected(b):
+        if isinstance(b, pmd.Bone_Rolling):
+            return False
+        if isinstance(b, pmd.Bone_Tweak):
+            return False
+        return True
+    def is_rotatable(b):
+        if isinstance(b, pmd.Bone_Rotate):
+            return True
+        if isinstance(b, pmd.Bone_RotateMove):
+            return True
+        if isinstance(b, pmd.Bone_RotateInfl):
+            return True
+        if isinstance(b, pmd.Bone_IKRotateInfl):
+            return True
+        if isinstance(b, pmd.Bone_Rolling):
+            return True
+        if isinstance(b, pmd.Bone_IKTarget):
+            return True
+        if isinstance(b, pmd.Bone_IK):
+            return True
+        if isinstance(b, pmd.Bone_Unvisible):
+            return True
+        if isinstance(b, pmd.Bone_Tweak):
+            return True
+    def is_movable(b):
+        if isinstance(b, pmd.Bone_RotateMove):
+            return True
+        if isinstance(b, pmd.Bone_IK):
+            return True
+    def is_visible(b):
+        if isinstance(b, pmd.Bone_Unvisible):
+            return False
+        if isinstance(b, pmd.Bone_IKTarget):
+            return False
+        if isinstance(b, pmd.Bone_Tweak):
+            return False
+        return True
+    def is_manupilatable(b):
+        return True
+    def has_ik(b):
+        if isinstance(b, pmd.Bone_IK):
+            return True
+    def is_external_rotation(b):
+        if isinstance(b, pmd.Bone_RotateInfl):
+            return True
+        if isinstance(b, pmd.Bone_Tweak):
+            return True
+    def is_fixed_axis(b):
+        if isinstance(b, pmd.Bone_Rolling):
+            return True
+    def is_local_axis(b):
+        pass
+    def after_physics(b):
+        pass
+    def external_parent(b):
+        pass
+    def get_bone_flag(b):
+        return (
+                (1 if is_connected(b) else 0)+
+                (2 if is_rotatable(b) else 0)+
+                (4 if is_movable(b) else 0)+
+                (8 if is_visible(b) else 0)+
+
+                (16 if is_manupilatable(b) else 0)+
+                (32 if has_ik(b) else 0)+
+                0+
+                0+
+
+                (256 if is_external_rotation(b) else 0)+
+                0+
+                (1024 if is_fixed_axis(b) else 0)+
+                (2048 if is_local_axis(b) else 0)+
+
+                (4096 if after_physics(b) else 0)+
+                (8192 if external_parent(b) else 0)
+                )
+
+    def get_tail_position(b):
+        return common.Vector3()
+    def get_tail_index(b):
+        if isinstance(b, pmd.Bone_Rolling):
+            return -1
+        if isinstance(b, pmd.Bone_IKTarget):
+            return -1
+        if isinstance(b, pmd.Bone_Unvisible):
+            return -1
+        if isinstance(b, pmd.Bone_Tweak):
+            return -1
+        return b.tail_index
+    def get_ik_link(bone_index):
+        b=src.bones[bone_index]
+        if b.english_name.find(b'knee')==-1:
+            return pmx.IkLink(
+                            bone_index, 0, 
+                            common.Vector3(), 
+                            common.Vector3())
+        else:
+            return pmx.IkLink(
+                            bone_index, 1, 
+                            common.Vector3(-3.1415927410125732, 0.0, 0.0), 
+                            common.Vector3(-0.00872664619237184524536132812500, 0.0, 0.0))
+    def get_ik(b):
+        if isinstance(b, pmd.Bone_IK):
+            ik=ik_map[b.index]
+            return pmx.Ik(
+                    ik.target, ik.iterations, ik.weight * 4, [
+                        get_ik_link(child) for child in ik.children ])
+        return None
+    def get_layer(b):
+        return 0
+    dst.bones=[
+            pmx.Bone(
+                name=b.name.decode('cp932'),
+                english_name=b.english_name.decode('cp932'),
+                position=b.pos,
+                parent_index=b.parent_index if b.parent_index!=65535 else -1,
+                layer=get_layer(b),
+                flag=get_bone_flag(b),
+                tail_position=get_tail_position(b),
+                tail_index=get_tail_index(b),
+                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=get_ik(b),
+                )
+            for i, b in enumerate(src.bones)]
+
+    return dst
+
+    def is_visible(b):
+        if isinstance(b, pmd.Bone_Unvisible):
+            return False
+        else:
+            return True
+    def is_manupilatable(b):
+        return True
+    def has_ik(b):
+        return False
+    def is_fixed_axis(b):
+        if isinstance(b, pmd.Bone_Rolling):
+            return True
+    def is_local_axis(b):
+        pass
+    def after_physics(b):
+        pass
+    def external_parent(b):
+        pass
+    def get_bone_flag(b):
+        return (
+                (1 if is_connected(b) else 0)+
+                (2 if is_rotatable(b) else 0)+
+                (4 if is_movable(b) else 0)+
+                (8 if is_visible(b) else 0)+
+
+                (16 if is_manupilatable(b) else 0)+
+                (32 if has_ik(b) else 0)+
+                0+
+                0+
+
+                (256 if isinstance(b, pmd.Bone_RotateInfl) else 0)+
+                0+
+                (1024 if is_fixed_axis(b) else 0)+
+                (2048 if is_local_axis(b) else 0)+
+
+                (4096 if after_physics(b) else 0)+
+                (8192 if external_parent(b) else 0)
+                )
+
+    def get_tail_position(b):
+        return common.Vector3()
+    def get_tail_index(b):
+        if isinstance(b, pmd.Bone_Rolling):
+            return -1
+        return b.tail_index
+    def get_ik(b):
+        return None
+    def get_layer(b):
+        return 0
+    dst.bones=[
+            pmx.Bone(
+                name=b.name.decode('cp932'),
+                english_name=b.english_name.decode('cp932'),
+                position=b.pos,
+                parent_index=b.parent_index if b.parent_index!=65535 else -1,
+                layer=get_layer(b),
+                flag=get_bone_flag(b),
+                tail_position=get_tail_position(b),
+                tail_index=get_tail_index(b),
+                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=get_ik(b),
+                )
+            for i, b in enumerate(src.bones)]
+
+    return dst
+
index f3c8e4f..839b637 100644 (file)
@@ -25,16 +25,31 @@ from .. import common
 
 
 class Vertex(object):
-    """pmd vertex struct.
-
-    Attributes:
-        pos: Vector3
-        normal: Vector3
-        uv: Vector2
-        bone0: bone index
-        bone1: bone index
-        weight0: bone0 influence
-        edge_flag: int flag
+    """
+    ==========
+    pmd vertex
+    ==========
+    two bone weighted vertex with normal and uv.
+
+    format
+    ~~~~~~
+    * http://blog.goo.ne.jp/torisu_tetosuki/e/5a1b16e2f61067838dfc66d010389707
+
+    :IVariables:
+        pos
+            Vector3
+        normal 
+            Vector3
+        uv 
+            Vector2
+        bone0 
+            bone index
+        bone1 
+            bone index
+        weight0 
+            bone0 influence.  min: 0, max: 100
+        edge_flag 
+            int flag.  0: edge on, 1: edge off
     """
     __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
     def __init__(self, pos, normal, uv, 
@@ -77,18 +92,34 @@ class Vertex(object):
 
 
 class Material(object):
-    """pmd material struct.
-
-    Attributes:
-        diffuse_color: RGB
-        alpha: float
-        specular_factor: float
-        specular_color: RGB
-        ambient_color: RGB
-        toon_index: int
-        edge_flag: int
-        vertex_count: indices length
-        texture_file: texture file path
+    """
+    ============
+    pmd material
+    ============
+
+    format
+    ~~~~~~
+    * http://blog.goo.ne.jp/torisu_tetosuki/e/ea0bb1b1d4c6ad98a93edbfe359dac32
+
+    :IVariables:
+        diffuse_color
+            RGB
+        alpha
+            float
+        specular_factor
+            float
+        specular_color
+            RGB
+        ambient_color
+            RGB
+        toon_index
+            int
+        edge_flag
+            int
+        vertex_count
+            indices length
+        texture_file
+            texture file path
     """
     __slots__=[
             'diffuse_color', 'alpha', 
@@ -130,22 +161,40 @@ class Material(object):
 
 
 class Bone(object):
-    """pmd material struct.
-
-    Attributes:
-        _name: 
-        index:
-        type:
-        ik:
-        pos:
-        _english_name:
-        ik_index:
-        parent_index:
-        tail_index:
-
-        parent:
-        tail:
-        children:
+    """
+    ==========
+    pmd bone
+    ==========
+
+    format
+    ~~~~~~
+    * http://blog.goo.ne.jp/torisu_tetosuki/e/638463f52d0ad6ca1c46fd315a9b17d0
+
+    :IVariables:
+        name 
+            bone name
+        english_name
+            bone english_name
+        index
+            boen index(append for internal use)
+        type
+            bone type
+        ik
+            ik(append for internal use)
+        pos
+            bone head position
+        ik_index
+            ik target bone index
+        parent_index
+            parent bone index
+        tail_index
+            tail bone index
+        parent
+            parent bone(append for internal use)
+        tail
+            tail bone(append for internal use)
+        children
+            children bone(append for internal use)
     """
     # kinds
     ROTATE = 0
index 9183c0d..b120052 100644 (file)
@@ -205,6 +205,7 @@ def read(ios):
 \r
         # build bone tree\r
         for i, child in enumerate(model.bones):\r
+            child.index=i\r
             if child.parent_index==0xFFFF:\r
                 # no parent\r
                 model.no_parent_bones.append(child)\r
index 77d45a3..7afe5f2 100644 (file)
@@ -30,7 +30,42 @@ from pymeshio import common
 \r
 \r
 \r
-class Ik(object):\r
+class DifferenceException(Exception):\r
+    pass\r
+\r
+\r
+class Diff(object):\r
+    def _diff(self, rhs, key):\r
+        l=getattr(self, key)\r
+        r=getattr(rhs, key)\r
+        if l!=r:\r
+            print(l)\r
+            print(r)\r
+            raise DifferenceException(key)\r
+\r
+    def _diff_array(self, rhs, key):\r
+        la=getattr(self, key)\r
+        ra=getattr(rhs, key)\r
+        if len(la)!=len(la):\r
+            raise DifferenceException(key)\r
+        for i, (l, r) in enumerate(zip(la, ra)):\r
+            if isinstance(l, Diff):\r
+                try:\r
+                    l.diff(r)\r
+                except DifferenceException as e:\r
+                    print(i)\r
+                    print(l)\r
+                    print(r)\r
+                    raise DifferenceException("{0}: {1}".format(key, e.message))\r
+            else:\r
+                if l!=r:\r
+                    print(i)\r
+                    print(l)\r
+                    print(r)\r
+                    raise DifferenceException("{0}".format(key))\r
+\r
+\r
+class Ik(Diff):\r
     """ik info\r
     """\r
     __slots__=[\r
@@ -39,14 +74,28 @@ class Ik(object):
             'limit_radian',\r
             'link',\r
             ]\r
-    def __init__(self, target_index, loop, limit_radian):\r
+    def __init__(self, target_index, loop, limit_radian, link=[]):\r
         self.target_index=target_index\r
         self.loop=loop\r
         self.limit_radian=limit_radian\r
-        self.link=[]\r
+        self.link=link\r
+\r
+    def __eq__(self, rhs):\r
+        return (\r
+                self.target_index==rhs.target_index\r
+                and self.loop==rhs.loop\r
+                and self.limit_radian==rhs.limit_radian\r
+                and self.link==rhs.link\r
+                )\r
 \r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'target_index')\r
+        self._diff(rhs, 'loop')\r
+        self._diff(rhs, 'limit_radian')\r
+        self._diff_array(rhs, 'link')\r
 \r
-class IkLink(object):\r
+\r
+class IkLink(Diff):\r
     """ik link info\r
     """\r
     __slots__=[\r
@@ -55,14 +104,28 @@ class IkLink(object):
             'limit_min',\r
             'limit_max',\r
             ]\r
-    def __init__(self, bone_index, limit_angle):\r
+    def __init__(self, bone_index, limit_angle, limit_min=common.Vector3(), limit_max=common.Vector3()):\r
         self.bone_index=bone_index\r
         self.limit_angle=limit_angle\r
-        self.limit_min=None\r
-        self.limit_max=None\r
+        self.limit_min=limit_min\r
+        self.limit_max=limit_max\r
 \r
+    def __eq__(self, rhs):\r
+        return (\r
+                self.bone_index==rhs.bone_index\r
+                and self.limit_angle==rhs.limit_angle\r
+                and self.limit_min==rhs.limit_min\r
+                and self.limit_max==rhs.limit_max\r
+                )\r
 \r
-class Bone(object):\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'bone_index')\r
+        self._diff(rhs, 'limit_angle')\r
+        self._diff(rhs, 'limit_min')\r
+        self._diff(rhs, 'limit_max')\r
+\r
+\r
+class Bone(Diff):\r
     """material\r
 \r
     Bone: see __init__\r
@@ -75,7 +138,7 @@ class Bone(object):
             'layer',\r
             'flag',\r
 \r
-            'tail_positoin',\r
+            'tail_position',\r
             'tail_index',\r
             'effect_index',\r
             'effect_factor',\r
@@ -91,7 +154,16 @@ class Bone(object):
             position,\r
             parent_index,\r
             layer,\r
-            flag\r
+            flag,\r
+            tail_position=common.Vector3(),\r
+            tail_index=-1,\r
+            effect_index=-1,\r
+            effect_factor=0.0,\r
+            fixed_axis=common.Vector3(),\r
+            local_x_vector=common.Vector3(),\r
+            local_z_vector=common.Vector3(),\r
+            external_key=-1,\r
+            ik=None\r
             ):\r
         self.name=name\r
         self.english_name=english_name\r
@@ -99,6 +171,15 @@ class Bone(object):
         self.parent_index=parent_index\r
         self.layer=layer\r
         self.flag=flag\r
+        self.tail_position=tail_position\r
+        self.tail_index=tail_index\r
+        self.effect_index=effect_index\r
+        self.effect_factor=effect_factor\r
+        self.fixed_axis=fixed_axis\r
+        self.local_x_vector=local_x_vector\r
+        self.local_z_vector=local_z_vector\r
+        self.external_key=external_key\r
+        self.ik=ik\r
 \r
     def __eq__(self, rhs):\r
         return (\r
@@ -110,6 +191,29 @@ class Bone(object):
                 and self.flag==rhs.flag\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'english_name')\r
+        self._diff(rhs, 'position')\r
+        self._diff(rhs, 'parent_index')\r
+        #self._diff(rhs, 'layer')\r
+        self._diff(rhs, 'flag')\r
+        self._diff(rhs, 'tail_position')\r
+        self._diff(rhs, 'tail_index')\r
+        #self._diff(rhs, 'effect_index')\r
+        #self._diff(rhs, 'effect_factor')\r
+        #self._diff(rhs, 'fixed_axis')\r
+        self._diff(rhs, 'local_x_vector')\r
+        self._diff(rhs, 'local_z_vector')\r
+        self._diff(rhs, 'external_key')\r
+        if self.ik and rhs.ik:\r
+            self.ik.diff(rhs.ik)\r
+        else:\r
+            self._diff(rhs, 'ik')\r
+\r
     def getConnectionFlag(self):\r
         return self.flag & 0x0001\r
 \r
@@ -132,7 +236,7 @@ class Bone(object):
         return (self.flag &  0x2000) >> 13\r
 \r
  \r
-class Material(object):\r
+class Material(Diff):\r
     """material\r
 \r
     Attributes: see __init__\r
@@ -161,8 +265,8 @@ class Material(object):
             english_name,\r
             diffuse_color,\r
             alpha,\r
-            specular_color,\r
             specular_factor,\r
+            specular_color,\r
             ambient_color,\r
             flag,\r
             edge_color,\r
@@ -170,7 +274,10 @@ class Material(object):
             texture_index,\r
             sphere_texture_index,\r
             sphere_mode,\r
-            toon_sharing_flag\r
+            toon_sharing_flag,\r
+            toon_texture_index=0,\r
+            comment=common.unicode(""),\r
+            vertex_count=0,\r
             ):\r
         self.name=name\r
         self.english_name=english_name\r
@@ -186,10 +293,9 @@ class Material(object):
         self.sphere_texture_index=sphere_texture_index\r
         self.sphere_mode=sphere_mode\r
         self.toon_sharing_flag=toon_sharing_flag\r
-        #\r
-        self.toon_texture_index=None\r
-        self.comment=name.__class__() # unicode\r
-        self.vertex_count=0\r
+        self.toon_texture_index=toon_texture_index\r
+        self.comment=comment\r
+        self.vertex_count=vertex_count\r
 \r
     def __eq__(self, rhs):\r
         return (\r
@@ -212,17 +318,35 @@ class Material(object):
                 and self.vertex_count==rhs.vertex_count\r
                 )\r
 \r
+    def diff(self, rhs):\r
+        #self._diff(rhs, "name")\r
+        self._diff(rhs, "english_name")\r
+        self._diff(rhs, "diffuse_color")\r
+        self._diff(rhs, "alpha")\r
+        self._diff(rhs, "specular_color")\r
+        self._diff(rhs, "specular_factor")\r
+        self._diff(rhs, "ambient_color")\r
+        self._diff(rhs, "flag")\r
+        self._diff(rhs, "edge_color")\r
+        self._diff(rhs, "edge_size")\r
+        self._diff(rhs, "texture_index")\r
+        self._diff(rhs, "sphere_texture_index")\r
+        self._diff(rhs, "sphere_mode")\r
+        self._diff(rhs, "toon_sharing_flag")\r
+        self._diff(rhs, "toon_texture_index")\r
+        self._diff(rhs, "comment")\r
+        self._diff(rhs, "vertex_count")\r
+\r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
     def __str__(self):\r
         return ("<pmx.Material {name}>".format(\r
             name=self.english_name\r
             ))\r
 \r
 \r
-class Deform(object):\r
-    pass\r
-\r
-\r
-class Bdef1(object):\r
+class Bdef1(Diff):\r
     """bone deform. use a weight\r
 \r
     Attributes: see __init__\r
@@ -231,11 +355,17 @@ class Bdef1(object):
     def __init__(self, index0):\r
         self.index0=index0\r
 \r
+    def __str__(self):\r
+        return "<Bdef1 {0}>".format(self.index0)\r
+\r
     def __eq__(self, rhs):\r
         return self.index0==rhs.index0\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
 \r
-class Bdef2(object):\r
+class Bdef2(Diff):\r
     """bone deform. use two weights\r
 \r
     Attributes: see __init__\r
@@ -249,18 +379,38 @@ class Bdef2(object):
         self.index1=index1\r
         self.weight0=weight0\r
 \r
+    def __str__(self):\r
+        return "<Bdef2 {0}, {1}, {2}>".format(self.index0, self.index1, self.weight0)\r
+\r
     def __eq__(self, rhs):\r
         return (\r
                 self.index0==rhs.index0\r
                 and self.index1==rhs.index1\r
-                and self.weight0==rhs.weight0\r
+                #and self.weight0==rhs.weight0\r
+                and abs(self.weight0-rhs.weight0)<1e-5\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
 \r
-class Vertex(object):\r
-    """pmx vertex\r
 \r
-    Attributes: see __init__\r
+class Vertex(Diff):\r
+    """\r
+    ==========\r
+    pmx vertex\r
+    ==========\r
+\r
+    :IVariables:\r
+        position\r
+            Vector3\r
+        normal \r
+            Vector3\r
+        uv \r
+            Vector2\r
+        deform\r
+            Bdef1, Bdef2 or Bdef4\r
+        edge_factor\r
+            float\r
     """\r
     __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]\r
     def __init__(self, \r
@@ -275,6 +425,11 @@ class Vertex(object):
         self.deform=deform\r
         self.edge_factor=edge_factor\r
 \r
+    def __str__(self):\r
+        return "<Vertex position:{0}, normal:{1}, uv:{2}, deform:{3}, edge:{4}".format(\r
+                self.position, self.normal, self.uv, self.deform, self.edge_factor\r
+                )\r
+\r
     def __eq__(self, rhs):\r
         return (\r
                 self.position==rhs.position\r
@@ -284,8 +439,18 @@ class Vertex(object):
                 and self.edge_factor==rhs.edge_factor\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
 \r
-class Morph(object):\r
+    def diff(self, rhs):\r
+        self._diff(rhs, "position")\r
+        self._diff(rhs, "normal")\r
+        self._diff(rhs, "uv")\r
+        self._diff(rhs, "deform")\r
+        self._diff(rhs, "edge_factor")\r
+\r
+\r
+class Morph(Diff):\r
     """pmx morph\r
 \r
     Attributes:\r
@@ -318,8 +483,18 @@ class Morph(object):
                 and self.offsets==rhs.offsets\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'english_name')\r
+        self._diff(rhs, 'panel')\r
+        self._diff(rhs, 'morph_type')\r
+        self._diff_array(rhs, 'offsets')\r
 \r
-class VerexMorphOffset(object):\r
+\r
+class VerexMorphOffset(Diff):\r
     """pmx vertex morph offset\r
 \r
     Attributes:\r
@@ -340,8 +515,15 @@ class VerexMorphOffset(object):
                 and self.position_offset==rhs.position_offset\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'english_name')\r
+\r
 \r
-class DisplaySlot(object):\r
+class DisplaySlot(Diff):\r
     """pmx display slot\r
 \r
     Attributes:\r
@@ -370,8 +552,17 @@ class DisplaySlot(object):
                 and self.refrences==rhs.refrences\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
 \r
-class RigidBodyParam(object):\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'english_name')\r
+        self._diff(rhs, 'special_flag')\r
+        self._diff_array(rhs, 'refrences')\r
+\r
+\r
+class RigidBodyParam(Diff):\r
     """pmx rigidbody param(for bullet)\r
 \r
     Attributes:\r
@@ -405,8 +596,18 @@ class RigidBodyParam(object):
                 and self.friction==rhs.friction\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'mass')\r
+        self._diff(rhs, 'linear_damping')\r
+        self._diff(rhs, 'angular_damping')\r
+        self._diff_array(rhs, 'restitution')\r
+        self._diff_array(rhs, 'friction')\r
 \r
-class RigidBody(object):\r
+\r
+class RigidBody(Diff):\r
     """pmx rigidbody\r
 \r
     Attributes:\r
@@ -476,8 +677,24 @@ class RigidBody(object):
                 and self.mode==rhs.mode\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'english_name')\r
+        self._diff(rhs, 'bone_index')\r
+        self._diff(rhs, 'collision_group')\r
+        self._diff(rhs, 'no_collision_group')\r
+        self._diff(rhs, 'shape_type')\r
+        self._diff(rhs, 'shape_size')\r
+        self._diff(rhs, 'shape_position')\r
+        self._diff(rhs, 'shape_rotation')\r
+        self._diff(rhs, 'param')\r
+        self._diff(rhs, 'mode')\r
 \r
-class Joint(object):\r
+\r
+class Joint(Diff):\r
     """pmx joint\r
 \r
     Attributes:\r
@@ -554,31 +771,64 @@ class Joint(object):
                 and self.spring_constant_rotation==rhs.spring_constant_rotation\r
                 )\r
 \r
-\r
-class Model(object):\r
-    """pmx data representation\r
-\r
-    Attributes:\r
-        version: pmx version(expected 2.0)\r
-        name: \r
-        english_name: \r
-        comment: \r
-        english_comment: \r
-        vertices:\r
-        textures:\r
-        materials:\r
-        bones:\r
-        morph:\r
-        display_slots:\r
-        rigidbodies:\r
-        joints:\r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, 'name')\r
+        self._diff(rhs, 'joint_type')\r
+        self._diff(rhs, 'rigidbody_index_a')\r
+        self._diff(rhs, 'rigidbody_index_b')\r
+        self._diff(rhs, 'position')\r
+        self._diff(rhs, 'rotation')\r
+        self._diff(rhs, 'translation_limit_min')\r
+        self._diff(rhs, 'translation_limit_max')\r
+        self._diff(rhs, 'rotation_limit_min')\r
+        self._diff(rhs, 'rotation_limit_max')\r
+        self._diff(rhs, 'spring_constant_translation')\r
+        self._diff(rhs, 'spring_constant_rotation')\r
+\r
+\r
+class Model(Diff):\r
+    """\r
+    ==========\r
+    pmx model\r
+    ==========\r
+\r
+    :IVariables:\r
+        version\r
+            pmx version(expected 2.0)\r
+        name \r
+            model name\r
+        english_name \r
+            model name\r
+        comment \r
+            comment\r
+        english_comment \r
+            comment\r
+        vertices\r
+            vertex list\r
+        textures\r
+            texture list\r
+        materials\r
+            material list\r
+        bones\r
+            bone list\r
+        morph\r
+            morph list\r
+        display_slots\r
+            display list for bone/morph grouping\r
+        rigidbodies\r
+            bullet physics rigidbody list\r
+        joints\r
+            bullet physics joint list\r
     """\r
     __slots__=[\r
-            'version', # pmx version\r
-            'name', # model name\r
-            'english_name', # model name in english\r
-            'comment', # model comment\r
-            'english_comment', # model comment in english\r
+            'version',\r
+            'name',\r
+            'english_name',\r
+            'comment',\r
+            'english_comment',\r
             'vertices',\r
             'indices',\r
             'textures',\r
@@ -589,7 +839,7 @@ class Model(object):
             'rigidbodies',\r
             'joints',\r
             ]\r
-    def __init__(self, version):\r
+    def __init__(self, version=2.0):\r
         self.version=version\r
         self.name=''\r
         self.english_name=''\r
@@ -630,3 +880,22 @@ class Model(object):
                 and self.joints==rhs.joints\r
                 )\r
 \r
+    def __ne__(self, rhs):\r
+        return not self.__eq__(rhs)\r
+\r
+    def diff(self, rhs):\r
+        self._diff(rhs, "version")\r
+        self._diff(rhs, "name")\r
+        self._diff(rhs, "english_name")\r
+        self._diff(rhs, "comment")\r
+        self._diff(rhs, "english_comment")\r
+        self._diff_array(rhs, "vertices")\r
+        self._diff_array(rhs, "indices")\r
+        self._diff_array(rhs, "textures")\r
+        self._diff_array(rhs, "materials")\r
+        self._diff_array(rhs, "bones")\r
+        self._diff_array(rhs, "morphs")\r
+        self._diff_array(rhs, "display_slots")\r
+        self._diff_array(rhs, "rigidbodies")\r
+        self._diff_array(rhs, "joints")\r
+\r
index ee3d211..8c08585 100644 (file)
@@ -25,12 +25,12 @@ class Reader(pymeshio.common.BinaryReader):
         if extended_uv>0:\r
             raise pymeshio.common.ParseException(\r
                     "extended uv is not supported", extended_uv)\r
-        self.read_vertex_index=lambda : self.read_uint(vertex_index_size)\r
-        self.read_texture_index=lambda : self.read_uint(texture_index_size)\r
-        self.read_material_index=lambda : self.read_uint(material_index_size)\r
-        self.read_bone_index=lambda : self.read_uint(bone_index_size)\r
-        self.read_morph_index=lambda : self.read_uint(morph_index_size)\r
-        self.read_rigidbody_index=lambda : self.read_uint(rigidbody_index_size)\r
+        self.read_vertex_index=lambda : self.read_int(vertex_index_size)\r
+        self.read_texture_index=lambda : self.read_int(texture_index_size)\r
+        self.read_material_index=lambda : self.read_int(material_index_size)\r
+        self.read_bone_index=lambda : self.read_int(bone_index_size)\r
+        self.read_morph_index=lambda : self.read_int(morph_index_size)\r
+        self.read_rigidbody_index=lambda : self.read_int(rigidbody_index_size)\r
 \r
     def __str__(self):\r
         return '<pymeshio.pmx.Reader>'\r
@@ -38,12 +38,12 @@ class Reader(pymeshio.common.BinaryReader):
     def get_read_text(self, text_encoding):\r
         if text_encoding==0:\r
             def read_text():\r
-                size=self.read_uint(4)\r
+                size=self.read_int(4)\r
                 return self.unpack("{0}s".format(size), size).decode("UTF16")\r
             return read_text\r
         elif text_encoding==1:\r
             def read_text():\r
-                size=self.read_uint(4)\r
+                size=self.read_int(4)\r
                 return self.unpack("{0}s".format(size), size).decode("UTF8")\r
             return read_text\r
         else:\r
@@ -59,7 +59,7 @@ class Reader(pymeshio.common.BinaryReader):
                 )\r
 \r
     def read_deform(self):\r
-        deform_type=self.read_uint(1)\r
+        deform_type=self.read_int(1)\r
         if deform_type==0:\r
             return pymeshio.pmx.Bdef1(self.read_bone_index())\r
         elif deform_type==1:\r
@@ -85,24 +85,24 @@ class Reader(pymeshio.common.BinaryReader):
                 specular_color=self.read_rgb(),\r
                 specular_factor=self.read_float(),\r
                 ambient_color=self.read_rgb(),\r
-                flag=self.read_uint(1),\r
+                flag=self.read_int(1),\r
                 edge_color=self.read_rgba(),\r
                 edge_size=self.read_float(),\r
                 texture_index=self.read_texture_index(),\r
                 sphere_texture_index=self.read_texture_index(),\r
-                sphere_mode=self.read_uint(1),\r
-                toon_sharing_flag=self.read_uint(1),\r
+                sphere_mode=self.read_int(1),\r
+                toon_sharing_flag=self.read_int(1),\r
                 )\r
         if material.toon_sharing_flag==0:\r
             material.toon_texture_index=self.read_texture_index()\r
         elif material.toon_sharing_flag==1:\r
-            material.toon_texture_index=self.read_uint(1)\r
+            material.toon_texture_index=self.read_int(1)\r
         else:\r
             raise pymeshio.common.ParseException(\r
                     "unknown toon_sharing_flag {0}".format(\r
                         material.toon_sharing_flag))\r
         material.comment=self.read_text()\r
-        material.vertex_count=self.read_uint(4)\r
+        material.vertex_count=self.read_int(4)\r
         return material\r
 \r
     def read_bone(self):\r
@@ -111,11 +111,11 @@ class Reader(pymeshio.common.BinaryReader):
                 english_name=self.read_text(),\r
                 position=self.read_vector3(),\r
                 parent_index=self.read_bone_index(),\r
-                layer=self.read_uint(4),\r
-                flag=self.read_uint(2)                \r
+                layer=self.read_int(4),\r
+                flag=self.read_int(2)                \r
                 )\r
         if bone.getConnectionFlag()==0:\r
-            bone.tail_positoin=self.read_vector3()\r
+            bone.tail_position=self.read_vector3()\r
         elif bone.getConnectionFlag()==1:\r
             bone.tail_index=self.read_bone_index()\r
         else:\r
@@ -135,7 +135,7 @@ class Reader(pymeshio.common.BinaryReader):
             bone.local_z_vector=self.read_vector3()\r
 \r
         if bone.getExternalParentDeformFlag()==1:\r
-            bone.external_key=self.read_uint(4)\r
+            bone.external_key=self.read_int(4)\r
 \r
         if bone.getIkFlag()==1:\r
             bone.ik=self.read_ik()\r
@@ -145,9 +145,9 @@ class Reader(pymeshio.common.BinaryReader):
     def read_ik(self):\r
         ik=pymeshio.pmx.Ik(\r
                 target_index=self.read_bone_index(),\r
-                loop=self.read_uint(4),\r
+                loop=self.read_int(4),\r
                 limit_radian=self.read_float())\r
-        link_size=self.read_uint(4)\r
+        link_size=self.read_int(4)\r
         ik.link=[self.read_ik_link() \r
                 for _ in range(link_size)]\r
         return ik\r
@@ -155,7 +155,7 @@ class Reader(pymeshio.common.BinaryReader):
     def read_ik_link(self):\r
         link=pymeshio.pmx.IkLink(\r
                 self.read_bone_index(),\r
-                self.read_uint(1))\r
+                self.read_int(1))\r
         if link.limit_angle==0:\r
             pass\r
         elif link.limit_angle==1:\r
@@ -170,9 +170,9 @@ class Reader(pymeshio.common.BinaryReader):
     def read_morgh(self):\r
         name=self.read_text()\r
         english_name=self.read_text()\r
-        panel=self.read_uint(1)\r
-        morph_type=self.read_uint(1)\r
-        offset_size=self.read_uint(4)\r
+        panel=self.read_int(1)\r
+        morph_type=self.read_int(1)\r
+        offset_size=self.read_int(4)\r
         if morph_type==0:\r
             # todo\r
             raise pymeshio.common.ParseException(\r
@@ -221,10 +221,10 @@ class Reader(pymeshio.common.BinaryReader):
 \r
     def read_display_slot(self):\r
         display_slot=pymeshio.pmx.DisplaySlot(self.read_text(), self.read_text(), \r
-                self.read_uint(1))\r
-        display_count=self.read_uint(4)\r
+                self.read_int(1))\r
+        display_count=self.read_int(4)\r
         for _ in range(display_count):\r
-            display_type=self.read_uint(1)\r
+            display_type=self.read_int(1)\r
             if display_type==0:\r
                 display_slot.refrences.append(\r
                         (display_type, self.read_bone_index()))\r
@@ -241,9 +241,9 @@ class Reader(pymeshio.common.BinaryReader):
                 name=self.read_text(), \r
                 english_name=self.read_text(),\r
                 bone_index=self.read_bone_index(),\r
-                collision_group=self.read_uint(1),\r
-                no_collision_group=self.read_uint(2),\r
-                shape_type=self.read_uint(1),\r
+                collision_group=self.read_int(1),\r
+                no_collision_group=self.read_int(2),\r
+                shape_type=self.read_int(1),\r
                 shape_size=self.read_vector3(),\r
                 shape_position=self.read_vector3(),\r
                 shape_rotation=self.read_vector3(),\r
@@ -252,14 +252,14 @@ class Reader(pymeshio.common.BinaryReader):
                 angular_damping=self.read_float(),\r
                 restitution=self.read_float(),\r
                 friction=self.read_float(),\r
-                mode=self.read_uint(1)\r
+                mode=self.read_int(1)\r
                 )\r
 \r
     def read_joint(self):\r
         return pymeshio.pmx.Joint(\r
                 name=self.read_text(),\r
                 english_name=self.read_text(),\r
-                joint_type=self.read_uint(1),\r
+                joint_type=self.read_int(1),\r
                 rigidbody_index_a=self.read_rigidbody_index(),\r
                 rigidbody_index_b=self.read_rigidbody_index(),\r
                 position=self.read_vector3(),\r
@@ -292,18 +292,18 @@ def read(ios):
     model=pymeshio.pmx.Model(version)\r
 \r
     # flags\r
-    flag_bytes=reader.read_uint(1)\r
+    flag_bytes=reader.read_int(1)\r
     if flag_bytes!=8:\r
         raise pymeshio.common.ParseException(\r
                 "invalid flag length", reader.flag_bytes)\r
-    text_encoding=reader.read_uint(1)\r
-    extended_uv=reader.read_uint(1)\r
-    vertex_index_size=reader.read_uint(1)\r
-    texture_index_size=reader.read_uint(1)\r
-    material_index_size=reader.read_uint(1)\r
-    bone_index_size=reader.read_uint(1)\r
-    morph_index_size=reader.read_uint(1)\r
-    rigidbody_index_size=reader.read_uint(1)\r
+    text_encoding=reader.read_int(1)\r
+    extended_uv=reader.read_int(1)\r
+    vertex_index_size=reader.read_int(1)\r
+    texture_index_size=reader.read_int(1)\r
+    material_index_size=reader.read_int(1)\r
+    bone_index_size=reader.read_int(1)\r
+    morph_index_size=reader.read_int(1)\r
+    rigidbody_index_size=reader.read_int(1)\r
     \r
     # pmx custom reader\r
     reader=Reader(reader.ios,\r
@@ -325,23 +325,23 @@ def read(ios):
 \r
     # model data\r
     model.vertices=[reader.read_vertex() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.indices=[reader.read_vertex_index() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.textures=[reader.read_text() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.materials=[reader.read_material() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.bones=[reader.read_bone() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.morphs=[reader.read_morgh() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.display_slots=[reader.read_display_slot() \r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.rigidbodies=[reader.read_rigidbody()\r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
     model.joints=[reader.read_joint()\r
-            for _ in range(reader.read_uint(4))]\r
+            for _ in range(reader.read_int(4))]\r
 \r
     return model\r
 \r
index bc0b13c..f823985 100644 (file)
@@ -18,28 +18,28 @@ class Writer(common.BinaryWriter):
         if text_encoding==0:\r
             def write_text(unicode):\r
                utf16=unicode.encode('utf16') \r
-               self.write_uint(len(utf16), 4)\r
+               self.write_int(len(utf16), 4)\r
                self.write_bytes(utf16)\r
             self.write_text=write_text\r
         elif text_encoding==1:\r
             def write_text(unicode):\r
                utf8=unicode.encode('utf8') \r
-               self.write_uint(len(utf8), 4)\r
+               self.write_int(len(utf8), 4)\r
                self.write_bytes(utf8)\r
             self.write_text=write_text\r
         else:\r
             raise WriteError(\r
                     "invalid text_encoding: {0}".format(text_encoding))\r
 \r
-        self.write_vertex_index=lambda index: self.write_uint(index, vertex_index_size)\r
-        self.write_texture_index=lambda index: self.write_uint(index, texture_index_size)\r
-        self.write_material_index=lambda index: self.write_uint(index, material_index_size)\r
-        self.write_bone_index=lambda index: self.write_uint(index, bone_index_size)\r
-        self.write_morph_index=lambda index: self.write_uint(index, morph_index_size)\r
-        self.write_rigidbody_index=lambda index: self.write_uint(index, rigidbody_index_size)\r
+        self.write_vertex_index=lambda index: self.write_int(index, vertex_index_size)\r
+        self.write_texture_index=lambda index: self.write_int(index, texture_index_size)\r
+        self.write_material_index=lambda index: self.write_int(index, material_index_size)\r
+        self.write_bone_index=lambda index: self.write_int(index, bone_index_size)\r
+        self.write_morph_index=lambda index: self.write_int(index, morph_index_size)\r
+        self.write_rigidbody_index=lambda index: self.write_int(index, rigidbody_index_size)\r
 \r
     def write_vertices(self, vertices):\r
-        self.write_uint(len(vertices), 4)\r
+        self.write_int(len(vertices), 4)\r
         for v in vertices:\r
             self.write_vector3(v.position)\r
             self.write_vector3(v.normal)\r
@@ -49,10 +49,10 @@ class Writer(common.BinaryWriter):
 \r
     def write_deform(self, deform):\r
         if isinstance(deform, pmx.Bdef1):\r
-            self.write_uint(0, 1)\r
+            self.write_int(0, 1)\r
             self.write_bone_index(deform.index0)\r
         elif isinstance(deform, pmx.Bdef2):\r
-            self.write_uint(1, 1)\r
+            self.write_int(1, 1)\r
             self.write_bone_index(deform.index0)\r
             self.write_bone_index(deform.index1)\r
             self.write_float(deform.weight0)\r
@@ -65,17 +65,17 @@ class Writer(common.BinaryWriter):
                     "unknown deform type: {0}".format(deform.type))\r
 \r
     def write_indices(self, indices):\r
-        self.write_uint(len(indices), 4)\r
+        self.write_int(len(indices), 4)\r
         for i in indices:\r
             self.write_vertex_index(i)\r
 \r
     def write_textures(self, textures):\r
-        self.write_uint(len(textures), 4)\r
+        self.write_int(len(textures), 4)\r
         for t in textures:\r
             self.write_text(t)\r
 \r
     def write_materials(self, materials):\r
-        self.write_uint(len(materials), 4)\r
+        self.write_int(len(materials), 4)\r
         for m in materials:\r
             self.write_text(m.name)\r
             self.write_text(m.english_name)\r
@@ -84,34 +84,34 @@ class Writer(common.BinaryWriter):
             self.write_rgb(m.specular_color)\r
             self.write_float(m.specular_factor)\r
             self.write_rgb(m.ambient_color)\r
-            self.write_uint(m.flag, 1)\r
+            self.write_int(m.flag, 1)\r
             self.write_rgba(m.edge_color)\r
             self.write_float(m.edge_size)\r
             self.write_texture_index(m.texture_index)\r
             self.write_texture_index(m.sphere_texture_index)\r
-            self.write_uint(m.sphere_mode, 1)\r
-            self.write_uint(m.toon_sharing_flag, 1)\r
+            self.write_int(m.sphere_mode, 1)\r
+            self.write_int(m.toon_sharing_flag, 1)\r
             if m.toon_sharing_flag==0:\r
                 self.write_texture_index(m.toon_texture_index)\r
             elif m.toon_sharing_flag==1:\r
-                self.write_uint(m.toon_texture_index, 1)\r
+                self.write_int(m.toon_texture_index, 1)\r
             else:\r
                 raise common.WriteException(\r
                         "unknown toon_sharing_flag {0}".format(m.toon_sharing_flag))\r
             self.write_text(m.comment)\r
-            self.write_uint(m.vertex_count, 4)\r
+            self.write_int(m.vertex_count, 4)\r
 \r
     def write_bones(self, bones):\r
-        self.write_uint(len(bones), 4)\r
+        self.write_int(len(bones), 4)\r
         for bone in bones:\r
             self.write_text(bone.name)\r
             self.write_text(bone.english_name)\r
             self.write_vector3(bone.position)\r
             self.write_bone_index(bone.parent_index)\r
-            self.write_uint(bone.layer, 4)\r
-            self.write_uint(bone.flag, 2)\r
+            self.write_int(bone.layer, 4)\r
+            self.write_int(bone.flag, 2)\r
             if bone.getConnectionFlag()==0:\r
-                self.write_vector3(bone.tail_positoin)\r
+                self.write_vector3(bone.tail_position)\r
             elif bone.getConnectionFlag()==1:\r
                 self.write_bone_index(bone.tail_index)\r
             else:\r
@@ -131,22 +131,22 @@ class Writer(common.BinaryWriter):
                 self.write_vector3(bone.local_z_vector)\r
 \r
             if bone.getExternalParentDeformFlag()==1:\r
-                self.write_uint(bone.external_key, 4)\r
+                self.write_int(bone.external_key, 4)\r
 \r
             if bone.getIkFlag()==1:\r
                 self.write_ik(bone.ik)\r
 \r
     def write_ik(self, ik):\r
         self.write_bone_index(ik.target_index)\r
-        self.write_uint(ik.loop, 4)\r
+        self.write_int(ik.loop, 4)\r
         self.write_float(ik.limit_radian)\r
-        self.write_uint(len(ik.link), 4)\r
+        self.write_int(len(ik.link), 4)\r
         for l in ik.link:\r
             self.write_ik_link(l)\r
 \r
     def write_ik_link(self, link):\r
         self.write_bone_index(link.bone_index)\r
-        self.write_uint(link.limit_angle, 1)\r
+        self.write_int(link.limit_angle, 1)\r
         if link.limit_angle==0:\r
             pass\r
         elif link.limit_angle==1:\r
@@ -158,18 +158,18 @@ class Writer(common.BinaryWriter):
                         link.limit_angle))\r
  \r
     def write_morph(self, morphs):\r
-        self.write_uint(len(morphs), 4)\r
+        self.write_int(len(morphs), 4)\r
         for m in morphs:\r
             self.write_text(m.name)\r
             self.write_text(m.english_name)\r
-            self.write_uint(m.panel, 1)\r
-            self.write_uint(m.morph_type, 1)\r
+            self.write_int(m.panel, 1)\r
+            self.write_int(m.morph_type, 1)\r
             if m.morph_type==0:\r
                 # todo\r
                 raise pymeshio.common.WriteException(\r
                         "not implemented GroupMorph")\r
             elif m.morph_type==1:\r
-                self.write_uint(len(m.offsets), 4)\r
+                self.write_int(len(m.offsets), 4)\r
                 for o in m.offsets:\r
                     self.write_vertex_index(o.vertex_index)\r
                     self.write_vector3(o.position_offset)\r
@@ -206,14 +206,14 @@ class Writer(common.BinaryWriter):
                         "unknown morph type: {0}".format(m.morph_type))\r
 \r
     def write_display_slots(self, display_slots):\r
-        self.write_uint(len(display_slots), 4)\r
+        self.write_int(len(display_slots), 4)\r
         for s in display_slots:\r
             self.write_text(s.name)\r
             self.write_text(s.english_name)\r
-            self.write_uint(s.special_flag, 1)\r
-            self.write_uint(len(s.refrences), 4)\r
+            self.write_int(s.special_flag, 1)\r
+            self.write_int(len(s.refrences), 4)\r
             for r in s.refrences:\r
-                self.write_uint(r[0], 1)\r
+                self.write_int(r[0], 1)\r
                 if r[0]==0:\r
                     self.write_bone_index(r[1])\r
                 elif r[0]==1:\r
@@ -223,14 +223,14 @@ class Writer(common.BinaryWriter):
                             "unknown display_type: {0}".format(r[0]))\r
 \r
     def write_rigidbodies(self, rigidbodies):\r
-        self.write_uint(len(rigidbodies), 4)\r
+        self.write_int(len(rigidbodies), 4)\r
         for rb in rigidbodies:\r
             self.write_text(rb.name)\r
             self.write_text(rb.english_name)\r
             self.write_bone_index(rb.bone_index)\r
-            self.write_uint(rb.collision_group, 1)\r
-            self.write_uint(rb.no_collision_group, 2)\r
-            self.write_uint(rb.shape_type, 1)\r
+            self.write_int(rb.collision_group, 1)\r
+            self.write_int(rb.no_collision_group, 2)\r
+            self.write_int(rb.shape_type, 1)\r
             self.write_vector3(rb.shape_size)\r
             self.write_vector3(rb.shape_position)\r
             self.write_vector3(rb.shape_rotation)\r
@@ -239,14 +239,14 @@ class Writer(common.BinaryWriter):
             self.write_float(rb.param.angular_damping)\r
             self.write_float(rb.param.restitution)\r
             self.write_float(rb.param.friction)\r
-            self.write_uint(rb.mode, 1)\r
+            self.write_int(rb.mode, 1)\r
 \r
     def write_joints(self, joints):\r
-        self.write_uint(len(joints), 4)\r
+        self.write_int(len(joints), 4)\r
         for j in joints:\r
             self.write_text(j.name)\r
             self.write_text(j.english_name)\r
-            self.write_uint(j.joint_type, 1)\r
+            self.write_int(j.joint_type, 1)\r
             self.write_rigidbody_index(j.rigidbody_index_a)\r
             self.write_rigidbody_index(j.rigidbody_index_b)\r
             self.write_vector3(j.position)\r
@@ -270,11 +270,11 @@ def write(ios, model, text_encoding=1):
     writer.write_float(model.version)\r
 \r
     # flags\r
-    writer.write_uint(8, 1)\r
+    writer.write_int(8, 1)\r
     # textencoding\r
-    writer.write_uint(text_encoding, 1)\r
+    writer.write_int(text_encoding, 1)\r
     # extend uv\r
-    writer.write_uint(0, 1)\r
+    writer.write_int(0, 1)\r
     def get_array_size(size):\r
         if size<128:\r
             return 1\r
@@ -287,22 +287,22 @@ def write(ios, model, text_encoding=1):
                     "invalid array_size: {0}".format(size))\r
     # vertex_index_size\r
     vertex_index_size=get_array_size(len(model.vertices))\r
-    writer.write_uint(vertex_index_size, 1)\r
+    writer.write_int(vertex_index_size, 1)\r
     # texture_index_size\r
     texture_index_size=get_array_size(len(model.textures))\r
-    writer.write_uint(texture_index_size, 1)\r
+    writer.write_int(texture_index_size, 1)\r
     # material_index_size\r
     material_index_size=get_array_size(len(model.materials))\r
-    writer.write_uint(material_index_size, 1)\r
+    writer.write_int(material_index_size, 1)\r
     # bone_index_size\r
     bone_index_size=get_array_size(len(model.bones))\r
-    writer.write_uint(bone_index_size, 1)\r
+    writer.write_int(bone_index_size, 1)\r
     # morph_index_size\r
     morph_index_size=get_array_size(len(model.morphs))\r
-    writer.write_uint(morph_index_size, 1)\r
+    writer.write_int(morph_index_size, 1)\r
     # rigidbody_index_size\r
     rigidbody_index_size=get_array_size(len(model.rigidbodies))\r
-    writer.write_uint(rigidbody_index_size, 1)\r
+    writer.write_int(rigidbody_index_size, 1)\r
 \r
     writer=Writer(writer.ios, \r
             text_encoding, 0,\r
index 914f6fe..fa64485 100644 (file)
@@ -2,12 +2,13 @@
 import sys
 import io
 import unittest
+import pymeshio.common
 import pymeshio.pmd
 import pymeshio.pmd.reader
 import pymeshio.pmd.writer
 
 
-PMD_FILE=pymeshio.unicode('resources/初音ミクVer2.pmd')
+PMD_FILE=pymeshio.common.unicode('resources/初音ミクVer2.pmd')
 
 
 class TestPmd(unittest.TestCase):
@@ -18,9 +19,9 @@ class TestPmd(unittest.TestCase):
     def test_read(self):
         model=pymeshio.pmd.reader.read_from_file(PMD_FILE)
         self.assertEqual(pymeshio.pmd.Model,  model.__class__)
-        self.assertEqual(pymeshio.unicode('初音ミク').encode('cp932'),  model.name)
-        self.assertEqual(pymeshio.unicode('Miku Hatsune').encode('cp932'),  model.english_name)
-        self.assertEqual(pymeshio.unicode(
+        self.assertEqual(pymeshio.common.unicode('初音ミク').encode('cp932'),  model.name)
+        self.assertEqual(pymeshio.common.unicode('Miku Hatsune').encode('cp932'),  model.english_name)
+        self.assertEqual(pymeshio.common.unicode(
             "PolyMo用モデルデータ:初音ミク ver.2.3\n"+
             "(物理演算対応モデル)\n"+
             "\n"+
@@ -28,7 +29,7 @@ class TestPmd(unittest.TestCase):
             "データ変換   :あにまさ氏\n"+
             "Copyright :CRYPTON FUTURE MEDIA, INC").encode('cp932'),
             model.comment)
-        self.assertEqual(pymeshio.unicode(
+        self.assertEqual(pymeshio.common.unicode(
             "MMD Model: Miku Hatsune ver.2.3\n"+
             "(Physical Model)\n"+
             "\n"+
@@ -57,4 +58,3 @@ class TestPmd(unittest.TestCase):
         model.diff(model2)
         self.assertEqual(model, model2)
 
-
index e9185ee..858f55e 100644 (file)
@@ -1,12 +1,15 @@
 # coding: utf-8\r
 import unittest\r
 import io\r
-import pymeshio.pmd\r
+import pymeshio.common\r
+import pymeshio.pmd.reader\r
 import pymeshio.pmx.reader\r
 import pymeshio.pmx.writer\r
+import pymeshio.converter\r
 \r
 \r
-PMX_FILE=pymeshio.unicode('resources/初音ミクVer2.pmx')\r
+PMD_FILE=pymeshio.common.unicode('resources/初音ミクVer2.pmd')\r
+PMX_FILE=pymeshio.common.unicode('resources/初音ミクVer2.pmx')\r
 \r
 \r
 class TestPmx(unittest.TestCase):\r
@@ -17,9 +20,9 @@ class TestPmx(unittest.TestCase):
     def test_read(self):\r
         model=pymeshio.pmx.reader.read_from_file(PMX_FILE)\r
         self.assertEqual(pymeshio.pmx.Model,  model.__class__)\r
-        self.assertEqual(pymeshio.unicode('初音ミク'),  model.name)\r
-        self.assertEqual(pymeshio.unicode('Miku Hatsune'),  model.english_name)\r
-        self.assertEqual(pymeshio.unicode(\r
+        self.assertEqual(pymeshio.common.unicode('初音ミク'),  model.name)\r
+        self.assertEqual(pymeshio.common.unicode('Miku Hatsune'),  model.english_name)\r
+        self.assertEqual(pymeshio.common.unicode(\r
                 "PolyMo用モデルデータ:初音ミク ver.2.3\r\n"+\r
                 "(物理演算対応モデル)\r\n"+\r
                 "\r\n"+\r
@@ -27,7 +30,7 @@ class TestPmx(unittest.TestCase):
                 "データ変換       :あにまさ氏\r\n"+\r
                 "Copyright     :CRYPTON FUTURE MEDIA, INC"),\r
                 model.comment)\r
-        self.assertEqual(pymeshio.unicode(\r
+        self.assertEqual(pymeshio.common.unicode(\r
                 "MMD Model: Miku Hatsune ver.2.3\r\n"+\r
                 "(Physical Model)\r\n"+\r
                 "\r\n"+\r
@@ -57,3 +60,14 @@ class TestPmx(unittest.TestCase):
         model2=pymeshio.pmx.reader.read(io.BytesIO(out.getvalue()))\r
         self.assertEqual(model, model2)\r
 \r
+    def test_convert(self):\r
+        # convert\r
+        pmd=pymeshio.pmd.reader.read_from_file(PMD_FILE)\r
+        converted=pymeshio.converter.pmd_to_pmx(pmd)\r
+        # validate\r
+        pmx=pymeshio.pmx.reader.read_from_file(PMX_FILE)\r
+        # check diffference\r
+        pmx.diff(converted)\r
+        #self.assertEqual(pmx, converted)\r
+        pymeshio.pmx.writer.write(io.open("tmp.pmx", "wb"), converted)\r
+\r