def pickup(event, right): """ Function to get the Name Stack right es si el boton pulsado es el derecho El viewport[3]-event.y() creo que es porque la medida de las Y está invertida Los problemas que tenía con windows de tener que hacer varios click se corrigieron sustituyendo la región de selección de 1,1 a 5,5 """ viewport = glGetIntegerv(GL_VIEWPORT) glMatrixMode(GL_PROJECTION) glPushMatrix() glSelectBuffer(512) glRenderMode(GL_SELECT) glLoadIdentity() gluPickMatrix(event.x(), viewport[3] - event.y(), 4, 4, viewport) aspect = viewport[2] / viewport[3] gluPerspective(60, aspect, 1.0, 400) glMatrixMode(GL_MODELVIEW) self.paintGL() glMatrixMode(GL_PROJECTION) if right == False: parseLeftButtonNameStack(glRenderMode(GL_RENDER)) else: parseRightButtonNameStack(glRenderMode(GL_RENDER)) glPopMatrix() glMatrixMode(GL_MODELVIEW)
def draw(self): # this code is modified from GLPane.drawcompass glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() glMatrixMode(GL_PROJECTION) # WARNING: we're now in nonstandard matrixmode (for sake of gluPickMatrix and glOrtho -- needed??##k) glPushMatrix() glLoadIdentity() try: glpane = self.env.glpane ## aspect = 1.0 ###WRONG -- should use glpane.aspect (which exists as of 070919) aspect = glpane.aspect # revised by bruce 070919, UNTESTED corner = self.corner delegate = self.delegate ###e should get glpane to do this for us (ie call a method in it to do this if necessary) # (this code is copied from it) glselect = glpane.current_glselect if glselect: # print "%r (ipath %r) setting up gluPickMatrix" % (self, self.ipath) x,y,w,h = glselect gluPickMatrix( x,y, w,h, glGetIntegerv( GL_VIEWPORT ) #k is this arg needed? it might be the default... ) # the first three cases here are still ###WRONG if corner == UPPER_RIGHT: glOrtho(-50*aspect, 5.5*aspect, -50, 5.5, -5, 500) # Upper Right elif corner == UPPER_LEFT: glOrtho(-5*aspect, 50.5*aspect, -50, 5.5, -5, 500) # Upper Left elif corner == LOWER_LEFT: glOrtho(-5*aspect, 50.5*aspect, -5, 50.5, -5, 500) # Lower Left else: ## glOrtho(-50*aspect, 5.5*aspect, -5, 50.5, -5, 500) # Lower Right ## glOrtho(-50*aspect, 0, 0, 50, -5, 500) # Lower Right [used now] -- x from -50*aspect to 0, y (bot to top) from 0 to 50 glOrtho(-glpane.width * PIXELS, 0, 0, glpane.height * PIXELS, -5, 500) # approximately right for the checkbox, but I ought to count pixels to be sure (note, PIXELS is a pretty inexact number) glMatrixMode(GL_MODELVIEW) ###k guess 061210 at possible bugfix (and obviously needed in general) -- # do this last to leave the matrixmode standard # (status of bugs & fixes unclear -- hard to test since even Highlightable(projection=True) w/o any change to # projection matrix (test _9cx) doesn't work!) offset = (-delegate.bright, delegate.bbottom) # only correct for LOWER_RIGHT glTranslatef(offset[0], offset[1], 0) self.drawkid( delegate) ## delegate.draw() finally: glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW) # be sure to do this last, to leave the matrixmode standard glPopMatrix() return
def setSelectMat(self, selectPoint, w, h, pickSize=5): '''Given the selection point, computes the projection matrices for the selection matrix. @param: selectPoint The point, in screen space, at which the selection is occuring. @param: w The viewport width. @param: h The viewport height. @param: pickSize The size of the box that selectables will be considered. ''' glMatrixMode(GL_PROJECTION) glLoadIdentity() viewport = (0, 0, w, h) gluPickMatrix(selectPoint[0], h - selectPoint[1], pickSize, pickSize, viewport) self._setProjMat(w, h)
def _setup_projection( self, glselect=False ): #bruce 050608 split this out; 050615 revised docstring """ Set up standard projection matrix contents using aspect, vdist, and some attributes of self. @warning: leaves matrixmode as GL_PROJECTION. Optional arg glselect should be False (default) or a 4-tuple (to prepare for GL_SELECT picking). """ glMatrixMode(GL_PROJECTION) glLoadIdentity() scale = self.scale #bruce 050608 used this to clarify following code near, far = self.near, self.far #bruce 080219 moved these from one of two callers into here, # to fix bug when insert from partlib is first operation in NE1 self.aspect = (self.width + 0.0) / (self.height + 0.0) self.vdist = 6.0 * scale if glselect: x, y, w, h = glselect gluPickMatrix( x, y, w, h, glGetIntegerv( GL_VIEWPORT ) #k is this arg needed? it might be the default... ) if self.ortho: glOrtho(-scale * self.aspect, scale * self.aspect, -scale, scale, self.vdist * near, self.vdist * far) else: glFrustum(-scale * near * self.aspect, scale * near * self.aspect, -scale * near, scale * near, self.vdist * near, self.vdist * far) return
def setSelectMatRegion(self, x0, y0, x1, y1, w, h): '''Given the selection point, computes the projection matrices for the selection matrix. @param: x0 The minimum x-value of the rectangular region. @param: y0 The minimum y-value of the rectangular region. @param: x1 The maximum x-value of the rectangular region. @param: y1 The amximum y-value of the rectangular region. @param: w The viewport width. @param: h The viewport height. ''' dx = abs(x1 - x0) dy = abs(y1 - y0) x = (x0 + x1) * 0.5 y = (y0 + y1) * 0.5 glMatrixMode(GL_PROJECTION) glLoadIdentity() viewport = (0, 0, w, h) gluPickMatrix(x, y, dx, dy, viewport) self._setProjMat(w, h)
def _setup_projection(self, glselect=False): ### WARNING: This is not actually private! TODO: rename it. """ Set up standard projection matrix contents using various attributes of self (aspect, vdist, scale, zoomFactor). Also reads the current OpenGL viewport bounds in window coordinates. (Warning: leaves matrixmode as GL_PROJECTION.) @param glselect: False (default) normally, or a 4-tuple (format not documented here) to prepare for GL_SELECT picking by calling gluPickMatrix(). If you are really going to draw in the pick window (for GL_RENDER and glReadPixels picking, rather than GL_SELECT picking), don't forget to set the glViewport *after* calling _setup_projection. Here's why: gluPickMatrix needs to know the current *whole-window* viewport, in order to set up a projection matrix to map a small portion of it to the clipping boundaries for GL_SELECT. From the gluPickMatrix doc page: viewport: Specifies the current viewport (as from a glGetIntegerv call). Description: gluPickMatrix creates a projection matrix that can be used to restrict drawing to a small region of the viewport. In the graphics pipeline, the clipper actually works in homogeneous coordinates, clipping polygons to the {X,Y}==+-W boundaries. This saves the work of doing the homogeneous division: {X,Y}/W==+-1.0, (and avoiding problems when W is zero for points on the eye plane in Z,) but it comes down to the same thing as clipping to X,Y==+-1 in orthographic. So the projection matrix decides what 3D model-space planes map to +-1 in X,Y. (I think it maps [near,far] to [0,1] in Z, because they're not clipped symmetrically.) Then glViewport sets the hardware transform that determines where the +-1 square of clipped output goes in screen pixels within the window. Normally you don't actually draw pixels while picking in GL_SELECT mode because the pipeline outputs hits after the clipping stage, so gluPickMatrix only reads the viewport and sets the projection matrix. """ #bruce 080912 moved this from GLPane into GLPane_minimal glMatrixMode(GL_PROJECTION) glLoadIdentity() scale = self.scale * self.zoomFactor near, far = self.near, self.far aspect = self.aspect vdist = self.vdist if glselect: x, y, w, h = glselect gluPickMatrix( x, y, w, h, glGetIntegerv( GL_VIEWPORT ) #k is this arg needed? it might be the default... ) if self.ortho: glOrtho(-scale * aspect, scale * aspect, -scale, scale, vdist * near, vdist * far) else: glFrustum(-scale * near * aspect, scale * near * aspect, -scale * near, scale * near, vdist * near, vdist * far) return
def draw(self, width, height, selection_box=None): scene = context.application.scene camera = context.application.camera glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) if selection_box is not None: # set up a select buffer glSelectBuffer(self.select_buffer_size) glRenderMode(GL_SELECT) glInitNames() glMatrixMode(GL_PROJECTION) glLoadIdentity() # Apply the pick matrix if selecting if selection_box is not None: gluPickMatrix(0.5 * (selection_box[0] + selection_box[2]), height - 0.5 * (selection_box[1] + selection_box[3]), selection_box[2] - selection_box[0] + 1, selection_box[3] - selection_box[1] + 1, (0, 0, width, height)) # Apply the frustum matrix znear = camera.znear zfar = camera.znear + camera.window_depth if width > height: w = 0.5 * float(width) / float(height) h = 0.5 else: w = 0.5 h = 0.5 * float(height) / float(width) if znear > 0.0: glFrustum(-w * camera.window_size, w * camera.window_size, -h * camera.window_size, h * camera.window_size, znear, zfar) else: glOrtho(-w * camera.window_size, w * camera.window_size, -h * camera.window_size, h * camera.window_size, znear, zfar) glMatrixMode(GL_MODELVIEW) glLoadIdentity() # Move to eye position (reverse) gl_apply_inverse(camera.eye) glTranslatef(0.0, 0.0, -znear) # Draw the rotation center, only when realy drawing objects: if selection_box is None: glMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) glShadeModel(GL_SMOOTH) self.call_list(scene.rotation_center_list) # Now rotate to the model frame and move back to the model center (reverse) gl_apply_inverse(camera.rotation) # Then bring the rotation center at the right place (reverse) gl_apply_inverse(camera.rotation_center) gl_apply_inverse(scene.model_center) scene.draw() if selection_box is not None: # now let the caller analyze the hits by returning the selection # buffer. Note: The selection buffer can be used as an iterator # over 3-tupples (near, far, names) where names is tuple that # contains the gl_names associated with the encountered vertices. return glRenderMode(GL_RENDER) else: # draw the interactive tool (e.g. selection rectangle): glCallList(self.tool.total_list)