OSDN Git Service

implement morph
authorousttrue <ousttrue@gmail.com>
Fri, 30 Sep 2011 14:39:57 +0000 (23:39 +0900)
committerousttrue <ousttrue@gmail.com>
Fri, 30 Sep 2011 14:39:57 +0000 (23:39 +0900)
pymeshio/pmx/__init__.py
pymeshio/pmx/loader.py
test/pmx_test.py

index cfdf03b..a5391d7 100644 (file)
@@ -218,6 +218,47 @@ class Vertex(object):
         self.edge_factor=edge_factor\r
 \r
 \r
+class Morph(object):\r
+    """pmx morph\r
+\r
+    Attributes:\r
+        name: \r
+        english_name: \r
+        panel:\r
+        morph_type:\r
+        offsets:\r
+    """\r
+    __slots__=[\r
+            'name',\r
+            'english_name',\r
+            'panel',\r
+            'morph_type',\r
+            'offsets',\r
+            ]\r
+    def __init__(self, name, english_name, panel, morph_type):\r
+        self.name=name\r
+        self.english_name=english_name\r
+        self.panel=panel\r
+        self.morph_type=morph_type\r
+        self.offsets=[]\r
+\r
+\r
+class VerexMorphOffset(object):\r
+    """pmx vertex morph offset\r
+\r
+    Attributes:\r
+        vertex_index:\r
+        position_offset: Vector3\r
+    """\r
+    __slots__=[\r
+            'vertex_index',\r
+            'position_offset',\r
+            ]\r
+    def __init__(self, vertex_index, position_offset):\r
+        self.vertex_index=vertex_index\r
+        self.position_offset=position_offset\r
+\r
+\r
 class Model(object):\r
     """pmx data representation\r
 \r
@@ -231,6 +272,8 @@ class Model(object):
         textures:\r
         materials:\r
         bones:\r
+        morph:\r
+        display_slots:\r
     """\r
     __slots__=[\r
             'version', # pmx version\r
@@ -243,6 +286,8 @@ class Model(object):
             'textures',\r
             'materials',\r
             'bones',\r
+            'morphs',\r
+            'display_slots',\r
             ]\r
     def __init__(self, version):\r
         self.version=version\r
index 45b34a7..18e19c0 100644 (file)
@@ -20,7 +20,7 @@ class Loader(pymeshio.common.BinaryLoader):
         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
+            raise pymeshio.common.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
@@ -58,24 +58,17 @@ class Loader(pymeshio.common.BinaryLoader):
         deform_type=self.read_uint(1)\r
         if deform_type==0:\r
             return pymeshio.pmx.Bdef1(self.read_bone_index())\r
-        if deform_type==1:\r
+        elif deform_type==1:\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 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
-        """\r
-        raise ParseException("unknown deform type: {0}".format(deform_type))\r
+        elif deform_type==2:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented Bdef4")\r
+        else:\r
+            raise pymeshio.common.ParseException("unknown deform type: {0}".format(deform_type))\r
 \r
     def read_material(self):\r
         material=pymeshio.pmx.Material(\r
@@ -99,7 +92,7 @@ class Loader(pymeshio.common.BinaryLoader):
         elif material.toon_sharing_flag==1:\r
             material.toon_texture_index=self.read_uint(1)\r
         else:\r
-            raise ParseException("unknown toon_sharing_flag {0}".format(material.toon_sharing_flag))\r
+            raise pymeshio.common.ParseException("unknown toon_sharing_flag {0}".format(material.toon_sharing_flag))\r
         material.comment=self.read_text()\r
         material.index_count=self.read_uint(4)\r
         return material\r
@@ -118,7 +111,7 @@ class Loader(pymeshio.common.BinaryLoader):
         elif bone.getConnectionFlag()==1:\r
             bone.tail_index=self.read_bone_index()\r
         else:\r
-            raise ParseException("unknown bone conenction flag: {0}".format(\r
+            raise pymeshio.common.ParseException("unknown bone conenction flag: {0}".format(\r
                 bone.getConnectionFlag()))\r
 \r
         if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1:\r
@@ -146,7 +139,7 @@ class Loader(pymeshio.common.BinaryLoader):
                 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
+        ik.link=[self.read_ik_link() for _ in range(link_size)]\r
 \r
     def read_ik_link(self):\r
         link=pymeshio.pmx.IkLink(\r
@@ -158,10 +151,53 @@ class Loader(pymeshio.common.BinaryLoader):
             link.limit_min=self.read_vector3()\r
             link.limit_max=self.read_vector3()\r
         else:\r
-            raise ParseException("invalid ik link limit_angle: {0}".format(\r
+            raise pymeshio.common.ParseException("invalid ik link limit_angle: {0}".format(\r
                 link.limit_angle))\r
         return link\r
 \r
+    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
+        if morph_type==0:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented GroupMorph")\r
+        elif morph_type==1:\r
+            morph=pymeshio.pmx.Morph(name, english_name, panel, morph_type)\r
+            morph.offsets=[self.read_vertex_morph_offset() for _ in range(offset_size)]\r
+            return morph\r
+        elif morph_type==2:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented BoneMorph")\r
+        elif morph_type==3:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented UvMorph")\r
+        elif morph_type==4:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented extended UvMorph1")\r
+        elif morph_type==5:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented extended UvMorph2")\r
+        elif morph_type==6:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented extended UvMorph3")\r
+        elif morph_type==7:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented extended UvMorph4")\r
+        elif morph_type==8:\r
+            # todo\r
+            raise pymeshio.common.ParseException("not implemented extended MaterialMorph")\r
+        else:\r
+            raise pymeshio.common.ParseException("unknown morph type: {0}".format(morph_type))\r
+\r
+    def read_vertex_morph_offset(self):\r
+        return pymeshio.pmx.VerexMorphOffset(self.read_vertex_index(), self.read_vector3())\r
+\r
+    def read_display_slot(self):\r
+        pass\r
+\r
 \r
 def load(path: str) -> pymeshio.pmx.Model:\r
     # general binary loader\r
@@ -172,7 +208,7 @@ def load(path: str) -> pymeshio.pmx.Model:
     # header\r
     signature=loader.unpack("4s", 4)\r
     if signature!=b"PMX ":\r
-        raise ParseException("invalid signature", loader.signature)\r
+        raise pymeshio.common.ParseException("invalid signature", loader.signature)\r
 \r
     version=loader.read_float()\r
     if version!=2.0:\r
@@ -182,7 +218,7 @@ def load(path: str) -> pymeshio.pmx.Model:
     # flags\r
     flag_bytes=loader.read_uint(1)\r
     if flag_bytes!=8:\r
-        raise ParseException("invalid flag length", loader.flag_bytes)\r
+        raise pymeshio.common.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
@@ -210,25 +246,27 @@ def load(path: str) -> pymeshio.pmx.Model:
     model.comment = loader.read_text()\r
     model.english_comment = loader.read_text()\r
 \r
-    # vertices\r
+    # model data\r
     vertex_count=loader.read_uint(4)\r
-    model.vertices=[loader.read_vertex() for i in range(vertex_count)]\r
+    model.vertices=[loader.read_vertex() for _ 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
+    model.indices=[loader.read_vertex_index() for _ 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
+    model.textures=[loader.read_text() for _ 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
+    model.materials=[loader.read_material() for _ 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
+    model.bones=[loader.read_bone() for _ in range(bone_count)]\r
+\r
+    morph_count=loader.read_uint(4)\r
+    model.morphs=[loader.read_morgh() for _ in range(morph_count)]\r
+\r
+    display_slot_count=loader.read_uint(4)\r
+    model.display_slots=[loader.read_display_slot() for _ in range(display_slot_count)]\r
 \r
     return model\r
 \r
index 1c3beea..8fd04cf 100644 (file)
@@ -31,3 +31,5 @@ def test_read():
     # texture\r
     assert len(model.materials)==17\r
     assert len(model.bones)==140\r
+    assert len(model.morphs)==30\r
+    assert len(model.display_slots)==9\r