util.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. try:
  2. from ctypes import c_float, c_int, c_double
  3. except ImportError:
  4. pass
  5. import pyglet.gl as pgl
  6. from sympy.core import S
  7. def get_model_matrix(array_type=c_float, glGetMethod=pgl.glGetFloatv):
  8. """
  9. Returns the current modelview matrix.
  10. """
  11. m = (array_type*16)()
  12. glGetMethod(pgl.GL_MODELVIEW_MATRIX, m)
  13. return m
  14. def get_projection_matrix(array_type=c_float, glGetMethod=pgl.glGetFloatv):
  15. """
  16. Returns the current modelview matrix.
  17. """
  18. m = (array_type*16)()
  19. glGetMethod(pgl.GL_PROJECTION_MATRIX, m)
  20. return m
  21. def get_viewport():
  22. """
  23. Returns the current viewport.
  24. """
  25. m = (c_int*4)()
  26. pgl.glGetIntegerv(pgl.GL_VIEWPORT, m)
  27. return m
  28. def get_direction_vectors():
  29. m = get_model_matrix()
  30. return ((m[0], m[4], m[8]),
  31. (m[1], m[5], m[9]),
  32. (m[2], m[6], m[10]))
  33. def get_view_direction_vectors():
  34. m = get_model_matrix()
  35. return ((m[0], m[1], m[2]),
  36. (m[4], m[5], m[6]),
  37. (m[8], m[9], m[10]))
  38. def get_basis_vectors():
  39. return ((1, 0, 0), (0, 1, 0), (0, 0, 1))
  40. def screen_to_model(x, y, z):
  41. m = get_model_matrix(c_double, pgl.glGetDoublev)
  42. p = get_projection_matrix(c_double, pgl.glGetDoublev)
  43. w = get_viewport()
  44. mx, my, mz = c_double(), c_double(), c_double()
  45. pgl.gluUnProject(x, y, z, m, p, w, mx, my, mz)
  46. return float(mx.value), float(my.value), float(mz.value)
  47. def model_to_screen(x, y, z):
  48. m = get_model_matrix(c_double, pgl.glGetDoublev)
  49. p = get_projection_matrix(c_double, pgl.glGetDoublev)
  50. w = get_viewport()
  51. mx, my, mz = c_double(), c_double(), c_double()
  52. pgl.gluProject(x, y, z, m, p, w, mx, my, mz)
  53. return float(mx.value), float(my.value), float(mz.value)
  54. def vec_subs(a, b):
  55. return tuple(a[i] - b[i] for i in range(len(a)))
  56. def billboard_matrix():
  57. """
  58. Removes rotational components of
  59. current matrix so that primitives
  60. are always drawn facing the viewer.
  61. |1|0|0|x|
  62. |0|1|0|x|
  63. |0|0|1|x| (x means left unchanged)
  64. |x|x|x|x|
  65. """
  66. m = get_model_matrix()
  67. # XXX: for i in range(11): m[i] = i ?
  68. m[0] = 1
  69. m[1] = 0
  70. m[2] = 0
  71. m[4] = 0
  72. m[5] = 1
  73. m[6] = 0
  74. m[8] = 0
  75. m[9] = 0
  76. m[10] = 1
  77. pgl.glLoadMatrixf(m)
  78. def create_bounds():
  79. return [[S.Infinity, S.NegativeInfinity, 0],
  80. [S.Infinity, S.NegativeInfinity, 0],
  81. [S.Infinity, S.NegativeInfinity, 0]]
  82. def update_bounds(b, v):
  83. if v is None:
  84. return
  85. for axis in range(3):
  86. b[axis][0] = min([b[axis][0], v[axis]])
  87. b[axis][1] = max([b[axis][1], v[axis]])
  88. def interpolate(a_min, a_max, a_ratio):
  89. return a_min + a_ratio * (a_max - a_min)
  90. def rinterpolate(a_min, a_max, a_value):
  91. a_range = a_max - a_min
  92. if a_max == a_min:
  93. a_range = 1.0
  94. return (a_value - a_min) / float(a_range)
  95. def interpolate_color(color1, color2, ratio):
  96. return tuple(interpolate(color1[i], color2[i], ratio) for i in range(3))
  97. def scale_value(v, v_min, v_len):
  98. return (v - v_min) / v_len
  99. def scale_value_list(flist):
  100. v_min, v_max = min(flist), max(flist)
  101. v_len = v_max - v_min
  102. return list(scale_value(f, v_min, v_len) for f in flist)
  103. def strided_range(r_min, r_max, stride, max_steps=50):
  104. o_min, o_max = r_min, r_max
  105. if abs(r_min - r_max) < 0.001:
  106. return []
  107. try:
  108. range(int(r_min - r_max))
  109. except (TypeError, OverflowError):
  110. return []
  111. if r_min > r_max:
  112. raise ValueError("r_min cannot be greater than r_max")
  113. r_min_s = (r_min % stride)
  114. r_max_s = stride - (r_max % stride)
  115. if abs(r_max_s - stride) < 0.001:
  116. r_max_s = 0.0
  117. r_min -= r_min_s
  118. r_max += r_max_s
  119. r_steps = int((r_max - r_min)/stride)
  120. if max_steps and r_steps > max_steps:
  121. return strided_range(o_min, o_max, stride*2)
  122. return [r_min] + list(r_min + e*stride for e in range(1, r_steps + 1)) + [r_max]
  123. def parse_option_string(s):
  124. if not isinstance(s, str):
  125. return None
  126. options = {}
  127. for token in s.split(';'):
  128. pieces = token.split('=')
  129. if len(pieces) == 1:
  130. option, value = pieces[0], ""
  131. elif len(pieces) == 2:
  132. option, value = pieces
  133. else:
  134. raise ValueError("Plot option string '%s' is malformed." % (s))
  135. options[option.strip()] = value.strip()
  136. return options
  137. def dot_product(v1, v2):
  138. return sum(v1[i]*v2[i] for i in range(3))
  139. def vec_sub(v1, v2):
  140. return tuple(v1[i] - v2[i] for i in range(3))
  141. def vec_mag(v):
  142. return sum(v[i]**2 for i in range(3))**(0.5)