def move(self, delta_x, delta_y, buttons, modifiers): # user is dragging to = (self.at - self.eye) distance = to.length() if int(buttons) & Qt.LeftButton and not int(modifiers) & Qt.ShiftModifier: right = QVector3D.crossProduct(to, self.up) right = right.normalized() up = QVector3D.crossProduct(right, to).normalized() translation = right*(delta_x*distance)\ + up*(delta_y*distance) self.eye -= translation*5 # correct eye position to maintain distance to = (self.at - self.eye) self.eye = self.at - to.normalized()*distance self.up = QVector3D.crossProduct(right, to).normalized() elif int(buttons) & Qt.MiddleButton or (int(buttons) & Qt.LeftButton and int(modifiers) & Qt.ShiftModifier): right = QVector3D.crossProduct(to, self.up).normalized() up = QVector3D.crossProduct(right, to).normalized() translation = right*(delta_x*distance)\ + up*(delta_y*distance) self.at -= translation self.eye -= translation elif int(buttons) & Qt.RightButton : translation = to*delta_y self.eye -= translation
def addVertex(self, v, n, startIndex, apex=False): """Add the vertex and associated normal. v -- [x, y, z] n -- [i, j, k], normal of vertex's parent triangle or an apex normal as described below startIndex -- index where vertex's Patch starts apex -- If True, the vertex is the apex of a cone. Its associated normal (n) will have been pre-calculated. v and n will be appended without any further checks or normal sums. """ for vv in self._sharedVertices[-1::-1]: if self.verticesEqual(v, vv): break else: self._sharedVertices.append(v) if not apex: # blend with the previous patch? startIndex = min(startIndex, self._prevPatchStartIndex) i = self._nVertices - 1 while i >= startIndex: if self.verticesEqual(self._vertices[i], v): # vertex found # sum its normal with the duplicate vertex's normal nn = QVector3D(*self._normals[i]) nn += QVector3D(*n) nn.normalize() self._normals[i] = [nn.x(), nn.y(), nn.z()] return i i -= 1 # vertex not found or it's an apex vertex self._vertices.append(v) self._normals.append(n) self._nVertices += 1 return self._nVertices - 1
def __init__(self, parent=None): ''' Viewer's Constructor ''' frmt = QGLFormat() frmt.setSampleBuffers(True) super(OGLViewer, self).__init__(frmt, parent) #self.setMouseTracking (True) self.__mouse = QCursor() self.setCursor(Qt.OpenHandCursor) self.setFocusPolicy(Qt.ClickFocus) self.__Ctrl_or_Meta_key_pressed = False self.__Alt_key_pressed = False self.__w = 720 self.__h = 450 self._init_camera_vars() self._init_objec_vars() # matrix changed signal. The signal's payload is the matrix itself. self.__GLMatrixChanged = SIGNAL("MatrixChanged (PyQt_PyObject)") self.__compo_light_pos = QVector3D(.3, .2, .1) self.__AmbientMaterial = QVector3D(.2, .2, .2)
def intersectRayTriangles(self, orig, dir): ''' method dealing with ray-triangles intersections. @param orig 3-list @param dir 3-list @return closest_intersection_param float ''' closest_intersection_param = None # closest intersection to camera origin. intersections = [] orig_v = QVector3D(orig[0], orig[1], orig[2]) dir_v = QVector3D(dir[0], dir[1], dir[2]) intersections_list = [] for pl in self.__poly_list_e: isect_t = self.intersect(orig_v, dir_v, pl) if isect_t != None: intersections_list.append([pl, isect_t]) # order the intersections_list tmp = 100000 if len(intersections_list) > 0: for isectn in intersections_list: if isectn[1] < tmp: tmp = isectn[1] closest_intersection_param = tmp return closest_intersection_param
def setParent(self, parent): self.parent = parent self.parent.pattern.clearTraps() rc = self.parent.cgh.rc r1 = rc + QVector3D(100, 0, 0) r2 = rc - QVector3D(0, 100, 0) r = [r1, r2] self.parent.pattern.createTraps(r)
def reset(self, other=None): if other is None: self.at = QVector3D(self.at0) self.eye = QVector3D(self.eye0) self.up = QVector3D(self.up0) else: self.at = other.at self.eye = other.eye self.up = other.up
def __init__(self): ''' Model constructor. ''' self.__pid = -1 # polygon id counter self.__poly_list = [] # by poly I really mean triangle. self.addIcosahedron(QVector3D(5, 3, 1), QVector3D(2, 2, 2)) self.addIcosahedron(QVector3D(-2, -2, 0), QVector3D(4, 4, 4))
def apply_transformation(self): min_vec = QVector3D(self._min.x(), self._min.y(), self._min.z()) max_vec = QVector3D(self._max.x(), self._max.y(), self._max.z()) min_vec = self._model2world_matrix * min_vec max_vec = self._model2world_matrix * max_vec from app.geoms.point import Vector3 self._min = Vector3(min_vec.x(), min_vec.y(), min_vec.z()) self._max = Vector3(max_vec.x(), max_vec.y(), max_vec.z())
def addIcosahedron(self, pos, scale): ''' this method generates a icosahedron. Kudos to The little Grasshopper. http://prideout.net/blog/?p=48 @param pos QVector3D @param scale QVector3D ''' p0 = pos.x() p1 = pos.y() p2 = pos.z() s0 = scale.x() s1 = scale.y() s2 = scale.z() faces = [ 2, 1, 0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 1, 5, 0, 11, 6, 7, 11, 7, 8, 11, 8, 9, 11, 9, 10, 11, 10, 6, 1, 2, 6, 2, 3, 7, 3, 4, 8, 4, 5, 9, 5, 1, 10, 2, 7, 6, 3, 8, 7, 4, 9, 8, 5, 10, 9, 1, 6, 10 ] verts = [ 0.0, 0.0, 1.0, 0.894, 0.0, 0.447, 0.276, 0.851, 0.447, -0.724, 0.526, 0.447, -0.724, -0.526, 0.447, 0.276, -0.851, 0.447, 0.724, 0.526, -0.447, -0.276, 0.851, -0.447, -0.894, 0.000, -0.447, -0.276, -0.851, -0.447, 0.724, -0.526, -0.447, 0.0, 0.0, -1.0 ] for i in range(0, len(faces), 3): fi = faces[i] * 3 fi1 = faces[i + 1] * 3 fi2 = faces[i + 2] * 3 a = QVector3D(verts[fi] * s0 + p0, verts[fi + 1] * s1 + p1, verts[fi + 2] * s2 + p2) b = QVector3D(verts[fi1] * s0 + p0, verts[fi1 + 1] * s1 + p1, verts[fi1 + 2] * s2 + p2) c = QVector3D(verts[fi2] * s0 + p0, verts[fi2 + 1] * s1 + p1, verts[fi2 + 2] * s2 + p2) self.__poly_list.append([ a, b, c, # 3 vertices QVector3D.normal(a, b), # normal to vector self.getNewId() ]) # polygon's id.
def renderNormals(self): gl.glDisable(gl.GL_LIGHTING) gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) gl.glDisable(gl.GL_LINE_SMOOTH) gl.glColor(0, 1, 0, 1) gl.glBegin(gl.GL_LINES) factor = max(*self._mesh._bbox.size()) * 0.01 for i in self._indices: v = self._mesh._vertices[i] n = self._mesh._normals[i] ep = QVector3D(*v) + QVector3D(*n) * factor gl.glVertex3f(*v) gl.glVertex3f(ep.x(), ep.y(), ep.z()) gl.glEnd() gl.glEnable(gl.GL_LINE_SMOOTH)
def _init_camera_vars(self): ''' static method. It initializes the math variables. ''' self.__compo_mtools = MathTools.Tools() self.__curr_angles = QPoint(0, 0) self.__last_pos = QPoint(0, 0) self.__delta = QPoint(0, 0) self.__orig = QVector3D(0.0, 0.0, 0.0) self.__cam_dist = 0.0 self.__z_near = 0.1 self.__z_far = 2000.0 self.__fovy = 45.0 self.__angle = self.__compo_mtools.getAngle(self.__fovy) self.__norm_mtx = QMatrix4x4() #(GLdouble * 16)() self.__norm_mtx.setToIdentity() self.__mtx = QMatrix4x4() #(GLdouble * 16)() self.__mtx.setToIdentity() self.__aspect_ratio = float(self.__w) / float(self.__h) self.__camera_list = []
def addIcosahedron (self, pos, scale): ''' this method generates a icosahedron. Kudos to The little Grasshopper. http://prideout.net/blog/?p=48 @param pos QVector3D @param scale QVector3D ''' p0=pos.x(); p1=pos.y(); p2=pos.z() s0=scale.x(); s1=scale.y(); s2=scale.z() faces = [2,1,0, 3,2,0, 4,3,0, 5,4,0, 1,5,0, 11,6,7, 11,7,8, 11,8,9, 11,9,10, 11,10,6, 1,2,6, 2,3,7, 3,4,8, 4,5,9, 5,1,10, 2,7,6, 3,8,7, 4,9,8, 5,10,9, 1,6,10] verts = [0.0,0.0,1.0, 0.894,0.0,0.447, 0.276,0.851,0.447, -0.724,0.526,0.447, -0.724,-0.526,0.447, 0.276,-0.851,0.447, 0.724,0.526,-0.447, -0.276,0.851,-0.447, -0.894,0.000,-0.447, -0.276,-0.851,-0.447, 0.724,-0.526,-0.447, 0.0,0.0,-1.0] for i in range (0, len(faces), 3): fi = faces[i]*3 fi1 = faces[i+1]*3 fi2 = faces[i+2]*3 a = QVector3D (verts[fi] *s0+p0, verts[fi+1] *s1+p1, verts[fi+2] *s2+p2) b = QVector3D (verts[fi1]*s0+p0, verts[fi1+1]*s1+p1, verts[fi1+2]*s2+p2) c = QVector3D (verts[fi2]*s0+p0, verts[fi2+1]*s1+p1, verts[fi2+2]*s2+p2) self.__poly_list.append ([a, b, c, # 3 vertices QVector3D.normal(a,b), # normal to vector self.getNewId()]) # polygon's id.
def frame(self): x = QVector3D(1.0, 0.0, 0.0) y = QVector3D(0.0, 1.0, 0.0) z = QVector3D(0.0, 0.0, 1.0) m = QMatrix4x4() m.rotate(self.y_rot, y) x = m * x z = m * z m = QMatrix4x4() m.rotate(self.x_rot, x) y = m * y z = m * z return (x, y, z)
def __init__(self): self.center = QVector3D(0.0, 0.0, 0.0) self.focal_len = 5.0 self.y_rot = 0.0 self.x_rot = 0.0 self.fovy = 60.0 self.aspect = 1.0 self.znear = 0.1 self.zfar = 1000.0
def intersect (self, orig_v, dir_v, pl): ''' method performing ray-triangle intersection (Moller-Trumbore algorithm) @param orig QVector3D @param dir QVector3D @return isect_t float or None ''' e1 = pl[1] - pl[0] e2 = pl[2] - pl[0] p = QVector3D.crossProduct (dir_v, e2) p_dot_e1 = QVector3D.dotProduct (p, e1) if p_dot_e1 == 0: return None inv_p_dot_e1 = 1.0 / p_dot_e1 t = orig_v - pl[0] isect_u = inv_p_dot_e1 * QVector3D.dotProduct (p, t) if isect_u<0 or isect_u>1: return None q = QVector3D.crossProduct (t, e1) isect_v = inv_p_dot_e1 * QVector3D.dotProduct (q, dir_v) if isect_v<0 or isect_u + isect_v>1: return None isect_t = inv_p_dot_e1 * QVector3D.dotProduct (e2, q) return isect_t
def intersect(self, orig_v, dir_v, pl): ''' method performing ray-triangle intersection (Moller-Trumbore algorithm) @param orig QVector3D @param dir QVector3D @return isect_t float or None ''' e1 = pl[1] - pl[0] e2 = pl[2] - pl[0] p = QVector3D.crossProduct(dir_v, e2) p_dot_e1 = QVector3D.dotProduct(p, e1) if p_dot_e1 == 0: return None inv_p_dot_e1 = 1.0 / p_dot_e1 t = orig_v - pl[0] isect_u = inv_p_dot_e1 * QVector3D.dotProduct(p, t) if isect_u < 0 or isect_u > 1: return None q = QVector3D.crossProduct(t, e1) isect_v = inv_p_dot_e1 * QVector3D.dotProduct(q, dir_v) if isect_v < 0 or isect_u + isect_v > 1: return None isect_t = inv_p_dot_e1 * QVector3D.dotProduct(e2, q) return isect_t
def addTri(self, a, b, c, apexVertex=None): """Add a triangle. a, b, c -- [x, y, z] The three vertices, given in CCLW winding order. apexVertex -- [x, y, z] The apex vertice, for a cone tip. Must be the same as a, b, c, or None. Return None. """ # triangle normal n = QVector3D.normal(QVector3D(*a), QVector3D(*b), QVector3D(*c)) n = [n.x(), n.y(), n.z()] self._indices.append(self._mesh.addVertex(a, n, self._startIndex, apexVertex == a)) self._indices.append(self._mesh.addVertex(b, n, self._startIndex, apexVertex == b)) self._indices.append(self._mesh.addVertex(c, n, self._startIndex, apexVertex == c)) self._nTris += 1
def dotask(self): sz = self.font.getsize(self.text) img = Image.new('L', sz, 0) draw = ImageDraw.Draw(img) draw.text((0, 0), self.text, font=self.font, fill=255) bmp = np.array(img) > 128 bmp = bmp[::-1] sz = self.parent.screen.video.device.size y, x = np.nonzero(bmp) x = x + normal(scale=self.fuzz, size=len(x)) - np.mean(x) y = y + normal(scale=self.fuzz, size=len(y)) - np.mean(y) x = x * self.spacing + sz.width() / 2 y = y * self.spacing + sz.height() / 2 p = list(map(lambda x, y: QVector3D(x, y, 0), x, y)) self.parent.pattern.createTraps(p)
def displayObjects (self): glClear (GL_COLOR_BUFFER_BIT) glEnable (GL_DEPTH_TEST) glDepthMask (GL_TRUE) #glEnable (GL_CULL_FACE) for poly in self.__poly_list: p0 = poly[0]; p1 = poly[1]; p2 = poly[2] glBegin (GL_TRIANGLES) col = .4 + 0.5*QVector3D.dotProduct (poly[3], self.__compo_light_pos) glColor3f (col, col, col) glVertex3f (p0.x(), p0.y(), p0.z()) glVertex3f (p1.x(), p1.y(), p1.z()) glVertex3f (p2.x(), p2.y(), p2.z()) glEnd ()
def displayObjects(self): glClear(GL_COLOR_BUFFER_BIT) glEnable(GL_DEPTH_TEST) glDepthMask(GL_TRUE) #glEnable (GL_CULL_FACE) for poly in self.__poly_list: p0 = poly[0] p1 = poly[1] p2 = poly[2] glBegin(GL_TRIANGLES) col = .4 + 0.5 * QVector3D.dotProduct(poly[3], self.__compo_light_pos) glColor3f(col, col, col) glVertex3f(p0.x(), p0.y(), p0.z()) glVertex3f(p1.x(), p1.y(), p1.z()) glVertex3f(p2.x(), p2.y(), p2.z()) glEnd()
def initialize(self): print('createtrap') pos = QVector3D(self.x, self.y, self.z) self.parent.pattern.createTraps(pos) self.done = True
def world_coords(self): return self._model2world_matrix * QVector3D(0.0, 0.0, 0.0)
def __init__(self, eye, at, up=QVector3D(0, 0, 1)): self.at0 = QVector3D(at) self.eye0 = QVector3D(eye) self.up0 = QVector3D(up) self.reset()
def apply_transformation(self): for vertex in self.renderable_vertex_array["coords"]: vec = QVector3D(vertex[0], vertex[1], vertex[2]) vec = self._model2world_matrix * vec vertex[0], vertex[1], vertex[2] = vec.x(), vec.y(), vec.z()