summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Smith <bruce@nanorex.com>2008-09-12 23:53:16 +0000
committerBruce Smith <bruce@nanorex.com>2008-09-12 23:53:16 +0000
commit4d5e3638a86c321f81840ee37c7237fa9f0613f9 (patch)
tree79d7698276a33a2e140fbb9e5efd91c2e281ed8b
parent4a1877bc49f194909d41405ab1e5b3cbbf5d53f3 (diff)
downloadnanoengineer-theirix-4d5e3638a86c321f81840ee37c7237fa9f0613f9.tar.gz
nanoengineer-theirix-4d5e3638a86c321f81840ee37c7237fa9f0613f9.zip
move some rendering setup code into GLPane_minimal from subclasses
-rwxr-xr-xcad/src/commands/Select/Select_GraphicsMode.py7
-rwxr-xr-xcad/src/exprs/projection.py14
-rwxr-xr-xcad/src/graphics/rendering/fileIO.py4
-rwxr-xr-xcad/src/graphics/widgets/GLPane.py159
-rw-r--r--cad/src/graphics/widgets/GLPane_lighting_methods.py7
-rw-r--r--cad/src/graphics/widgets/GLPane_minimal.py171
-rwxr-xr-xcad/src/graphics/widgets/ThumbView.py129
-rwxr-xr-xcad/src/tools/Refactoring/make_gl_imports.py15
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'