Package pymeshio :: Module common
[hide private]
[frames] | no frames]

Source Code for Module pymeshio.common

  1  # coding: utf-8
 
  2  """
 
  3  common utilities.
 
  4  """ 
  5  import math 
  6  import struct 
  7  import sys 
  8  import io 
9 10 11 -def unicode(src):
12 """ 13 literal to unicode for python2 and python3 compatiblity. 14 15 in python2 str to unicode. 16 in python3 str(as unicode) to str. 17 """ 18 if sys.version_info[0]<3: 19 return src.decode('utf-8') 20 else: 21 return src
22 23 """ 24 common structures. 25 """
26 -class Vector2(object):
27 """ 28 2D coordinate for uv value 29 """ 30 __slots__=['x', 'y']
31 - def __init__(self, x=0, y=0):
32 self.x=x 33 self.y=y
34
35 - def __str__(self):
36 return "<%f %f>" % (self.x, self.y)
37
38 - def __eq__(self, rhs):
39 return self.x==rhs.x and self.y==rhs.y
40
41 - def __ne__(self, rhs):
42 return not self.__eq__(rhs)
43
44 - def __getitem__(self, key):
45 if key==0: 46 return self.x 47 elif key==1: 48 return self.y 49 else: 50 assert(False)
51
52 - def to_tuple(self):
53 return (self.x, self.y)
54
55 - def cross(self, rhs):
56 """cross(outer) product""" 57 return self.x*rhs.y-self.y*rhs.x
58
59 60 -class Vector3(object):
61 """ 62 3D coordinate for vertex position, normal direction 63 """ 64 __slots__=['x', 'y', 'z']
65 - def __init__(self, x=0, y=0, z=0):
66 self.x=x 67 self.y=y 68 self.z=z
69
70 - def __str__(self):
71 return "<%f %.32f %f>" % (self.x, self.y, self.z)
72
73 - def __eq__(self, rhs):
74 return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z
75
76 - def __ne__(self, rhs):
77 return not self.__eq__(rhs)
78
79 - def __getitem__(self, key):
80 if key==0: 81 return self.x 82 elif key==1: 83 return self.y 84 elif key==2: 85 return self.z 86 else: 87 assert(False)
88
89 - def to_tuple(self):
90 return (self.x, self.y, self.z)
91
92 - def __add__(self, r):
93 return Vector3(self.x+r.x, self.y+r.y, self.z+r.z)
94
95 - def __sub__(self, rhs):
96 return Vector3(self.x-rhs.x, self.y-rhs.y, self.z-rhs.z)
97
98 - def getSqNorm(self):
99 return self.x*self.x + self.y*self.y + self.z*self.z
100
101 - def getNorm(self):
102 return math.sqrt(self.getSqNorm())
103
104 - def normalize(self):
105 factor=1.0/self.getNorm() 106 self.x*=factor 107 self.y*=factor 108 self.z*=factor 109 return self
110
111 - def to_a(self):
112 return [self.x, self.y, self.z]
113
114 - def dot(self, rhs):
115 """dot(inner) product""" 116 return self.x*rhs.x + self.y*rhs.y + self.z*rhs.z
117
118 - def cross(self, rhs):
119 """cross(outer) product""" 120 return Vector3( 121 self.y*rhs.z - rhs.y*self.z, 122 self.z*rhs.x - rhs.z*self.x, 123 self.x*rhs.y - rhs.x*self.y, 124 )
125
126 127 -class Quaternion(object):
128 """ 129 rotation representation in vmd motion 130 """ 131 __slots__=['x', 'y', 'z', 'w']
132 - def __init__(self, x=0, y=0, z=0, w=1):
133 self.x=x 134 self.y=y 135 self.z=z 136 self.w=w
137
138 - def __str__(self):
139 return "<%f %f %f %f>" % (self.x, self.y, self.z, self.w)
140
141 - def __mul__(self, rhs):
142 u=numpy.array([self.x, self.y, self.z], 'f') 143 v=numpy.array([rhs.x, rhs.y, rhs.z], 'f') 144 xyz=self.w*v+rhs.w*u+numpy.cross(u, v) 145 q=Quaternion(xyz[0], xyz[1], xyz[2], self.w*rhs.w-numpy.dot(u, v)) 146 return q
147
148 - def dot(self, rhs):
149 return self.x*rhs.x+self.y*rhs.y+self.z*rhs.z+self.w*rhs.w
150
151 - def getMatrix(self):
152 sqX=self.x*self.x 153 sqY=self.y*self.y 154 sqZ=self.z*self.z 155 xy=self.x*self.y 156 xz=self.x*self.z 157 yz=self.y*self.z 158 wx=self.w*self.x 159 wy=self.w*self.y 160 wz=self.w*self.z 161 return numpy.array([ 162 # 1 163 [1-2*sqY-2*sqZ, 2*xy+2*wz, 2*xz-2*wy, 0], 164 # 2 165 [2*xy-2*wz, 1-2*sqX-2*sqZ, 2*yz+2*wx, 0], 166 # 3 167 [2*xz+2*wy, 2*yz-2*wx, 1-2*sqX-2*sqY, 0], 168 # 4 169 [0, 0, 0, 1]], 170 'f')
171
172 - def getRHMatrix(self):
173 x=-self.x 174 y=-self.y 175 z=self.z 176 w=self.w 177 sqX=x*x 178 sqY=y*y 179 sqZ=z*z 180 xy=x*y 181 xz=x*z 182 yz=y*z 183 wx=w*x 184 wy=w*y 185 wz=w*z 186 return numpy.array([ 187 # 1 188 [1-2*sqY-2*sqZ, 2*xy+2*wz, 2*xz-2*wy, 0], 189 # 2 190 [2*xy-2*wz, 1-2*sqX-2*sqZ, 2*yz+2*wx, 0], 191 # 3 192 [2*xz+2*wy, 2*yz-2*wx, 1-2*sqX-2*sqY, 0], 193 # 4 194 [0, 0, 0, 1]], 195 'f')
196
197 - def getRollPitchYaw(self):
198 m=self.getMatrix() 199 200 roll = math.atan2(m[0, 1], m[1, 1]) 201 pitch = math.asin(-m[2, 1]) 202 yaw = math.atan2(m[2, 0], m[2, 2]) 203 204 if math.fabs(math.cos(pitch)) < 1.0e-6: 205 roll += m[0, 1] > math.pi if 0.0 else -math.pi 206 yaw += m[2, 0] > math.pi if 0.0 else -math.pi 207 208 return roll, pitch, yaw
209
210 - def getSqNorm(self):
211 return self.x*self.x+self.y*self.y+self.z*self.z+self.w*self.w
212
213 - def getNormalized(self):
214 f=1.0/self.getSqNorm() 215 q=Quaternion(self.x*f, self.y*f, self.z*f, self.w*f) 216 return q
217
218 - def getRightHanded(self):
219 "swap y and z axis" 220 return Quaternion(-self.x, -self.z, -self.y, self.w)
221 222 @staticmethod
223 - def createFromAxisAngle(axis, rad):
224 q=Quaternion() 225 half_rad=rad/2.0 226 c=math.cos(half_rad) 227 s=math.sin(half_rad) 228 return Quaternion(axis[0]*s, axis[1]*s, axis[2]*s, c)
229
230 231 -class RGB(object):
232 """ 233 material color 234 """ 235 __slots__=['r', 'g', 'b']
236 - def __init__(self, r=0, g=0, b=0):
237 self.r=r 238 self.g=g 239 self.b=b
240
241 - def __eq__(self, rhs):
242 return self.r==rhs.r and self.g==rhs.g and self.b==rhs.b
243
244 - def __ne__(self, rhs):
245 return not self.__eq__(rhs)
246
247 - def __getitem__(self, key):
248 if key==0: 249 return self.r 250 elif key==1: 251 return self.g 252 elif key==2: 253 return self.b 254 else: 255 assert(False)
256
257 258 -class RGBA(object):
259 """ 260 material color 261 """ 262 __slots__=['r', 'g', 'b', 'a']
263 - def __init__(self, r=0, g=0, b=0, a=1):
264 self.r=r 265 self.g=g 266 self.b=b 267 self.a=a
268
269 - def __eq__(self, rhs):
270 return self.r==rhs.r and self.g==rhs.g and self.b==rhs.b and self.a==rhs.a
271
272 - def __ne__(self, rhs):
273 return not self.__eq__(rhs)
274
275 - def __getitem__(self, key):
276 if key==0: 277 return self.r 278 elif key==1: 279 return self.g 280 elif key==2: 281 return self.b 282 elif key==3: 283 return self.a 284 else: 285 assert(False)
286 287 288 """ 289 utilities 290 """
291 -def radian_to_degree(x):
292 """darian to deglee""" 293 294 return x/math.pi * 180.0
295
296 297 -class ParseException(Exception):
298 """ 299 Exception in reader 300 """ 301 pass
302
303 304 -def readall(path):
305 """read all bytes from path 306 """ 307 with open(path, "rb") as f: 308 return f.read()
309
310 311 -class BinaryReader(object):
312 """general BinaryReader 313 """
314 - def __init__(self, ios):
315 current=ios.tell() 316 #ios.seek(0, io.SEEK_END) 317 ios.seek(0, 2) 318 self.end=ios.tell() 319 ios.seek(current) 320 self.ios=ios
321
322 - def is_end(self):
323 #print(self.ios.tell(), self.end) 324 return self.ios.tell()>=self.end
325 #return not self.ios.readable() 326
327 - def unpack(self, fmt, size):
328 result=struct.unpack(fmt, self.ios.read(size)) 329 return result[0]
330
331 - def read_int(self, size):
332 if size==1: 333 return self.unpack("b", size) 334 if size==2: 335 return self.unpack("h", size) 336 if size==4: 337 return self.unpack("i", size) 338 print("not reach here") 339 raise ParseException("invalid int size: "+size)
340
341 - def read_uint(self, size):
342 if size==1: 343 return self.unpack("B", size) 344 if size==2: 345 return self.unpack("H", size) 346 if size==4: 347 return self.unpack("I", size) 348 print("not reach here") 349 raise ParseException("invalid int size: "+size)
350
351 - def read_float(self):
352 return self.unpack("f", 4)
353
354 - def read_vector2(self):
355 return Vector2( 356 self.read_float(), 357 self.read_float() 358 )
359
360 - def read_vector3(self):
361 return Vector3( 362 self.read_float(), 363 self.read_float(), 364 self.read_float() 365 )
366
367 - def read_rgba(self):
368 return RGBA( 369 self.read_float(), 370 self.read_float(), 371 self.read_float(), 372 self.read_float() 373 )
374
375 - def read_rgb(self):
376 return RGB( 377 self.read_float(), 378 self.read_float(), 379 self.read_float() 380 )
381
382 383 -class WriteException(Exception):
384 """ 385 Exception in writer 386 """ 387 pass
388
389 390 -class BinaryWriter(object):
391 - def __init__(self, ios):
392 self.ios=ios
393
394 - def write_bytes(self, v, size=None):
395 if size: 396 self.ios.write(struct.pack("={0}s".format(size), v)) 397 else: 398 self.ios.write(v)
399
400 - def write_float(self, v):
401 self.ios.write(struct.pack("f", v))
402
403 - def write_int(self, v, size):
404 if size==1: 405 self.ios.write(struct.pack("b", v)) 406 elif size==2: 407 self.ios.write(struct.pack("h", v)) 408 elif size==4: 409 self.ios.write(struct.pack("i", v)) 410 else: 411 raise WriteError("invalid int uint size")
412
413 - def write_uint(self, v, size):
414 if size==1: 415 self.ios.write(struct.pack("B", v)) 416 elif size==2: 417 self.ios.write(struct.pack("H", v)) 418 elif size==4: 419 self.ios.write(struct.pack("I", v)) 420 else: 421 raise WriteError("invalid int uint size")
422
423 - def write_vector2(self, v):
424 self.ios.write(struct.pack("=2f", v.x, v.y))
425
426 - def write_vector3(self, v):
427 self.ios.write(struct.pack("=3f", v.x, v.y, v.z))
428
429 - def write_rgb(self, v):
430 self.ios.write(struct.pack("=3f", v.r, v.g, v.b))
431
432 - def write_rgba(self, v):
433 self.ios.write(struct.pack("=4f", v.r, v.g, v.b, v.a))
434