try: from ctypes import c_float, c_int, c_double except ImportError: pass import pyglet.gl as pgl from sympy.core import S def get_model_matrix(array_type=c_float, glGetMethod=pgl.glGetFloatv): """ Returns the current modelview matrix. """ m = (array_type*16)() glGetMethod(pgl.GL_MODELVIEW_MATRIX, m) return m def get_projection_matrix(array_type=c_float, glGetMethod=pgl.glGetFloatv): """ Returns the current modelview matrix. """ m = (array_type*16)() glGetMethod(pgl.GL_PROJECTION_MATRIX, m) return m def get_viewport(): """ Returns the current viewport. """ m = (c_int*4)() pgl.glGetIntegerv(pgl.GL_VIEWPORT, m) return m def get_direction_vectors(): m = get_model_matrix() return ((m[0], m[4], m[8]), (m[1], m[5], m[9]), (m[2], m[6], m[10])) def get_view_direction_vectors(): m = get_model_matrix() return ((m[0], m[1], m[2]), (m[4], m[5], m[6]), (m[8], m[9], m[10])) def get_basis_vectors(): return ((1, 0, 0), (0, 1, 0), (0, 0, 1)) def screen_to_model(x, y, z): m = get_model_matrix(c_double, pgl.glGetDoublev) p = get_projection_matrix(c_double, pgl.glGetDoublev) w = get_viewport() mx, my, mz = c_double(), c_double(), c_double() pgl.gluUnProject(x, y, z, m, p, w, mx, my, mz) return float(mx.value), float(my.value), float(mz.value) def model_to_screen(x, y, z): m = get_model_matrix(c_double, pgl.glGetDoublev) p = get_projection_matrix(c_double, pgl.glGetDoublev) w = get_viewport() mx, my, mz = c_double(), c_double(), c_double() pgl.gluProject(x, y, z, m, p, w, mx, my, mz) return float(mx.value), float(my.value), float(mz.value) def vec_subs(a, b): return tuple(a[i] - b[i] for i in range(len(a))) def billboard_matrix(): """ Removes rotational components of current matrix so that primitives are always drawn facing the viewer. |1|0|0|x| |0|1|0|x| |0|0|1|x| (x means left unchanged) |x|x|x|x| """ m = get_model_matrix() # XXX: for i in range(11): m[i] = i ? m[0] = 1 m[1] = 0 m[2] = 0 m[4] = 0 m[5] = 1 m[6] = 0 m[8] = 0 m[9] = 0 m[10] = 1 pgl.glLoadMatrixf(m) def create_bounds(): return [[S.Infinity, S.NegativeInfinity, 0], [S.Infinity, S.NegativeInfinity, 0], [S.Infinity, S.NegativeInfinity, 0]] def update_bounds(b, v): if v is None: return for axis in range(3): b[axis][0] = min([b[axis][0], v[axis]]) b[axis][1] = max([b[axis][1], v[axis]]) def interpolate(a_min, a_max, a_ratio): return a_min + a_ratio * (a_max - a_min) def rinterpolate(a_min, a_max, a_value): a_range = a_max - a_min if a_max == a_min: a_range = 1.0 return (a_value - a_min) / float(a_range) def interpolate_color(color1, color2, ratio): return tuple(interpolate(color1[i], color2[i], ratio) for i in range(3)) def scale_value(v, v_min, v_len): return (v - v_min) / v_len def scale_value_list(flist): v_min, v_max = min(flist), max(flist) v_len = v_max - v_min return list(scale_value(f, v_min, v_len) for f in flist) def strided_range(r_min, r_max, stride, max_steps=50): o_min, o_max = r_min, r_max if abs(r_min - r_max) < 0.001: return [] try: range(int(r_min - r_max)) except (TypeError, OverflowError): return [] if r_min > r_max: raise ValueError("r_min cannot be greater than r_max") r_min_s = (r_min % stride) r_max_s = stride - (r_max % stride) if abs(r_max_s - stride) < 0.001: r_max_s = 0.0 r_min -= r_min_s r_max += r_max_s r_steps = int((r_max - r_min)/stride) if max_steps and r_steps > max_steps: return strided_range(o_min, o_max, stride*2) return [r_min] + list(r_min + e*stride for e in range(1, r_steps + 1)) + [r_max] def parse_option_string(s): if not isinstance(s, str): return None options = {} for token in s.split(';'): pieces = token.split('=') if len(pieces) == 1: option, value = pieces[0], "" elif len(pieces) == 2: option, value = pieces else: raise ValueError("Plot option string '%s' is malformed." % (s)) options[option.strip()] = value.strip() return options def dot_product(v1, v2): return sum(v1[i]*v2[i] for i in range(3)) def vec_sub(v1, v2): return tuple(v1[i] - v2[i] for i in range(3)) def vec_mag(v): return sum(v[i]**2 for i in range(3))**(0.5)