def doFileLoadThread(self): for obj in self.objectList: if obj.filename is not None and os.path.isfile( obj.filename) and obj.fileTime != os.stat( obj.filename).st_mtime: obj.fileTime = os.stat(obj.filename).st_mtime try: mesh = meshLoader.loadMesh(obj.filename) except: wx.CallAfter(self.ShowWarningPopup, 'Failed to load %s' % (obj.filename)) obj.mesh = None obj.filename = None else: obj.mesh = mesh obj.dirty = True obj.steepDirty = True self.updateModelTransform() if self.objectsBoundaryCircleSize is not None: self.glCanvas.zoom = self.objectsBoundaryCircleSize * 6.0 self.errorList = [] wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) elif obj.filename is None or not os.path.isfile(obj.filename): obj.mesh = None obj.filename = None if os.path.isfile( self.gcodeFilename) and self.gcodeFileTime != os.stat( self.gcodeFilename).st_mtime: self.gcodeFileTime = os.stat(self.gcodeFilename).st_mtime self.gcodeDirty = True self.gcode = gcodeInterpreter.gcode() self.gcode.progressCallback = self.loadProgress self.gcode.load(self.gcodeFilename) 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 is not 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 wx.CallAfter(self.checkReloadFileTimer.Start, 1000)
def doFileLoadThread(self): for obj in self.objectList: if obj.filename is not None and os.path.isfile( obj.filename) and obj.fileTime != os.stat( obj.filename).st_mtime: obj.fileTime = os.stat(obj.filename).st_mtime mesh = meshLoader.loadMesh(obj.filename) obj.mesh = mesh obj.dirty = True obj.steepDirty = True self.updateModelTransform() self.OnScaleMax(True) self.glCanvas.zoom = numpy.max(self.objectsSize) * 3.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 is not 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 wx.CallAfter(self.checkReloadFileTimer.Start, 1000)
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.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 DrawGCodeLayer(layer, drawQuick=True): 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, 1], [0.0, 0.5, 0.5, 1], [0.5, 0.0, 0.5, 1]] moveColor = [0, 0, 1, 0.5] retractColor = [1, 0, 0.5, 0.5] supportColor = [0, 1, 1, 1] extrudeColor = [[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1], [1, 0, 1, 1]] innerWallColor = [0, 1, 0, 1] skirtColor = [0, 0.5, 0.5, 1] prevPathWasRetract = False glDisable(GL_CULL_FACE) for path in layer: if path.type == 'move': if prevPathWasRetract: c = retractColor else: c = moveColor if drawQuick: continue 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[path.extruder] if path.type == 'retract': c = retractColor if path.type == 'extrude' and not drawQuick: drawLength = 0.0 prevNormal = None for i in xrange(0, len(path.points) - 1): v0 = path.points[i] v1 = path.points[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 * v1.extrudeAmountMultiply 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) glColor4fv(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 is not None: n = (normal + prevNormal) n.normalize() vv4 = v0 + n * lineWidth vv5 = v0 - n * lineWidth glBegin(GL_QUADS) glColor4fv(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: glColor4fv(c) glBegin(GL_TRIANGLES) for v in path.points: glVertex3f(v[0], v[1], v[2]) glEnd() if not path.type == 'move': prevPathWasRetract = False #if path.type == 'retract' and path.points[0].almostEqual(path.points[-1]): # prevPathWasRetract = True glEnable(GL_CULL_FACE)
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.objectsBoundaryCircleSize = None self.loadThread = None self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 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.OnWarningPopup, 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) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.glCanvas, 1, flag=wx.EXPAND) self.SetSizer(sizer) self.checkReloadFileTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnCheckReloadFile, self.checkReloadFileTimer) self.checkReloadFileTimer.Start(1000) group = [] self.rotateToolButton = openglGui.glRadioButton( self.glCanvas, 8, 'Rotate', (0, -1), group, self.OnToolSelect) self.scaleToolButton = openglGui.glRadioButton(self.glCanvas, 9, 'Scale', (1, -1), group, self.OnToolSelect) self.mirrorToolButton = openglGui.glRadioButton( self.glCanvas, 10, 'Mirror', (2, -1), group, self.OnToolSelect) self.resetRotationButton = openglGui.glButton(self.glCanvas, 12, 'Reset', (0, -2), self.OnRotateReset) self.layFlatButton = openglGui.glButton(self.glCanvas, 16, 'Lay flat', (0, -3), self.OnLayFlat) self.resetScaleButton = openglGui.glButton(self.glCanvas, 13, 'Reset', (1, -2), self.OnScaleReset) self.scaleMaxButton = openglGui.glButton(self.glCanvas, 17, 'To max', (1, -3), self.OnScaleMax) self.mirrorXButton = openglGui.glButton(self.glCanvas, 14, 'Mirror X', (2, -2), lambda: self.OnMirror(0)) self.mirrorYButton = openglGui.glButton(self.glCanvas, 18, 'Mirror Y', (2, -3), lambda: self.OnMirror(1)) self.mirrorZButton = openglGui.glButton(self.glCanvas, 22, 'Mirror Z', (2, -4), lambda: self.OnMirror(2)) self.openFileButton = openglGui.glButton( self.glCanvas, 4, 'Load', (0, 0), lambda: self.GetParent().GetParent().GetParent( )._showModelLoadDialog(1)) self.sliceButton = openglGui.glButton( self.glCanvas, 5, 'Prepare', (1, 0), lambda: self.GetParent().GetParent().GetParent().OnSlice(None)) self.printButton = openglGui.glButton( self.glCanvas, 6, 'Print', (2, 0), lambda: self.GetParent().GetParent().GetParent().OnPrint(None)) self.rotateToolButton.setExpandArrow(True) self.scaleToolButton.setExpandArrow(True) self.mirrorToolButton.setExpandArrow(True) extruderCount = int(profile.getPreference('extruder_amount')) if extruderCount > 1: openglGui.glButton( self.glCanvas, 4, 'Load dual', (0, 1), lambda: self.GetParent( ).GetParent().GetParent()._showModelLoadDialog(2)) if extruderCount > 2: openglGui.glButton( self.glCanvas, 4, 'Load triple', (0, 2), lambda: self. GetParent().GetParent().GetParent()._showModelLoadDialog(3)) if extruderCount > 3: openglGui.glButton( self.glCanvas, 4, 'Load quad', (0, 3), lambda: self.GetParent( ).GetParent().GetParent()._showModelLoadDialog(4)) self.scaleForm = openglGui.glFrame(self.glCanvas, (2, -2)) openglGui.glGuiLayoutGrid(self.scaleForm) openglGui.glLabel(self.scaleForm, 'Scale X', (0, 0)) self.scaleXctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 0), lambda value: self.OnScaleEntry(value, 0)) openglGui.glLabel(self.scaleForm, 'Scale Y', (0, 1)) self.scaleYctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 1), lambda value: self.OnScaleEntry(value, 1)) openglGui.glLabel(self.scaleForm, 'Scale Z', (0, 2)) self.scaleZctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 2), lambda value: self.OnScaleEntry(value, 2)) openglGui.glLabel(self.scaleForm, 'Size X (mm)', (0, 4)) self.scaleXmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 4), lambda value: self.OnScaleEntryMM(value, 0)) openglGui.glLabel(self.scaleForm, 'Size Y (mm)', (0, 5)) self.scaleYmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 5), lambda value: self.OnScaleEntryMM(value, 1)) openglGui.glLabel(self.scaleForm, 'Size Z (mm)', (0, 6)) self.scaleZmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 6), lambda value: self.OnScaleEntryMM(value, 2)) openglGui.glLabel(self.scaleForm, 'Uniform scale', (0, 8)) self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1, 8), None) self.viewSelection = openglGui.glComboButton( self.glCanvas, 'View mode', [7, 11, 15, 19, 23], ['Normal', 'Transparent', 'X-Ray', 'Overhang', 'Layers'], (-1, 0), self.OnViewChange) self.layerSelect = openglGui.glSlider(self.glCanvas, 0, 0, 100, (-1, -2), lambda: self.Refresh()) self.OnViewChange() self.OnToolSelect() self.updateModelTransform() self.matrix = numpy.matrix( numpy.array(profile.getObjectMatrix(), numpy.float64).reshape(( 3, 3, )))
def _load(self, gcodeFile): filePos = 0 pos = util3d.Vector3() posOffset = util3d.Vector3() currentE = 0.0 totalExtrusion = 0.0 maxExtrusion = 0.0 currentExtruder = 0 extrudeAmountMultiply = 1.0 totalMoveTimeMinute = 0.0 absoluteE = True scale = 1.0 posAbs = True feedRate = 3600 layerThickness = 0.1 pathType = 'CUSTOM' startCodeDone = False currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos.copy()) currentPath.list[0].e = totalExtrusion currentPath.list[0].extrudeAmountMultiply = extrudeAmountMultiply currentLayer.append(currentPath) for line in gcodeFile: if type(line) is tuple: line = line[0] if self.progressCallback != None: if filePos != gcodeFile.tell(): filePos = gcodeFile.tell() self.progressCallback( float(filePos) / float(self._fileSize)) #Parse Cura_SF comments if line.startswith(';TYPE:'): pathType = line[6:].strip() if pathType != "CUSTOM": startCodeDone = True if ';' in line: #Slic3r GCode comment parser comment = line[line.find(';') + 1:].strip() if comment == 'fill': pathType = 'FILL' elif comment == 'perimeter': pathType = 'WALL-INNER' elif comment == 'skirt': pathType = 'SKIRT' if comment.startswith('LAYER:'): self.layerList.append(currentLayer) currentLayer = [] if pathType != "CUSTOM": startCodeDone = True line = line[0:line.find(';')] T = self.getCodeInt(line, 'T') if T is not None: if currentExtruder > 0: posOffset.x -= profile.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset.y -= profile.getPreferenceFloat( 'extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset.x += profile.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset.y += profile.getPreferenceFloat( 'extruder_offset_y%d' % (currentExtruder)) G = self.getCodeInt(line, 'G') if G is not None: if G == 0 or G == 1: #Move x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') f = self.getCodeFloat(line, 'F') oldPos = pos.copy() if x is not None: if posAbs: pos.x = x * scale + posOffset.x else: pos.x += x * scale if y is not None: if posAbs: pos.y = y * scale + posOffset.y else: pos.y += y * scale if z is not None: if posAbs: pos.z = z * scale + posOffset.z else: pos.z += z * scale if f is not None: feedRate = f if x is not None or y is not None or z is not None: totalMoveTimeMinute += (oldPos - pos).vsize() / feedRate moveType = 'move' if e is not None: if not absoluteE: e += currentE if posAbs: if e > currentE: moveType = 'extrude' if e < currentE: moveType = 'retract' else: if e > 0: moveType = 'extrude' if e < 0: moveType = 'retract' totalExtrusion += e - currentE currentE = e if totalExtrusion > maxExtrusion: maxExtrusion = totalExtrusion if moveType == 'move' and oldPos.z != pos.z: if oldPos.z > pos.z and abs( oldPos.z - pos.z) > 5.0 and pos.z < 1.0: oldPos.z = 0.0 layerThickness = abs(oldPos.z - pos.z) if currentPath.type != moveType or currentPath.pathType != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.list[-1]) currentLayer.append(currentPath) newPos = pos.copy() newPos.e = totalExtrusion newPos.extrudeAmountMultiply = extrudeAmountMultiply currentPath.list.append(newPos) elif G == 4: #Delay S = self.getCodeFloat(line, 'S') if S is not None: totalMoveTimeMinute += S / 60 P = self.getCodeFloat(line, 'P') if P is not None: totalMoveTimeMinute += P / 60 / 1000 elif G == 20: #Units are inches scale = 25.4 elif G == 21: #Units are mm scale = 1.0 elif G == 28: #Home x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') if x is None and y is None and z is None: pos = util3d.Vector3() else: if x is not None: pos.x = 0.0 if y is not None: pos.y = 0.0 if z is not None: pos.z = 0.0 elif G == 90: #Absolute position posAbs = True elif G == 91: #Relative position posAbs = False elif G == 92: x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') if e is not None: currentE = e if x is not None: posOffset.x = pos.x - x if y is not None: posOffset.y = pos.y - y if z is not None: posOffset.z = pos.z - z else: print "Unknown G code:" + str(G) else: M = self.getCodeInt(line, 'M') if M is not None: if M == 1: #Message with possible wait (ignored) pass elif M == 80: #Enable power supply pass elif M == 81: #Suicide/disable power supply pass elif M == 82: #Absolute E absoluteE = True elif M == 83: #Relative E absoluteE = False elif M == 84: #Disable step drivers pass elif M == 92: #Set steps per unit pass elif M == 101: #Enable extruder pass elif M == 103: #Disable extruder pass elif M == 104: #Set temperature, no wait pass elif M == 105: #Get temperature pass elif M == 106: #Enable fan pass elif M == 107: #Disable fan pass elif M == 108: #Extruder RPM (these should not be in the final GCode, but they are) pass elif M == 109: #Set temperature, wait pass elif M == 110: #Reset N counter pass elif M == 113: #Extruder PWM (these should not be in the final GCode, but they are) pass elif M == 140: #Set bed temperature pass elif M == 190: #Set bed temperature & wait pass elif M == 221: #Extrude amount multiplier s = self.getCodeFloat(line, 'S') if s != None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) self.layerList.append(currentLayer) self.extrusionAmount = maxExtrusion self.totalMoveTimeMinute = totalMoveTimeMinute
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.getSize() / 2 + numpy.array([ item.centerX, item.centerY, 0 ]) - extraSizeMin #- self.parent.extruderOffset[item.extruder] iMax1 = item.getSize() / 2 + numpy.array([ item.centerX, item.centerY, 0 ]) + extraSizeMax #- self.parent.extruderOffset[item.extruder] if iMin1[0] < -self.parent.headSizeMin[0] or iMin1[ 1] < -self.parent.headSizeMin[1]: item.validPlacement = False if iMax1[0] > machineSize[0] + self.parent.headSizeMax[0] or iMax1[ 1] > machineSize[1] + self.parent.headSizeMax[1]: item.validPlacement = False for idx2 in xrange(0, idx1): item2 = self.parent.list[idx2] iMin2 = -item2.getSize() / 2 + numpy.array( [item2.centerX, item2.centerY, 0]) iMax2 = item2.getSize() / 2 + 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 is None: item.modelDisplayList = glGenLists(1) if item.modelDirty: item.modelDirty = False 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) vMin = item.getMinimum() vMax = item.getMaximum() offset = -vMin - (vMax - vMin) / 2 matrix = opengl.convert3x3MatrixTo4x4(item.matrix) glPushMatrix() glTranslate(0, 0, item.getSize()[2] / 2) if self.tempMatrix is not None and item == self.parent.selection: tempMatrix = opengl.convert3x3MatrixTo4x4(self.tempMatrix) glMultMatrixf(tempMatrix) glTranslate(0, 0, -item.getSize()[2] / 2) glTranslate(offset[0], offset[1], -vMin[2]) glMultMatrixf(matrix) glCallList(item.modelDisplayList) glPopMatrix() vMin = -item.getSize() / 2 vMax = item.getSize() / 2 vMax[2] -= vMin[2] vMin[2] = 0 vMinHead = vMin - extraSizeMin # - self.parent.extruderOffset[item.extruder] vMaxHead = vMax + extraSizeMax # - self.parent.extruderOffset[item.extruder] glDisable(GL_LIGHTING) if not self.parent.alwaysAutoPlace: glLineWidth(1) 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])) if self.parent.selection is not None: glPushMatrix() glTranslate(self.parent.selection.centerX, self.parent.selection.centerY, self.parent.selection.getSize()[2] / 2) self.parent.tool.OnDraw() glPopMatrix()
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.objectsBoundaryCircleSize = None self.loadThread = None self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 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.OnWarningPopup, 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.showSteepOverhang = toolbarUtil.ToggleButton( self.toolbar, '', 'steepOverhang-on.png', 'steepOverhang-off.png', 'Show steep overhang', 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) 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) self.SetSizer(sizer) self.checkReloadFileTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnCheckReloadFile, self.checkReloadFileTimer) self.checkReloadFileTimer.Start(1000) group = [] self.rotateToolButton = openglGui.glRadioButton( self.glCanvas, 1, 'Rotate', (0, 1), group, self.OnToolSelect) self.scaleToolButton = openglGui.glRadioButton(self.glCanvas, 2, 'Scale', (0, 2), group, self.OnToolSelect) self.mirrorToolButton = openglGui.glRadioButton( self.glCanvas, 12, 'Mirror', (0, 3), group, self.OnToolSelect) self.resetRotationButton = openglGui.glButton(self.glCanvas, 4, 'Reset rotation', (1, 1), self.OnRotateReset) self.layFlatButton = openglGui.glButton(self.glCanvas, 5, 'Lay flat', (1, 2), self.OnLayFlat) self.resetScaleButton = openglGui.glButton(self.glCanvas, 8, 'Scale reset', (1, 1), self.OnScaleReset) self.scaleMaxButton = openglGui.glButton(self.glCanvas, 9, 'Scale to machine size', (1, 2), self.OnScaleMax) self.mirrorXButton = openglGui.glButton(self.glCanvas, 12, 'Mirror X', (1, 1), lambda: self.OnMirror(0)) self.mirrorYButton = openglGui.glButton(self.glCanvas, 13, 'Mirror Y', (1, 2), lambda: self.OnMirror(1)) self.mirrorZButton = openglGui.glButton(self.glCanvas, 14, 'Mirror Z', (1, 3), lambda: self.OnMirror(2)) self.openFileButton = openglGui.glButton( self.glCanvas, 3, 'Load model', (0, 0), lambda: self.GetParent(). GetParent().GetParent()._showModelLoadDialog(1)) self.sliceButton = openglGui.glButton( self.glCanvas, 6, 'Prepare model', (0, -2), lambda: self.GetParent().GetParent().GetParent().OnSlice(None)) self.printButton = openglGui.glButton( self.glCanvas, 7, 'Print model', (0, -1), lambda: self.GetParent().GetParent().GetParent().OnPrint(None)) extruderCount = int(profile.getPreference('extruder_amount')) if extruderCount > 1: openglGui.glButton( self.glCanvas, 3, 'Load dual model', (1, 0), lambda: self.GetParent().GetParent( ).GetParent()._showModelLoadDialog(2)) if extruderCount > 2: openglGui.glButton( self.glCanvas, 3, 'Load triple model', (2, 0), lambda: self. GetParent().GetParent().GetParent()._showModelLoadDialog(3)) if extruderCount > 3: openglGui.glButton( self.glCanvas, 3, 'Load quad model', (3, 0), lambda: self.GetParent().GetParent( ).GetParent()._showModelLoadDialog(4)) self.scaleForm = openglGui.glFrame(self.glCanvas, (1, 3)) openglGui.glGuiLayoutGrid(self.scaleForm) openglGui.glLabel(self.scaleForm, 'Scale X', (0, 0)) self.scaleXctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 0), lambda value: self.OnScaleEntry(value, 0)) openglGui.glLabel(self.scaleForm, 'Scale Y', (0, 1)) self.scaleYctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 1), lambda value: self.OnScaleEntry(value, 1)) openglGui.glLabel(self.scaleForm, 'Scale Z', (0, 2)) self.scaleZctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 2), lambda value: self.OnScaleEntry(value, 2)) openglGui.glLabel(self.scaleForm, 'Size X (mm)', (0, 4)) self.scaleXmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 4), lambda value: self.OnScaleEntryMM(value, 0)) openglGui.glLabel(self.scaleForm, 'Size Y (mm)', (0, 5)) self.scaleYmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 5), lambda value: self.OnScaleEntryMM(value, 1)) openglGui.glLabel(self.scaleForm, 'Size Z (mm)', (0, 6)) self.scaleZmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 6), lambda value: self.OnScaleEntryMM(value, 2)) openglGui.glLabel(self.scaleForm, 'Uniform scale', (0, 8)) self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1, 8), None) self.OnViewChange() self.OnToolSelect() self.returnToModelViewAndUpdateModel() self.matrix = numpy.matrix( numpy.array(profile.getObjectMatrix(), numpy.float64).reshape(( 3, 3, )))