1
2 """
3 pmx reader
4 """
5 import io
6 from .. import common
7 from .. import pmx
8
9
10 -class Reader(common.BinaryReader):
11 """pmx reader
12 """
13 - def __init__(self, ios,
14 text_encoding,
15 extended_uv,
16 vertex_index_size,
17 texture_index_size,
18 material_index_size,
19 bone_index_size,
20 morph_index_size,
21 rigidbody_index_size
22 ):
23 super(Reader, self).__init__(ios)
24 self.read_text=self.get_read_text(text_encoding)
25 if extended_uv>0:
26 raise common.ParseException(
27 "extended uv is not supported", extended_uv)
28 self.read_vertex_index=lambda : self.read_int(vertex_index_size)
29 self.read_texture_index=lambda : self.read_int(texture_index_size)
30 self.read_material_index=lambda : self.read_int(material_index_size)
31 self.read_bone_index=lambda : self.read_int(bone_index_size)
32 self.read_morph_index=lambda : self.read_int(morph_index_size)
33 self.read_rigidbody_index=lambda : self.read_int(rigidbody_index_size)
34
37
38 - def get_read_text(self, text_encoding):
39 if text_encoding==0:
40 def read_text():
41 size=self.read_int(4)
42 return self.unpack("{0}s".format(size), size).decode("UTF16")
43 return read_text
44 elif text_encoding==1:
45 def read_text():
46 size=self.read_int(4)
47 return self.unpack("{0}s".format(size), size).decode("UTF8")
48 return read_text
49 else:
50 print("unknown text encoding", text_encoding)
51
60
78
80 material=pmx.Material(
81 name=self.read_text(),
82 english_name=self.read_text(),
83 diffuse_color=self.read_rgb(),
84 alpha=self.read_float(),
85 specular_color=self.read_rgb(),
86 specular_factor=self.read_float(),
87 ambient_color=self.read_rgb(),
88 flag=self.read_int(1),
89 edge_color=self.read_rgba(),
90 edge_size=self.read_float(),
91 texture_index=self.read_texture_index(),
92 sphere_texture_index=self.read_texture_index(),
93 sphere_mode=self.read_int(1),
94 toon_sharing_flag=self.read_int(1),
95 )
96 if material.toon_sharing_flag==0:
97 material.toon_texture_index=self.read_texture_index()
98 elif material.toon_sharing_flag==1:
99 material.toon_texture_index=self.read_int(1)
100 else:
101 raise common.ParseException(
102 "unknown toon_sharing_flag {0}".format(
103 material.toon_sharing_flag))
104 material.comment=self.read_text()
105 material.vertex_count=self.read_int(4)
106 return material
107
144
154
169
217
221
238
239 - def read_rigidbody(self):
240 return pmx.RigidBody(
241 name=self.read_text(),
242 english_name=self.read_text(),
243 bone_index=self.read_bone_index(),
244 collision_group=self.read_int(1),
245 no_collision_group=self.read_int(2),
246 shape_type=self.read_int(1),
247 shape_size=self.read_vector3(),
248 shape_position=self.read_vector3(),
249 shape_rotation=self.read_vector3(),
250 mass=self.read_float(),
251 linear_damping=self.read_float(),
252 angular_damping=self.read_float(),
253 restitution=self.read_float(),
254 friction=self.read_float(),
255 mode=self.read_int(1)
256 )
257
259 return pmx.Joint(
260 name=self.read_text(),
261 english_name=self.read_text(),
262 joint_type=self.read_int(1),
263 rigidbody_index_a=self.read_rigidbody_index(),
264 rigidbody_index_b=self.read_rigidbody_index(),
265 position=self.read_vector3(),
266 rotation=self.read_vector3(),
267 translation_limit_min=self.read_vector3(),
268 translation_limit_max=self.read_vector3(),
269 rotation_limit_min=self.read_vector3(),
270 rotation_limit_max=self.read_vector3(),
271 spring_constant_translation=self.read_vector3(),
272 spring_constant_rotation=self.read_vector3())
273
274
276 """
277 read from file path, then return the pmx.Model.
278
279 :Parameters:
280 path
281 file path
282
283 >>> import pmx.reader
284 >>> m=pmx.reader.read_from_file('resources/初音ミクVer2.pmx')
285 >>> print(m)
286 <pmx-2.0 "Miku Hatsune" 12354vertices>
287
288 """
289 pmx=read(io.BytesIO(common.readall(path)))
290 pmx.path=path
291 return pmx
292
293
295 """
296 read from ios, then return the pmx pmx.Model.
297
298 :Parameters:
299 ios
300 input stream (in io.IOBase)
301
302 >>> import pmx.reader
303 >>> m=pmx.reader.read(io.open('resources/初音ミクVer2.pmx', 'rb'))
304 >>> print(m)
305 <pmx-2.0 "Miku Hatsune" 12354vertices>
306
307 """
308 assert(isinstance(ios, io.IOBase))
309 reader=common.BinaryReader(ios)
310
311
312 signature=reader.unpack("4s", 4)
313 if signature!=b"PMX ":
314 raise common.ParseException(
315 "invalid signature", signature)
316
317 version=reader.read_float()
318 if version!=2.0:
319 print("unknown version", version)
320 model=pmx.Model(version)
321
322
323 flag_bytes=reader.read_int(1)
324 if flag_bytes!=8:
325 raise common.ParseException(
326 "invalid flag length", reader.flag_bytes)
327 text_encoding=reader.read_int(1)
328 extended_uv=reader.read_int(1)
329 vertex_index_size=reader.read_int(1)
330 texture_index_size=reader.read_int(1)
331 material_index_size=reader.read_int(1)
332 bone_index_size=reader.read_int(1)
333 morph_index_size=reader.read_int(1)
334 rigidbody_index_size=reader.read_int(1)
335
336
337 reader=Reader(reader.ios,
338 text_encoding,
339 extended_uv,
340 vertex_index_size,
341 texture_index_size,
342 material_index_size,
343 bone_index_size,
344 morph_index_size,
345 rigidbody_index_size
346 )
347
348
349 model.name = reader.read_text()
350 model.english_name = reader.read_text()
351 model.comment = reader.read_text()
352 model.english_comment = reader.read_text()
353
354
355 model.vertices=[reader.read_vertex()
356 for _ in range(reader.read_int(4))]
357 model.indices=[reader.read_vertex_index()
358 for _ in range(reader.read_int(4))]
359 model.textures=[reader.read_text()
360 for _ in range(reader.read_int(4))]
361 model.materials=[reader.read_material()
362 for _ in range(reader.read_int(4))]
363 model.bones=[reader.read_bone()
364 for _ in range(reader.read_int(4))]
365 model.morphs=[reader.read_morgh()
366 for _ in range(reader.read_int(4))]
367 model.display_slots=[reader.read_display_slot()
368 for _ in range(reader.read_int(4))]
369 model.rigidbodies=[reader.read_rigidbody()
370 for _ in range(reader.read_int(4))]
371 model.joints=[reader.read_joint()
372 for _ in range(reader.read_int(4))]
373
374 return model
375