def __str__(self):\r
return "<%f %f>" % (self.x, self.y)\r
\r
+ def __eq__(self, rhs):\r
+ return self.x==rhs.x and self.y==rhs.y\r
+\r
def __getitem__(self, key):\r
if key==0:\r
return self.x\r
def __str__(self):\r
return "<%f %f %f>" % (self.x, self.y, self.z)\r
\r
+ def __eq__(self, rhs):\r
+ return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z\r
+\r
def __getitem__(self, key):\r
if key==0:\r
return self.x\r
self.g=g\r
self.b=b\r
\r
+ def __eq__(self, rhs):\r
+ return self.r==rhs.r and self.g==rhs.g and self.b==rhs.b\r
+\r
def __getitem__(self, key):\r
if key==0:\r
return self.r\r
class BinaryLoader(object):\r
"""general BinaryLoader\r
"""\r
- def __init__(self, io):\r
- self.io=io\r
+ def __init__(self, ios):\r
+ self.ios=ios\r
\r
def is_end(self):\r
- return not self.io.readable()\r
+ return not self.ios.readable()\r
\r
def unpack(self, fmt, size):\r
- result=struct.unpack(fmt, self.io.read(size))\r
+ result=struct.unpack(fmt, self.ios.read(size))\r
return result[0]\r
\r
def read_uint(self, size):\r
self.read_float()\r
)\r
\r
+\r
+class BinaryWriter(object):\r
+ def __init__(self, ios):\r
+ self.ios=ios\r
+\r
+ def write_text(self, v, size=None):\r
+ if size:\r
+ self.ios.write(struct.pack("={0}s".format(size), v))\r
+ else:\r
+ self.ios.write(v)\r
+\r
+ def write_float(self, v):\r
+ self.ios.write(struct.pack("f", v))\r
+\r
+ def write_uint(self, v, size):\r
+ if size==1:\r
+ self.ios.write(struct.pack("B", v))\r
+ elif size==2:\r
+ self.ios.write(struct.pack("H", v))\r
+ elif size==4:\r
+ self.ios.write(struct.pack("I", v))\r
+ else:\r
+ raise WriteError("invalid int uint size")\r
+\r
+ def write_vector2(self, v):\r
+ self.ios.write(struct.pack("=2f", v.x, v.y))\r
+\r
+ def write_vector3(self, v):\r
+ self.ios.write(struct.pack("=3f", v.x, v.y, v.z))\r
+\r
+ def write_rgb(self, v):\r
+ self.ios.write(struct.pack("=3f", v.r, v.g, v.b))\r
+\r
+\r
\r
def read(self, path):\r
warnings.warn("'pymeshio.mqo.IO.read' will be replaced by 'pymeshio.mqo.loader.load'")\r
- model=pymeshio.mqo.loader.load(path)\r
+ model=pymeshio.mqo.loader.load_from_file(path)\r
if model:\r
self.has_mikoto=model.has_mikoto\r
self.materials=model.materials\r
"eof", "io", "lines",\r
"materials", "objects",\r
]\r
- def __init__(self, io):\r
- self.io=io\r
+ def __init__(self, ios):\r
+ self.ios=ios\r
self.eof=False\r
self.lines=0\r
\r
self.lines, len(self.materials), len(self.objects))\r
\r
def getline(self):\r
- line=self.io.readline()\r
+ line=self.ios.readline()\r
self.lines+=1\r
if line=="":\r
self.eof=True\r
return False\r
\r
\r
-def load(path):\r
- with open(path, 'rb') as io:\r
- loader=Loader(io)\r
- model=pymeshio.mqo.Model()\r
+def load_from_file(path):\r
+ with open(path, 'rb') as ios:\r
+ load(ios)\r
\r
- line=loader.getline()\r
- if line!="Metasequoia Document":\r
- print("invalid signature")\r
- return False\r
\r
- line=loader.getline()\r
- if line!="Format Text Ver 1.0":\r
- print("unknown version: %s" % line)\r
+def load(ios):\r
+ assert(isinstance(ios, io.IOBase))\r
+ loader=Loader(ios)\r
+ model=pymeshio.mqo.Model()\r
\r
- while True:\r
- line=loader.getline()\r
- if line==None:\r
- # eof\r
- break;\r
- if line=="":\r
- # empty line\r
- continue\r
+ line=loader.getline()\r
+ if line!="Metasequoia Document":\r
+ print("invalid signature")\r
+ return False\r
\r
- tokens=line.split()\r
- key=tokens[0]\r
- if key=="Eof":\r
- return model\r
- elif key=="Scene":\r
- if not loader.readChunk():\r
- return\r
- elif key=="Material":\r
- materials=loader.readMaterial()\r
- if not materials:\r
- return\r
- model.materials=materials\r
- elif key=="Object":\r
- firstQuote=line.find('"')\r
- secondQuote=line.find('"', firstQuote+1)\r
- obj=loader.readObject(line[firstQuote+1:secondQuote])\r
- if not obj:\r
- return\r
- model.objects.append(obj)\r
- elif key=="BackImage":\r
- if not loader.readChunk():\r
- return\r
- elif key=="IncludeXml":\r
- firstQuote=line.find('"')\r
- secondQuote=line.find('"', firstQuote+1)\r
- print("IncludeXml", line[firstQuote+1:secondQuote])\r
- else:\r
- print("unknown key: %s" % key)\r
- if not loader.readChunk():\r
- return\r
- # error not reach here\r
- raise ParseException("invalid eof")\r
+ line=loader.getline()\r
+ if line!="Format Text Ver 1.0":\r
+ print("unknown version: %s" % line)\r
+\r
+ while True:\r
+ line=loader.getline()\r
+ if line==None:\r
+ # eof\r
+ break;\r
+ if line=="":\r
+ # empty line\r
+ continue\r
+\r
+ tokens=line.split()\r
+ key=tokens[0]\r
+ if key=="Eof":\r
+ return model\r
+ elif key=="Scene":\r
+ if not loader.readChunk():\r
+ return\r
+ elif key=="Material":\r
+ materials=loader.readMaterial()\r
+ if not materials:\r
+ return\r
+ model.materials=materials\r
+ elif key=="Object":\r
+ firstQuote=line.find('"')\r
+ secondQuote=line.find('"', firstQuote+1)\r
+ obj=loader.readObject(line[firstQuote+1:secondQuote])\r
+ if not obj:\r
+ return\r
+ model.objects.append(obj)\r
+ elif key=="BackImage":\r
+ if not loader.readChunk():\r
+ return\r
+ elif key=="IncludeXml":\r
+ firstQuote=line.find('"')\r
+ secondQuote=line.find('"', firstQuote+1)\r
+ print("IncludeXml", line[firstQuote+1:secondQuote])\r
+ else:\r
+ print("unknown key: %s" % key)\r
+ if not loader.readChunk():\r
+ return\r
+ # error not reach here\r
+ raise ParseException("invalid eof")\r
\r
str(self.uv),
self.bone0, self.bone1, self.weight0)
+ def __eq__(self, rhs):
+ return (
+ self.pos==rhs.pos
+ and self.normal==rhs.normal
+ and self.uv==rhs.uv
+ and self.bone0==rhs.bone0
+ and self.bone1==rhs.bone1
+ and self.weight0==rhs.weight0
+ and self.edge_flag==rhs.edge_flag
+ )
+
def __getitem__(self, key):
if key==0:
return self.pos.x
self.diffuse[2], self.diffuse[3],
)
+ def __eq__(self, rhs):
+ return (
+ self.diffuse_color==rhs.diffuse_color
+ and self.alpha==rhs.alpha
+ and self.specular_factor==rhs.specular_factor
+ and self.specular_color==rhs.specular_color
+ and self.ambient_color==rhs.ambient_color
+ and self.toon_index==rhs.toon_index
+ and self.edge_flag==rhs.edge_flag
+ and self.vertex_count==rhs.vertex_count
+ and self.texture_file==rhs.texture_file
+ )
+
class Bone(object):
"""pmd material struct.
self.children=[]
self.english_name=''
+ def __eq__(self, rhs):
+ return (
+ self.name==rhs.name
+ and self.index==rhs.index
+ and self.type==rhs.type
+ and self.parent_index==rhs.parent_index
+ and self.tail_index==rhs.tail_index
+ and self.tail==rhs.tail
+ and self.ik_index==rhs.ik_index
+ and self.pos==rhs.pos
+ and self.children==rhs.children
+ and self.english_name==rhs.english_name
+ )
+
def hasParent(self):
return self.parent_index!=0xFFFF
def __str__(self):
return "<IK index: %d, target: %d, iterations: %d, weight: %f, children: %s(%d)>" %(self.index, self.target, self.iterations, self.weight, '-'.join([str(i) for i in self.children]), len(self.children))
+ def __eq__(self, rhs):
+ return (
+ self.index==rhs.index
+ and self.target==rhs.target
+ and self.iterations==rhs.iterations
+ and self.weight==rhs.weight
+ and self.children==rhs.children
+ )
+
-class Skin(object):
+class Morph(object):
__slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
'vertex_count']
- def __init__(self, name='skin'):
+ def __init__(self, name):
self.name=name
self.type=None
self.indices=[]
return '<Skin name: "%s", type: %d, vertex: %d>' % (
self.name, self.type, len(self.indices))
+ def __eq__(self, rhs):
+ return (
+ self.name==rhs.name
+ and self.type==rhs.type
+ and self.indices==rhs.indices
+ and self.pos_list==rhs.pos_list
+ and self.english_name==rhs.english_name
+ and self.vertex_count==rhs.vertex_count
+ )
+
class BoneGroup(object):
__slots__=['_name', '_english_name']
self.friction=friction
self.mode=mode
+ def __eq__(self, rhs):
+ return (
+ self.name==rhs.name
+ and self.bone_index==rhs.bone_index
+ and self.collision_group==rhs.collision_group
+ and self.no_collision_group==rhs.no_collision_group
+ and self.shape_type==rhs.shape_type
+ and self.shape_size==rhs.shape_size
+ and self.shape_position==rhs.shape_position
+ and self.shape_rotation==rhs.shape_rotation
+ and self.mass==rhs.mass
+ and self.linear_damping==rhs.linear_damping
+ and self.angular_damping==rhs.angular_damping
+ and self.restitution==rhs.restitution
+ and self.friction==rhs.friction
+ and self.mode==rhs.mode
+ )
+
class Joint(object):
__slots__=[ 'name', 'rigidbody_index_a', 'rigidbody_index_b',
self.spring_constant_translation=spring_constant_translation
self.spring_constant_rotation=spring_constant_rotation
+ def __eq__(self, rhs):
+ return (
+ self.name==rhs.name
+ and self.rigidbody_index_a==rhs.rigidbody_index_a
+ and self.rigidbody_index_b==rhs.rigidbody_index_b
+ and self.position==rhs.position
+ and self.rotation==rhs.rotation
+ and self.translation_limit_max==rhs.translation_limit_max
+ and self.translation_limit_min==rhs.translation_limit_min
+ and self.rotation_limit_max==rhs.rotation_limit_max
+ and self.rotation_limit_min==rhs.rotation_limit_min
+ and self.spring_constant_translation==rhs.spring_constant_translation
+ and self.spring_constant_rotation==rhs.spring_constant_rotation
+ )
+
class ToonTextures(object):
__slots__=['_toon_textures']
'vertices', 'indices', 'materials', 'bones',
'ik_list', 'morphs',
'morph_indices', 'bone_group_list', 'bone_display_list',
+ 'bone_group_english_list',
'toon_textures',
- 'no_parent_bones',
'rigidbodies', 'joints',
+
+ 'no_parent_bones',
]
def __init__(self, version):
self.version=version
self.bone_group_list=[]
self.bone_display_list=[]
# extend
+ self.bone_group_english_list=[]
self.toon_textures=ToonTextures()
self.rigidbodies=[]
self.joints=[]
self.version, self.name, len(self.vertices), len(self.indices),
len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
+ def __eq__(self, rhs):
+ return (
+ self.name==rhs.name
+ and self.comment==rhs.comment
+ and self.english_name==rhs.english_name
+ and self.english_comment==rhs.english_comment
+ and self.vertices==rhs.vertices
+ and self.indices==rhs.indices
+ and self.materials==rhs.materials
+ and self.bones==rhs.bones
+ and self.ik_list==rhs.ik_list
+ and self.morphs==rhs.morphs
+ and self.morph_indices==rhs.morph_indices
+ and self.bone_group_list==rhs.bone_group_list
+ and self.bone_display_list==rhs.bone_display_list
+ and self.bone_group_english_list==rhs.bone_group_english_list
+ and self.toon_textures==rhs.toon_textures
+ and self.rigidbodies==rhs.rigidbodies
+ and self.joints==rhs.joints
+ )
+
class IO(object):
def __init__(self):
def read(self, path):
warnings.warn("'pymeshio.mqo.IO.read' will be replaced by 'pymeshio.mqo.loader.load'")
- model=pymeshio.pmd.loader.load(path)
+ model=pymeshio.pmd.loader.load_from_file(path)
if model:
return True
class Loader(pymeshio.common.BinaryLoader):\r
"""pmx loader\r
"""\r
- def __init__(self, io, version):\r
- super(Loader, self).__init__(io)\r
+ def __init__(self, ios, version):\r
+ super(Loader, self).__init__(ios)\r
self.version=version\r
\r
def read_text(self, size):\r
return ik\r
\r
def read_morph(self):\r
- skin=pymeshio.pmd.Skin(self.read_text(20))\r
- skin_size = self.read_uint(4)\r
- skin.type = self.read_uint(1)\r
- for j in range(skin_size):\r
- skin.indices.append(self.read_uint(4))\r
- skin.pos_list.append(self.read_vector3())\r
- return skin\r
+ morph=pymeshio.pmd.Morph(self.read_text(20))\r
+ morph_size = self.read_uint(4)\r
+ morph.type = self.read_uint(1)\r
+ for j in range(morph_size):\r
+ morph.indices.append(self.read_uint(4))\r
+ morph.pos_list.append(self.read_vector3())\r
+ return morph\r
\r
def read_rigidbody(self):\r
return pymeshio.pmd.RigidBody(\r
if morph.name==b'base':\r
continue\r
morph.english_name=loader.read_text(20)\r
- for bone_group in model.bone_group_list:\r
- bone_group=loader.read_text(50)\r
+ model.bone_group_english_list=[loader.read_text(50)\r
+ for _ in model.bone_group_list]\r
\r
############################################################\r
# extend2: toon_textures\r
return True\r
\r
\r
-def load(path):\r
- # general binary loader\r
- #loader=pymeshio.common.BinaryLoader(open(path, 'rb'))\r
- loader=pymeshio.common.BinaryLoader(io.BytesIO(pymeshio.common.readall(path)))\r
+def load_from_file(path):\r
+ return load(io.BytesIO(pymeshio.common.readall(path)))\r
+\r
+\r
+def load(ios):\r
+ assert(isinstance(ios, io.IOBase))\r
+ loader=pymeshio.common.BinaryLoader(ios)\r
\r
# header\r
signature=loader.unpack("3s", 3)\r
version=loader.read_float()\r
\r
model=pymeshio.pmd.Model(version)\r
- loader=Loader(loader.io, version)\r
+ loader=Loader(loader.ios, version)\r
if(__load(loader, model)):\r
# check eof\r
if not loader.is_end():\r
- print("can not reach eof.")\r
+ #print("can not reach eof.")\r
+ pass\r
\r
# build bone tree\r
for i, child in enumerate(model.bones):\r
parent=model.bones[child.parent_index]\r
child.parent=parent\r
parent.children.append(child)\r
- # \8cã\88Ê\92u\r
+ # 後位置\r
if child.hasChild():\r
child.tail=model.bones[child.tail_index].pos\r
\r
return model\r
\r
\r
-def save(self, path):\r
- io=open(path, 'wb')\r
- if not io:\r
- return False\r
- # Header\r
- io.write(b"Pmd")\r
- io.write(struct.pack("f", self.version))\r
- io.write(struct.pack("20s", self.name))\r
- io.write(struct.pack("256s", self.comment))\r
-\r
- # Vertices\r
- io.write(struct.pack("I", len(self.vertices)))\r
- sVertex=struct.Struct("=8f2H2B") # 38byte\r
- assert(sVertex.size==38)\r
- for v in self.vertices:\r
- data=sVertex.pack( \r
- v.pos[0], v.pos[1], v.pos[2],\r
- v.normal[0], v.normal[1], v.normal[2],\r
- v.uv[0], v.uv[1],\r
- v.bone0, v.bone1, v.weight0, v.edge_flag)\r
- io.write(data)\r
-\r
- # Faces\r
- io.write(struct.pack("I", len(self.indices)))\r
- io.write(struct.pack("=%dH" % len(self.indices), *self.indices))\r
-\r
- # material\r
- io.write(struct.pack("I", len(self.materials)))\r
- sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte\r
- assert(sMaterial.size==70)\r
- for m in self.materials:\r
- io.write(sMaterial.pack(\r
- m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],\r
- m.shinness, \r
- m.specular[0], m.specular[1], m.specular[2],\r
- m.ambient[0], m.ambient[1], m.ambient[2],\r
- m.toon_index, m.flag,\r
- m.vertex_count,\r
- m.texture\r
- ))\r
-\r
- # bone\r
- io.write(struct.pack("H", len(self.bones)))\r
- sBone=struct.Struct("=20sHHBH3f")\r
- assert(sBone.size==39)\r
- for b in self.bones:\r
- io.write(sBone.pack(\r
- b.name,\r
- b.parent_index, b.tail_index, b.type, b.ik_index,\r
- b.pos[0], b.pos[1], b.pos[2]))\r
-\r
- # IK\r
- io.write(struct.pack("H", len(self.ik_list)))\r
- for ik in self.ik_list:\r
- io.write(struct.pack("=2HBHf", \r
- ik.index, ik.target, ik.length, ik.iterations, ik.weight\r
- ))\r
- for c in ik.children:\r
- io.write(struct.pack("H", c))\r
-\r
- # skin\r
- io.write(struct.pack("H", len(self.morph_list)))\r
- for s in self.morph_list:\r
- io.write(struct.pack("20sIB", \r
- s.name, len(s.indices), s.type))\r
- for i, v in zip(s.indices, s.pos_list):\r
- io.write(struct.pack("I3f", i, v[0], v[1], v[2]))\r
-\r
- # skin disp list\r
- io.write(struct.pack("B", len(self.face_list)))\r
- for i in self.face_list:\r
- io.write(struct.pack("H", i))\r
-\r
- # bone disp list\r
- io.write(struct.pack("B", len(self.bone_group_list)))\r
- for g in self.bone_group_list:\r
- io.write(struct.pack("50s", g.name))\r
-\r
- io.write(struct.pack("I", len(self.bone_display_list)))\r
- for l in self.bone_display_list:\r
- io.write(struct.pack("=HB", *l))\r
-\r
- ############################################################\r
- # extend data\r
- ############################################################\r
- io.write(struct.pack("B", 1))\r
- # english name\r
- io.write(struct.pack("=20s", self.english_name))\r
- io.write(struct.pack("=256s", self.english_comment))\r
- # english bone name\r
- for bone in self.bones:\r
- io.write(struct.pack("=20s", bone.english_name))\r
- # english skin list\r
- for skin in self.morph_list:\r
- #print(skin.name)\r
- if skin.name==b'base':\r
- continue\r
- io.write(struct.pack("=20s", skin.english_name))\r
- # english bone list\r
- for bone_group in self.bone_group_list:\r
- io.write(struct.pack("50s", bone_group.english_name))\r
- # toon texture\r
- for toon_texture in self.toon_textures:\r
- io.write(struct.pack("=100s", toon_texture))\r
- # rigid\r
- io.write(struct.pack("I", len(self.rigidbodies)))\r
- for r in self.rigidbodies:\r
- io.write(struct.pack("=20sHBHB14fB",\r
- r.name, r.boneIndex, r.group, r.target, r.shapeType,\r
- r.w, r.h, r.d, \r
- r.position.x, r.position.y, r.position.z, \r
- r.rotation.x, r.rotation.y, r.rotation.z, \r
- r.weight,\r
- r.linearDamping, r.angularDamping, r.restitution,\r
- r.friction, r.processType))\r
-\r
- # constraint\r
- io.write(struct.pack("I", len(self.constraints)))\r
- for c in self.constraints:\r
- io.write(struct.pack("=20sII24f",\r
- c.name, c.rigidA, c.rigidB,\r
- c.pos.x, c.pos.y, c.pos.z,\r
- c.rot.x, c.rot.y, c.rot.z,\r
- c.constraintPosMin.x, c.constraintPosMin.y, c.constraintPosMin.z,\r
- c.constraintPosMax.x, c.constraintPosMax.y, c.constraintPosMax.z,\r
- c.constraintRotMin.x, c.constraintRotMin.y, c.constraintRotMin.z,\r
- c.constraintRotMax.x, c.constraintRotMax.y, c.constraintRotMax.z,\r
- c.springPos.x, c.springPos.y, c.springPos.z,\r
- c.springRot.x, c.springRot.y, c.springRot.z\r
- ))\r
-\r
- return True\r
\r
--- /dev/null
+# coding: utf-8\r
+import io\r
+import struct\r
+import pymeshio.common\r
+import pymeshio.pmd\r
+\r
+\r
+class Writer(pymeshio.common.BinaryWriter):\r
+ def write_veritices(self, vertices):\r
+ self.write_uint(len(vertices), 4)\r
+ for v in vertices:\r
+ self.write_vector3(v.pos)\r
+ self.write_vector3(v.normal)\r
+ self.write_vector2(v.uv)\r
+ self.write_uint(v.bone0, 2)\r
+ self.write_uint(v.bone1, 2)\r
+ self.write_uint(v.weight0, 1)\r
+ self.write_uint(v.edge_flag, 1)\r
+\r
+ def write_indices(self, indices):\r
+ self.write_uint(len(indices), 4)\r
+ self.ios.write(struct.pack("=%dH" % len(indices), *indices))\r
+\r
+ def write_materials(self, materials):\r
+ self.write_uint(len(materials), 4)\r
+ for m in materials:\r
+ self.write_rgb(m.diffuse_color)\r
+ self.write_float(m.alpha)\r
+ self.write_float(m.specular_factor)\r
+ self.write_rgb(m.specular_color)\r
+ self.write_rgb(m.ambient_color)\r
+ self.write_uint(m.toon_index, 1)\r
+ self.write_uint(m.edge_flag, 1)\r
+ self.write_uint(m.vertex_count, 4)\r
+ self.write_text(m.texture_file, 20)\r
+\r
+ def write_bones(self, bones):\r
+ self.write_uint(len(bones), 2)\r
+ sBone=struct.Struct("=20sHHBH3f")\r
+ assert(sBone.size==39)\r
+ for b in bones:\r
+ self.write_text(b.name, 20)\r
+ self.write_uint(b.parent_index, 2)\r
+ self.write_uint(b.tail_index, 2)\r
+ self.write_uint(b.type, 1)\r
+ self.write_uint(b.ik_index, 2)\r
+ self.write_vector3(b.pos)\r
+\r
+ def write_ik_list(self, ik_list):\r
+ self.write_uint(len(ik_list), 2)\r
+ for ik in ik_list:\r
+ self.write_uint(ik.index, 2)\r
+ self.write_uint(ik.target, 2)\r
+ self.write_uint(len(ik.children), 1)\r
+ self.write_uint(ik.iterations, 2)\r
+ self.write_float(ik.weight)\r
+ self.ios.write(struct.pack("=%dH" % len(ik.children), *ik.children))\r
+\r
+ def write_morphs(self, morphs):\r
+ self.write_uint(len(morphs), 2)\r
+ for morph in morphs:\r
+ self.write_text(morph.name, 20)\r
+ self.write_uint(len(morph.indices), 4)\r
+ self.write_uint(morph.type, 1)\r
+ for i, v in zip(morph.indices, morph.pos_list):\r
+ self.write_uint(i, 4)\r
+ self.write_vector3(v)\r
+\r
+ def write_morph_indices(self, morph_indices):\r
+ self.write_uint(len(morph_indices), 1)\r
+ self.ios.write(struct.pack("=%dH" % len(morph_indices), *morph_indices))\r
+\r
+ def write_bone_group_list(self, bone_group_list):\r
+ self.write_uint(len(bone_group_list), 1)\r
+ for g in bone_group_list:\r
+ self.write_text(g, 50)\r
+\r
+ def write_bone_display_list(self, bone_display_list):\r
+ self.write_uint(len(bone_display_list), 4)\r
+ for l in bone_display_list:\r
+ self.write_uint(l[0], 2)\r
+ self.write_uint(l[1], 1)\r
+\r
+ def write_rigidbodies(self, rigidbodies):\r
+ self.write_uint(len(rigidbodies), 4)\r
+ for r in rigidbodies:\r
+ self.write_text(r.name, 20)\r
+ self.write_uint(r.bone_index, 2)\r
+ self.write_uint(r.collision_group, 1)\r
+ self.write_uint(r.no_collision_group, 2)\r
+ self.write_uint(r.shape_type, 1)\r
+ self.write_vector3(r.shape_size)\r
+ self.write_vector3(r.shape_position)\r
+ self.write_vector3(r.shape_rotation)\r
+ self.write_float(r.mass)\r
+ self.write_float(r.linear_damping)\r
+ self.write_float(r.angular_damping)\r
+ self.write_float(r.restitution)\r
+ self.write_float(r.friction)\r
+ self.write_uint(r.mode, 1)\r
+\r
+ def write_joints(self, joints):\r
+ self.write_uint(len(joints), 4)\r
+ for j in joints:\r
+ self.write_text(j.name, 20)\r
+ self.write_uint(j.rigidbody_index_a, 4)\r
+ self.write_uint(j.rigidbody_index_b, 4)\r
+ self.write_vector3(j.position)\r
+ self.write_vector3(j.rotation)\r
+ self.write_vector3(j.translation_limit_min)\r
+ self.write_vector3(j.translation_limit_max)\r
+ self.write_vector3(j.rotation_limit_min)\r
+ self.write_vector3(j.rotation_limit_max)\r
+ self.write_vector3(j.spring_constant_translation)\r
+ self.write_vector3(j.spring_constant_rotation)\r
+\r
+\r
+def write(ios, model):\r
+ assert(isinstance(ios, io.IOBase))\r
+ assert(isinstance(model, pymeshio.pmd.Model))\r
+ writer=Writer(ios)\r
+ writer.write_text(b"Pmd")\r
+ writer.write_float(model.version)\r
+ writer.write_text(model.name, 20)\r
+ writer.write_text(model.comment, 256)\r
+ writer.write_veritices(model.vertices)\r
+ writer.write_indices(model.indices)\r
+ writer.write_materials(model.materials)\r
+ writer.write_bones(model.bones)\r
+ writer.write_ik_list(model.ik_list)\r
+ writer.write_morphs(model.morphs)\r
+ writer.write_morph_indices(model.morph_indices)\r
+ writer.write_bone_group_list(model.bone_group_list)\r
+ writer.write_bone_display_list(model.bone_display_list)\r
+ # extend data\r
+ writer.write_uint(1, 1)\r
+ writer.write_text(model.english_name, 20)\r
+ writer.write_text(model.english_comment, 256)\r
+ for bone in model.bones:\r
+ writer.write_text(bone.english_name, 20)\r
+ for skin in model.morphs:\r
+ if skin.name==b'base':\r
+ continue\r
+ writer.write_text(skin.english_name, 20)\r
+ for english in model.bone_group_english_list:\r
+ writer.write_text(english, 50)\r
+ for toon_texture in model.toon_textures:\r
+ writer.write_text(toon_texture, 100)\r
+ writer.write_rigidbodies(model.rigidbodies)\r
+ writer.write_joints(model.joints)\r
+ return True\r
+\r
class Loader(pymeshio.common.BinaryLoader):\r
"""pmx loader\r
"""\r
- def __init__(self, io,\r
+ def __init__(self, ios,\r
text_encoding,\r
extended_uv,\r
vertex_index_size,\r
morph_index_size,\r
rigidbody_index_size\r
):\r
- super(Loader, self).__init__(io)\r
+ super(Loader, self).__init__(ios)\r
self.read_text=self.get_read_text(text_encoding)\r
if extended_uv>0:\r
raise pymeshio.common.ParseException(\r
spring_constant_rotation=self.read_vector3())\r
\r
\r
-def load(path):\r
- # general binary loader\r
- loader=pymeshio.common.BinaryLoader(\r
- io.BytesIO(\r
- pymeshio.common.readall(path)))\r
- #loader=pymeshio.common.BinaryLoader(open(path, 'rb'))\r
+def load_from_file(path):\r
+ return load(io.BytesIO(pymeshio.common.readall(path)))\r
\r
\r
+def load(ios):\r
+ assert(isinstance(ios, io.IOBase))\r
+ loader=pymeshio.common.BinaryLoader(ios)\r
+\r
# header\r
signature=loader.unpack("4s", 4)\r
if signature!=b"PMX ":\r
assert io.read(MQO_FILE)
def test_mqo_load():
- model=pymeshio.mqo.loader.load(MQO_FILE)
+ model=pymeshio.mqo.loader.load_from_file(MQO_FILE)
print(model.materials)
assert pymeshio.mqo.Model==model.__class__
assert 6==len(model.materials)
# coding: utf-8
-import pymeshio.pmd
-import pymeshio.pmd.loader
import sys
+import io
import unittest
+import pymeshio.pmd
+import pymeshio.pmd.loader
+import pymeshio.pmd.writer
PMD_FILE=u'resources/初音ミクVer2.pmd'
def test_old_pmd_load():
- io=pymeshio.pmd.IO()
- assert io.read(PMD_FILE)
+ loader=pymeshio.pmd.IO()
+ assert loader.read(PMD_FILE)
class TestPmd(unittest.TestCase):
def setUp(self):
pass
- def test_read(self):
- model=pymeshio.pmd.loader.load(PMD_FILE)
+ def test_load(self):
+ model=pymeshio.pmd.loader.load_from_file(PMD_FILE)
self.assertEqual(pymeshio.pmd.Model, model.__class__)
self.assertEqual(u'初音ミク'.encode('cp932'), model.name)
self.assertEqual(u'Miku Hatsune'.encode('cp932'), model.english_name)
self.assertEqual(45, len(model.rigidbodies))
self.assertEqual(27, len(model.joints))
+ def test_write(self):
+ # read source file
+ buf=pymeshio.common.readall(PMD_FILE)
+ # load and write to out
+ model=pymeshio.pmd.loader.load(io.BytesIO(buf))
+ out=io.BytesIO()
+ pymeshio.pmd.writer.write(out, model)
+ # read out buffer again
+ model2=pymeshio.pmd.loader.load(io.BytesIO(out.getvalue()))
+ self.assertEqual(model, model2)
+
pass\r
\r
def test_read(self):\r
- model=pymeshio.pmx.loader.load(PMX_FILE)\r
+ model=pymeshio.pmx.loader.load_from_file(PMX_FILE)\r
self.assertEqual(pymeshio.pmx.Model, model.__class__)\r
self.assertEqual(u'初音ミク', model.name)\r
self.assertEqual(u'Miku Hatsune', model.english_name)\r