Package pymeshio :: Package pmx :: Module reader
[hide private]
[frames] | no frames]

Source Code for Module pymeshio.pmx.reader

  1  # coding: utf-8
 
  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
35 - def __str__(self):
36 return '<pmx.Reader>'
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
52 - def read_vertex(self):
53 return pmx.Vertex( 54 self.read_vector3(), # pos 55 self.read_vector3(), # normal 56 self.read_vector2(), # uv 57 self.read_deform(), # deform(bone weight) 58 self.read_float() # edge factor 59 )
60
61 - def read_deform(self):
62 deform_type=self.read_int(1) 63 if deform_type==0: 64 return pmx.Bdef1(self.read_bone_index()) 65 elif deform_type==1: 66 return pmx.Bdef2( 67 self.read_bone_index(), 68 self.read_bone_index(), 69 self.read_float() 70 ) 71 elif deform_type==2: 72 # todo 73 raise common.ParseException( 74 "not implemented Bdef4") 75 else: 76 raise common.ParseException( 77 "unknown deform type: {0}".format(deform_type))
78
79 - def read_material(self):
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
108 - def read_bone(self):
109 bone=pmx.Bone( 110 name=self.read_text(), 111 english_name=self.read_text(), 112 position=self.read_vector3(), 113 parent_index=self.read_bone_index(), 114 layer=self.read_int(4), 115 flag=self.read_int(2) 116 ) 117 if bone.getConnectionFlag()==0: 118 bone.tail_position=self.read_vector3() 119 elif bone.getConnectionFlag()==1: 120 bone.tail_index=self.read_bone_index() 121 else: 122 raise common.ParseException( 123 "unknown bone conenction flag: {0}".format( 124 bone.getConnectionFlag())) 125 126 if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1: 127 bone.effect_index=self.read_bone_index() 128 bone.effect_factor=self.read_float() 129 130 if bone.getFixedAxisFlag()==1: 131 bone.fixed_axis=self.read_vector3() 132 133 if bone.getLocalCoordinateFlag()==1: 134 bone.local_x_vector=self.read_vector3() 135 bone.local_z_vector=self.read_vector3() 136 137 if bone.getExternalParentDeformFlag()==1: 138 bone.external_key=self.read_int(4) 139 140 if bone.getIkFlag()==1: 141 bone.ik=self.read_ik() 142 143 return bone
144
145 - def read_ik(self):
146 ik=pmx.Ik( 147 target_index=self.read_bone_index(), 148 loop=self.read_int(4), 149 limit_radian=self.read_float()) 150 link_size=self.read_int(4) 151 ik.link=[self.read_ik_link() 152 for _ in range(link_size)] 153 return ik
154 169
170 - def read_morgh(self):
171 name=self.read_text() 172 english_name=self.read_text() 173 panel=self.read_int(1) 174 morph_type=self.read_int(1) 175 offset_size=self.read_int(4) 176 if morph_type==0: 177 # todo 178 raise common.ParseException( 179 "not implemented GroupMorph") 180 elif morph_type==1: 181 morph=pmx.Morph(name, english_name, 182 panel, morph_type) 183 morph.offsets=[self.read_vertex_morph_offset() 184 for _ in range(offset_size)] 185 return morph 186 elif morph_type==2: 187 # todo 188 raise common.ParseException( 189 "not implemented BoneMorph") 190 elif morph_type==3: 191 # todo 192 raise common.ParseException( 193 "not implemented UvMorph") 194 elif morph_type==4: 195 # todo 196 raise common.ParseException( 197 "not implemented extended UvMorph1") 198 elif morph_type==5: 199 # todo 200 raise common.ParseException( 201 "not implemented extended UvMorph2") 202 elif morph_type==6: 203 # todo 204 raise common.ParseException( 205 "not implemented extended UvMorph3") 206 elif morph_type==7: 207 # todo 208 raise common.ParseException( 209 "not implemented extended UvMorph4") 210 elif morph_type==8: 211 # todo 212 raise common.ParseException( 213 "not implemented extended MaterialMorph") 214 else: 215 raise common.ParseException( 216 "unknown morph type: {0}".format(morph_type))
217
218 - def read_vertex_morph_offset(self):
219 return pmx.VertexMorphOffset( 220 self.read_vertex_index(), self.read_vector3())
221
222 - def read_display_slot(self):
223 display_slot=pmx.DisplaySlot(self.read_text(), self.read_text(), 224 self.read_int(1)) 225 display_count=self.read_int(4) 226 for _ in range(display_count): 227 display_type=self.read_int(1) 228 if display_type==0: 229 display_slot.references.append( 230 (display_type, self.read_bone_index())) 231 elif display_type==1: 232 display_slot.references.append( 233 (display_type, self.read_morph_index())) 234 else: 235 raise common.ParseException( 236 "unknown display_type: {0}".format(display_type)) 237 return display_slot
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
258 - def read_joint(self):
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
275 -def read_from_file(path):
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
294 -def read(ios):
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 # header 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 # flags 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 # pmx custom reader 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 # model info 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 # model data 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