OSDN Git Service

refactoring
authorousttrue <ousttrue@gmail.com>
Fri, 30 Sep 2011 14:06:07 +0000 (23:06 +0900)
committerousttrue <ousttrue@gmail.com>
Fri, 30 Sep 2011 14:06:07 +0000 (23:06 +0900)
pymeshio/common.py
pymeshio/pmx/__init__.py
pymeshio/pmx/loader.py

index 8ec017d..e67580d 100644 (file)
@@ -3,20 +3,12 @@
 common utilities.\r
 """\r
 import math\r
-\r
-def radian_to_degree(x):\r
-    """darian to deglee"""\r
-\r
-    return x/math.pi * 180.0\r
+import struct\r
 \r
 \r
 """\r
 common structures.\r
 """\r
-class ParseException(Exception):\r
-    pass\r
-\r
-\r
 class Vector2(object):\r
     """\r
     2D coordinate for uv value\r
@@ -219,3 +211,72 @@ class RGBA(object):
         else:\r
             assert(False)\r
 \r
+\r
+"""\r
+utilities\r
+"""\r
+def radian_to_degree(x):\r
+    """darian to deglee"""\r
+\r
+    return x/math.pi * 180.0\r
+\r
+\r
+class ParseException(Exception):\r
+    pass\r
+\r
+\r
+def readall(path: str) -> bytes:\r
+    with open(path, "rb") as f:\r
+        return f.read()\r
+\r
+\r
+class BinaryLoader(object):\r
+    def __init__(self, io):\r
+        self.io=io\r
+\r
+    def unpack(self, fmt: str, size: int) -> "read value as format":\r
+        result=struct.unpack(fmt, self.io.read(size))\r
+        return result[0]\r
+\r
+    def read_uint(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_float(self):\r
+        return self.unpack("f", 4)\r
+\r
+    def read_vector2(self):\r
+        return Vector2(\r
+                self.read_float(), \r
+                self.read_float()\r
+                )\r
+\r
+    def read_vector3(self):\r
+        return Vector3(\r
+                self.read_float(), \r
+                self.read_float(), \r
+                self.read_float()\r
+                )\r
+\r
+    def read_rgba(self):\r
+        return RGBA(\r
+                self.read_float(), \r
+                self.read_float(), \r
+                self.read_float(),\r
+                self.read_float()\r
+                )\r
+\r
+    def read_rgb(self):\r
+        return RGB(\r
+                self.read_float(), \r
+                self.read_float(), \r
+                self.read_float()\r
+                )\r
+\r
+\r
index 6d8a831..cfdf03b 100644 (file)
@@ -244,8 +244,8 @@ class Model(object):
             'materials',\r
             'bones',\r
             ]\r
-    def __init__(self):\r
-        self.version=0.0\r
+    def __init__(self, version):\r
+        self.version=version\r
         self.name=''\r
         self.english_name=''\r
         self.comment=''\r
index fbcc0d8..45b34a7 100644 (file)
@@ -1,88 +1,52 @@
-from pymeshio.pmx import *\r
-#self.__pos=self.__io.tell()\r
+# coding: utf-8\r
+import io\r
+import pymeshio.common\r
+import pymeshio.pmx\r
 \r
 \r
-\r
-class Loader(object):\r
+class Loader(pymeshio.common.BinaryLoader):\r
     """pmx loader\r
-\r
-    Attributes:\r
-        text_encoding: \r
-        extended_uv:\r
-        vertex_index_size:\r
-        texture_index_size:\r
-        material_index_size:\r
-        bone_index_size:\r
-        morph_index_size:\r
-        rigidbody_index_size:\r
     """\r
-    def __init__(self, loader):\r
-        self.__io=loader\r
+    def __init__(self, io,\r
+            text_encoding,\r
+            extended_uv,\r
+            vertex_index_size,\r
+            texture_index_size,\r
+            material_index_size,\r
+            bone_index_size,\r
+            morph_index_size,\r
+            rigidbody_index_size\r
+            ):\r
+        super(Loader, self).__init__(io)\r
+        self.read_text=self.get_read_text(text_encoding)\r
+        if extended_uv>0:\r
+            raise ParseException("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
 \r
     def __str__(self) -> str:\r
-        return '<PmxIO>'\r
-\r
-    def unpack(self, fmt: str, size: int) -> "read value as format":\r
-        result=struct.unpack(fmt, self.__io.read(size))\r
-        return result[0]\r
+        return '<pymeshio.pmx.Loader>'\r
 \r
-    def get_read_text(self) -> "text process function":\r
-        if self.text_encoding==0:\r
+    def get_read_text(self, text_encoding) -> "text process function":\r
+        if text_encoding==0:\r
             def read_text():\r
                 size=self.read_uint(4)\r
                 return self.unpack("{0}s".format(size), size).decode("UTF16")\r
             return read_text\r
-        elif self.text_encoding==1:\r
+        elif text_encoding==1:\r
             def read_text():\r
                 size=self.read_uint(4)\r
                 return self.unpack("{0}s".format(size), size).decode("UTF8")\r
             return read_text\r
         else:\r
-            print("unknown text encoding", self.text_encoding)\r
-\r
-    def read_uint(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_float(self):\r
-        return self.unpack("f", 4)\r
-\r
-    def read_vector2(self):\r
-        return common.Vector2(\r
-                self.read_float(), \r
-                self.read_float()\r
-                )\r
-\r
-    def read_vector3(self):\r
-        return common.Vector3(\r
-                self.read_float(), \r
-                self.read_float(), \r
-                self.read_float()\r
-                )\r
-\r
-    def read_rgba(self):\r
-        return common.RGBA(\r
-                self.read_float(), \r
-                self.read_float(), \r
-                self.read_float(),\r
-                self.read_float()\r
-                )\r
-\r
-    def read_rgb(self):\r
-        return common.RGB(\r
-                self.read_float(), \r
-                self.read_float(), \r
-                self.read_float()\r
-                )\r
+            print("unknown text encoding", text_encoding)\r
 \r
     def read_vertex(self):\r
-        return Vertex(\r
+        return pymeshio.pmx.Vertex(\r
                 self.read_vector3(), # pos\r
                 self.read_vector3(), # normal\r
                 self.read_vector2(), # uv\r
@@ -93,20 +57,20 @@ class Loader(object):
     def read_deform(self):\r
         deform_type=self.read_uint(1)\r
         if deform_type==0:\r
-            return Bdef1(self.read_uint(self.bone_index_size))\r
+            return pymeshio.pmx.Bdef1(self.read_bone_index())\r
         if deform_type==1:\r
-            return Bdef2(\r
-                    self.read_uint(self.bone_index_size),\r
-                    self.read_uint(self.bone_index_size),\r
+            return pymeshio.pmx.Bdef2(\r
+                    self.read_bone_index(),\r
+                    self.read_bone_index(),\r
                     self.read_float()\r
                     )\r
         """\r
         if deform_type==2:\r
-            return Bdef4(\r
-                    self.read_uint(self.bone_index_size),\r
-                    self.read_uint(self.bone_index_size),\r
-                    self.read_uint(self.bone_index_size),\r
-                    self.read_uint(self.bone_index_size),\r
+            return pymeshio.pmx.Bdef4(\r
+                    self.read_bone_index(),\r
+                    self.read_bone_index(),\r
+                    self.read_bone_index(),\r
+                    self.read_bone_index(),\r
                     self.read_float(), self.read_float(),\r
                     self.read_float(), self.read_float()\r
                     )\r
@@ -114,7 +78,7 @@ class Loader(object):
         raise ParseException("unknown deform type: {0}".format(deform_type))\r
 \r
     def read_material(self):\r
-        material=Material(\r
+        material=pymeshio.pmx.Material(\r
                 name=self.read_text(),\r
                 english_name=self.read_text(),\r
                 diffuse_color=self.read_rgb(),\r
@@ -125,13 +89,13 @@ class Loader(object):
                 flag=self.read_uint(1),\r
                 edge_color=self.read_rgba(),\r
                 edge_size=self.read_float(),\r
-                texture_index=self.read_uint(self.texture_index_size),\r
-                sphia_texture_index=self.read_uint(self.texture_index_size),\r
+                texture_index=self.read_texture_index(),\r
+                sphia_texture_index=self.read_texture_index(),\r
                 sphia_mode=self.read_uint(1),\r
                 toon_sharing_flag=self.read_uint(1),\r
                 )\r
         if material.toon_sharing_flag==0:\r
-            material.toon_texture_index=self.read_uint(self.texture_index_size)\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
         else:\r
@@ -141,24 +105,24 @@ class Loader(object):
         return material\r
 \r
     def read_bone(self):\r
-        bone=Bone(\r
+        bone=pymeshio.pmx.Bone(\r
                 name=self.read_text(),\r
                 english_name=self.read_text(),\r
                 position=self.read_vector3(),\r
-                parent_index=self.read_uint(self.bone_index_size),\r
+                parent_index=self.read_bone_index(),\r
                 layer=self.read_uint(4),\r
                 flag=self.read_uint(2)                \r
                 )\r
         if bone.getConnectionFlag()==0:\r
             bone.tail_positoin=self.read_vector3()\r
         elif bone.getConnectionFlag()==1:\r
-            bone.tail_index=self.read_uint(self.bone_index_size)\r
+            bone.tail_index=self.read_bone_index()\r
         else:\r
             raise ParseException("unknown bone conenction flag: {0}".format(\r
                 bone.getConnectionFlag()))\r
 \r
         if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1:\r
-            bone.effect_index=self.read_uint(self.bone_index_size)\r
+            bone.effect_index=self.read_bone_index()\r
             bone.effect_factor=self.read_float()\r
 \r
         if bone.getFixedAxisFlag()==1:\r
@@ -177,16 +141,16 @@ class Loader(object):
         return bone\r
 \r
     def read_ik(self):\r
-        ik=Ik(\r
-                target_index=self.read_uint(self.bone_index_size),\r
+        ik=pymeshio.pmx.Ik(\r
+                target_index=self.read_bone_index(),\r
                 loop=self.read_uint(4),\r
                 limit_radian=self.read_float())\r
         link_size=self.read_uint(4)\r
         ik.link=[self.read_ik_link() for i in range(link_size)]\r
 \r
     def read_ik_link(self):\r
-        link=IkLink(\r
-                self.read_uint(self.bone_index_size),\r
+        link=pymeshio.pmx.IkLink(\r
+                self.read_bone_index(),\r
                 self.read_uint(1))\r
         if link.limit_angle==0:\r
             pass\r
@@ -199,85 +163,72 @@ class Loader(object):
         return link\r
 \r
 \r
-def load(path: str) -> Model:\r
-    with open(path, "rb") as f:\r
-        model=Model()\r
-        loader=Loader(f)\r
-\r
-        ####################\r
-        # header\r
-        ####################\r
-        signature=loader.unpack("4s", 4)\r
-        if signature!=b"PMX ":\r
-            raise ParseException("invalid signature", loader.signature)\r
-\r
-        version=loader.read_float()\r
-        if version!=2.0:\r
-            print("unknown version", version)\r
-\r
-        model.version=version\r
-        # flags\r
-        flag_bytes=loader.read_uint(1)\r
-        if flag_bytes!=8:\r
-            raise ParseException("invalid flag length", loader.flag_bytes)\r
-\r
-        # text encoding\r
-        loader.text_encoding=loader.read_uint(1)\r
-        loader.read_text=loader.get_read_text()\r
-        # uv\r
-        loader.extended_uv=loader.read_uint(1)\r
-        if loader.extended_uv>0:\r
-            raise ParseException("extended uv is not supported", loader.extended_uv)\r
-\r
-        # index size\r
-        loader.vertex_index_size=loader.read_uint(1)\r
-        loader.texture_index_size=loader.read_uint(1)\r
-        loader.material_index_size=loader.read_uint(1)\r
-        loader.bone_index_size=loader.read_uint(1)\r
-        loader.morph_index_size=loader.read_uint(1)\r
-        loader.rigidbody_index_size=loader.read_uint(1)\r
-\r
-        ####################\r
-        # model info\r
-        ####################\r
-        model.name = loader.read_text()\r
-        model.english_name = loader.read_text()\r
-        model.comment = loader.read_text()\r
-        model.english_comment = loader.read_text()\r
-\r
-        ####################\r
-        # vertices\r
-        ####################\r
-        vertex_count=loader.read_uint(4)\r
-        model.vertices=[loader.read_vertex() \r
-                for i in range(vertex_count)]\r
-\r
-        ####################\r
-        # indices\r
-        ####################\r
-        index_count=loader.read_uint(4)\r
-        model.indices=[loader.read_uint(loader.vertex_index_size) \r
-                for i in range(index_count)]\r
-\r
-        ####################\r
-        # textures\r
-        ####################\r
-        texture_count=loader.read_uint(4)\r
-        model.textures=[loader.read_text() \r
-                for i in range(texture_count)]\r
-\r
-        ####################\r
-        # materials\r
-        ####################\r
-        material_count=loader.read_uint(4)\r
-        model.materials=[loader.read_material() \r
-                for i in range(material_count)]\r
-\r
-        ####################\r
-        # bones\r
-        ####################\r
-        bone_count=loader.read_uint(4)\r
-        model.bones=[loader.read_bone() \r
-                for i in range(bone_count)]\r
-        return model\r
+def load(path: str) -> pymeshio.pmx.Model:\r
+    # general binary loader\r
+    loader=pymeshio.common.BinaryLoader(\r
+            io.BytesIO(\r
+                pymeshio.common.readall(path)))\r
+\r
+    # header\r
+    signature=loader.unpack("4s", 4)\r
+    if signature!=b"PMX ":\r
+        raise ParseException("invalid signature", loader.signature)\r
+\r
+    version=loader.read_float()\r
+    if version!=2.0:\r
+        print("unknown version", version)\r
+    model=pymeshio.pmx.Model(version)\r
+\r
+    # flags\r
+    flag_bytes=loader.read_uint(1)\r
+    if flag_bytes!=8:\r
+        raise ParseException("invalid flag length", loader.flag_bytes)\r
+    text_encoding=loader.read_uint(1)\r
+    extended_uv=loader.read_uint(1)\r
+    vertex_index_size=loader.read_uint(1)\r
+    texture_index_size=loader.read_uint(1)\r
+    material_index_size=loader.read_uint(1)\r
+    bone_index_size=loader.read_uint(1)\r
+    morph_index_size=loader.read_uint(1)\r
+    rigidbody_index_size=loader.read_uint(1)\r
+    \r
+    # pmx custom loader\r
+    loader=Loader(loader.io,\r
+            text_encoding,\r
+            extended_uv,\r
+            vertex_index_size,\r
+            texture_index_size,\r
+            material_index_size,\r
+            bone_index_size,\r
+            morph_index_size,\r
+            rigidbody_index_size\r
+            )\r
+\r
+    # model info\r
+    model.name = loader.read_text()\r
+    model.english_name = loader.read_text()\r
+    model.comment = loader.read_text()\r
+    model.english_comment = loader.read_text()\r
+\r
+    # vertices\r
+    vertex_count=loader.read_uint(4)\r
+    model.vertices=[loader.read_vertex() for i in range(vertex_count)]\r
+\r
+    # indices\r
+    index_count=loader.read_uint(4)\r
+    model.indices=[loader.read_vertex_index() for i in range(index_count)]\r
+\r
+    # textures\r
+    texture_count=loader.read_uint(4)\r
+    model.textures=[loader.read_text() for i in range(texture_count)]\r
+\r
+    # materials\r
+    material_count=loader.read_uint(4)\r
+    model.materials=[loader.read_material() for i in range(material_count)]\r
+\r
+    # bones\r
+    bone_count=loader.read_uint(4)\r
+    model.bones=[loader.read_bone() for i in range(bone_count)]\r
+\r
+    return model\r
 \r