diff options
author | Bruce Smith <bruce@nanorex.com> | 2008-09-12 23:53:16 +0000 |
---|---|---|
committer | Bruce Smith <bruce@nanorex.com> | 2008-09-12 23:53:16 +0000 |
commit | 4d5e3638a86c321f81840ee37c7237fa9f0613f9 (patch) | |
tree | 79d7698276a33a2e140fbb9e5efd91c2e281ed8b | |
parent | 4a1877bc49f194909d41405ab1e5b3cbbf5d53f3 (diff) | |
download | nanoengineer-theirix-4d5e3638a86c321f81840ee37c7237fa9f0613f9.tar.gz nanoengineer-theirix-4d5e3638a86c321f81840ee37c7237fa9f0613f9.zip |
move some rendering setup code into GLPane_minimal from subclasses
-rwxr-xr-x | cad/src/commands/Select/Select_GraphicsMode.py | 7 | ||||
-rwxr-xr-x | cad/src/exprs/projection.py | 14 | ||||
-rwxr-xr-x | cad/src/graphics/rendering/fileIO.py | 4 | ||||
-rwxr-xr-x | cad/src/graphics/widgets/GLPane.py | 159 | ||||
-rw-r--r-- | cad/src/graphics/widgets/GLPane_lighting_methods.py | 7 | ||||
-rw-r--r-- | cad/src/graphics/widgets/GLPane_minimal.py | 171 | ||||
-rwxr-xr-x | cad/src/graphics/widgets/ThumbView.py | 129 | ||||
-rwxr-xr-x | cad/src/tools/Refactoring/make_gl_imports.py | 15 |
8 files changed, 264 insertions, 242 deletions
diff --git a/cad/src/commands/Select/Select_GraphicsMode.py b/cad/src/commands/Select/Select_GraphicsMode.py index ee5574cab..1015bdd1f 100755 --- a/cad/src/commands/Select/Select_GraphicsMode.py +++ b/cad/src/commands/Select/Select_GraphicsMode.py @@ -93,7 +93,7 @@ import foundation.env as env from utilities.debug_prefs import debug_pref from utilities.debug_prefs import Choice -from geometry.VQT import V, A, vlen +from geometry.VQT import A, vlen from graphics.behaviors.shape import SelectionShape from model.bonds import Bond @@ -642,10 +642,11 @@ class Select_basicGraphicsMode(Select_GraphicsMode_DrawMethod_preMixin, self.o.selArea_List += [selCurve_AreaPt] # Add the last point. self.o.selArea_List += [self.o.selArea_List[0]] # Close the selection area. - self.o.shape=SelectionShape(self.o.right, self.o.up, self.o.lineOfSight) + self.o.shape = SelectionShape(self.o.right, self.o.up, self.o.lineOfSight) # Create the selection shape object. - eyeball = (-self.o.quat).rot(V(0,0,6*self.o.scale)) - self.o.pov + ## eyeball = (-self.o.quat).rot(V(0,0,6*self.o.scale)) - self.o.pov + eyeball = self.o.eyeball() #bruce 080912 change, should be equivalent if self.selShape == SELSHAPE_RECT : # prepare a rectangle selection self.o.shape.pickrect(self.o.selArea_List[0], diff --git a/cad/src/exprs/projection.py b/cad/src/exprs/projection.py index b02f0cd16..08ef4f548 100755 --- a/cad/src/exprs/projection.py +++ b/cad/src/exprs/projection.py @@ -71,7 +71,6 @@ class DrawInCorner_projection(DelegatingInstanceOrExpr): 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 @@ -90,14 +89,14 @@ class DrawInCorner_projection(DelegatingInstanceOrExpr): # 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 + 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 + 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 + 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(-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) @@ -165,7 +164,6 @@ class DrawInCorner(DelegatingInstanceOrExpr): 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 @@ -205,7 +203,7 @@ class DrawInCorner(DelegatingInstanceOrExpr): ## print x1,y1,z1 x1wish = glpane.width / 2.0 * PIXELS # / 2.0 because in these coords, screen center indeed has x == y == 0 r = x1/x1wish - glScale(r,r,r) # compensate for zoom*scale in _setup_projection, for error in PIXELS, and for want_depth != cov_depth + glScale(r,r,r) # compensate for zoom * scale in _setup_projection, for error in PIXELS, and for want_depth != cov_depth ## x1 /= r ## y1 /= r z1 /= r diff --git a/cad/src/graphics/rendering/fileIO.py b/cad/src/graphics/rendering/fileIO.py index cd97e3daf..e8fe5317a 100755 --- a/cad/src/graphics/rendering/fileIO.py +++ b/cad/src/graphics/rendering/fileIO.py @@ -62,6 +62,10 @@ def writepovfile(part, glpane, filename): if aspect < 1.0: vdist = cdist / aspect eyePos = vdist * glpane.scale*glpane.out-glpane.pov + # note: this is probably the same as glpane.eyeball(), + # in perspective view, except for the aspect < 1.0 correction. + # See comments in def eyeball about whether that correction + # is needed there as well. [bruce 080912 comment] f.write("#declare cameraPosition = "+ povpoint(eyePos) + ";\n" + "\ncamera {\n location cameraPosition" + diff --git a/cad/src/graphics/widgets/GLPane.py b/cad/src/graphics/widgets/GLPane.py index 893365421..c515b74f8 100755 --- a/cad/src/graphics/widgets/GLPane.py +++ b/cad/src/graphics/widgets/GLPane.py @@ -67,10 +67,8 @@ from PyQt4.QtOpenGL import QGLWidget from OpenGL.GL import glDepthFunc from OpenGL.GL import GL_STENCIL_BITS -from OpenGL.GL import GL_PROJECTION from OpenGL.GL import GL_DEPTH_TEST from OpenGL.GL import glEnable -from OpenGL.GL import glLoadIdentity from OpenGL.GL import GL_DEPTH_COMPONENT from OpenGL.GL import glReadPixelsf from OpenGL.GL import GL_LEQUAL @@ -91,7 +89,6 @@ from OpenGL.GL import GL_REPLACE from OpenGL.GL import glStencilOp from OpenGL.GL import GL_STENCIL_TEST from OpenGL.GL import glPushMatrix -from OpenGL.GL import glTranslatef from OpenGL.GL import glDisable from OpenGL.GL import glPopMatrix from OpenGL.GL import GL_MODELVIEW @@ -101,13 +98,7 @@ from OpenGL.GL import glColorMask from OpenGL.GL import GL_DEPTH_BUFFER_BIT from OpenGL.GL import glClear from OpenGL.GL import GL_TRUE -from OpenGL.GL import GL_VIEWPORT -from OpenGL.GL import glGetIntegerv -from OpenGL.GL import glFrustum -from OpenGL.GL import glOrtho -from OpenGL.GL import glRotatef -from OpenGL.GL import GL_LIGHTING -from OpenGL.GL import glViewport +from OpenGL.GL import GL_LIGHTING from OpenGL.GL import GL_RGB from OpenGL.GL import GL_UNSIGNED_BYTE from OpenGL.GL import glReadPixels @@ -123,6 +114,7 @@ from OpenGL.GLU import gluUnProject, gluPickMatrix from geometry.VQT import V, Q, A, norm, vlen, angleBetween from geometry.VQT import planeXline, ptonline + from Numeric import dot import graphics.drawing.drawing_globals as drawing_globals @@ -468,6 +460,16 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal return # from GLPane.__init__ + def resizeGL(self, width, height): + """ + Called by QtGL when the drawing window is resized. + """ + #bruce 080912 moved most of this into superclass + GLPane_minimal.resizeGL(self, width, height) # call superclass method + self.gl_update() # REVIEW: ok for superclass? + # needed here? (Guess yes, to set needs_repaint flag) + return + # == if not GLPANE_IS_COMMAND_SEQUENCER: @@ -902,28 +904,6 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal env.end_op(mc) return - def __getattr__(self, name): # in class GLPane - # TODO: turn these into property defs - - # return space vectors corresponding to various directions - # relative to the screen (can be used during drawing - # or when handling mouse events) - if name == 'lineOfSight': - return self.quat.unrot(V(0, 0, -1)) - elif name == 'right': - return self.quat.unrot(V(1, 0, 0)) - elif name == 'left': - return self.quat.unrot(V(-1, 0, 0)) - elif name == 'up': - return self.quat.unrot(V(0, 1, 0)) - elif name == 'down': - return self.quat.unrot(V(0, -1, 0)) - elif name == 'out': - return self.quat.unrot(V(0, 0, 1)) - else: - raise AttributeError, 'GLPane has no "%s"' % name - pass - # == #bruce 060220 changes related to supporting self.modkeys, self.in_drag. @@ -1677,13 +1657,6 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal p2 = p1 + k*(p2-p1) return (p1, p2) - def eyeball(self): #bruce 060219 ##e should call this to replace equivalent formulae in other places - """ - Return the location of the eyeball in model coordinates. - """ - return self.quat.unrot(V(0, 0, self.vdist)) - self.pov # note: self.vdist is (usually??) 6 * self.scale - ##k need to review whether this is correct for tall aspect ratio GLPane - def SaveMouse(self, event): """ Extracts the mouse position from event and saves it in the I{MousePos} @@ -1909,6 +1882,19 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal # QWidget.update() method -- ask Qt to call self.paintGL() # (via some sort of paintEvent to our superclass) # very soon after the current event handler returns + # + ### REVIEW: why does this not call self.updateGL() like ThumbView.py does? + # I tried calling self.updateGL() here, and got an exception + # inside a paintGL subroutine (AttributeError on self.guides), + # captured somewhere inside it by print_compact_stack, + # which occurred before a print statement here just after my call. + # The toplevel Python call shown in print_compact_stack was paintGL. + # This means: updateGL causes an immediate call by Qt into paintGL, + # in the same event handler, but from C code which stops print_compact_stack + # from seeing what was outside it. (Digression: we could work around + # that by grabbing the stack frame here and storing it somewhere!) + # Conclusion: never call updateGL in GLPane, and review whether + # ThumbView should continue to call it. [bruce 080912 comment] return def gl_update_highlight(self): #bruce 070626 @@ -2431,15 +2417,6 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal # - 'selobj/preDraw_glselect_dict' -- like selobj, but color buffer drawing is off ###e which coord system, incl projection?? # [end] - def get_vdist(self): # [revised bruce 070920] - """ - Recompute and return the desired distance between - eyeball and center of view. - """ - return 6.0 * self.scale - - vdist = property(get_vdist) - def _compute_frustum_planes(self): # Piotr 080331 """ Compute six planes to be used for frustum culling @@ -2806,7 +2783,7 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal # draw coordinate-orientation arrows at upper right corner of glpane if env.prefs[displayCompass_prefs_key]: - self.drawcompass(self.aspect) + self.drawcompass() # review: needs drawing_phase? [bruce 070124 q] for stereo_image in self.stereo_images_to_draw: @@ -3464,67 +3441,11 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal print "%s: target depth %r NOT reached by %r at %r" % (debug_prefix, targetdepth, candidate, newdepth) return None - def _setup_modelview(self): - """ - set up modelview coordinate system - """ - #bruce 070919 removed vdist arg, getting it from self.vdist - vdist = self.vdist - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - glTranslatef( 0.0, 0.0, - vdist) - # [bruce comment 050615] - # translate coords for drawing, away from eye (through screen and beyond it) by vdist; - # this places origin at desired position in eyespace for "center of view" (and for center of trackball rotation). - - # bruce 041214 comment: some code assumes vdist is always 6.0 * self.scale - # (e.g. eyeball computations, see bug 30), thus has bugs for aspect < 1.0. - # We should have glpane attrs for aspect, w_scale, h_scale, eyeball, - # clipping planes, etc, like we do now for right, up, etc. ###e - - q = self.quat - glRotatef( q.angle*180.0/math.pi, q.x, q.y, q.z) # rotate those coords by the trackball quat - glTranslatef( self.pov[0], self.pov[1], self.pov[2]) # and translate them by -cov, to bring cov (center of view) to origin - return - - 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. - (Warning: leaves matrixmode as GL_PROJECTION.) - Optional arg glselect should be False (default) or a 4-tuple (to prepare for GL_SELECT picking). - """ - #bruce 070919 removed aspect, vdist args, getting them from attrs - # (as was already done in ThumbView.py) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - - scale = self.scale * self.zoomFactor #bruce 050608 used this to clarify following code - 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 drawcompass(self, aspect): #bruce 080910 moved body into its own file + def drawcompass(self): + #bruce 080910 moved body into its own file + #bruce 080912 removed aspect argument drawcompass(self, - aspect, + self.aspect, self.quat, self.compassPosition, self.graphicsMode.compass_moved_in_from_corner, @@ -3534,26 +3455,6 @@ class GLPane(GLPane_lighting_methods, # this needs to come before GLPane_minimal # == - def resizeGL(self, width, height): - """ - Called by QtGL when the drawing window is resized. - """ - self.width = width - self.height = height - self.aspect = (self.width + 0.0)/(self.height + 0.0) - #bruce 070919 made this self.aspect rather than aspect, - # and moved it here from standard_repaint_0 - - ## glViewport(10, 15, (self.width-10)/2, (self.height-15)/3) # (guess: just an example of using a smaller viewport) - glViewport(0, 0, self.width, self.height) - if not self.initialised: - self.initialised = 1 - if width < 300: width = 300 - if height < 300: height = 300 - self.trackball.rescale(width, height) - self.gl_update() - return - def makemenu(self, menu_spec, menu): # this overrides the one from DebugMenuMixin (with the same code), but that's ok, # since we want to be self-contained in case someone later removes that mixin class; diff --git a/cad/src/graphics/widgets/GLPane_lighting_methods.py b/cad/src/graphics/widgets/GLPane_lighting_methods.py index 4ec442c0d..fc8b4cb19 100644 --- a/cad/src/graphics/widgets/GLPane_lighting_methods.py +++ b/cad/src/graphics/widgets/GLPane_lighting_methods.py @@ -125,12 +125,17 @@ class GLPane_lighting_methods(object): """ return list(self._lights) - def _setup_lighting(self): # as of bruce 060415, this is mostly duplicated between here (has comments) and ThumbView ###@@@ + def _setup_lighting(self): """ [private method] Set up lighting in the model (according to self._lights). [Called from both initializeGL and paintGL.] """ + # note: there is some duplicated code in this method + # in GLPane_lighting_methods (has more comments) and ThumbView, + # but also significant differences. Should refactor sometime. + # [bruce 060415/080912 comment] + glEnable(GL_NORMALIZE) # bruce comment 050311: I don't know if this relates to lighting or not # grantham 20051121: Yes, if NORMALIZE is not enabled (and normals diff --git a/cad/src/graphics/widgets/GLPane_minimal.py b/cad/src/graphics/widgets/GLPane_minimal.py index 05199cc45..5695c4048 100644 --- a/cad/src/graphics/widgets/GLPane_minimal.py +++ b/cad/src/graphics/widgets/GLPane_minimal.py @@ -12,15 +12,27 @@ need a common superclass (and have common code that needs merging). It needs to be in its own file to avoid import loop problems. """ -from OpenGL.GL import glDepthRange +import math + from OpenGL.GL import GL_CULL_FACE from OpenGL.GL import GL_DEPTH_TEST from OpenGL.GL import GL_MODELVIEW +from OpenGL.GL import GL_PROJECTION from OpenGL.GL import GL_SMOOTH +from OpenGL.GL import GL_VIEWPORT +from OpenGL.GL import glDepthRange from OpenGL.GL import glEnable +from OpenGL.GL import glFrustum +from OpenGL.GL import glGetIntegerv from OpenGL.GL import glLoadIdentity from OpenGL.GL import glMatrixMode +from OpenGL.GL import glOrtho +from OpenGL.GL import glRotatef from OpenGL.GL import glShadeModel +from OpenGL.GL import glTranslatef +from OpenGL.GL import glViewport + +from OpenGL.GLU import gluPickMatrix from PyQt4.QtOpenGL import QGLFormat from PyQt4.QtOpenGL import QGLWidget @@ -178,6 +190,66 @@ class GLPane_minimal(QGLWidget, object): #bruce 070914 return + def __getattr__(self, name): # in class GLPane_minimal + # bruce 080912 moved from GLPane into GLPane_minimal + # TODO: turn these into property defs + + # return space vectors corresponding to various directions + # relative to the screen (can be used during drawing + # or when handling mouse events) + if name == 'lineOfSight': + return self.quat.unrot(V(0, 0, -1)) + elif name == 'right': + return self.quat.unrot(V(1, 0, 0)) + elif name == 'left': + return self.quat.unrot(V(-1, 0, 0)) + elif name == 'up': + return self.quat.unrot(V(0, 1, 0)) + elif name == 'down': + return self.quat.unrot(V(0, -1, 0)) + elif name == 'out': + return self.quat.unrot(V(0, 0, 1)) + else: + raise AttributeError, 'GLPane_minimal has no "%s"' % name + pass + + def __get_vdist(self): + """ + Recompute and return the desired distance between + eyeball and center of view. + """ + #bruce 070920 revised; bruce 080912 moved from GLPane into GLPane_minimal + # Note: an old comment from elsewhere in GLPane claims: + # bruce 041214 comment: some code assumes vdist is always 6.0 * self.scale + # (e.g. eyeball computations, see bug 30), thus has bugs for aspect < 1.0. + # We should have glpane attrs for aspect, w_scale, h_scale, eyeball, + # clipping planes, etc, like we do now for right, up, etc. ###e + # I don't know if vdist could ever have a different value, + # or if we still have aspect < 1.0 bugs due to some other cause. + return 6.0 * self.scale + + vdist = property(__get_vdist) + + def eyeball(self): #bruce 060219 ##e should call this to replace equivalent formulae in other places + """ + Return the location of the eyeball in model coordinates. + + @note: this is not meaningful except when using perspective projection. + """ + ### REVIEW: whether this is correct for tall aspect ratio GLPane. + # See also the comment in __get_vdist, above, mentioning bug 30. + # There is related code in writepovfile which computes a camera position + # which corrects vdist when aspect < 1.0: + ## # Camera info + ## vdist = cdist + ## if aspect < 1.0: + ## vdist = cdist / aspect + ## eyePos = vdist * glpane.scale*glpane.out-glpane.pov + # [bruce comment 080912] + #bruce 0809122 moved this from GLPane into GLPane_minimal, + # and made region selection code call it for the first time. + return self.quat.unrot(V(0, 0, self.vdist)) - self.pov + def __repr__(self): return "<%s at %#x>" % (self.__class__.__name__.split('.')[-1], id(self)) @@ -198,6 +270,95 @@ class GLPane_minimal(QGLWidget, object): #bruce 070914 self._setup_display_lists() return + def resizeGL(self, width, height): + """ + Called by QtGL when the drawing window is resized. + """ + #bruce 080912 moved this from GLPane into GLPane_minimal ###IMPORTS + self.width = width + self.height = height + + glViewport(0, 0, self.width, self.height) + # example of using a smaller viewport: + ## glViewport(10, 15, (self.width-10)/2, (self.height-15)/3) + + if not self.initialised: + self.initialised = True ###k 1 vs True + + # modify width and height for trackball + # (note: this was done in GLPane but not in ThumbView until 080912) + if width < 300: + width = 300 + if height < 300: + height = 300 + + return + + def __get_aspect(self): + #bruce 080912 made this a property, moved to this class + return (self.width + 0.0) / (self.height + 0.0) + + aspect = property(__get_aspect) + + 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). + + (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 + """ + #bruce 080912 moved this from GLPane into GLPane_minimal ###IMPORTS + 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 _setup_modelview(self): + """ + set up modelview coordinate system + """ + #bruce 080912 moved this from GLPane into GLPane_minimal ###IMPORTS + # note: it's not yet used in ThumbView, but maybe it could be. + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + glTranslatef( 0.0, 0.0, - self.vdist) + # translate coords for drawing, away from eye (through screen + # and beyond it) by vdist; this places origin at desired position + # in eyespace for "center of view" (and for center of trackball + # rotation) + q = self.quat + glRotatef( q.angle * 180.0 / math.pi, q.x, q.y, q.z) + # rotate those coords by the trackball quat + glTranslatef( self.pov[0], self.pov[1], self.pov[2]) + # and translate them by -cov, to bring cov (center of view) + # to origin + return + def _setup_lighting(self): # note: in subclass GLPane, as of 080911 this is defined in # its mixin superclass GLPane_lighting_methods @@ -317,6 +478,14 @@ class GLPane_minimal(QGLWidget, object): #bruce 070914 # == + # REVIEW: + # the following "Undo view" methods probably don't work in subclasses other + # than GLPane. It might make sense to have them here, but only if they are + # refactored a bit, e.g. so that self.animateToView works in other + # subclassses even if it doesn't animate. Ultimately it might be better + # to refactor them a lot and/or move them out of this class hierarchy + # entirely. [bruce 080912 comment] + def current_view_for_Undo(self, assy): #e shares code with saveNamedView """ Return the current view in this glpane (which we assume is showing diff --git a/cad/src/graphics/widgets/ThumbView.py b/cad/src/graphics/widgets/ThumbView.py index aa8f12b43..821598221 100755 --- a/cad/src/graphics/widgets/ThumbView.py +++ b/cad/src/graphics/widgets/ThumbView.py @@ -1,35 +1,25 @@ # Copyright 2004-2008 Nanorex, Inc. See LICENSE file for details. """ -ThumbView.py - a simpler OpenGL widget, similar to GLPane +ThumbView.py - a simpler OpenGL widget, similar to GLPane +(which unfortunately has a lot of duplicated but partly modified +code copied from GLPane) @author: Huaicai @version: $Id$ @copyright: 2004-2008 Nanorex, Inc. See LICENSE file for details. """ -import math from Numeric import dot from OpenGL.GL import GL_NORMALIZE -from OpenGL.GL import GL_SMOOTH -from OpenGL.GL import glShadeModel -from OpenGL.GL import GL_DEPTH_TEST from OpenGL.GL import glEnable -from OpenGL.GL import GL_CULL_FACE from OpenGL.GL import GL_MODELVIEW from OpenGL.GL import glMatrixMode from OpenGL.GL import glLoadIdentity -from OpenGL.GL import glViewport -from OpenGL.GL import GL_VIEWPORT -from OpenGL.GL import glGetIntegerv -from OpenGL.GL import glOrtho -from OpenGL.GL import glFrustum from OpenGL.GL import glClearColor from OpenGL.GL import GL_COLOR_BUFFER_BIT from OpenGL.GL import GL_DEPTH_BUFFER_BIT from OpenGL.GL import glClear -from OpenGL.GL import glTranslatef -from OpenGL.GL import glRotatef from OpenGL.GL import GL_STENCIL_INDEX from OpenGL.GL import glReadPixelsi from OpenGL.GL import GL_DEPTH_COMPONENT @@ -59,7 +49,7 @@ from OpenGL.GL import glPopMatrix from OpenGL.GL import glDepthFunc from OpenGL.GL import GL_LEQUAL -from OpenGL.GLU import gluPickMatrix, gluUnProject +from OpenGL.GLU import gluUnProject from PyQt4.Qt import Qt @@ -191,12 +181,17 @@ class ThumbView(GLPane_minimal): assy = property(__get_assy) #bruce 080220, for per-assy glname dict - def _setup_lighting(self): # as of bruce 060415, this is mostly duplicated between GLPane_lighting_methods (has comments) and ThumbView ###@@@ + def _setup_lighting(self): """ [private method] Set up lighting in the model. [Called from both initializeGL and paintGL.] """ + # note: there is some duplicated code in this method + # in GLPane_lighting_methods (has more comments) and ThumbView, + # but also significant differences. Should refactor sometime. + # [bruce 060415/080912 comment] + glEnable(GL_NORMALIZE) glMatrixMode(GL_PROJECTION) @@ -245,59 +240,6 @@ class ThumbView(GLPane_minimal): else: self.backgroundGradient = gradient - def resizeGL(self, width, height): - """ - Called by QtGL when the drawing window is resized. - """ - self.width = width - self.height = height - - glViewport(0, 0, self.width, self.height) - - self.trackball.rescale(width, height) - - if not self.initialised: - self.initialised = True - - - 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 paintGL(self): """ Called by QtGL when redrawing is needed. For every redraw, color & @@ -343,18 +285,15 @@ class ThumbView(GLPane_minimal): drawFullWindow(_bgGradient)# gradient color -## self.aspect = (self.width + 0.0) / (self.height + 0.0) -## self.vdist = 6.0 * self.scale self._setup_projection() - - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - glTranslatef(0.0, 0.0, -self.vdist) - - q = self.quat - - glRotatef(q.angle * 180.0 / math.pi, q.x, q.y, q.z) - glTranslatef(self.pov[0], self.pov[1], self.pov[2]) + + self._setup_modelview() +## glMatrixMode(GL_MODELVIEW) +## glLoadIdentity() +## glTranslatef(0.0, 0.0, - self.vdist) +## q = self.quat +## glRotatef(q.angle * 180.0 / math.pi, q.x, q.y, q.z) +## glTranslatef(self.pov[0], self.pov[1], self.pov[2]) if self.model_is_valid(): #bruce 080117 [testing this at start of paintGL to skip most of it]: @@ -371,22 +310,6 @@ class ThumbView(GLPane_minimal): # names and comments). [bruce 080220] self.drawModel() - def __getattr__(self, name): # in class ThumbView - if name == 'lineOfSight': - return self.quat.unrot(V(0, 0, -1)) - elif name == 'right': - return self.quat.unrot(V(1, 0, 0)) - elif name == 'left': - return self.quat.unrot(V(-1, 0, 0)) - elif name == 'up': - return self.quat.unrot(V(0, 1, 0)) - elif name == 'down': - return self.quat.unrot(V(0, -1, 0)) - elif name == 'out': - return self.quat.unrot(V(0, 0, 1)) - else: - raise AttributeError, 'ThumbView has no "%s"' % name #bruce 060209 revised text - def mousePressEvent(self, event): """ Dispatches mouse press events depending on shift and @@ -692,7 +615,7 @@ class ThumbView(GLPane_minimal): glClear(GL_STENCIL_BUFFER_BIT) glDepthMask(GL_FALSE) # turn off depth writing (but not depth test) - #glDisable(GL_DEPTH_TEST) + ## glDisable(GL_DEPTH_TEST) glStencilFunc(GL_ALWAYS, 1, 1) glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) glEnable(GL_STENCIL_TEST) @@ -707,7 +630,7 @@ class ThumbView(GLPane_minimal): Restore OpenGL settings changed by _preHighlight to standard values. """ glDepthMask(GL_TRUE) - #glEnable(GL_DEPTH_TEST) + ## glEnable(GL_DEPTH_TEST) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) glDisable(GL_STENCIL_TEST) @@ -1082,8 +1005,14 @@ class MMKitView(ThumbView): else: ## Assembly part = self.model.part bbox = part.bbox - self.scale = bbox.scale() - + self.scale = bbox.scale() + + # guess: the following is a KLUGE for width and height + # being the names of Qt superclass methods + # but also being assigned to ints by our own code. + # I don't know why it could ever be needed, since resizeGL + # sets them -- maybe this can be called before that ever is?? + # [bruce 080912 comment] if isinstance(self.width, int): width = self.width else: @@ -1094,7 +1023,7 @@ class MMKitView(ThumbView): height = float(self.height()) aspect = width / height - + # REVIEW: likely bug: integer division is possible [bruce 080912 comment] ##aspect = float(self.width) / self.height if aspect < 1.0: diff --git a/cad/src/tools/Refactoring/make_gl_imports.py b/cad/src/tools/Refactoring/make_gl_imports.py index 9a2d7922a..eb2b6b32c 100755 --- a/cad/src/tools/Refactoring/make_gl_imports.py +++ b/cad/src/tools/Refactoring/make_gl_imports.py @@ -17,6 +17,19 @@ tokenize the input, and for each unique identifier matching gl* or GL*, make an import statement based on its initial characters, handling gl vs glu appropriately. +BUGS: + +It thinks identifiers in import statements are in code, +so it will never remove imports when run on an entire file, +and it can get confused and suggest unnecessary ones +such as "from OpenGL.GL import GL" (from seeing the "GL" +in "OpenGL.GL" in an existing import statement). + +It doesn't verify the symbol is available in the module +it proposes to import, so it will get confused by local +variables that start with 'gl' or classnames that +start with 'GL' (e.g. "GLPane"), for example. + TODO: generalize to a tool which fixes up all toplevel imports @@ -49,6 +62,8 @@ def process_token(tup5): if tokname == 'NAME': # keyword or identifier if text[:2] in ('gl', 'GL'): + if text == 'global': + return kind = 'gl' # might be modified if text[:3] in ('glu', 'GLU'): kind = 'glu' |