OSDN Git Service

add pmx_test
[meshio/pymeshio.git] / pymeshio / pmx.py
index e4b9ba5..ff04e6f 100644 (file)
@@ -10,3 +10,104 @@ __author__="ousttrue"
 __license__="zlib"\r
 __versioon__="0.0.1"\r
 \r
+\r
+import io\r
+import os\r
+import struct\r
+\r
+\r
+class Model(object):\r
+    """pmx data holder\r
+\r
+    version: pmx version\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
+            ]\r
+    def __init__(self):\r
+        self.version=0.0\r
+\r
+\r
+class IO(object):\r
+    """pmx loader\r
+\r
+    Attributes:\r
+        name: model name\r
+    """\r
+    def __init__(self):\r
+        self.__io=None\r
+        self.__pos=-1\r
+        self.__end=-1\r
+        self.__model=Model()\r
+\r
+    def read(self, path: 'filepath') -> Model:\r
+        size=os.path.getsize(path)\r
+        with open(path, "rb") as f:\r
+            if self.load(path, f, size):\r
+                return self.__model\r
+\r
+    def load(self, path: 'filepath', io: io.IOBase, size: int) -> bool: \r
+        self.__io=io\r
+        self.__end=size\r
+        self.__check_position()\r
+\r
+        if not self.__loadHeader():\r
+            return False\r
+        self.__check_position()\r
+        # model info\r
+        self.__model.name = self.__read_text()\r
+        self.__model.english_name = self.__read_text()\r
+        self.__model.comment = self.__read_text()\r
+        self.__model.english_comment = self.__read_text()\r
+        return True\r
+\r
+    def __str__(self) -> str:\r
+        return '<PmxIO>'\r
+\r
+    def __check_position(self):\r
+        self.__pos=self.__io.tell()\r
+\r
+    def __unpack(self, fmt: str, size: int) -> "read value as format":\r
+        return struct.unpack(fmt, self.__io.read(size))[0]\r
+\r
+    def __loadHeader(self) -> bool:\r
+        signature=self.__unpack("4s", 4)\r
+        if signature!=b"PMX ":\r
+            print("invalid signature", signature)\r
+            return False\r
+        version=self.__unpack("f", 4)\r
+        if version!=2.0:\r
+            print("unknown version", version)\r
+        self.__model.version=version\r
+        # flags\r
+        flag_bytes=self.__unpack("B", 1)\r
+        if flag_bytes!=8:\r
+            print("invalid flag length", flag_bytes)\r
+            return False\r
+        # text encoding\r
+        text_encoding=self.__unpack("B", 1)\r
+        if text_encoding==0:\r
+            def read_text():\r
+                size=self.__unpack("I", 4)\r
+                return self.__unpack("{0}s".format(size), size).decode("UTF16")\r
+        elif text_encoding==1:\r
+            def read_text():\r
+                size=self.__unpack("I", 4)\r
+                return self.__unpack("{0}s".format(size), size).decode("UTF8")\r
+        else:\r
+            print("unknown text encoding", text_encoding)\r
+            return False\r
+        self.__read_text=read_text\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        self.__unpack("B", 1)\r
+        return True\r
+\r