"""\r
__author__="ousttrue"\r
__license__="zlib"\r
-__versioon__="0.0.1"\r
+__versioon__="1.0.0"\r
\r
\r
import io\r
import os\r
import struct\r
+from . import common\r
+\r
+\r
+class ParseException(Exception):\r
+ pass\r
+\r
+\r
+class Deform(object):\r
+ pass\r
+\r
+\r
+class Bdef1(object):\r
+ """bone deform. use a weight\r
+\r
+ Attributes: see __init__\r
+ """\r
+ __slots__=[ 'bone_index']\r
+ def __init__(self, bone_index: int):\r
+ self.bone_index=bone_index\r
+\r
+\r
+class Bdef2(object):\r
+ """bone deform. use two weights\r
+\r
+ Attributes: see __init__\r
+ """\r
+ __slots__=[ 'index0', 'index1', 'weight0']\r
+ def __init__(self, \r
+ index0: int,\r
+ index1: int,\r
+ weight0: float):\r
+ self.index0=index0\r
+ self.index1=index1\r
+ self.weight0=weight0\r
+\r
+\r
+class Vertex(object):\r
+ """pmx vertex\r
+\r
+ Attributes: see __init__\r
+ """\r
+ __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]\r
+ def __init__(self, \r
+ position: common.Vector3, \r
+ normal: common.Vector3, \r
+ uv: common.Vector2, \r
+ deform: Deform, \r
+ edge_factor: float):\r
+ self.position=position \r
+ self.normal=normal\r
+ self.uv=uv\r
+ self.deform=deform\r
+ self.edge_factor=edge_factor\r
\r
\r
class Model(object):\r
- """pmx data holder\r
+ """pmx data representation\r
\r
- version: pmx version\r
+ Attributes:\r
+ version: pmx version(expected 2.0)\r
+ name: \r
+ english_name: \r
+ comment: \r
+ english_comment: \r
+ vertices:\r
"""\r
__slots__=[\r
'version', # pmx version\r
'english_name', # model name in english\r
'comment', # model comment\r
'english_comment', # model comment in english\r
+ 'vertices'\r
]\r
def __init__(self):\r
self.version=0.0\r
+ self.name=''\r
+ self.english_name=''\r
+ self.comment=''\r
+ self.english_comment=''\r
+ self.vertices=[]\r
\r
\r
class IO(object):\r
"""pmx loader\r
\r
Attributes:\r
- name: model name\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):\r
self.__io=None\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
+ if self.__load(path, f, size):\r
return self.__model\r
\r
- def load(self, path: 'filepath', io: io.IOBase, size: int) -> bool: \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
+ self.__pos=0\r
\r
- if not self.__loadHeader():\r
+ ####################\r
+ # header\r
+ ####################\r
+ signature=self.__unpack("4s", 4)\r
+ if signature!=b"PMX ":\r
+ print("invalid signature", self.signature)\r
return False\r
- self.__check_position()\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", self.flag_bytes)\r
+ return False\r
+ # text encoding\r
+ self.text_encoding=self.__unpack("B", 1)\r
+ self.__read_text=self.__get_read_text()\r
+ # uv\r
+ self.extended_uv=self.__unpack("B", 1)\r
+ if self.extended_uv>0:\r
+ print("extended uv is not supported", self.extended_uv)\r
+ return False\r
+ # index size\r
+ self.vertex_index_size=self.__unpack("B", 1)\r
+ self.texture_index_size=self.__unpack("B", 1)\r
+ self.material_index_size=self.__unpack("B", 1)\r
+ self.bone_index_size=self.__unpack("B", 1)\r
+ self.morph_index_size=self.__unpack("B", 1)\r
+ self.rigidbody_index_size=self.__unpack("B", 1)\r
+\r
+ ####################\r
# model info\r
+ ####################\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
+\r
+ ####################\r
+ # vertices\r
+ ####################\r
+ #vertex_count=self.__read_int(self.vertex_index_size)\r
+ # pmdeditor 131c bug?\r
+ vertex_count=self.__read_int(4)\r
+ self.__model.vertices=[self.__read_vertex() for i in range(vertex_count)]\r
+\r
return True\r
\r
def __str__(self) -> str:\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
+ result=struct.unpack(fmt, self.__io.read(size))\r
+ self.__check_position()\r
+ return result[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 __get_read_text(self) -> "text process function":\r
+ if self.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
+ return read_text\r
+ elif self.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
+ return read_text\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
+ print("unknown text encoding", self.text_encoding)\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_vertex(self):\r
+ return Vertex(\r
+ self.__read_vector3(), # pos\r
+ self.__read_vector3(), # normal\r
+ self.__read_vector2(), # uv\r
+ self.__read_deform(), # deform(bone weight)\r
+ self.__unpack("f", 4) # edge factor\r
+ )\r
+\r
+ def __read_vector2(self):\r
+ print(self.__pos)\r
+ return common.Vector2(\r
+ self.__unpack("f", 4), \r
+ self.__unpack("f", 4)\r
+ )\r
+\r
+ def __read_vector3(self):\r
+ print(self.__pos)\r
+ return common.Vector3(\r
+ self.__unpack("f", 4), \r
+ self.__unpack("f", 4), \r
+ self.__unpack("f", 4)\r
+ )\r
+\r
+ def __read_deform(self):\r
+ print(self.__pos)\r
+ deform_type=self.__unpack("B", 1)\r
+ if deform_type==0:\r
+ return Bdef1(self.__read_int(self.bone_index_size))\r
+ if deform_type==1:\r
+ return Bdef2(\r
+ self.__read_int(self.bone_index_size),\r
+ self.__read_int(self.bone_index_size),\r
+ self.__unpack("f", 4)\r
+ )\r
+ """\r
+ if deform_type==2:\r
+ return Bdef4(\r
+ self.__read_int(self.bone_index_size),\r
+ self.__read_int(self.bone_index_size),\r
+ self.__read_int(self.bone_index_size),\r
+ self.__read_int(self.bone_index_size),\r
+ self.__unpack("f", 4), self.__unpack("f", 4),\r
+ self.__unpack("f", 4), self.__unpack("f", 4)\r
+ )\r
+ """\r
+ raise ParseException("unknown deform type: {0}".format(deform_type))\r
\r