def doFileLoadThread(self): for obj in self.objectList: if obj.filename != None and os.path.isfile( obj.filename) and obj.fileTime != os.stat( obj.filename).st_mtime: obj.ileTime = os.stat(obj.filename).st_mtime mesh = meshLoader.loadMesh(obj.filename) obj.dirty = False obj.mesh = mesh self.updateModelTransform() scale = profile.getProfileSettingFloat('model_scale') size = (self.objectsMaxV - self.objectsMinV) * scale if size[0] > self.machineSize.x or size[ 1] > self.machineSize.y or size[2] > self.machineSize.z: self.OnScaleMax(None) self.glCanvas.zoom = numpy.max(size) * 2.5 self.errorList = [] wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) if os.path.isfile( self.gcodeFilename) and self.gcodeFileTime != os.stat( self.gcodeFilename).st_mtime: self.gcodeFileTime = os.stat(self.gcodeFilename).st_mtime gcode = gcodeInterpreter.gcode() gcode.progressCallback = self.loadProgress gcode.load(self.gcodeFilename) self.gcodeDirty = False self.gcode = gcode self.gcodeDirty = True errorList = [] for line in open(self.gcodeFilename, "rt"): res = re.search( ';Model error\(([a-z ]*)\): \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\) \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\)', line) if res != None: v1 = util3d.Vector3(float(res.group(2)), float(res.group(3)), float(res.group(4))) v2 = util3d.Vector3(float(res.group(5)), float(res.group(6)), float(res.group(7))) errorList.append([v1, v2]) self.errorList = errorList wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) elif not os.path.isfile(self.gcodeFilename): self.gcode = None
def doFileLoadThread(self): for obj in self.objectList: if obj.filename != None and os.path.isfile( obj.filename) and obj.fileTime != os.stat( obj.filename).st_mtime: obj.ileTime = os.stat(obj.filename).st_mtime mesh = stl.stlModel() mesh.load(obj.filename) obj.dirty = False obj.mesh = mesh self.updateModelTransform() wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) if os.path.isfile( self.gcodeFilename) and self.gcodeFileTime != os.stat( self.gcodeFilename).st_mtime: self.gcodeFileTime = os.stat(self.gcodeFilename).st_mtime gcode = gcodeInterpreter.gcode() gcode.progressCallback = self.loadProgress gcode.load(self.gcodeFilename) self.gcodeDirty = False self.errorList = [] self.gcode = gcode self.gcodeDirty = True wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) elif not os.path.isfile(self.gcodeFilename): self.gcode = None if os.path.isfile(self.logFilename): errorList = [] for line in open(self.logFilename, "rt"): res = re.search( 'Model error\(([a-z ]*)\): \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\) \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\)', line) if res != None: v1 = util3d.Vector3(float(res.group(2)), float(res.group(3)), float(res.group(4))) v2 = util3d.Vector3(float(res.group(5)), float(res.group(6)), float(res.group(7))) errorList.append([v1, v2]) self.errorList = errorList wx.CallAfter(self.glCanvas.Refresh)
def __init__(self): super(flatSlicerWindow, self).__init__(None, title='Cura - ' + version.getVersion()) self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.filename = None self.svg = None wx.EVT_CLOSE(self, self.OnClose) self.panel = wx.Panel(self, -1) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) #self.SetIcon(icon.getMainIcon()) self.toolbar = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar, self.OnOpenSVG, 'open.png', 'Open SVG') self.toolbar.AddSeparator() group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner') self.toolbar.Realize() sizer = wx.GridBagSizer(2, 2) self.panel.SetSizer(sizer) self.preview = PreviewGLCanvas(self.panel, self) sizer.Add(self.toolbar, (0, 0), span=(1, 1), flag=wx.EXPAND | wx.LEFT | wx.RIGHT) sizer.Add(self.preview, (1, 0), span=(5, 1), flag=wx.EXPAND) sizer.AddGrowableCol(0) sizer.AddGrowableRow(1) self.SetSize((600, 400))
def __init__(self, parent): super(previewPanel, self).__init__(parent, -1) self.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DDKSHADOW)) self.SetMinSize((440, 320)) self.objectList = [] self.errorList = [] self.gcode = None self.objectsMinV = None self.objectsMaxV = None self.loadThread = None self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineCenter = util3d.Vector3( float(profile.getProfileSetting('machine_center_x')), float(profile.getProfileSetting('machine_center_y')), 0) self.glCanvas = PreviewGLCanvas(self) #Create the popup window self.warningPopup = wx.PopupWindow(self, flags=wx.BORDER_SIMPLE) self.warningPopup.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK)) self.warningPopup.text = wx.StaticText( self.warningPopup, -1, 'Reset scale, rotation and mirror?') self.warningPopup.yesButton = wx.Button(self.warningPopup, -1, 'yes', style=wx.BU_EXACTFIT) self.warningPopup.noButton = wx.Button(self.warningPopup, -1, 'no', style=wx.BU_EXACTFIT) self.warningPopup.sizer = wx.BoxSizer(wx.HORIZONTAL) self.warningPopup.SetSizer(self.warningPopup.sizer) self.warningPopup.sizer.Add(self.warningPopup.text, 1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=1) self.warningPopup.sizer.Add(self.warningPopup.yesButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.sizer.Add(self.warningPopup.noButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.Fit() self.warningPopup.Layout() self.warningPopup.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnHideWarning, self.warningPopup.timer) self.Bind(wx.EVT_BUTTON, self.OnResetAll, self.warningPopup.yesButton) self.Bind(wx.EVT_BUTTON, self.OnHideWarning, self.warningPopup.noButton) parent.Bind(wx.EVT_MOVE, self.OnMove) parent.Bind(wx.EVT_SIZE, self.OnMove) self.toolbar = toolbarUtil.Toolbar(self) group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick) self.toolbar.AddSeparator() self.showBorderButton = toolbarUtil.ToggleButton( self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange) self.toolbar.AddSeparator() group = [] self.normalViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Normal model view', callback=self.OnViewChange) self.transparentViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-transparent-on.png', 'view-transparent-off.png', 'Transparent model view', callback=self.OnViewChange) self.xrayViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-xray-on.png', 'view-xray-off.png', 'X-Ray view', callback=self.OnViewChange) self.gcodeViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-gcode-on.png', 'view-gcode-off.png', 'GCode view', callback=self.OnViewChange) self.mixedViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-mixed-on.png', 'view-mixed-off.png', 'Mixed model/GCode view', callback=self.OnViewChange) self.toolbar.AddSeparator() self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21 * 4, 21), style=wx.SP_ARROW_KEYS) self.toolbar.AddControl(self.layerSpin) self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin) self.toolbar2 = toolbarUtil.Toolbar(self) # Mirror self.mirrorX = toolbarUtil.ToggleButton( self.toolbar2, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.updateModelTransform) self.mirrorY = toolbarUtil.ToggleButton( self.toolbar2, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.updateModelTransform) self.mirrorZ = toolbarUtil.ToggleButton( self.toolbar2, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.updateModelTransform) self.toolbar2.AddSeparator() # Swap self.swapXZ = toolbarUtil.ToggleButton( self.toolbar2, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.updateModelTransform) self.swapYZ = toolbarUtil.ToggleButton( self.toolbar2, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.updateModelTransform) self.toolbar2.AddSeparator() # Scale self.scaleReset = toolbarUtil.NormalButton(self.toolbar2, self.OnScaleReset, 'object-scale.png', 'Reset model scale') self.scale = wx.TextCtrl(self.toolbar2, -1, profile.getProfileSetting('model_scale'), size=(21 * 2, 21)) self.toolbar2.AddControl(self.scale) self.scale.Bind(wx.EVT_TEXT, self.OnScale) self.scaleMax = toolbarUtil.NormalButton( self.toolbar2, self.OnScaleMax, 'object-max-size.png', 'Scale object to fit machine size') self.toolbar2.AddSeparator() # Multiply #self.mulXadd = toolbarUtil.NormalButton(self.toolbar2, self.OnMulXAddClick, 'object-mul-x-add.png', 'Increase number of models on X axis') #self.mulXsub = toolbarUtil.NormalButton(self.toolbar2, self.OnMulXSubClick, 'object-mul-x-sub.png', 'Decrease number of models on X axis') #self.mulYadd = toolbarUtil.NormalButton(self.toolbar2, self.OnMulYAddClick, 'object-mul-y-add.png', 'Increase number of models on Y axis') #self.mulYsub = toolbarUtil.NormalButton(self.toolbar2, self.OnMulYSubClick, 'object-mul-y-sub.png', 'Decrease number of models on Y axis') #self.toolbar2.AddSeparator() # Rotate self.rotateReset = toolbarUtil.NormalButton(self.toolbar2, self.OnRotateReset, 'object-rotate.png', 'Reset model rotation') self.rotate = wx.SpinCtrl( self.toolbar2, -1, profile.getProfileSetting('model_rotate_base'), size=(21 * 3, 21), style=wx.SP_WRAP | wx.SP_ARROW_KEYS) self.rotate.SetRange(0, 360) self.rotate.Bind(wx.EVT_TEXT, self.OnRotate) self.toolbar2.AddControl(self.rotate) self.toolbar2.Realize() self.OnViewChange() sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.toolbar, 0, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=1) sizer.Add(self.glCanvas, 1, flag=wx.EXPAND) sizer.Add(self.toolbar2, 0, flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, border=1) self.SetSizer(sizer)
def DrawGCodeLayer(layer): filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentArea = math.pi * filamentRadius * filamentRadius lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10 fillCycle = 0 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]] moveColor = [0, 0, 1] retractColor = [1, 0, 0.5] supportColor = [0, 1, 1] extrudeColor = [1, 0, 0] innerWallColor = [0, 1, 0] skirtColor = [0, 0.5, 0.5] prevPathWasRetract = False glDisable(GL_CULL_FACE) for path in layer: if path.type == 'move': if prevPathWasRetract: c = retractColor else: c = moveColor zOffset = 0.01 if path.type == 'extrude': if path.pathType == 'FILL': c = fillColorCycle[fillCycle] fillCycle = (fillCycle + 1) % len(fillColorCycle) elif path.pathType == 'WALL-INNER': c = innerWallColor zOffset = 0.02 elif path.pathType == 'SUPPORT': c = supportColor elif path.pathType == 'SKIRT': c = skirtColor else: c = extrudeColor if path.type == 'retract': c = [0, 1, 1] if path.type == 'extrude': drawLength = 0.0 prevNormal = None for i in xrange(0, len(path.list) - 1): v0 = path.list[i] v1 = path.list[i + 1] # Calculate line width from ePerDistance (needs layer thickness and filament diameter) dist = (v0 - v1).vsize() if dist > 0 and path.layerThickness > 0: extrusionMMperDist = (v1.e - v0.e) / dist lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 drawLength += (v0 - v1).vsize() normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1)) normal.normalize() vv2 = v0 + normal * lineWidth vv3 = v1 + normal * lineWidth vv0 = v0 - normal * lineWidth vv1 = v1 - normal * lineWidth glBegin(GL_QUADS) glColor3fv(c) glVertex3f(vv0.x, vv0.y, vv0.z - zOffset) glVertex3f(vv1.x, vv1.y, vv1.z - zOffset) glVertex3f(vv3.x, vv3.y, vv3.z - zOffset) glVertex3f(vv2.x, vv2.y, vv2.z - zOffset) glEnd() if prevNormal != None: n = (normal + prevNormal) n.normalize() vv4 = v0 + n * lineWidth vv5 = v0 - n * lineWidth glBegin(GL_QUADS) glColor3fv(c) glVertex3f(vv2.x, vv2.y, vv2.z - zOffset) glVertex3f(vv4.x, vv4.y, vv4.z - zOffset) glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset) glVertex3f(v0.x, v0.y, v0.z - zOffset) glVertex3f(vv0.x, vv0.y, vv0.z - zOffset) glVertex3f(vv5.x, vv5.y, vv5.z - zOffset) glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset) glVertex3f(v0.x, v0.y, v0.z - zOffset) glEnd() prevNormal = normal prevVv1 = vv1 prevVv3 = vv3 else: glBegin(GL_LINE_STRIP) glColor3fv(c) for v in path.list: glVertex3f(v.x, v.y, v.z) glEnd() if not path.type == 'move': prevPathWasRetract = False if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]): prevPathWasRetract = True glEnable(GL_CULL_FACE)
def OnDraw(self): machineSize = self.parent.machineSize extraSizeMin, extraSizeMax = self.parent.getExtraHeadSize() for item in self.parent.list: item.validPlacement = True item.gotHit = False for idx1 in xrange(0, len(self.parent.list)): item = self.parent.list[idx1] iMin1 = (item.getMinimum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - extraSizeMin - self.parent.extruderOffset[item.extruder] iMax1 = (item.getMaximum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) + extraSizeMax - self.parent.extruderOffset[item.extruder] for idx2 in xrange(0, idx1): item2 = self.parent.list[idx2] iMin2 = (item2.getMinimum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0]) iMax2 = (item2.getMaximum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0]) if item != item2 and iMax1[0] >= iMin2[0] and iMin1[0] <= iMax2[0] and iMax1[1] >= iMin2[1] and iMin1[1] <= iMax2[1]: item.validPlacement = False item2.gotHit = True seenSelected = False for item in self.parent.list: if item == self.parent.selection: seenSelected = True if item.modelDisplayList == None: item.modelDisplayList = glGenLists(1); if item.modelDirty: item.modelDirty = False modelSize = item.getMaximum() - item.getMinimum() glNewList(item.modelDisplayList, GL_COMPILE) opengl.DrawMesh(item.mesh) glEndList() if item.validPlacement: if self.parent.selection == item: glLightfv(GL_LIGHT0, GL_DIFFUSE, map(lambda x: x + 0.2, self.objColor)) glLightfv(GL_LIGHT0, GL_AMBIENT, map(lambda x: x / 2, self.objColor)) else: glLightfv(GL_LIGHT0, GL_DIFFUSE, self.objColor) glLightfv(GL_LIGHT0, GL_AMBIENT, map(lambda x: x / 2, self.objColor)) else: if self.parent.selection == item: glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.0, 0.0, 0.0]) glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.0, 0.0, 0.0]) else: glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.0, 0.0, 0.0]) glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.0, 0.0, 0.0]) glPushMatrix() glEnable(GL_LIGHTING) glTranslate(item.centerX, item.centerY, 0) glPushMatrix() glScalef(item.scale, item.scale, item.scale) glCallList(item.modelDisplayList) glPopMatrix() vMin = item.getMinimum() * item.scale vMax = item.getMaximum() * item.scale vMinHead = vMin - extraSizeMin - self.parent.extruderOffset[item.extruder] vMaxHead = vMax + extraSizeMax - self.parent.extruderOffset[item.extruder] glDisable(GL_LIGHTING) if not self.parent.alwaysAutoPlace: if self.parent.selection == item: if item.gotHit: glColor3f(1.0,0.0,0.3) else: glColor3f(1.0,0.0,1.0) opengl.DrawBox(vMin, vMax) if item.gotHit: glColor3f(1.0,0.3,0.0) else: glColor3f(1.0,1.0,0.0) opengl.DrawBox(vMinHead, vMaxHead) elif seenSelected: if item.gotHit: glColor3f(0.5,0.0,0.1) else: glColor3f(0.5,0.0,0.5) opengl.DrawBox(vMinHead, vMaxHead) else: if item.gotHit: glColor3f(0.7,0.1,0.0) else: glColor3f(0.7,0.7,0.0) opengl.DrawBox(vMin, vMax) glPopMatrix() opengl.DrawMachine(util3d.Vector3(machineSize[0], machineSize[1], machineSize[2])) glFlush()