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

Source Code for Module pymeshio.pmd.reader

  1  #coding: utf-8
 
  2  """
 
  3  pmd reader
 
  4  """ 
  5  import io 
  6  from .. import common 
  7  from .. import pmd 
  8  
 
  9  
 
10 -class Reader(common.BinaryReader):
11 """pmx reader 12 """
13 - def __init__(self, ios, version):
14 super(Reader, self).__init__(ios) 15 self.version=version
16
17 - def read_text(self, size):
18 """read cp932 text 19 """ 20 src=self.unpack("%ds" % size, size) 21 assert(type(src)==bytes) 22 pos = src.find(b"\x00") 23 if pos==-1: 24 return src 25 else: 26 return src[:pos]
27
28 - def read_vertex(self):
29 return pmd.Vertex( 30 self.read_vector3(), 31 self.read_vector3(), 32 self.read_vector2(), 33 self.read_uint(2), 34 self.read_uint(2), 35 self.read_uint(1), 36 self.read_uint(1))
37
38 - def read_material(self):
39 return pmd.Material( 40 diffuse_color=self.read_rgb(), 41 alpha=self.read_float(), 42 specular_factor=self.read_float(), 43 specular_color=self.read_rgb(), 44 ambient_color=self.read_rgb(), 45 toon_index=self.read_int(1), 46 edge_flag=self.read_uint(1), 47 vertex_count=self.read_uint(4), 48 texture_file=self.read_text(20) 49 )
50
51 - def read_bone(self):
52 name=self.read_text(20) 53 parent_index=self.read_uint(2) 54 tail_index=self.read_uint(2) 55 bone=pmd.createBone(name, self.read_uint(1)) 56 bone.parent_index=parent_index 57 bone.tail_index=tail_index 58 bone.ik_index = self.read_uint(2) 59 bone.pos = self.read_vector3() 60 return bone
61
62 - def read_ik(self):
63 ik=pmd.IK(self.read_uint(2), self.read_uint(2)) 64 ik.length = self.read_uint(1) 65 ik.iterations = self.read_uint(2) 66 ik.weight = self.read_float() 67 ik.children=[self.read_uint(2) for _ in range(ik.length)] 68 return ik
69
70 - def read_morph(self):
71 morph=pmd.Morph(self.read_text(20)) 72 morph_size = self.read_uint(4) 73 morph.type = self.read_uint(1) 74 for j in range(morph_size): 75 morph.indices.append(self.read_uint(4)) 76 morph.pos_list.append(self.read_vector3()) 77 return morph
78
79 - def read_rigidbody(self):
80 return pmd.RigidBody( 81 name=self.read_text(20), 82 bone_index=self.read_int(2), 83 collision_group=self.read_int(1), 84 no_collision_group=self.read_int(2), 85 shape_type=self.read_uint(1), 86 shape_size=self.read_vector3(), 87 shape_position=self.read_vector3(), 88 shape_rotation=self.read_vector3(), 89 mass=self.read_float(), 90 linear_damping=self.read_float(), 91 angular_damping=self.read_float(), 92 restitution=self.read_float(), 93 friction=self.read_float(), 94 mode=self.read_uint(1) 95 )
96
97 - def read_joint(self):
110 111 112
113 -def __read(reader, model):
114 # model info 115 model.name=reader.read_text(20) 116 model.comment=reader.read_text(256) 117 118 # model data 119 model.vertices=[reader.read_vertex() 120 for _ in range(reader.read_uint(4))] 121 model.indices=[reader.read_uint(2) 122 for _ in range(reader.read_uint(4))] 123 model.materials=[reader.read_material() 124 for _ in range(reader.read_uint(4))] 125 model.bones=[reader.read_bone() 126 for _ in range(reader.read_uint(2))] 127 model.ik_list=[reader.read_ik() 128 for _ in range(reader.read_uint(2))] 129 model.morphs=[reader.read_morph() 130 for _ in range(reader.read_uint(2))] 131 model.morph_indices=[reader.read_uint(2) 132 for _ in range(reader.read_uint(1))] 133 model.bone_group_list=[pmd.BoneGroup(reader.read_text(50)) 134 for _ in range(reader.read_uint(1))] 135 model.bone_display_list=[(reader.read_uint(2), reader.read_uint(1)) 136 for _i in range(reader.read_uint(4))] 137 138 if reader.is_end(): 139 # EOF 140 return True 141 142 ############################################################ 143 # extend1: english name 144 ############################################################ 145 if reader.read_uint(1)==1: 146 print("no extend flag") 147 #return True 148 model.english_name=reader.read_text(20) 149 model.english_comment=reader.read_text(256) 150 for bone in model.bones: 151 bone.english_name=reader.read_text(20) 152 for morph in model.morphs: 153 if morph.name==b'base': 154 continue 155 morph.english_name=reader.read_text(20) 156 for g in model.bone_group_list: 157 g.english_name=reader.read_text(50) 158 159 160 ############################################################ 161 # extend2: toon_textures 162 ############################################################ 163 if reader.is_end(): 164 # EOF 165 return True 166 model.toon_textures=[reader.read_text(100) 167 for _ in range(10)] 168 169 ############################################################ 170 # extend2: rigidbodies and joints 171 ############################################################ 172 if reader.is_end(): 173 # EOF 174 return True 175 176 model.rigidbodies=[reader.read_rigidbody() 177 for _ in range(reader.read_uint(4))] 178 model.joints=[reader.read_joint() 179 for _ in range(reader.read_uint(4))] 180 181 return True
182 183
184 -def read_from_file(path):
185 """ 186 read from file path, then return the pymeshio.pmd.Model. 187 188 :Parameters: 189 path 190 file path 191 192 >>> import pymeshio.pmd.reader 193 >>> m=pymeshio.pmd.reader.read_from_file('resources/初音ミクVer2.pmd') 194 >>> print(m) 195 <pmd-2.0 "Miku Hatsune" 12354vertices> 196 197 """ 198 pmd=read(io.BytesIO(common.readall(path))) 199 pmd.path=path 200 return pmd
201 202
203 -def read(ios):
204 """ 205 read from ios, then return the pymeshio.pmd.Model. 206 207 :Parameters: 208 ios 209 input stream (in io.IOBase) 210 211 >>> import pymeshio.pmd.reader 212 >>> m=pymeshio.pmd.reader.read(io.open('resources/初音ミクVer2.pmd', 'rb')) 213 >>> print(m) 214 <pmd-2.0 "Miku Hatsune" 12354vertices> 215 216 """ 217 assert(isinstance(ios, io.IOBase)) 218 reader=common.BinaryReader(ios) 219 220 # header 221 signature=reader.unpack("3s", 3) 222 if signature!=b"Pmd": 223 raise common.ParseException( 224 "invalid signature: {0}".format(signature)) 225 version=reader.read_float() 226 227 model=pmd.Model(version) 228 reader=Reader(reader.ios, version) 229 if(__read(reader, model)): 230 # check eof 231 if not reader.is_end(): 232 #print("can not reach eof.") 233 pass 234 235 # build bone tree 236 for i, child in enumerate(model.bones): 237 child.index=i 238 if child.parent_index==0xFFFF: 239 # no parent 240 model.no_parent_bones.append(child) 241 child.parent=None 242 else: 243 # has parent 244 parent=model.bones[child.parent_index] 245 child.parent=parent 246 parent.children.append(child) 247 # 後位置 248 if child.hasChild(): 249 child.tail=model.bones[child.tail_index].pos 250 251 return model
252