-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
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
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
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
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
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
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