From 3ad0920234b419ae00bc01f6d23745194e666e5a Mon Sep 17 00:00:00 2001 From: daid303 Date: Fri, 25 Jan 2013 10:05:55 +0100 Subject: [PATCH] Move the OpenGL GUI base code to a seperate class for easier re-use. --- Cura/gui/preview3d.py | 69 ++----------- Cura/gui/projectPlanner.py | 31 ++---- Cura/gui/util/opengl.py | 179 +++++++++++++--------------------- Cura/gui/util/openglGui.py | 83 +++++++++++++++- Cura/gui/util/previewTools.py | 15 +++ 5 files changed, 180 insertions(+), 197 deletions(-) diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index c3378da3..69b0828a 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -40,8 +40,6 @@ class previewPanel(wx.Panel): self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DDKSHADOW)) self.SetMinSize((440,320)) - self.buttonSize = 64 - self.glButtonList = [] self.objectList = [] self.errorList = [] self.gcode = None @@ -108,15 +106,15 @@ class previewPanel(wx.Panel): self.Bind(wx.EVT_TIMER, self.OnCheckReloadFile, self.checkReloadFileTimer) self.checkReloadFileTimer.Start(1000) - self.infoToolButton = openglGui.glButton(self, 0, 0,0, self.OnInfoSelect) - self.rotateToolButton = openglGui.glButton(self, 1, 0,1, self.OnRotateSelect) - self.scaleToolButton = openglGui.glButton(self, 2, 0,2, self.OnScaleSelect) + self.infoToolButton = openglGui.glButton(self.glCanvas, 0, 'Info', 0,0, self.OnInfoSelect) + self.rotateToolButton = openglGui.glButton(self.glCanvas, 1, 'Rotate', 0,1, self.OnRotateSelect) + self.scaleToolButton = openglGui.glButton(self.glCanvas, 2, 'Scale', 0,2, self.OnScaleSelect) - self.resetRotationButton = openglGui.glButton(self, 4, 1,0, self.OnRotateReset) - self.layFlatButton = openglGui.glButton(self, 5, 2,0, self.OnLayFlat) + self.resetRotationButton = openglGui.glButton(self.glCanvas, 4, 'Reset rotation', 1,0, self.OnRotateReset) + self.layFlatButton = openglGui.glButton(self.glCanvas, 5, 'Lay flat', 2,0, self.OnLayFlat) - self.resetScaleButton = openglGui.glButton(self, 8, 1,0, self.OnScaleReset) - self.scaleMaxButton = openglGui.glButton(self, 9, 2,0, self.OnScaleMax) + self.resetScaleButton = openglGui.glButton(self.glCanvas, 8, 'Scale reset', 1,0, self.OnScaleReset) + self.scaleMaxButton = openglGui.glButton(self.glCanvas, 9, 'Scale to machine size', 2,0, self.OnScaleMax) self.infoToolButton.setSelected(True) self.returnToModelViewAndUpdateModel() @@ -443,18 +441,11 @@ class previewPanel(wx.Panel): self.updateModelTransform() self.glCanvas.updateProfileToControls() -class PreviewGLCanvas(glcanvas.GLCanvas): +class PreviewGLCanvas(openglGui.glGuiPanel): def __init__(self, parent): - attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8) - glcanvas.GLCanvas.__init__(self, parent, attribList = attribList) - self.parent = parent - self.context = glcanvas.GLContext(self) - wx.EVT_PAINT(self, self.OnPaint) - wx.EVT_SIZE(self, self.OnSize) - wx.EVT_ERASE_BACKGROUND(self, self.OnEraseBackground) - wx.EVT_MOUSE_EVENTS(self, self.OnMouseEvents) - wx.EVT_MOTION(self, self.OnMouseMotion) + super(PreviewGLCanvas, self).__init__(parent) wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel) + self.parent = parent self.yaw = 30 self.pitch = 60 self.zoom = 300 @@ -477,17 +468,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.objColor[2] = profile.getPreferenceColour('model_colour3') self.objColor[3] = profile.getPreferenceColour('model_colour4') - def OnMouseEvents(self,e): - if e.ButtonDown() and e.LeftIsDown(): - for ctrl in self.parent.glButtonList: - if ctrl.OnMouseDown(e.GetX(), e.GetY()): - return - def OnMouseMotion(self,e): - self.Refresh() - for ctrl in self.parent.glButtonList: - if ctrl.OnMouseMotion(e.GetX(), e.GetY()): - return if self.parent.objectsMaxV is not None and self.viewport is not None and self.viewMode != 'GCode' and self.viewMode != 'Mixed': p0 = opengl.unproject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 0, self.modelMatrix, self.projMatrix, self.viewport) p1 = opengl.unproject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 1, self.modelMatrix, self.projMatrix, self.viewport) @@ -553,17 +534,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas): if self.zoom > 500: self.zoom = 500 self.Refresh() - - def OnEraseBackground(self,event): - #Workaround for windows background redraw flicker. - pass - - def OnSize(self,e): - self.Refresh() def OnPaint(self,e): - dc = wx.PaintDC(self) - self.SetCurrent(self.context) opengl.InitGL(self, self.view3D, self.zoom) if self.view3D: glTranslate(0,0,-self.zoom) @@ -585,7 +557,6 @@ class PreviewGLCanvas(glcanvas.GLCanvas): glTranslate(-self.parent.machineCenter.x, -self.parent.machineCenter.y, 0) self.OnDraw() - self.SwapBuffers() def OnDraw(self): machineSize = self.parent.machineSize @@ -774,26 +745,6 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.parent.tool.OnDraw() glPopMatrix() - self.drawGui() - - glFlush() - - def drawGui(self): - glDisable(GL_DEPTH_TEST) - glEnable(GL_BLEND) - glDisable(GL_LIGHTING) - glColor4ub(255,255,255,255) - - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - size = self.GetSize() - glOrtho(0, size.GetWidth()-1, size.GetHeight()-1, 0, -1000.0, 1000.0) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - - for glButton in self.parent.glButtonList: - glButton.draw() - def drawModel(self, displayList): vMin = self.parent.objectsMinV vMax = self.parent.objectsMaxV diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index e0260881..94dc6d84 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -43,26 +43,15 @@ class ProjectObject(object): self.parent = parent self.filename = filename - self.scale = 1.0 - self.rotate = 0.0 - self.flipX = False - self.flipY = False - self.flipZ = False - self.swapXZ = False - self.swapYZ = False - self.extruder = 0 - self.profile = None + self.matrix = numpy.matrix([[1,0,0],[0,1,0],[0,0,1]], numpy.float64) self.modelDisplayList = None - self.modelDirty = False + self.modelDirty = True - self.centerX = -self.getMinimum()[0] + 5 - self.centerY = -self.getMinimum()[1] + 5 - - self.updateModelTransform() + self.centerX = -self.getSize()[0]/2 + 5 + self.centerY = -self.getSize()[1]/2 + 5 - self.centerX = -self.getMinimum()[0] + 5 - self.centerY = -self.getMinimum()[1] + 5 + self.updateModelTransform() def isSameExceptForPosition(self, other): if self.filename != other.filename: @@ -88,14 +77,8 @@ class ProjectObject(object): return True def updateModelTransform(self): - self.mesh.setRotateMirror(self.rotate, self.flipX, self.flipY, self.flipZ, self.swapXZ, self.swapYZ) - minZ = self.mesh.getMinimumZ() - minV = self.getMinimum() - maxV = self.getMaximum() - self.mesh.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minZ]) - minZ = self.mesh.getMinimumZ() - self.modelDirty = True - + self.mesh.processMatrix() + def getMinimum(self): return self.mesh.getMinimum() def getMaximum(self): diff --git a/Cura/gui/util/opengl.py b/Cura/gui/util/opengl.py index 0f10077e..1a160571 100644 --- a/Cura/gui/util/opengl.py +++ b/Cura/gui/util/opengl.py @@ -54,10 +54,40 @@ def InitGL(window, view3D, zoom): platformMesh = None def DrawMachine(machineSize): + glDisable(GL_LIGHTING) + glDisable(GL_CULL_FACE) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + + sx = machineSize.x + sy = machineSize.y + for x in xrange(-int(sx/20)-1, int(sx / 20) + 1): + for y in xrange(-int(sx/20)-1, int(sy / 20) + 1): + x1 = sx/2+x * 10 + x2 = x1 + 10 + y1 = sx/2+y * 10 + y2 = y1 + 10 + x1 = max(min(x1, sx), 0) + y1 = max(min(y1, sy), 0) + x2 = max(min(x2, sx), 0) + y2 = max(min(y2, sy), 0) + if (x & 1) == (y & 1): + glColor4ub(5, 171, 231, 127) + else: + glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128) + glBegin(GL_QUADS) + glVertex3f(x1, y1, -0.02) + glVertex3f(x2, y1, -0.02) + glVertex3f(x2, y2, -0.02) + glVertex3f(x1, y2, -0.02) + glEnd() + + glEnable(GL_CULL_FACE) + if profile.getPreference('machine_type') == 'ultimaker': glPushMatrix() glEnable(GL_LIGHTING) - glTranslate(100, 200, -5) + glTranslate(100, 200, -1) glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8]) glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5]) glEnable(GL_BLEND) @@ -73,117 +103,46 @@ def DrawMachine(machineSize): if platformMesh: DrawMesh(platformMesh) glPopMatrix() - - glDisable(GL_LIGHTING) - if False: - glColor3f(0.7, 0.7, 0.7) - glLineWidth(2) - glBegin(GL_LINES) - for i in xrange(0, int(machineSize.x), 10): - glVertex3f(i, 0, 0) - glVertex3f(i, machineSize.y, 0) - for i in xrange(0, int(machineSize.y), 10): - glVertex3f(0, i, 0) - glVertex3f(machineSize.x, i, 0) - glEnd() - - glEnable(GL_LINE_SMOOTH) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); - - glColor3f(0.0, 0.0, 0.0) - glLineWidth(4) - glBegin(GL_LINE_LOOP) - glVertex3f(0, 0, 0) - glVertex3f(machineSize.x, 0, 0) - glVertex3f(machineSize.x, machineSize.y, 0) - glVertex3f(0, machineSize.y, 0) - glEnd() - - glLineWidth(2) - glBegin(GL_LINE_LOOP) - glVertex3f(0, 0, machineSize.z) - glVertex3f(machineSize.x, 0, machineSize.z) - glVertex3f(machineSize.x, machineSize.y, machineSize.z) - glVertex3f(0, machineSize.y, machineSize.z) - glEnd() - glBegin(GL_LINES) - glVertex3f(0, 0, 0) - glVertex3f(0, 0, machineSize.z) - glVertex3f(machineSize.x, 0, 0) - glVertex3f(machineSize.x, 0, machineSize.z) - glVertex3f(machineSize.x, machineSize.y, 0) - glVertex3f(machineSize.x, machineSize.y, machineSize.z) - glVertex3f(0, machineSize.y, 0) - glVertex3f(0, machineSize.y, machineSize.z) - glEnd() - else: - glDisable(GL_CULL_FACE) - glEnable(GL_BLEND) + glDisable(GL_LIGHTING) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - sx = machineSize.x - sy = machineSize.y - for x in xrange(-int(sx/20)-1, int(sx / 20) + 1): - for y in xrange(-int(sx/20)-1, int(sy / 20) + 1): - x1 = sx/2+x * 10 - x2 = x1 + 10 - y1 = sx/2+y * 10 - y2 = y1 + 10 - x1 = max(min(x1, sx), 0) - y1 = max(min(y1, sy), 0) - x2 = max(min(x2, sx), 0) - y2 = max(min(y2, sy), 0) - if (x & 1) == (y & 1): - glColor4ub(5, 171, 231, 127) - else: - glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128) - glBegin(GL_QUADS) - glVertex3f(x1, y1, -0.01) - glVertex3f(x2, y1, -0.01) - glVertex3f(x2, y2, -0.01) - glVertex3f(x1, y2, -0.01) - glEnd() + glColor4ub(5, 171, 231, 64) + glBegin(GL_QUADS) + glVertex3f(0, 0, machineSize.z) + glVertex3f(0, machineSize.y, machineSize.z) + glVertex3f(machineSize.x, machineSize.y, machineSize.z) + glVertex3f(machineSize.x, 0, machineSize.z) + glEnd() + + glColor4ub(5, 171, 231, 96) + glBegin(GL_QUADS) + glVertex3f(0, 0, 0) + glVertex3f(0, 0, machineSize.z) + glVertex3f(machineSize.x, 0, machineSize.z) + glVertex3f(machineSize.x, 0, 0) + + glVertex3f(0, machineSize.y, machineSize.z) + glVertex3f(0, machineSize.y, 0) + glVertex3f(machineSize.x, machineSize.y, 0) + glVertex3f(machineSize.x, machineSize.y, machineSize.z) + glEnd() + + glColor4ub(5, 171, 231, 128) + glBegin(GL_QUADS) + glVertex3f(0, 0, machineSize.z) + glVertex3f(0, 0, 0) + glVertex3f(0, machineSize.y, 0) + glVertex3f(0, machineSize.y, machineSize.z) - glEnable(GL_CULL_FACE) - - glColor4ub(5, 171, 231, 64) - glBegin(GL_QUADS) - glVertex3f(0, 0, machineSize.z) - glVertex3f(0, machineSize.y, machineSize.z) - glVertex3f(machineSize.x, machineSize.y, machineSize.z) - glVertex3f(machineSize.x, 0, machineSize.z) - glEnd() - - glColor4ub(5, 171, 231, 96) - glBegin(GL_QUADS) - glVertex3f(0, 0, 0) - glVertex3f(0, 0, machineSize.z) - glVertex3f(machineSize.x, 0, machineSize.z) - glVertex3f(machineSize.x, 0, 0) - - glVertex3f(0, machineSize.y, machineSize.z) - glVertex3f(0, machineSize.y, 0) - glVertex3f(machineSize.x, machineSize.y, 0) - glVertex3f(machineSize.x, machineSize.y, machineSize.z) - glEnd() - - glColor4ub(5, 171, 231, 128) - glBegin(GL_QUADS) - glVertex3f(0, 0, machineSize.z) - glVertex3f(0, 0, 0) - glVertex3f(0, machineSize.y, 0) - glVertex3f(0, machineSize.y, machineSize.z) - - glVertex3f(machineSize.x, 0, 0) - glVertex3f(machineSize.x, 0, machineSize.z) - glVertex3f(machineSize.x, machineSize.y, machineSize.z) - glVertex3f(machineSize.x, machineSize.y, 0) - glEnd() - - glDisable(GL_BLEND) + glVertex3f(machineSize.x, 0, 0) + glVertex3f(machineSize.x, 0, machineSize.z) + glVertex3f(machineSize.x, machineSize.y, machineSize.z) + glVertex3f(machineSize.x, machineSize.y, 0) + glEnd() + + glDisable(GL_BLEND) + #Draw the X/Y/Z indicator glPushMatrix() glTranslate(5, 5, 2) glLineWidth(2) @@ -234,10 +193,10 @@ def glDrawStringCenter(s): glRasterPos2f(0, 0) width = 0 for c in s: - width += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, ord(c)) + width += glutBitmapWidth(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c)) glBitmap(0,0,0,0, -width/2, 0, None) for c in s: - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord(c)) + glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c)) def unproject(winx, winy, winz, modelMatrix, projMatrix, viewport): npModelMatrix = numpy.matrix(numpy.array(modelMatrix, numpy.float64).reshape((4,4))) diff --git a/Cura/gui/util/openglGui.py b/Cura/gui/util/openglGui.py index 8ce9df40..ce362d5d 100644 --- a/Cura/gui/util/openglGui.py +++ b/Cura/gui/util/openglGui.py @@ -1,6 +1,8 @@ from __future__ import absolute_import from __future__ import division +import wx +from wx import glcanvas import OpenGL OpenGL.ERROR_CHECKING = False from OpenGL.GL import * @@ -9,14 +11,82 @@ from Cura.gui.util import opengl glButtonsTexture = None +class glGuiPanel(glcanvas.GLCanvas): + def __init__(self, parent): + attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8) + glcanvas.GLCanvas.__init__(self, parent, attribList = attribList) + self._parent = parent + self._context = glcanvas.GLContext(self) + self._glGuiControlList = [] + self._buttonSize = 64 + + wx.EVT_PAINT(self, self._OnGuiPaint) + wx.EVT_SIZE(self, self._OnSize) + wx.EVT_ERASE_BACKGROUND(self, self._OnEraseBackground) + wx.EVT_MOUSE_EVENTS(self, self._OnGuiMouseEvents) + wx.EVT_MOTION(self, self._OnGuiMouseMotion) + + def _OnGuiMouseEvents(self,e): + if e.ButtonDown() and e.LeftIsDown(): + for ctrl in self._glGuiControlList: + if ctrl.OnMouseDown(e.GetX(), e.GetY()): + return + + def _OnGuiMouseMotion(self,e): + self.Refresh() + for ctrl in self._glGuiControlList: + if ctrl.OnMouseMotion(e.GetX(), e.GetY()): + return + self.OnMouseMotion(e) + + def _OnGuiPaint(self, e): + dc = wx.PaintDC(self) + self.SetCurrent(self._context) + self.OnPaint(e) + self._drawGui() + glFlush() + self.SwapBuffers() + + def _drawGui(self): + glDisable(GL_DEPTH_TEST) + glEnable(GL_BLEND) + glDisable(GL_LIGHTING) + glColor4ub(255,255,255,255) + + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + size = self.GetSize() + glOrtho(0, size.GetWidth()-1, size.GetHeight()-1, 0, -1000.0, 1000.0) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + + for glButton in self._glGuiControlList: + glButton.draw() + + def _OnEraseBackground(self,event): + #Workaround for windows background redraw flicker. + pass + + def _OnSize(self,e): + self.Refresh() + + def OnMouseEvents(self,e): + pass + + def OnMouseMotion(self, e): + pass + def OnPaint(self, e): + pass + class glButton(object): - def __init__(self, parent, imageID, x, y, callback): + def __init__(self, parent, imageID, tooltip, x, y, callback): + self._tooltip = tooltip self._parent = parent self._imageID = imageID self._x = x self._y = y self._callback = callback - self._parent.glButtonList.append(self) + self._parent._glGuiControlList.append(self) self._selected = False self._focus = False self._hidden = False @@ -39,7 +109,7 @@ class glButton(object): cx = (self._imageID % 4) / 4 cy = int(self._imageID / 4) / 4 - bs = self._parent.buttonSize + bs = self._parent._buttonSize glPushMatrix() glTranslatef(self._x * bs * 1.3 + bs * 0.8, self._y * bs * 1.3 + bs * 0.8, 0) @@ -51,6 +121,7 @@ class glButton(object): elif self._focus: scale = 0.9 glScalef(bs * scale, bs * scale, bs * scale) + glColor4ub(255,255,255,255) glBegin(GL_QUADS) glTexCoord2f(cx+0.25, cy) glVertex2f( 0.5,-0.5) @@ -62,12 +133,16 @@ class glButton(object): glVertex2f( 0.5, 0.5) glEnd() glDisable(GL_TEXTURE_2D) + if self._focus: + glColor4ub(0,0,0,255) + glTranslatef(0, -0.55, 0) + opengl.glDrawStringCenter(self._tooltip) glPopMatrix() def _checkHit(self, x, y): if self._hidden: return False - bs = self._parent.buttonSize + bs = self._parent._buttonSize return -bs * 0.5 <= x - (self._x * bs * 1.3 + bs * 0.8) <= bs * 0.5 and -bs * 0.5 <= y - (self._y * bs * 1.3 + bs * 0.8) <= bs * 0.5 def OnMouseMotion(self, x, y): diff --git a/Cura/gui/util/previewTools.py b/Cura/gui/util/previewTools.py index 131e9c2d..0de3bf67 100644 --- a/Cura/gui/util/previewTools.py +++ b/Cura/gui/util/previewTools.py @@ -365,6 +365,21 @@ class toolScale(object): glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + glColor3ub(0,0,0) + size = self.parent.getObjectSize() + radius = self.parent.getObjectBoundaryCircle() * max(scaleX, scaleY, scaleZ) + glPushMatrix() + glTranslate(0,0,size[2]/2 + 5) + glRotate(-self.parent.yaw, 0,0,1) + if self.parent.pitch < 80: + glTranslate(0, radius + 5,0) + elif self.parent.pitch < 100: + glTranslate(0, (radius + 5) * (90 - self.parent.pitch) / 10,0) + else: + glTranslate(0,-(radius + 5),0) + opengl.glDrawStringCenter("%dx%dx%d" % (size[0] * scaleX, size[1] * scaleY, size[2] * scaleZ)) + glPopMatrix() + glLineWidth(1) glBegin(GL_LINES) glColor3ub(128,0,0) -- 2.30.2