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

Source Code for Module pymeshio.pmx.writer

  1  # coding: utf-8
 
  2  """
 
  3  pmx writer
 
  4  """ 
  5  import io 
  6  import struct 
  7  from .. import common 
  8  from .. import pmx 
  9  
 
10 -class Writer(common.BinaryWriter):
11 """pmx writer 12 """
13 - def __init__(self, ios, 14 text_encoding, extended_uv, 15 vertex_index_size, texture_index_size, material_index_size, 16 bone_index_size, morph_index_size, rigidbody_index_size):
17 super(Writer, self).__init__(ios) 18 if text_encoding==0: 19 def write_text(unicode): 20 utf16=unicode.encode('utf16') 21 self.write_int(len(utf16), 4) 22 self.write_bytes(utf16)
23 self.write_text=write_text 24 elif text_encoding==1: 25 def write_text(unicode): 26 utf8=unicode.encode('utf8') 27 self.write_int(len(utf8), 4) 28 self.write_bytes(utf8)
29 self.write_text=write_text 30 else: 31 raise WriteError( 32 "invalid text_encoding: {0}".format(text_encoding)) 33 34 self.write_vertex_index=lambda index: self.write_int(index, vertex_index_size) 35 self.write_texture_index=lambda index: self.write_int(index, texture_index_size) 36 self.write_material_index=lambda index: self.write_int(index, material_index_size) 37 self.write_bone_index=lambda index: self.write_int(index, bone_index_size) 38 self.write_morph_index=lambda index: self.write_int(index, morph_index_size) 39 self.write_rigidbody_index=lambda index: self.write_int(index, rigidbody_index_size) 40
41 - def write_vertices(self, vertices):
42 self.write_int(len(vertices), 4) 43 for v in vertices: 44 self.write_vector3(v.position) 45 self.write_vector3(v.normal) 46 self.write_vector2(v.uv) 47 self.write_deform(v.deform) 48 self.write_float(v.edge_factor)
49
50 - def write_deform(self, deform):
51 if isinstance(deform, pmx.Bdef1): 52 self.write_int(0, 1) 53 self.write_bone_index(deform.index0) 54 elif isinstance(deform, pmx.Bdef2): 55 self.write_int(1, 1) 56 self.write_bone_index(deform.index0) 57 self.write_bone_index(deform.index1) 58 self.write_float(deform.weight0) 59 elif isinstance(deform, pmx.Bdef4): 60 # todo 61 raise pymeshio.common.WriteException( 62 "not implemented Bdef4") 63 else: 64 raise pymeshio.common.WriteException( 65 "unknown deform type: {0}".format(deform.type))
66
67 - def write_indices(self, indices):
68 self.write_int(len(indices), 4) 69 for i in indices: 70 self.write_vertex_index(i)
71
72 - def write_textures(self, textures):
73 self.write_int(len(textures), 4) 74 for t in textures: 75 self.write_text(t)
76
77 - def write_materials(self, materials):
78 self.write_int(len(materials), 4) 79 for m in materials: 80 self.write_text(m.name) 81 self.write_text(m.english_name) 82 self.write_rgb(m.diffuse_color) 83 self.write_float(m.alpha) 84 self.write_rgb(m.specular_color) 85 self.write_float(m.specular_factor) 86 self.write_rgb(m.ambient_color) 87 self.write_int(m.flag, 1) 88 self.write_rgba(m.edge_color) 89 self.write_float(m.edge_size) 90 self.write_texture_index(m.texture_index) 91 self.write_texture_index(m.sphere_texture_index) 92 self.write_int(m.sphere_mode, 1) 93 self.write_int(m.toon_sharing_flag, 1) 94 if m.toon_sharing_flag==0: 95 self.write_texture_index(m.toon_texture_index) 96 elif m.toon_sharing_flag==1: 97 self.write_int(m.toon_texture_index, 1) 98 else: 99 raise common.WriteException( 100 "unknown toon_sharing_flag {0}".format(m.toon_sharing_flag)) 101 self.write_text(m.comment) 102 self.write_int(m.vertex_count, 4)
103
104 - def write_bones(self, bones):
105 self.write_int(len(bones), 4) 106 for bone in bones: 107 self.write_text(bone.name) 108 self.write_text(bone.english_name) 109 self.write_vector3(bone.position) 110 self.write_bone_index(bone.parent_index) 111 self.write_int(bone.layer, 4) 112 self.write_int(bone.flag, 2) 113 if bone.getConnectionFlag()==0: 114 self.write_vector3(bone.tail_position) 115 elif bone.getConnectionFlag()==1: 116 self.write_bone_index(bone.tail_index) 117 else: 118 raise pymeshio.common.WriteException( 119 "unknown bone conenction flag: {0}".format( 120 bone.getConnectionFlag())) 121 122 if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1: 123 self.write_bone_index(bone.effect_index) 124 self.write_float(bone.effect_factor) 125 126 if bone.getFixedAxisFlag()==1: 127 self.write_vector3(bone.fixed_axis) 128 129 if bone.getLocalCoordinateFlag()==1: 130 self.write_vector3(bone.local_x_vector) 131 self.write_vector3(bone.local_z_vector) 132 133 if bone.getExternalParentDeformFlag()==1: 134 self.write_int(bone.external_key, 4) 135 136 if bone.getIkFlag()==1: 137 self.write_ik(bone.ik)
138
139 - def write_ik(self, ik):
140 self.write_bone_index(ik.target_index) 141 self.write_int(ik.loop, 4) 142 self.write_float(ik.limit_radian) 143 self.write_int(len(ik.link), 4) 144 for l in ik.link: 145 self.write_ik_link(l)
146 159
160 - def write_morph(self, morphs):
161 self.write_int(len(morphs), 4) 162 for m in morphs: 163 self.write_text(m.name) 164 self.write_text(m.english_name) 165 self.write_int(m.panel, 1) 166 self.write_int(m.morph_type, 1) 167 if m.morph_type==0: 168 # todo 169 raise pymeshio.common.WriteException( 170 "not implemented GroupMorph") 171 elif m.morph_type==1: 172 self.write_int(len(m.offsets), 4) 173 for o in m.offsets: 174 self.write_vertex_index(o.vertex_index) 175 self.write_vector3(o.position_offset) 176 elif m.morph_type==2: 177 # todo 178 raise pymeshio.common.WriteException( 179 "not implemented BoneMorph") 180 elif m.morph_type==3: 181 # todo 182 raise pymeshio.common.WriteException( 183 "not implemented UvMorph") 184 elif m.morph_type==4: 185 # todo 186 raise pymeshio.common.WriteException( 187 "not implemented extended UvMorph1") 188 elif m.morph_type==5: 189 # todo 190 raise pymeshio.common.WriteException( 191 "not implemented extended UvMorph2") 192 elif m.morph_type==6: 193 # todo 194 raise pymeshio.common.WriteException( 195 "not implemented extended UvMorph3") 196 elif m.morph_type==7: 197 # todo 198 raise pymeshio.common.WriteException( 199 "not implemented extended UvMorph4") 200 elif m.morph_type==8: 201 # todo 202 raise pymeshio.common.WriteException( 203 "not implemented extended MaterialMorph") 204 else: 205 raise pymeshio.common.WriteException( 206 "unknown morph type: {0}".format(m.morph_type))
207
208 - def write_display_slots(self, display_slots):
209 self.write_int(len(display_slots), 4) 210 for s in display_slots: 211 self.write_text(s.name) 212 self.write_text(s.english_name) 213 self.write_int(s.special_flag, 1) 214 self.write_int(len(s.references), 4) 215 for r in s.references: 216 self.write_int(r[0], 1) 217 if r[0]==0: 218 self.write_bone_index(r[1]) 219 elif r[0]==1: 220 self.write_morph_index(r[1]) 221 else: 222 raise pymeshio.common.WriteException( 223 "unknown display_type: {0}".format(r[0]))
224
225 - def write_rigidbodies(self, rigidbodies):
226 self.write_int(len(rigidbodies), 4) 227 for rb in rigidbodies: 228 self.write_text(rb.name) 229 self.write_text(rb.english_name) 230 self.write_bone_index(rb.bone_index) 231 self.write_int(rb.collision_group, 1) 232 self.write_int(rb.no_collision_group, 2) 233 self.write_int(rb.shape_type, 1) 234 self.write_vector3(rb.shape_size) 235 self.write_vector3(rb.shape_position) 236 self.write_vector3(rb.shape_rotation) 237 self.write_float(rb.param.mass) 238 self.write_float(rb.param.linear_damping) 239 self.write_float(rb.param.angular_damping) 240 self.write_float(rb.param.restitution) 241 self.write_float(rb.param.friction) 242 self.write_int(rb.mode, 1)
243
244 - def write_joints(self, joints):
245 self.write_int(len(joints), 4) 246 for j in joints: 247 self.write_text(j.name) 248 self.write_text(j.english_name) 249 self.write_int(j.joint_type, 1) 250 self.write_rigidbody_index(j.rigidbody_index_a) 251 self.write_rigidbody_index(j.rigidbody_index_b) 252 self.write_vector3(j.position) 253 self.write_vector3(j.rotation) 254 self.write_vector3(j.translation_limit_min) 255 self.write_vector3(j.translation_limit_max) 256 self.write_vector3(j.rotation_limit_min) 257 self.write_vector3(j.rotation_limit_max) 258 self.write_vector3(j.spring_constant_translation) 259 self.write_vector3(j.spring_constant_rotation)
260 261
262 -def write(ios, model, text_encoding=1):
263 """ 264 write model to ios. 265 266 :Parameters: 267 ios 268 output stream (in io.IOBase) 269 model 270 pmx model 271 text_encoding 272 text field encoding (0: UTF16, 1:UTF-8). 273 0: UTF16 has bug. it write BOM(FFFE). 274 275 >>> import pymeshio.pmx.writer 276 >>> pymeshio.pmx.writer.write(io.open('out.pmx', 'wb'), pmx_model) 277 278 """ 279 assert(isinstance(ios, io.IOBase)) 280 assert(isinstance(model, pmx.Model)) 281 writer=common.BinaryWriter(ios) 282 # header 283 writer.write_bytes(b"PMX ") 284 writer.write_float(model.version) 285 286 # flags 287 writer.write_int(8, 1) 288 # textencoding 289 writer.write_int(text_encoding, 1) 290 # extend uv 291 writer.write_int(0, 1) 292 def get_array_size(size): 293 if size<128: 294 return 1 295 elif size<32768: 296 return 2 297 elif size<2147483647: 298 return 4 299 else: 300 raise common.WriteError( 301 "invalid array_size: {0}".format(size))
302 # vertex_index_size 303 vertex_index_size=get_array_size(len(model.vertices)) 304 writer.write_int(vertex_index_size, 1) 305 # texture_index_size 306 texture_index_size=get_array_size(len(model.textures)) 307 writer.write_int(texture_index_size, 1) 308 # material_index_size 309 material_index_size=get_array_size(len(model.materials)) 310 writer.write_int(material_index_size, 1) 311 # bone_index_size 312 bone_index_size=get_array_size(len(model.bones)) 313 writer.write_int(bone_index_size, 1) 314 # morph_index_size 315 morph_index_size=get_array_size(len(model.morphs)) 316 writer.write_int(morph_index_size, 1) 317 # rigidbody_index_size 318 rigidbody_index_size=get_array_size(len(model.rigidbodies)) 319 writer.write_int(rigidbody_index_size, 1) 320 321 writer=Writer(writer.ios, 322 text_encoding, 0, 323 vertex_index_size, texture_index_size, material_index_size, 324 bone_index_size, morph_index_size, rigidbody_index_size) 325 326 # model info 327 writer.write_text(model.name) 328 writer.write_text(model.english_name) 329 writer.write_text(model.comment) 330 writer.write_text(model.english_comment) 331 332 # model data 333 writer.write_vertices(model.vertices) 334 writer.write_indices(model.indices) 335 writer.write_textures(model.textures) 336 writer.write_materials(model.materials) 337 writer.write_bones(model.bones) 338 writer.write_morph(model.morphs) 339 writer.write_display_slots(model.display_slots) 340 writer.write_rigidbodies(model.rigidbodies) 341 writer.write_joints(model.joints) 342 return True 343