6 from .. import common
\r
10 class Reader(common.BinaryReader):
\r
13 def __init__(self, ios, version):
\r
14 super(Reader, self).__init__(ios)
\r
15 self.version=version
\r
17 def read_text(self, size):
\r
20 src=self.unpack("%ds" % size, size)
\r
21 assert(type(src)==bytes)
\r
22 pos = src.find(b"\x00")
\r
28 def read_vertex(self):
\r
30 self.read_vector3(),
\r
31 self.read_vector3(),
\r
32 self.read_vector2(),
\r
38 def read_material(self):
\r
39 return pmd.Material(
\r
40 diffuse_color=self.read_rgb(),
\r
41 alpha=self.read_float(),
\r
42 specular_factor=self.read_float(),
\r
43 specular_color=self.read_rgb(),
\r
44 ambient_color=self.read_rgb(),
\r
45 toon_index=self.read_int(1),
\r
46 edge_flag=self.read_uint(1),
\r
47 vertex_count=self.read_uint(4),
\r
48 texture_file=self.read_text(20)
\r
51 def read_bone(self):
\r
52 name=self.read_text(20)
\r
53 parent_index=self.read_uint(2)
\r
54 tail_index=self.read_uint(2)
\r
55 bone=pmd.createBone(name, self.read_uint(1))
\r
56 bone.parent_index=parent_index
\r
57 bone.tail_index=tail_index
\r
58 bone.ik_index = self.read_uint(2)
\r
59 bone.pos = self.read_vector3()
\r
63 ik=pmd.IK(self.read_uint(2), self.read_uint(2))
\r
64 ik.length = self.read_uint(1)
\r
65 ik.iterations = self.read_uint(2)
\r
66 ik.weight = self.read_float()
\r
67 ik.children=[self.read_uint(2) for _ in range(ik.length)]
\r
70 def read_morph(self):
\r
71 morph=pmd.Morph(self.read_text(20))
\r
72 morph_size = self.read_uint(4)
\r
73 morph.type = self.read_uint(1)
\r
74 for j in range(morph_size):
\r
75 morph.indices.append(self.read_uint(4))
\r
76 morph.pos_list.append(self.read_vector3())
\r
79 def read_rigidbody(self):
\r
80 return pmd.RigidBody(
\r
81 name=self.read_text(20),
\r
82 bone_index=self.read_int(2),
\r
83 collision_group=self.read_int(1),
\r
84 no_collision_group=self.read_int(2),
\r
85 shape_type=self.read_uint(1),
\r
86 shape_size=self.read_vector3(),
\r
87 shape_position=self.read_vector3(),
\r
88 shape_rotation=self.read_vector3(),
\r
89 mass=self.read_float(),
\r
90 linear_damping=self.read_float(),
\r
91 angular_damping=self.read_float(),
\r
92 restitution=self.read_float(),
\r
93 friction=self.read_float(),
\r
94 mode=self.read_uint(1)
\r
97 def read_joint(self):
\r
99 name=self.read_text(20),
\r
100 rigidbody_index_a=self.read_uint(4),
\r
101 rigidbody_index_b=self.read_uint(4),
\r
102 position=self.read_vector3(),
\r
103 rotation=self.read_vector3(),
\r
104 translation_limit_min=self.read_vector3(),
\r
105 translation_limit_max=self.read_vector3(),
\r
106 rotation_limit_min=self.read_vector3(),
\r
107 rotation_limit_max=self.read_vector3(),
\r
108 spring_constant_translation=self.read_vector3(),
\r
109 spring_constant_rotation=self.read_vector3())
\r
113 def __read(reader, model):
\r
115 model.name=reader.read_text(20)
\r
116 model.comment=reader.read_text(256)
\r
119 model.vertices=[reader.read_vertex()
\r
120 for _ in range(reader.read_uint(4))]
\r
121 model.indices=[reader.read_uint(2)
\r
122 for _ in range(reader.read_uint(4))]
\r
123 model.materials=[reader.read_material()
\r
124 for _ in range(reader.read_uint(4))]
\r
125 model.bones=[reader.read_bone()
\r
126 for _ in range(reader.read_uint(2))]
\r
127 model.ik_list=[reader.read_ik()
\r
128 for _ in range(reader.read_uint(2))]
\r
129 model.morphs=[reader.read_morph()
\r
130 for _ in range(reader.read_uint(2))]
\r
131 model.morph_indices=[reader.read_uint(2)
\r
132 for _ in range(reader.read_uint(1))]
\r
133 model.bone_group_list=[pmd.BoneGroup(reader.read_text(50))
\r
134 for _ in range(reader.read_uint(1))]
\r
135 model.bone_display_list=[(reader.read_uint(2), reader.read_uint(1))
\r
136 for _i in range(reader.read_uint(4))]
\r
138 if reader.is_end():
\r
142 ############################################################
\r
143 # extend1: english name
\r
144 ############################################################
\r
145 if reader.read_uint(1)==1:
\r
146 print("no extend flag")
\r
148 model.english_name=reader.read_text(20)
\r
149 model.english_comment=reader.read_text(256)
\r
150 for bone in model.bones:
\r
151 bone.english_name=reader.read_text(20)
\r
152 for morph in model.morphs:
\r
153 if morph.name==b'base':
\r
155 morph.english_name=reader.read_text(20)
\r
156 for g in model.bone_group_list:
\r
157 g.english_name=reader.read_text(50)
\r
160 ############################################################
\r
161 # extend2: toon_textures
\r
162 ############################################################
\r
163 if reader.is_end():
\r
166 model.toon_textures=[reader.read_text(100)
\r
167 for _ in range(10)]
\r
169 ############################################################
\r
170 # extend2: rigidbodies and joints
\r
171 ############################################################
\r
172 if reader.is_end():
\r
176 model.rigidbodies=[reader.read_rigidbody()
\r
177 for _ in range(reader.read_uint(4))]
\r
178 model.joints=[reader.read_joint()
\r
179 for _ in range(reader.read_uint(4))]
\r
184 def read_from_file(path):
\r
186 read from file path, then return the pymeshio.pmd.Model.
\r
192 >>> import pymeshio.pmd.reader
\r
193 >>> m=pymeshio.pmd.reader.read_from_file('resources/初音ミクVer2.pmd')
\r
195 <pmd-2.0 "Miku Hatsune" 12354vertices>
\r
198 pmd=read(io.BytesIO(common.readall(path)))
\r
205 read from ios, then return the pymeshio.pmd.Model.
\r
209 input stream (in io.IOBase)
\r
211 >>> import pymeshio.pmd.reader
\r
212 >>> m=pymeshio.pmd.reader.read(io.open('resources/初音ミクVer2.pmd', 'rb'))
\r
214 <pmd-2.0 "Miku Hatsune" 12354vertices>
\r
217 assert(isinstance(ios, io.IOBase))
\r
218 reader=common.BinaryReader(ios)
\r
221 signature=reader.unpack("3s", 3)
\r
222 if signature!=b"Pmd":
\r
223 raise common.ParseException(
\r
224 "invalid signature: {0}".format(signature))
\r
225 version=reader.read_float()
\r
227 model=pmd.Model(version)
\r
228 reader=Reader(reader.ios, version)
\r
229 if(__read(reader, model)):
\r
231 if not reader.is_end():
\r
232 #print("can not reach eof.")
\r
236 for i, child in enumerate(model.bones):
\r
238 if child.parent_index==0xFFFF:
\r
240 model.no_parent_bones.append(child)
\r
244 parent=model.bones[child.parent_index]
\r
245 child.parent=parent
\r
246 parent.children.append(child)
\r
248 if child.hasChild():
\r
249 child.tail=model.bones[child.tail_index].pos
\r