import threading\r
import re\r
import time\r
+import os\r
\r
from wx import glcanvas\r
import wx\r
self.toolbar.AddControl(button)\r
self.Bind(wx.EVT_BUTTON, self.OnTopClick, button)\r
\r
- self.transparentButton = wx.Button(self.toolbar, -1, "T", size=(21,21))\r
- self.toolbar.AddControl(self.transparentButton)\r
- self.Bind(wx.EVT_BUTTON, self.OnTransparentClick, self.transparentButton)\r
- self.XRayButton = wx.Button(self.toolbar, -1, "X-RAY", size=(21*2,21))\r
- self.toolbar.AddControl(self.XRayButton)\r
- self.Bind(wx.EVT_BUTTON, self.OnXRayClick, self.XRayButton)\r
- \r
+ self.viewSelect = wx.ComboBox(self.toolbar, -1, 'Model - Normal', choices=['Model - Normal', 'Model - Transparent', 'Model - X-Ray', 'GCode', 'Mixed'], style=wx.CB_DROPDOWN|wx.CB_READONLY)\r
+ self.toolbar.AddControl(self.viewSelect)\r
+ self.viewSelect.Bind(wx.EVT_TEXT, self.OnViewChange)\r
+ self.glCanvas.viewMode = self.viewSelect.GetValue()\r
+\r
self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)\r
self.toolbar.AddControl(self.layerSpin)\r
self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)\r
self.glCanvas.Refresh()\r
\r
def OnLayerNrChange(self, e):\r
- self.modelDirty = True\r
+ self.gcodeDirty = True\r
self.glCanvas.Refresh()\r
\r
def updateCenterX(self, x):\r
\r
def loadModelFile(self, filename):\r
self.modelFilename = filename\r
+ self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode"\r
#Do the STL file loading in a background thread so we don't block the UI.\r
thread = threading.Thread(target=self.DoModelLoad)\r
thread.start()\r
triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy()\r
triangleMesh.getMinimumZ()\r
self.triangleMesh = triangleMesh\r
- self.gcode = None\r
self.updateModelTransform()\r
wx.CallAfter(self.updateToolbar)\r
wx.CallAfter(self.glCanvas.Refresh)\r
+ \r
+ if os.path.isfile(self.gcodeFilename):\r
+ self.DoGCodeLoad()\r
\r
def DoGCodeLoad(self):\r
gcode = gcodeInterpreter.gcode(self.gcodeFilename)\r
- self.modelDirty = False\r
+ self.gcodeDirty = False\r
self.gcode = gcode\r
- self.triangleMesh = None\r
- self.modelDirty = True\r
+ self.gcodeDirty = True\r
wx.CallAfter(self.updateToolbar)\r
wx.CallAfter(self.glCanvas.Refresh)\r
\r
def updateToolbar(self):\r
- self.transparentButton.Show(self.triangleMesh != None)\r
- self.XRayButton.Show(self.triangleMesh != None)\r
self.layerSpin.Show(self.gcode != None)\r
if self.gcode != None:\r
self.layerSpin.SetRange(1, self.gcode.layerCount)\r
self.toolbar.Realize()\r
\r
- def OnTransparentClick(self, e):\r
- self.glCanvas.renderTransparent = not self.glCanvas.renderTransparent\r
- if self.glCanvas.renderTransparent:\r
- self.glCanvas.renderXRay = False\r
- self.glCanvas.Refresh()\r
- \r
- def OnXRayClick(self, e):\r
- self.glCanvas.renderXRay = not self.glCanvas.renderXRay\r
- if self.glCanvas.renderXRay:\r
- self.glCanvas.renderTransparent = False\r
+ def OnViewChange(self, e):\r
+ self.glCanvas.viewMode = self.viewSelect.GetValue()\r
self.glCanvas.Refresh()\r
\r
def updateModelTransform(self, f=0):\r
self.lineWidth = 0.4\r
self.fillLineWidth = 0.4\r
self.view3D = True\r
- self.renderTransparent = False\r
- self.renderXRay = False\r
self.modelDisplayList = None\r
+ self.gcodeDisplayList = None\r
\r
def OnMouseMotion(self,e):\r
if e.Dragging() and e.LeftIsDown():\r
self.Refresh()\r
\r
def OnEraseBackground(self,event):\r
+ #Workaround for windows background redraw flicker.\r
pass\r
\r
def OnSize(self,event):\r
glEnd()\r
\r
if self.parent.gcode != None:\r
- if self.modelDisplayList == None:\r
- self.modelDisplayList = glGenLists(1);\r
- if self.parent.modelDirty:\r
- self.parent.modelDirty = False\r
- glNewList(self.modelDisplayList, GL_COMPILE)\r
+ if self.gcodeDisplayList == None:\r
+ self.gcodeDisplayList = glGenLists(1);\r
+ if self.parent.gcodeDirty:\r
+ self.parent.gcodeDirty = False\r
+ glNewList(self.gcodeDisplayList, GL_COMPILE)\r
for path in self.parent.gcode.pathList:\r
c = 1.0\r
if path['layerNr'] != self.parent.layerSpin.GetValue():\r
for i in xrange(0, len(path['list'])-1):\r
v0 = path['list'][i]\r
v1 = path['list'][i+1]\r
+ dist = (v0 - v1).vsize()\r
+ if dist > 0:\r
+ extrusionMMperDist = (v1.e - v0.e) / (v0 - v1).vsize() / self.parent.gcode.stepsPerE\r
+ #TODO: Calculate line width from ePerDistance (needs layer thickness, steps_per_E and filament diameter)\r
normal = (v0 - v1).cross(util3d.Vector3(0,0,1))\r
normal.normalize()\r
v2 = v0 + normal * lineWidth\r
v1 = v1 - normal * lineWidth\r
\r
glBegin(GL_QUADS)\r
- glVertex3f(v0.x, v0.y, v0.z - 0.001)\r
- glVertex3f(v1.x, v1.y, v1.z - 0.001)\r
- glVertex3f(v3.x, v3.y, v3.z - 0.001)\r
- glVertex3f(v2.x, v2.y, v2.z - 0.001)\r
+ if path['pathType'] == 'FILL': #Remove depth buffer fighting on infill/wall overlap\r
+ glVertex3f(v0.x, v0.y, v0.z - 0.02)\r
+ glVertex3f(v1.x, v1.y, v1.z - 0.02)\r
+ glVertex3f(v3.x, v3.y, v3.z - 0.02)\r
+ glVertex3f(v2.x, v2.y, v2.z - 0.02)\r
+ else:\r
+ glVertex3f(v0.x, v0.y, v0.z - 0.01)\r
+ glVertex3f(v1.x, v1.y, v1.z - 0.01)\r
+ glVertex3f(v3.x, v3.y, v3.z - 0.01)\r
+ glVertex3f(v2.x, v2.y, v2.z - 0.01)\r
glEnd()\r
for v in path['list']:\r
glBegin(GL_TRIANGLE_FAN)\r
glVertex3f(v.x, v.y, v.z - 0.001)\r
for i in xrange(0, 16+1):\r
- glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.001)\r
+ if path['pathType'] == 'FILL': #Remove depth buffer fighting on infill/wall overlap\r
+ glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.02)\r
+ else:\r
+ glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.01)\r
glEnd()\r
else:\r
glBegin(GL_LINE_STRIP)\r
glVertex3f(v.x, v.y, v.z)\r
glEnd()\r
glEndList()\r
- glCallList(self.modelDisplayList)\r
+ if self.viewMode == "GCode" or self.viewMode == "Mixed":\r
+ glCallList(self.gcodeDisplayList)\r
\r
if self.parent.triangleMesh != None:\r
if self.modelDisplayList == None:\r
glPopMatrix()\r
glPopMatrix()\r
glEndList()\r
- if self.renderTransparent:\r
+ if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":\r
#If we want transparent, then first render a solid black model to remove the printer size lines.\r
- glDisable(GL_BLEND)\r
- glDisable(GL_LIGHTING)\r
- glColor3f(0,0,0)\r
- glCallList(self.modelDisplayList)\r
- glColor3f(1,1,1)\r
+ if self.viewMode != "Mixed":\r
+ glDisable(GL_BLEND)\r
+ glDisable(GL_LIGHTING)\r
+ glColor3f(0,0,0)\r
+ glCallList(self.modelDisplayList)\r
+ glColor3f(1,1,1)\r
#After the black model is rendered, render the model again but now with lighting and no depth testing.\r
glDisable(GL_DEPTH_TEST)\r
glEnable(GL_LIGHTING)\r
glBlendFunc(GL_ONE, GL_ONE)\r
glEnable(GL_LIGHTING)\r
glCallList(self.modelDisplayList)\r
- elif self.renderXRay:\r
+ elif self.viewMode == "Model - X-Ray":\r
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)\r
glDisable(GL_DEPTH_TEST)\r
glEnable(GL_STENCIL_TEST);\r
\r
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)\r
glStencilFunc(GL_EQUAL, 0, 1);\r
- glColor(0, 1, 0)\r
+ glColor(1, 1, 1)\r
glCallList(self.modelDisplayList)\r
glStencilFunc(GL_EQUAL, 1, 1);\r
glColor(1, 0, 0)\r
\r
glPushMatrix()\r
glLoadIdentity()\r
- for i in xrange(2, 20, 2):\r
+ for i in xrange(2, 15, 2):\r
glStencilFunc(GL_EQUAL, i, 0xFF);\r
- glColor(0, float(i)/10, 0)\r
+ glColor(float(i)/10, float(i)/10, float(i)/5)\r
glBegin(GL_QUADS)\r
glVertex3f(-1000,-1000,-1)\r
glVertex3f( 1000,-1000,-1)\r
glVertex3f( 1000, 1000,-1)\r
glVertex3f(-1000, 1000,-1)\r
glEnd()\r
- for i in xrange(1, 20, 2):\r
+ for i in xrange(1, 15, 2):\r
glStencilFunc(GL_EQUAL, i, 0xFF);\r
glColor(float(i)/10, 0, 0)\r
glBegin(GL_QUADS)\r
\r
glDisable(GL_STENCIL_TEST);\r
glEnable(GL_DEPTH_TEST)\r
- else:\r
+ elif self.viewMode == "Model - Normal":\r
glEnable(GL_LIGHTING)\r
glCallList(self.modelDisplayList)\r
glFlush()\r
size = self.GetSize()\r
glViewport(0,0, size.GetWidth(), size.GetHeight())\r
\r
- if self.renderTransparent:\r
+ if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":\r
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0])\r
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0])\r
else:\r