Exemple #1
0
 def mcStateChange(self, state):
     if self.comm is None:
         return
     if self.comm.isOperational():
         if self._wizardState == 0:
             wx.CallAfter(self.infoBox.SetInfo, 'Homing printer...')
             self.comm.sendCommand('M105')
             self.comm.sendCommand('G28')
             self._wizardState = 1
         elif self._wizardState == 10 and not self.comm.isPrinting():
             self.comm.sendCommand(
                 'G1 Z15 F%d' %
                 (profile.getProfileSettingFloat('max_z_speed') * 60))
             self.comm.sendCommand('G92 E0')
             self.comm.sendCommand(
                 'G1 E-10 F%d' %
                 (profile.getProfileSettingFloat('retraction_speed') * 60))
             self.comm.sendCommand('M104 S0')
             wx.CallAfter(
                 self.infoBox.SetInfo,
                 'Calibration finished.\nThe squares on the bed should slightly touch each other.'
             )
             wx.CallAfter(self.infoBox.SetReadyIndicator)
             wx.CallAfter(self.GetParent().FindWindowById(
                 wx.ID_FORWARD).Enable)
             wx.CallAfter(self.connectButton.Enable, True)
             self._wizardState = 11
     elif self.comm.isError():
         wx.CallAfter(
             self.infoBox.SetError,
             'Failed to establish connection with the printer.',
             'http://wiki.ultimaker.com/Cura:_Connection_problems')
Exemple #2
0
	def loadModelFiles(self, filelist, showWarning = False):
		while len(filelist) > len(self.objectList):
			self.objectList.append(previewObject())
		for idx in xrange(len(filelist), len(self.objectList)):
			self.objectList[idx].mesh = None
			self.objectList[idx].filename = None
		for idx in xrange(0, len(filelist)):
			obj = self.objectList[idx]
			if obj.filename != filelist[idx]:
				obj.fileTime = None
				self.gcodeFileTime = None
				self.logFileTime = None
			obj.filename = filelist[idx]
		
		self.gcodeFilename = sliceRun.getExportFilename(filelist[0])
		#Do the STL file loading in a background thread so we don't block the UI.
		if self.loadThread != None and self.loadThread.isAlive():
			self.loadThread.join()
		self.loadThread = threading.Thread(target=self.doFileLoadThread)
		self.loadThread.daemon = True
		self.loadThread.start()
		
		if showWarning:
			if profile.getProfileSettingFloat('model_scale') != 1.0 or profile.getProfileSettingFloat('model_rotate_base') != 0 or profile.getProfileSetting('flip_x') != 'False' or profile.getProfileSetting('flip_y') != 'False' or profile.getProfileSetting('flip_z') != 'False' or profile.getProfileSetting('swap_xz') != 'False' or profile.getProfileSetting('swap_yz') != 'False' or len(profile.getPluginConfig()) > 0:
				self.ShowWarningPopup('Reset scale, rotation, mirror and plugins?', self.OnResetAll)
Exemple #3
0
 def OnScaleMax(self):
     if self.objectsMinV is None:
         return
     vMin = self.objectsMinV
     vMax = self.objectsMaxV
     skirtSize = 3
     if profile.getProfileSettingFloat('skirt_line_count') > 0:
         skirtSize = 3 + profile.getProfileSettingFloat(
             'skirt_line_count') * profile.calculateEdgeWidth(
             ) + profile.getProfileSettingFloat('skirt_gap')
     scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / (
         (vMax[0] - vMin[0]) / 2)
     scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / (
         (vMax[1] - vMin[1]) / 2)
     scaleX2 = (self.machineCenter.x - skirtSize) / (
         (vMax[0] - vMin[0]) / 2)
     scaleY2 = (self.machineCenter.y - skirtSize) / (
         (vMax[1] - vMin[1]) / 2)
     scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
     scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
     self.matrix *= numpy.matrix(
         [[scale, 0, 0], [0, scale, 0], [0, 0, scale]], numpy.float64)
     if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
         self.setViewMode('Normal')
     self.updateModelTransform()
Exemple #4
0
	def OnResume(self, e):
		feedZ = profile.getProfileSettingFloat('max_z_speed') * 60
		feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
		if self._wizardState == 2:
			wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back left corner...')
			self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
			self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getPreferenceFloat('machine_depth'), feedTravel))
			self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
			self.comm.sendCommand('M400')
			self._wizardState = 3
		elif self._wizardState == 4:
			wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back right corner...')
			self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
			self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth') - 20, feedTravel))
			self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
			self.comm.sendCommand('M400')
			self._wizardState = 5
		elif self._wizardState == 6:
			wx.CallAfter(self.infoBox.SetBusy, 'Moving head to front right corner...')
			self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
			self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getPreferenceFloat('machine_width'), 20, feedTravel))
			self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
			self.comm.sendCommand('M400')
			self._wizardState = 7
		elif self._wizardState == 8:
			wx.CallAfter(self.infoBox.SetBusy, 'Heating up printer...')
			self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
			self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature')))
			self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
			self._wizardState = 9
		self.resumeButton.Enable(False)
Exemple #5
0
 def mcStateChange(self, state):
     if self.comm is None:
         return
     if self.comm.isOperational():
         if self._wizardState == 0:
             wx.CallAfter(self.infoBox.SetInfo, "Homing printer...")
             self.comm.sendCommand("M105")
             self.comm.sendCommand("G28")
             self._wizardState = 1
         elif self._wizardState == 10 and not self.comm.isPrinting():
             self.comm.sendCommand("G1 Z15 F%d" % (profile.getProfileSettingFloat("max_z_speed") * 60))
             self.comm.sendCommand("G92 E0")
             self.comm.sendCommand("G1 E-10 F%d" % (profile.getProfileSettingFloat("retraction_speed") * 60))
             self.comm.sendCommand("M104 S0")
             wx.CallAfter(
                 self.infoBox.SetInfo,
                 "Calibration finished.\nThe squares on the bed should slightly touch each other.",
             )
             wx.CallAfter(self.infoBox.SetReadyIndicator)
             wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
             wx.CallAfter(self.connectButton.Enable, True)
             self._wizardState = 11
     elif self.comm.isError():
         wx.CallAfter(
             self.infoBox.SetError,
             "Failed to establish connection with the printer.",
             "http://wiki.ultimaker.com/Cura:_Connection_problems",
         )
    def validate(self):
        from Cura.util import profile
        try:
            wallThickness = profile.getProfileSettingFloat('wall_thickness')
            nozzleSize = profile.getProfileSettingFloat('nozzle_size')
            if wallThickness < 0.01:
                return SUCCESS, ''
            if wallThickness <= nozzleSize * 0.5:
                return ERROR, 'Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable'
            if wallThickness <= nozzleSize * 0.85:
                return WARNING, 'Trying to print walls thinner then the 0.8 * nozzle size. Small chance that this will produce usable results'
            if wallThickness < nozzleSize:
                return SUCCESS, ''
            if nozzleSize <= 0:
                return ERROR, 'Incorrect nozzle size'

            lineCount = int(wallThickness / nozzleSize)
            lineWidth = wallThickness / lineCount
            lineWidthAlt = wallThickness / (lineCount + 1)
            if lineWidth >= nozzleSize * 1.5 and lineWidthAlt <= nozzleSize * 0.85:
                return WARNING, 'Current selected wall thickness results in a line thickness of ' + str(
                    lineWidthAlt
                ) + 'mm which is not recommended with your nozzle of ' + str(
                    nozzleSize) + 'mm'
            return SUCCESS, ''
        except ValueError:
            #We already have an error by the int/float validator in this case.
            return SUCCESS, ''
Exemple #7
0
    def validate(self):
        from Cura.util import profile

        try:
            nozzleSize = profile.getProfileSettingFloat("nozzle_size")
            layerHeight = profile.getProfileSettingFloat("layer_height")
            raw_user_input = self.setting.getValue()
            new_print_speed = raw_user_input.replace(",", ".")
            try:
                evaluated = eval(new_print_speed, {}, {})  # Converts unicode into numeric
            except SyntaxError:  # Caused by unicode string being empty
                evaluated = 0.0
            printSpeed = float(evaluated)
            if printSpeed == 0.0:
                printSpeed = profile.getProfileSettingFloat("print_speed")

            printVolumePerMM = layerHeight * nozzleSize
            printVolumePerSecond = printVolumePerMM * printSpeed
            # Using 8mm3 per second with a 0.4mm nozzle
            maxPrintVolumePerSecond = 8 / (math.pi * (0.2 * 0.2)) * (math.pi * (nozzleSize / 2 * nozzleSize / 2))

            if printVolumePerSecond > maxPrintVolumePerSecond:
                return (
                    WARNING,
                    "You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)"
                    % (maxPrintVolumePerSecond, printVolumePerSecond),
                )

            return SUCCESS, "You are printing at %0.1fmm^3 per second" % (printVolumePerSecond)
        except ValueError:
            # We already have an error by the int/float validator in this case.
            return SUCCESS, ""
Exemple #8
0
    def validate(self):
        from Cura.util import profile
        try:
            nozzleSize = profile.getProfileSettingFloat('nozzle_size')
            layerHeight = profile.getProfileSettingFloat('layer_height')
            printSpeed = float(
                eval(self.setting.getValue().replace(',', '.'), {}, {}))
            if printSpeed == 0.0:
                printSpeed = profile.getProfileSettingFloat('print_speed')

            printVolumePerMM = layerHeight * nozzleSize
            printVolumePerSecond = printVolumePerMM * printSpeed
            #Using 8mm3 per second with a 0.4mm nozzle
            maxPrintVolumePerSecond = 8 / (math.pi * (0.2 * 0.2)) * (
                math.pi * (nozzleSize / 2 * nozzleSize / 2))

            if printVolumePerSecond > maxPrintVolumePerSecond:
                return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (
                    maxPrintVolumePerSecond, printVolumePerSecond)

            return SUCCESS, 'You are printing at %0.1fmm^3 per second' % (
                printVolumePerSecond)
        except ValueError:
            #We already have an error by the int/float validator in this case.
            return SUCCESS, ''
Exemple #9
0
	def validate(self):
		from Cura.util import profile
		try:
			wallThickness = profile.getProfileSettingFloat('wall_thickness')
			nozzleSize = profile.getProfileSettingFloat('nozzle_size')
			if wallThickness < 0.01:
				return SUCCESS, ''
			if wallThickness <= nozzleSize * 0.5:
				return ERROR, 'Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable'
			if wallThickness <= nozzleSize * 0.85:
				return WARNING, 'Trying to print walls thinner then the 0.8 * nozzle size. Small chance that this will produce usable results'
			if wallThickness < nozzleSize:
				return SUCCESS, ''
			if nozzleSize <= 0:
				return ERROR, 'Incorrect nozzle size'
			
			lineCount = int(wallThickness / nozzleSize)
			lineWidth = wallThickness / lineCount
			lineWidthAlt = wallThickness / (lineCount + 1)
			if lineWidth >= nozzleSize * 1.5 and lineWidthAlt <= nozzleSize * 0.85:
				return WARNING, 'Current selected wall thickness results in a line thickness of ' + str(lineWidthAlt) + 'mm which is not recommended with your nozzle of ' + str(nozzleSize) + 'mm'
			return SUCCESS, ''
		except ValueError:
			#We already have an error by the int/float validator in this case.
			return SUCCESS, ''
Exemple #10
0
def calcLayerSkip(setting):
    bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
    layerThickness = profile.getProfileSettingFloat('layer_height')
    if bottomThickness < layerThickness:
        return 0
    return int(
        math.ceil((bottomThickness - layerThickness) / layerThickness +
                  0.0001) - 1)
	def calculateCost(self):
		cost_kg = profile.getProfileSettingFloat('filament_cost_kg')
		cost_meter = profile.getProfileSettingFloat('filament_cost_meter')
		if cost_kg > 0.0 and cost_meter > 0.0:
			return "%.2f euros / %.2f euros" % (self.calculateWeight() * cost_kg, self.extrusionAmount / 1000 * cost_meter)
		elif cost_kg > 0.0:
			return "%.2f euros" % (self.calculateWeight() * cost_kg)
		elif cost_meter > 0.0:
			return "%.2f euros" % (self.extrusionAmount / 1000 * cost_meter)
		return None
Exemple #12
0
 def calculateCost(self):
     cost_kg = profile.getProfileSettingFloat('filament_cost_kg')
     cost_meter = profile.getProfileSettingFloat('filament_cost_meter')
     if cost_kg > 0.0 and cost_meter > 0.0:
         return "%.2f euros / %.2f euros" % (self.calculateWeight() *
                                             cost_kg, self.extrusionAmount /
                                             1000 * cost_meter)
     elif cost_kg > 0.0:
         return "%.2f euros" % (self.calculateWeight() * cost_kg)
     elif cost_meter > 0.0:
         return "%.2f euros" % (self.extrusionAmount / 1000 * cost_meter)
     return None
Exemple #13
0
	def __init__(self):
		self._feedPrint = profile.getProfileSettingFloat('print_speed') * 60
		self._feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
		self._feedRetract = profile.getProfileSettingFloat('retraction_speed') * 60
		filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
		filamentArea = math.pi * filamentRadius * filamentRadius
		self._ePerMM = (profile.getProfileSettingFloat('nozzle_size') * 0.1) / filamentArea
		self._eValue = 0.0
		self._x = 0
		self._y = 0
		self._z = 0

		self._list = ['M110', 'G92 E0']
Exemple #14
0
	def updateModelTransform(self, f=0):
		if len(self.objectList) < 1 or self.objectList[0].mesh == None:
			return
		
		rotate = profile.getProfileSettingFloat('model_rotate_base')
		mirrorX = profile.getProfileSetting('flip_x') == 'True'
		mirrorY = profile.getProfileSetting('flip_y') == 'True'
		mirrorZ = profile.getProfileSetting('flip_z') == 'True'
		swapXZ = profile.getProfileSetting('swap_xz') == 'True'
		swapYZ = profile.getProfileSetting('swap_yz') == 'True'

		for obj in self.objectList:
			if obj.mesh == None:
				continue
			obj.mesh.setRotateMirror(rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ)
		
		minV = self.objectList[0].mesh.getMinimum()
		maxV = self.objectList[0].mesh.getMaximum()
		objectsBounderyCircleSize = self.objectList[0].mesh.bounderyCircleSize
		for obj in self.objectList:
			if obj.mesh == None:
				continue

			obj.mesh.getMinimumZ()
			minV = numpy.minimum(minV, obj.mesh.getMinimum())
			maxV = numpy.maximum(maxV, obj.mesh.getMaximum())
			objectsBounderyCircleSize = max(objectsBounderyCircleSize, obj.mesh.bounderyCircleSize)

		self.objectsMaxV = maxV
		self.objectsMinV = minV
		self.objectsBounderyCircleSize = objectsBounderyCircleSize
		for obj in self.objectList:
			if obj.mesh == None:
				continue

			obj.mesh.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minV[2]])
			#for v in obj.mesh.vertexes:
			#	v[2] -= minV[2]
			#	v[0] -= minV[0] + (maxV[0] - minV[0]) / 2
			#	v[1] -= minV[1] + (maxV[1] - minV[1]) / 2
			obj.mesh.getMinimumZ()
			obj.dirty = True

		scale = profile.getProfileSettingFloat('model_scale')
		size = (self.objectsMaxV - self.objectsMinV) * scale
		self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))

		self.glCanvas.Refresh()
Exemple #15
0
 def calculateWeight(self):
     #Calculates the weight of the filament in kg
     radius = getProfileSettingFloat('filament_diameter') / 2
     volumeM3 = (self.extrusionAmount *
                 (math.pi * radius * radius)) / (1000 * 1000 * 1000)
     return volumeM3 * profile.getProfileSettingFloat(
         'filament_physical_density')
Exemple #16
0
	def _load_profile_settings(self):
		self._layer_height = profile.getProfileSettingFloat('layer_height')
		self._spiralize = profile.getProfileSetting('spiralize')
		self._filament_diameter = profile.getProfileSetting('filament_diameter')
		self._filament_physical_density = profile.getPreferenceFloat('filament_physical_density')
		self._filament_cost_kg = profile.getPreferenceFloat('filament_cost_kg')
		self._filament_cost_meter = profile.getPreferenceFloat('filament_cost_meter')
Exemple #17
0
	def OnPaint(self,e):
		dc = wx.PaintDC(self)
		if not hasOpenGLlibs:
			dc.Clear()
			dc.DrawText("No PyOpenGL installation found.\nNo preview window available.", 10, 10)
			return
		self.SetCurrent(self.context)
		opengl.InitGL(self, self.view3D, self.zoom)
		if self.view3D:
			glTranslate(0,0,-self.zoom)
			glRotate(-self.pitch, 1,0,0)
			glRotate(self.yaw, 0,0,1)
			if self.viewMode == "GCode" or self.viewMode == "Mixed":
				if self.parent.gcode != None and len(self.parent.gcode.layerList) > self.parent.layerSpin.GetValue() and len(self.parent.gcode.layerList[self.parent.layerSpin.GetValue()]) > 0:
					glTranslate(0,0,-self.parent.gcode.layerList[self.parent.layerSpin.GetValue()][0].list[-1].z)
			else:
				if self.parent.objectsMaxV != None:
					glTranslate(0,0,-(self.parent.objectsMaxV[2]-self.parent.objectsMinV[2]) * profile.getProfileSettingFloat('model_scale') / 2)
		else:
			glTranslate(self.offsetX, self.offsetY, 0)

		self.viewport = glGetIntegerv(GL_VIEWPORT);
		self.modelMatrix = glGetDoublev(GL_MODELVIEW_MATRIX);
		self.projMatrix = glGetDoublev(GL_PROJECTION_MATRIX);

		glTranslate(-self.parent.machineCenter.x, -self.parent.machineCenter.y, 0)

		self.OnDraw()
		self.SwapBuffers()
Exemple #18
0
	def mcStateChange(self, state):
		if self.comm is None:
			return
		if self.comm.isOperational():
			if self._wizardState == 0:
				wx.CallAfter(self.infoBox.SetInfo, 'Homing printer and heating up both extruders.')
				self.comm.sendCommand('M105')
				self.comm.sendCommand('M104 S220 T0')
				self.comm.sendCommand('M104 S220 T1')
				self.comm.sendCommand('G28')
				self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
				self._wizardState = 1
			if not self.comm.isPrinting():
				if self._wizardState == 3:
					self._wizardState = 4
					wx.CallAfter(self.infoBox.SetAttention, 'Please measure the distance between the vertical lines in millimeters.')
					wx.CallAfter(self.textEntry.SetValue, '0.0')
					wx.CallAfter(self.textEntry.Enable, True)
					wx.CallAfter(self.resumeButton.Enable, True)
					wx.CallAfter(self.resumeButton.SetFocus)
				elif self._wizardState == 6:
					self._wizardState = 7
					wx.CallAfter(self.infoBox.SetAttention, 'Which vertical line number lays perfect on top of each other? Leftmost line is zero.')
					wx.CallAfter(self.textEntry.SetValue, '10')
					wx.CallAfter(self.textEntry.Enable, True)
					wx.CallAfter(self.resumeButton.Enable, True)
					wx.CallAfter(self.resumeButton.SetFocus)

		elif self.comm.isError():
			wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.', 'http://wiki.ultimaker.com/Cura:_Connection_problems')
Exemple #19
0
 def OnSettingChange(self, e):
     changed_panel = e.GetEventObject().GetParent()
     panelChildren = changed_panel.GetSizer().GetChildren()
     for panelChild in panelChildren:
         panelWidget = panelChild.GetWindow()
         # The only disabled textctrl by line is the one containing the height info
         if isinstance(panelWidget,
                       wx.TextCtrl) and not panelWidget.IsEnabled():
             height_value = 0
             try:
                 height_value = float(
                     e.GetEventObject().GetValue()) * float(
                         profile.getProfileSettingFloat('layer_height'))
             except:
                 print "Invalid user value in pause input: '%s'" % e.GetEventObject(
                 ).GetValue()
             if (e.IsCommandEvent()):
                 panelWidget.SetValue(str(height_value) + ' mm')
     for panel in self.panelList:
         idx = self.panelList.index(panel)
         for k in panel.paramCtrls.keys():
             self.pluginConfig[idx]['params'][k] = panel.paramCtrls[
                 k].GetValue()
     pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
     self.callback()
Exemple #20
0
	def StoreData(self):
		profile.putPreference('machine_width', self.machineWidth.GetValue())
		profile.putPreference('machine_depth', self.machineDepth.GetValue())
		profile.putPreference('machine_height', self.machineHeight.GetValue())
		profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
		profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
		profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
Exemple #21
0
    def updateHeadSize(self, obj=None):
        xMin = profile.getMachineSettingFloat('extruder_head_size_min_x')
        xMax = profile.getMachineSettingFloat('extruder_head_size_max_x')
        yMin = profile.getMachineSettingFloat('extruder_head_size_min_y')
        yMax = profile.getMachineSettingFloat('extruder_head_size_max_y')
        gantryHeight = profile.getMachineSettingFloat(
            'extruder_head_size_height')
        objectSink = profile.getProfileSettingFloat("object_sink")

        self._leftToRight = xMin < xMax
        self._frontToBack = yMin < yMax
        self._headSizeOffsets[0] = min(xMin, xMax)
        self._headSizeOffsets[1] = min(yMin, yMax)
        self._gantryHeight = gantryHeight
        self._oneAtATime = self._gantryHeight > 0 and profile.getPreference(
            'oneAtATime') == 'True'
        for obj in self._objectList:
            if obj.getSize()[2] - objectSink > self._gantryHeight:
                self._oneAtATime = False

        headArea = numpy.array(
            [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]],
            numpy.float32)

        if obj is None:
            for obj in self._objectList:
                obj.setHeadArea(headArea, self._headSizeOffsets)
        else:
            obj.setHeadArea(headArea, self._headSizeOffsets)
	def _renderObject(self, obj, brightness = False, addSink = True):
		glPushMatrix()
		if addSink:
			glTranslate(obj.getPosition()[0], obj.getPosition()[1], obj.getSize()[2] / 2 - profile.getProfileSettingFloat('object_sink'))
		else:
			glTranslate(obj.getPosition()[0], obj.getPosition()[1], obj.getSize()[2] / 2)

		if self.tempMatrix is not None and obj == self._selectedObj:
			tempMatrix = opengl.convert3x3MatrixTo4x4(self.tempMatrix)
			glMultMatrixf(tempMatrix)

		offset = obj.getDrawOffset()
		glTranslate(-offset[0], -offset[1], -offset[2] - obj.getSize()[2] / 2)

		tempMatrix = opengl.convert3x3MatrixTo4x4(obj.getMatrix())
		glMultMatrixf(tempMatrix)

		n = 0
		for m in obj._meshList:
			if m.vbo is None:
				m.vbo = opengl.GLVBO(m.vertexes, m.normal)
			if brightness:
				glColor4fv(map(lambda n: n * brightness, self._objColors[n]))
				n += 1
			m.vbo.render()
		glPopMatrix()
Exemple #23
0
    def validate(self):
        from Cura.util import profile

        try:
            wallThickness = profile.getProfileSettingFloat("wall_thickness")
            nozzleSize = profile.getProfileSettingFloat("nozzle_size")
            if wallThickness < 0.01:
                return SUCCESS, ""
            if wallThickness <= nozzleSize * 0.5:
                return (
                    ERROR,
                    "Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable",
                )
            if wallThickness <= nozzleSize * 0.85:
                return (
                    WARNING,
                    "Trying to print walls thinner then the 0.8 * nozzle size. Small chance that this will produce usable results",
                )
            if wallThickness < nozzleSize:
                return SUCCESS, ""
            if nozzleSize <= 0:
                return ERROR, "Incorrect nozzle size"

            lineCount = int(wallThickness / nozzleSize)
            lineWidth = wallThickness / lineCount
            lineWidthAlt = wallThickness / (lineCount + 1)
            if lineWidth >= nozzleSize * 1.5 and lineWidthAlt <= nozzleSize * 0.85:
                return (
                    WARNING,
                    "Current selected shell thickness results in a line thickness of "
                    + str(lineWidthAlt)
                    + "mm which is not recommended with your nozzle of "
                    + str(nozzleSize)
                    + "mm",
                )
            if (
                abs((lineCount * nozzleSize) - wallThickness) > 0.01
                and abs(((lineCount + 1) * nozzleSize) - wallThickness) > 0.01
            ):
                return (
                    WARNING,
                    "Currently selected shell thickness is not a multiple of the nozzle size. While this prints fine, it does not give optimal results.",
                )
            return SUCCESS, ""
        except ValueError:
            # We already have an error by the int/float validator in this case.
            return SUCCESS, ""
Exemple #24
0
    def _buildPluginPanel(self, pluginConfig):
        pausePluginPanel = wx.Panel(self.pluginEnabledPanel)
        s = wx.GridBagSizer(1, 4)
        pausePluginPanel.SetSizer(s)
        pausePluginPanel.paramCtrls = {}
        scene = self.GetParent().GetParent().GetParent().GetParent().scene

        remButton1 = wx.Button(pausePluginPanel,
                               id=-1,
                               label="x",
                               style=wx.BU_EXACTFIT)
        s.Add(remButton1, pos=(0, 0), span=(1, 1), flag=wx.ALIGN_LEFT)

        i = 1
        for param in self.plugin.getParams():
            #value = param['default']
            value = ''
            if param['name'] in pluginConfig['params']:
                value = pluginConfig['params'][param['name']]

            ctrl = wx.TextCtrl(pausePluginPanel, -1, value)
            height_value = float(value) * float(
                profile.getProfileSettingFloat('layer_height'))
            height_label = wx.TextCtrl(pausePluginPanel, -1,
                                       str(height_value) + ' mm')
            height_label.Disable()
            if value == '':
                ctrl.Disable()
            s.Add(ctrl, pos=(0, i), span=(1, 1), flag=wx.EXPAND)
            s.Add(height_label, pos=(0, i + 1), span=(1, 1), flag=wx.EXPAND)
            ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)

            pausePluginPanel.paramCtrls[param['name']] = ctrl

            i += 1
        remButton2 = wx.Button(pausePluginPanel,
                               id=-1,
                               label="x",
                               style=wx.BU_EXACTFIT)
        s.Add(remButton2, pos=(0, i + 1), span=(1, 1), flag=wx.ALIGN_LEFT)

        s.AddGrowableCol(1)
        s.AddGrowableCol(2)

        self.Bind(wx.EVT_BUTTON, self.OnRem, remButton1)
        self.Bind(wx.EVT_BUTTON, self.OnRem, remButton2)

        pausePluginPanel.SetBackgroundColour(
            self.GetParent().GetBackgroundColour())
        pausePluginPanel.Layout()
        self.pluginEnabledPanel.GetSizer().Add(pausePluginPanel,
                                               flag=wx.EXPAND | wx.LEFT
                                               | wx.RIGHT)
        self.pluginEnabledPanel.Layout()
        self.pluginEnabledPanel.SetSize((1, 1))
        self.Layout()
        self.pluginEnabledPanel.ScrollChildIntoView(pausePluginPanel)
        self.panelList.append(pausePluginPanel)
        return True
Exemple #25
0
 def StoreData(self):
     profile.putPreference("machine_width", self.machineWidth.GetValue())
     profile.putPreference("machine_depth", self.machineDepth.GetValue())
     profile.putPreference("machine_height", self.machineHeight.GetValue())
     profile.putProfileSetting("nozzle_size", self.nozzleSize.GetValue())
     profile.putProfileSetting("wall_thickness", float(profile.getProfileSettingFloat("nozzle_size")) * 2)
     profile.putPreference("has_heated_bed", str(self.heatedBed.GetValue()))
     profile.putPreference("machine_center_is_zero", str(self.HomeAtCenter.GetValue()))
Exemple #26
0
	def validate(self):
		from Cura.util import profile
		try:
			fill_distance = profile.getProfileSettingFloat('fill_distance')
			infill_type = profile.getProfileSetting('infill_type')
		#	print infill_type
			if infill_type == 'None':
				return 	DISABLED, 'Infill has been disabled'
			else :
				if profile.getProfileSettingFloat('fill_distance') < profile.calculateEdgeWidth() :
					return 	ERROR, 'Distance between infill cannot be less than extrusion width : '+str(profile.calculateEdgeWidth())	+'mm'
				#elif profile.getProfileSettingFloat('fill_distance') > 0:
				#	return 	SUCCESS
			return SUCCESS, ''
		except ValueError:
			#We already have an error by the int/float validator in this case.
			return SUCCESS, ''
Exemple #27
0
	def OnScaleMax(self):
		if self.objectsMinV is None:
			return
		vMin = self.objectsMinV
		vMax = self.objectsMaxV
		skirtSize = 3
		if profile.getProfileSettingFloat('skirt_line_count') > 0:
			skirtSize = 3 + profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
		scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
		scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
		scaleX2 = (self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
		scaleY2 = (self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
		scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
		scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
		self.matrix *= numpy.matrix([[scale,0,0],[0,scale,0],[0,0,scale]], numpy.float64)
		if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
			self.setViewMode('Normal')
		self.updateModelTransform()
Exemple #28
0
	def validate(self):
		try:
			nozzleSize = profile.getProfileSettingFloat('nozzle_size')
			layerHeight = profile.getProfileSettingFloat('layer_height')
			printSpeed = profile.getProfileSettingFloat('print_speed')
			
			printVolumePerMM = layerHeight * nozzleSize
			printVolumePerSecond = printVolumePerMM * printSpeed
			#Using 10mm3 per second with a 0.4mm nozzle (normal max according to Joergen Geerds)
			maxPrintVolumePerSecond = 10 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2))
			
			if printVolumePerSecond > maxPrintVolumePerSecond:
				return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (maxPrintVolumePerSecond, printVolumePerSecond)
			
			return SUCCESS, ''
		except ValueError:
			#We already have an error by the int/float validator in this case.
			return SUCCESS, ''
Exemple #29
0
	def validate(self):
		try:
			nozzleSize = profile.getProfileSettingFloat('nozzle_size')
			layerHeight = profile.getProfileSettingFloat('layer_height')
			printSpeed = profile.getProfileSettingFloat('print_speed')
			
			printVolumePerMM = layerHeight * nozzleSize
			printVolumePerSecond = printVolumePerMM * printSpeed
			#Using 10mm3 per second with a 0.4mm nozzle (normal max according to Joergen Geerds)
			maxPrintVolumePerSecond = 10 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2))
			
			if printVolumePerSecond > maxPrintVolumePerSecond:
				return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (maxPrintVolumePerSecond, printVolumePerSecond)
			
			return SUCCESS, ''
		except ValueError:
			#We already have an error by the int/float validator in this case.
			return SUCCESS, ''
Exemple #30
0
    def _gcodeToVBO_quads(self, gcodeLayers, extrudeType):
        useFilamentArea = profile.getMachineSetting(
            'gcode_flavor') == 'UltiGCode'
        filamentRadius = profile.getProfileSettingFloat(
            'filament_diameter') / 2
        filamentArea = math.pi * filamentRadius * filamentRadius

        if ':' in extrudeType:
            extruder = int(extrudeType[extrudeType.find(':') + 1:])
            extrudeType = extrudeType[0:extrudeType.find(':')]
        else:
            extruder = None

        verts = numpy.zeros((0, 3), numpy.float32)
        indices = numpy.zeros((0), numpy.uint32)
        for layer in gcodeLayers:
            for path in layer:
                if path['type'] == 'extrude' and path[
                        'pathType'] == extrudeType and (
                            extruder is None or path['extruder'] == extruder):
                    a = path['points']
                    if extrudeType == 'FILL':
                        a[:, 2] += 0.01

                    #Construct the normals of each line 90deg rotated on the X/Y plane
                    normals = a[1:] - a[:-1]
                    lengths = numpy.sqrt(normals[:, 0]**2 + normals[:, 1]**2)
                    normals[:,
                            0], normals[:,
                                        1] = -normals[:,
                                                      1] / lengths, normals[:,
                                                                            0] / lengths
                    normals[:, 2] /= lengths

                    ePerDist = path['extrusion'][1:] / lengths
                    if useFilamentArea:
                        lineWidth = ePerDist / path['layerThickness'] / 2.0
                    else:
                        lineWidth = ePerDist * (filamentArea /
                                                path['layerThickness'] / 2)

                    normals[:, 0] *= lineWidth
                    normals[:, 1] *= lineWidth

                    b = numpy.zeros((len(a) - 1, 0), numpy.float32)
                    b = numpy.concatenate((b, a[1:] + normals), 1)
                    b = numpy.concatenate((b, a[1:] - normals), 1)
                    b = numpy.concatenate((b, a[:-1] - normals), 1)
                    b = numpy.concatenate((b, a[:-1] + normals), 1)
                    b = b.reshape((len(b) * 4, 3))

                    i = numpy.arange(len(verts),
                                     len(verts) + len(b), 1, numpy.uint32)

                    verts = numpy.concatenate((verts, b))
                    indices = numpy.concatenate((indices, i))
        return openglHelpers.GLVBO(GL_QUADS, verts, indicesArray=indices)
Exemple #31
0
	def updateProfileToControls(self):
		self.scale.SetValue(profile.getProfileSetting('model_scale'))
		self.rotate.SetValue(profile.getProfileSettingFloat('model_rotate_base'))
		self.mirrorX.SetValue(profile.getProfileSetting('flip_x') == 'True')
		self.mirrorY.SetValue(profile.getProfileSetting('flip_y') == 'True')
		self.mirrorZ.SetValue(profile.getProfileSetting('flip_z') == 'True')
		self.swapXZ.SetValue(profile.getProfileSetting('swap_xz') == 'True')
		self.swapYZ.SetValue(profile.getProfileSetting('swap_yz') == 'True')
		self.updateModelTransform()
		self.glCanvas.updateProfileToControls()
Exemple #32
0
	def OnScaleMax(self, e = None, onlyScaleDown = False):
		if self.objectsMinV is None:
			return
		vMin = self.objectsMinV
		vMax = self.objectsMaxV
		skirtSize = 3
		if profile.getProfileSettingFloat('skirt_line_count') > 0:
			skirtSize = 3 + profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
		scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
		scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
		scaleX2 = (self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
		scaleY2 = (self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
		scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
		scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
		if scale > 1.0 and onlyScaleDown:
			return
		if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
			self.setViewMode('Normal')
		self.glCanvas.Refresh()
Exemple #33
0
 def OnResume(self, e):
     feedZ = profile.getProfileSettingFloat('max_z_speed') * 60
     feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
     if self._wizardState == 2:
         wx.CallAfter(self.infoBox.SetBusy,
                      'Moving head to back left corner...')
         self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
         self.comm.sendCommand(
             'G1 X%d Y%d F%d' %
             (0, profile.getPreferenceFloat('machine_depth'), feedTravel))
         self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
         self.comm.sendCommand('M400')
         self._wizardState = 3
     elif self._wizardState == 4:
         wx.CallAfter(self.infoBox.SetBusy,
                      'Moving head to back right corner...')
         self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
         self.comm.sendCommand(
             'G1 X%d Y%d F%d' %
             (profile.getPreferenceFloat('machine_width'),
              profile.getPreferenceFloat('machine_depth') - 25, feedTravel))
         self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
         self.comm.sendCommand('M400')
         self._wizardState = 5
     elif self._wizardState == 6:
         wx.CallAfter(self.infoBox.SetBusy,
                      'Moving head to front right corner...')
         self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
         self.comm.sendCommand(
             'G1 X%d Y%d F%d' %
             (profile.getPreferenceFloat('machine_width'), 20, feedTravel))
         self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
         self.comm.sendCommand('M400')
         self._wizardState = 7
     elif self._wizardState == 8:
         wx.CallAfter(self.infoBox.SetBusy, 'Heating up printer...')
         self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
         self.comm.sendCommand(
             'M104 S%d' %
             (profile.getProfileSettingFloat('print_temperature')))
         self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
         self._wizardState = 9
     self.resumeButton.Enable(False)
Exemple #34
0
 def _load_profile_settings(self):
     self._layer_height = profile.getProfileSettingFloat('layer_height')
     self._spiralize = profile.getProfileSetting('spiralize')
     self._filament_diameter = profile.getProfileSetting(
         'filament_diameter')
     self._filament_physical_density = profile.getPreferenceFloat(
         'filament_physical_density')
     self._filament_cost_kg = profile.getPreferenceFloat('filament_cost_kg')
     self._filament_cost_meter = profile.getPreferenceFloat(
         'filament_cost_meter')
Exemple #35
0
    def _watchStderr(self, stderr):
        objectNr = 0
        line = stderr.readline()
        while len(line) > 0:
            line = line.strip()
            if line.startswith('Progress:'):
                line = line.split(':')
                if line[1] == 'process':
                    objectNr += 1
                elif line[1] in self._progressSteps:
                    progressValue = float(line[2]) / float(line[3])
                    progressValue /= len(self._progressSteps)
                    progressValue += 1.0 / len(
                        self._progressSteps) * self._progressSteps.index(
                            line[1])

                    progressValue /= self._objCount
                    progressValue += 1.0 / self._objCount * objectNr
                    try:
                        self._callback(progressValue)
                    except:
                        pass
            elif line.startswith('Print time:'):
                self._result._printTimeSeconds = int(
                    line.split(':')[1].strip())
            elif line.startswith('Filament:'):
                self._result._filamentMM[0] = int(line.split(':')[1].strip())
                if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
                    radius = profile.getProfileSettingFloat(
                        'filament_diameter') / 2.0
                    self._result._filamentMM[0] /= (math.pi * radius * radius)
            elif line.startswith('Filament2:'):
                self._result._filamentMM[1] = int(line.split(':')[1].strip())
                if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
                    radius = profile.getProfileSettingFloat(
                        'filament_diameter') / 2.0
                    self._result._filamentMM[1] /= (math.pi * radius * radius)
            elif line.startswith('Replace:'):
                self._result._replaceInfo[line.split(
                    ':')[1].strip()] = line.split(':')[2].strip()
            else:
                self._result.addLog(line)
            line = stderr.readline()
	def getExtraHeadSize(self):
		extraSizeMin = self.headSizeMin
		extraSizeMax = self.headSizeMax
		if profile.getProfileSettingFloat('skirt_line_count') > 0:
			skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
			extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])
			extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])
		if profile.getProfileSetting('enable_raft') != 'False':
			raftSize = profile.getProfileSettingFloat('raft_margin') * 2
			extraSizeMin = extraSizeMin + numpy.array([raftSize, raftSize, 0])
			extraSizeMax = extraSizeMax + numpy.array([raftSize, raftSize, 0])
		if profile.getProfileSetting('support') != 'None':
			extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])
			extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])

		if self.printMode == 1:
			extraSizeMin = numpy.array([6.0, 6.0, 0])
			extraSizeMax = numpy.array([6.0, 6.0, 0])
		
		return extraSizeMin, extraSizeMax
Exemple #37
0
 def StoreData(self):
     profile.putPreference('machine_width', self.machineWidth.GetValue())
     profile.putPreference('machine_depth', self.machineDepth.GetValue())
     profile.putPreference('machine_height', self.machineHeight.GetValue())
     profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
     profile.putProfileSetting(
         'wall_thickness',
         float(profile.getProfileSettingFloat('nozzle_size')) * 2)
     profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
     profile.putPreference('machine_center_is_zero',
                           str(self.HomeAtCenter.GetValue()))
	def OnAddHeight(self, e):
		scene = self.GetParent().GetParent().GetParent().GetParent().scene
		if scene.viewMode == 'normal':
			pauseLevel = 5.0
		else:
			pauseLevel = scene._engineResultView.layerSelect.getValue() * float(profile.getProfileSettingFloat('layer_height'))
		newConfig = {'filename': self.plugin.getFilename(), 'params': { 'pauseLevel': str(pauseLevel) }}
		if not self._buildPluginPanel(newConfig):
			return
		self.pluginConfig.append(newConfig)
		pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
		self.callback()
Exemple #39
0
	def validate(self):
		from Cura.util import profile
		try:
			nozzleSize = profile.getProfileSettingFloat('nozzle_size')
			layerHeight = profile.getProfileSettingFloat('layer_height')
			printSpeed = float(eval(self.setting.getValue().replace(',','.'), {}, {}))
			if printSpeed == 0.0:
				printSpeed = profile.getProfileSettingFloat('print_speed')
			
			printVolumePerMM = layerHeight * nozzleSize
			printVolumePerSecond = printVolumePerMM * printSpeed
			#Using 8mm3 per second with a 0.4mm nozzle
			maxPrintVolumePerSecond = 8 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2))
			
			if printVolumePerSecond > maxPrintVolumePerSecond:
				return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (maxPrintVolumePerSecond, printVolumePerSecond)
			
			return SUCCESS, 'You are printing at %0.1fmm^3 per second' % (printVolumePerSecond)
		except ValueError:
			#We already have an error by the int/float validator in this case.
			return SUCCESS, ''
Exemple #40
0
    def getExtraHeadSize(self):
        extraSizeMin = self.headSizeMin
        extraSizeMax = self.headSizeMax
        if profile.getProfileSettingFloat("skirt_line_count") > 0:
            skirtSize = profile.getProfileSettingFloat(
                "skirt_line_count"
            ) * profile.calculateEdgeWidth() + profile.getProfileSettingFloat("skirt_gap")
            extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])
            extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])
        if profile.getProfileSetting("enable_raft") != "False":
            raftSize = profile.getProfileSettingFloat("raft_margin") * 2
            extraSizeMin = extraSizeMin + numpy.array([raftSize, raftSize, 0])
            extraSizeMax = extraSizeMax + numpy.array([raftSize, raftSize, 0])
        if profile.getProfileSetting("support") != "None":
            extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])
            extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])

        if self.printMode == 1:
            extraSizeMin = numpy.array([6.0, 6.0, 0])
            extraSizeMax = numpy.array([6.0, 6.0, 0])

        return extraSizeMin, extraSizeMax
Exemple #41
0
	def checkPlatform(self, obj):
		objectSink = profile.getProfileSettingFloat("object_sink")

		area = obj._printAreaHull + obj.getPosition()
		if obj.getSize()[2] - objectSink > self._machineSize[2]:
			return False
		if not polygon.fullInside(area, self._machinePolygons[0]):
			return False
		#Check the "no go zones"
		for poly in self._machinePolygons[1:]:
			if polygon.polygonCollision(poly, area):
				return False
		return True
Exemple #42
0
	def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
		if self._wizardState == 1:
			self._wizardState = 2
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 3:
			self._wizardState = 4
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 5:
			self._wizardState = 6
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 7:
			self._wizardState = 8
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 9:
			if temp < profile.getProfileSettingFloat('print_temperature') - 5:
				wx.CallAfter(self.infoBox.SetInfo, 'Heating up printer: %d/%d' % (temp, profile.getProfileSettingFloat('print_temperature')))
			else:
				self._wizardState = 10
				wx.CallAfter(self.infoBox.SetInfo, 'Printing a square on the printer bed at 0.3mm height.')
				feedZ = profile.getProfileSettingFloat('max_z_speed') * 60
				feedPrint = profile.getProfileSettingFloat('print_speed') * 60
				feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
				w = profile.getPreferenceFloat('machine_width')
				d = profile.getPreferenceFloat('machine_depth')
				filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
				filamentArea = math.pi * filamentRadius * filamentRadius
				ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea
				eValue = 0.0

				gcodeList = [
					'G1 Z2 F%d' % (feedZ),
					'G92 E0',
					'G1 X%d Y%d F%d' % (5, 5, feedTravel),
					'G1 Z0.3 F%d' % (feedZ)]
				eValue += 5;
				gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60))

				for i in xrange(0, 3):
					dist = 5.0 + 0.4 * i
					eValue += (d - 2*dist) * ePerMM
					gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, d - dist, eValue, feedPrint))
					eValue += (w - 2*dist) * ePerMM
					gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, d - dist, eValue, feedPrint))
					eValue += (d - 2*dist) * ePerMM
					gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, dist, eValue, feedPrint))
					eValue += (w - 2*dist) * ePerMM
					gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, dist, eValue, feedPrint))

				gcodeList.append('M400')
				self.comm.printGCode(gcodeList)
def gcodePath(newType, pathType, layerThickness, startPoint):
	"""
	Build a gcodePath object. This used to be objects, however, this code is timing sensitive and dictionaries proved to be faster.
	"""
	if layerThickness <= 0.0:
		layerThickness = 0.01
	if profile.getProfileSetting('spiralize') == 'True':
		layerThickness = profile.getProfileSettingFloat('layer_height')
	return {'type': newType,
			'pathType': pathType,
			'layerThickness': layerThickness,
			'points': [startPoint],
			'extrusion': [0.0]}
Exemple #44
0
    def checkPlatform(self, obj):
        objectSink = profile.getProfileSettingFloat("object_sink")

        area = obj._printAreaHull + obj.getPosition()
        if obj.getSize()[2] - objectSink > self._machineSize[2]:
            return False
        if not polygon.fullInside(area, self._machinePolygons[0]):
            return False
        #Check the "no go zones"
        for poly in self._machinePolygons[1:]:
            if polygon.polygonCollision(poly, area):
                return False
        return True
Exemple #45
0
	def StoreData(self):
		profile.putPreference('machine_width', self.machineWidth.GetValue())
		profile.putPreference('machine_depth', self.machineDepth.GetValue())
		profile.putPreference('machine_height', self.machineHeight.GetValue())
		profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
		profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
		profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
		profile.putPreference('machine_center_is_zero', str(self.HomeAtCenter.GetValue()))
		profile.putPreference('extruder_head_size_min_x', '0')
		profile.putPreference('extruder_head_size_min_y', '0')
		profile.putPreference('extruder_head_size_max_x', '0')
		profile.putPreference('extruder_head_size_max_y', '0')
		profile.putPreference('extruder_head_size_height', '0')
Exemple #46
0
    def updateHeadSize(self, obj=None):
        xMin = profile.getMachineSettingFloat('extruder_head_size_min_x')
        xMax = profile.getMachineSettingFloat('extruder_head_size_max_x')
        yMin = profile.getMachineSettingFloat('extruder_head_size_min_y')
        yMax = profile.getMachineSettingFloat('extruder_head_size_max_y')
        gantryHeight = profile.getMachineSettingFloat(
            'extruder_head_size_height')
        objectSink = profile.getProfileSettingFloat("object_sink")

        self._leftToRight = xMin < xMax
        self._frontToBack = yMin < yMax
        self._headSizeOffsets[0] = min(xMin, xMax)
        self._headSizeOffsets[1] = min(yMin, yMax)
        self._gantryHeight = gantryHeight

        printOneAtATime = profile.getPreference('oneAtATime') == 'True'
        self._oneAtATime = self._gantryHeight > 0 and printOneAtATime
        if self._oneAtATime:
            if not self._lastOneAtATime:
                #print mode was changed by user. We need to reset that value to test with current scene content
                self._lastResultOneAtATime = True

            for obj in self._objectList:
                if obj.getSize()[2] - objectSink > self._gantryHeight:
                    self._oneAtATime = False
                    if self._lastResultOneAtATime:
                        if self._sceneView:
                            self._sceneView.notification.message(
                                "Info: Print one at a time mode disabled. Object too tall."
                            )
                        break

        if self._lastOneAtATime and self._oneAtATime and not self._lastResultOneAtATime:
            if self._sceneView:
                self._sceneView.notification.message(
                    "Info: Print one at a time mode re-enabled.")

        self._lastResultOneAtATime = self._oneAtATime
        self._lastOneAtATime = printOneAtATime

        headArea = numpy.array(
            [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]],
            numpy.float32)

        if obj is None:
            for obj in self._objectList:
                obj.setHeadArea(headArea, self._headSizeOffsets)
        else:
            obj.setHeadArea(headArea, self._headSizeOffsets)
Exemple #47
0
 def OnScaleMax(self, onlyScaleDown=False):
     if self.objectsMinV is None:
         return
     vMin = self.objectsMinV
     vMax = self.objectsMaxV
     skirtSize = 3
     if profile.getProfileSettingFloat("skirt_line_count") > 0:
         skirtSize = (
             3
             + profile.getProfileSettingFloat("skirt_line_count") * profile.calculateEdgeWidth()
             + profile.getProfileSettingFloat("skirt_gap")
         )
     scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
     scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
     scaleX2 = (self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
     scaleY2 = (self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
     scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
     scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
     if scale > 1.0 and onlyScaleDown:
         return
     self.matrix *= numpy.matrix([[scale, 0, 0], [0, scale, 0], [0, 0, scale]], numpy.float64)
     if self.glCanvas.viewMode == "GCode" or self.glCanvas.viewMode == "Mixed":
         self.setViewMode("Normal")
     self.updateModelTransform()
Exemple #48
0
    def getExtraHeadSize(self):
        extraSizeMin = self.headSizeMin
        extraSizeMax = self.headSizeMax
        if profile.getProfileSettingFloat('skirt_line_count') > 0:
            skirtSize = profile.getProfileSettingFloat(
                'skirt_line_count') * profile.calculateEdgeWidth(
                ) + profile.getProfileSettingFloat('skirt_gap')
            extraSizeMin = extraSizeMin + numpy.array(
                [skirtSize, skirtSize, 0])
            extraSizeMax = extraSizeMax + numpy.array(
                [skirtSize, skirtSize, 0])
        if profile.getProfileSetting('enable_raft') != 'False':
            raftSize = profile.getProfileSettingFloat('raft_margin') * 2
            extraSizeMin = extraSizeMin + numpy.array([raftSize, raftSize, 0])
            extraSizeMax = extraSizeMax + numpy.array([raftSize, raftSize, 0])
        if profile.getProfileSetting('support') != 'None':
            extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])
            extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])

        if self.printMode == 1:
            extraSizeMin = numpy.array([6.0, 6.0, 0])
            extraSizeMax = numpy.array([6.0, 6.0, 0])

        return extraSizeMin, extraSizeMax
Exemple #49
0
	def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
		if self._wizardState == 1:
			self._wizardState = 2
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 3:
			self._wizardState = 4
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 5:
			self._wizardState = 6
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 7:
			self._wizardState = 8
			wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.')
			wx.CallAfter(self.resumeButton.Enable, True)
		elif self._wizardState == 9:
			if temp[0] < profile.getProfileSettingFloat('print_temperature') - 5:
				wx.CallAfter(self.infoBox.SetInfo, 'Heating up printer: %d/%d' % (temp[0], profile.getProfileSettingFloat('print_temperature')))
			else:
				wx.CallAfter(self.infoBox.SetAttention, 'The printer is hot now. Please insert some PLA filament into the printer.')
				wx.CallAfter(self.resumeButton.Enable, True)
				self._wizardState = 10
Exemple #50
0
def gcodePath(newType, pathType, layerThickness, startPoint):
    """
	Build a gcodePath object. This used to be objects, however, this code is timing sensitive and dictionaries proved to be faster.
	"""
    if layerThickness <= 0.0:
        layerThickness = 0.01
    if profile.getProfileSetting('spiralize') == 'True':
        layerThickness = profile.getProfileSettingFloat('layer_height')
    return {
        'type': newType,
        'pathType': pathType,
        'layerThickness': layerThickness,
        'points': [startPoint],
        'extrusion': [0.0]
    }
Exemple #51
0
    def checkPlatform(self, obj):
        objectSink = profile.getProfileSettingFloat("object_sink")
        if profile.getPreference('startMode') == 'Simple':
            objectSink = float(
                profile.settingsDictionary["object_sink"].getDefault())

        area = obj._printAreaHull + obj.getPosition()
        if obj.getSize()[2] - objectSink > self._machineSize[2]:
            return False
        if not polygon.fullInside(area, self._machinePolygons[0]):
            return False
        #Check the "no go zones"
        for poly in self._machinePolygons[1:]:
            if polygon.polygonCollision(poly, area):
                return False
        return True
Exemple #52
0
    def updateHeadSize(self, obj=None):
        xMin = profile.getMachineSettingFloat('extruder_head_size_min_x')
        xMax = profile.getMachineSettingFloat('extruder_head_size_max_x')
        yMin = profile.getMachineSettingFloat('extruder_head_size_min_y')
        yMax = profile.getMachineSettingFloat('extruder_head_size_max_y')
        gantryHeight = profile.getMachineSettingFloat(
            'extruder_head_size_height')
        objectSink = profile.getProfileSettingFloat("object_sink")
        if profile.getPreference('startMode') == 'Simple':
            objectSink = float(
                profile.settingsDictionary["object_sink"].getDefault())

        self._leftToRight = xMin < xMax
        self._frontToBack = yMin < yMax
        self._headSizeOffsets[0] = min(xMin, xMax)
        self._headSizeOffsets[1] = min(yMin, yMax)
        self._gantryHeight = gantryHeight

        printOneAtATime = profile.getPreference('oneAtATime') == 'True'
        self._oneAtATime = self._gantryHeight > 0 and printOneAtATime
        if self._oneAtATime:
            if not self._lastOneAtATime:
                #print mode was changed by user. We need to reset that value to test with current scene content
                self._lastResultOneAtATime = True

            for objIter in self._objectList:
                if objIter.getSize()[2] - objectSink > self._gantryHeight:
                    self._oneAtATime = False
                    if self._lastResultOneAtATime:
                        if self._sceneView:
                            self._sceneView.notification.message(
                                "Object must be shorter than {}mm for this printer/tool head. Reduce object size or swap to \"All at once\" mode. "
                                .format(self._gantryHeight))
                        break

        self._lastResultOneAtATime = self._oneAtATime
        self._lastOneAtATime = printOneAtATime

        headArea = numpy.array(
            [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]],
            numpy.float32)

        if obj is None:
            for obj in self._objectList:
                obj.setHeadArea(headArea, self._headSizeOffsets)
        else:
            obj.setHeadArea(headArea, self._headSizeOffsets)
Exemple #53
0
 def OnAddHeight(self, e):
     scene = self.GetParent().GetParent().GetParent().GetParent().scene
     if scene.viewMode == 'normal':
         pauseLevel = 5.0
     else:
         pauseLevel = scene._engineResultView.layerSelect.getValue(
         ) * float(profile.getProfileSettingFloat('layer_height'))
     newConfig = {
         'filename': self.plugin.getFilename(),
         'params': {
             'pauseLevel': str(pauseLevel)
         }
     }
     if not self._buildPluginPanel(newConfig):
         return
     self.pluginConfig.append(newConfig)
     pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
     self.callback()
Exemple #54
0
def stitchMultiExtruder(outputList, resultFile):
    print "Stitching %i files for multi-extrusion" % (len(outputList))
    currentExtruder = 0
    resultFile.write('T%d\n' % (currentExtruder))
    layerNr = 0
    hasLine = True
    outputList = map(lambda o: o.split('\n'), outputList)
    outputOrder = range(0, len(outputList))
    outputSlice = []
    for n in xrange(0, len(outputList)):
        outputSlice.append([0, 0])
    currentX = 0
    currentY = 0
    currentZ = 0
    currentF = 60
    while hasLine:
        hasLine = layerNr < 1000
        for n in xrange(0, len(outputList)):
            outputSlice[n][0] = outputSlice[n][1] + 1
            outputSlice[n][1] = outputSlice[n][0]
            while outputSlice[n][1] < len(outputList[n]) and not outputList[n][
                    outputSlice[n][1]].startswith(';LAYER:'):
                outputSlice[n][1] += 1
        outputOrder = range(currentExtruder, len(outputList)) + range(
            0, currentExtruder)
        for n in outputOrder:
            if outputSlice[n][1] > outputSlice[n][0] + 1:
                nextExtruder = n
                resultFile.write(';LAYER:%d\n' % (layerNr))
                resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))

                startSlice = outputSlice[n][0]
                endSlice = outputSlice[n][1]

                currentE = 0
                while startSlice < len(outputList[n]) and not isPrintingLine(
                        outputList[n][startSlice]):
                    currentE = getCodeFloat(outputList[n][startSlice], 'E',
                                            currentE)
                    currentX = getCodeFloat(outputList[n][startSlice], 'X',
                                            currentX)
                    currentY = getCodeFloat(outputList[n][startSlice], 'Y',
                                            currentY)
                    currentZ = getCodeFloat(outputList[n][startSlice], 'Z',
                                            currentZ)
                    currentF = getCodeFloat(outputList[n][startSlice], 'F',
                                            currentF)
                    startSlice += 1
                while not isPrintingLine(outputList[n][endSlice - 1]):
                    endSlice -= 1

                if nextExtruder != currentExtruder:
                    profile.setTempOverride('extruder', nextExtruder)
                    profile.setTempOverride('new_x', currentX)
                    profile.setTempOverride('new_y', currentY)
                    profile.setTempOverride('new_z', currentZ)
                    resultFile.write(
                        profile.getAlterationFileContents(
                            'switchExtruder.gcode') + '\n')
                    profile.resetTempOverride()
                    currentExtruder = nextExtruder

                for idx in xrange(outputSlice[n][0], startSlice):
                    if not 'G1' in outputList[n][idx]:
                        resultFile.write(outputList[n][idx])
                        resultFile.write('\n')

                resultFile.write(
                    'G1 X%f Y%f Z%f F%f\n' %
                    (currentX, currentY, currentZ,
                     profile.getProfileSettingFloat('travel_speed') * 60))
                resultFile.write('G1 F%f\n' % (currentF))
                resultFile.write('G92 E%f\n' % (currentE))
                for idx in xrange(startSlice, endSlice):
                    resultFile.write(outputList[n][idx])
                    resultFile.write('\n')
                    currentX = getCodeFloat(outputList[n][idx], 'X', currentX)
                    currentY = getCodeFloat(outputList[n][idx], 'Y', currentY)
                    currentZ = getCodeFloat(outputList[n][idx], 'Z', currentZ)
                    hasLine = True
                resultFile.write('G92 E0\n')
        layerNr += 1
Exemple #55
0
	def OnDraw(self):
		if not self._enabled:
			return

		self._resultLock.acquire()
		result = self._result
		if result is not None:
			gcodeLayers = result.getGCodeLayers(self._gcodeLoadCallback)
			if result._polygons is not None and len(result._polygons) > 0:
				self.layerSelect.setRange(1, len(result._polygons))
			elif gcodeLayers is not None and len(gcodeLayers) > 0:
				self.layerSelect.setRange(1, len(gcodeLayers))
		else:
			gcodeLayers = None

		glPushMatrix()
		glEnable(GL_BLEND)
		if profile.getMachineSetting('machine_center_is_zero') != 'True':
			glTranslate(-profile.getMachineSettingFloat('machine_width') / 2, -profile.getMachineSettingFloat('machine_depth') / 2, 0)
		glLineWidth(2)

		layerNr = self.layerSelect.getValue()
		if layerNr == self.layerSelect.getMaxValue() and result is not None and len(result._polygons) > 0:
			layerNr = max(layerNr, len(result._polygons))
		if result is not None and len(result._polygons) > layerNr-1 and 'inset0' in result._polygons[layerNr-1] and len(result._polygons[layerNr-1]['inset0']) > 0 and len(result._polygons[layerNr-1]['inset0'][0]) > 0:
			viewZ = result._polygons[layerNr-1]['inset0'][0][0][2]
		else:
			viewZ = (layerNr - 1) * profile.getProfileSettingFloat('layer_height') + profile.getProfileSettingFloat('bottom_thickness')
		self._parent._viewTarget[2] = viewZ
		msize = max(profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth'))
		lineTypeList = [
			('inset0',     'WALL-OUTER', [1,0,0,1]),
			('insetx',     'WALL-INNER', [0,1,0,1]),
			('openoutline', None,        [1,0,0,1]),
			('skin',       'SKIN',       [1,1,0,1]),
			('infill',     'FILL',       [1,1,0,1]),
			('support',    'SUPPORT',    [0,1,1,1]),
			('skirt',      'SKIRT',      [0,1,1,1]),
			('outline',     None,        [0,0,0,1])
		]
		n = layerNr - 1
		generatedVBO = False
		if result is not None:
			while n >= 0:
				if layerNr - n > 30 and n % 20 == 0 and len(result._polygons) > 0:
					idx = n / 20
					while len(self._layer20VBOs) < idx + 1:
						self._layer20VBOs.append({})
					if result._polygons is not None and n + 20 < len(result._polygons):
						layerVBOs = self._layer20VBOs[idx]
						for typeName, typeNameGCode, color in lineTypeList:
							allow = typeName in result._polygons[n + 19]
							if typeName == 'skirt':
								for i in xrange(0, 20):
									if typeName in result._polygons[n + i]:
										allow = True
							if allow:
								if typeName not in layerVBOs:
									if generatedVBO:
										continue
									polygons = []
									for i in xrange(0, 20):
										if typeName in result._polygons[n + i]:
											polygons += result._polygons[n + i][typeName]
									layerVBOs[typeName] = self._polygonsToVBO_lines(polygons)
									generatedVBO = True
								glColor4f(color[0]*0.5,color[1]*0.5,color[2]*0.5,color[3])
								layerVBOs[typeName].render()
					n -= 20
				else:
					c = 1.0 - ((layerNr - n) - 1) * 0.05
					c = max(0.5, c)
					while len(self._layerVBOs) < n + 1:
						self._layerVBOs.append({})
					layerVBOs = self._layerVBOs[n]
					if gcodeLayers is not None and ((layerNr - 10 < n < (len(gcodeLayers) - 1)) or len(result._polygons) < 1):
						for typeNamePolygons, typeName, color in lineTypeList:
							if typeName is None:
								continue
							if 'GCODE-' + typeName not in layerVBOs:
								layerVBOs['GCODE-' + typeName] = self._gcodeToVBO_quads(gcodeLayers[n+1:n+2], typeName)
							glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3])
							layerVBOs['GCODE-' + typeName].render()

						if n == layerNr - 1:
							if 'GCODE-MOVE' not in layerVBOs:
								layerVBOs['GCODE-MOVE'] = self._gcodeToVBO_lines(gcodeLayers[n+1:n+2])
							glColor4f(0,0,c,1)
							layerVBOs['GCODE-MOVE'].render()
					elif n < len(result._polygons):
						polygons = result._polygons[n]
						for typeName, typeNameGCode, color in lineTypeList:
							if typeName in polygons:
								if typeName not in layerVBOs:
									layerVBOs[typeName] = self._polygonsToVBO_lines(polygons[typeName])
								glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3])
								layerVBOs[typeName].render()
					n -= 1
		glPopMatrix()
		if generatedVBO:
			self._parent._queueRefresh()

		if gcodeLayers is not None and self._gcodeLoadProgress != 0.0 and self._gcodeLoadProgress != 1.0:
			glPushMatrix()
			glLoadIdentity()
			glTranslate(0,-0.8,-2)
			glColor4ub(60,60,60,255)
			openglHelpers.glDrawStringCenter(_("Loading toolpath for visualization (%d%%)") % (self._gcodeLoadProgress * 100))
			glPopMatrix()
		self._resultLock.release()
Exemple #56
0
    def _engineSettings(self, extruderCount):
        settings = {
            'layerThickness':
            int(profile.getProfileSettingFloat('layer_height') * 1000),
            'initialLayerThickness':
            int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if
            profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int(
                profile.getProfileSettingFloat('layer_height') * 1000),
            'filamentDiameter':
            int(profile.getProfileSettingFloat('filament_diameter') * 1000),
            'filamentFlow':
            int(profile.getProfileSettingFloat('filament_flow')),
            'extrusionWidth':
            int(profile.calculateEdgeWidth() * 1000),
            'insetCount':
            int(profile.calculateLineCount()),
            'downSkinCount':
            int(profile.calculateSolidLayerCount())
            if profile.getProfileSetting('solid_bottom') == 'True' else 0,
            'upSkinCount':
            int(profile.calculateSolidLayerCount())
            if profile.getProfileSetting('solid_top') == 'True' else 0,
            'infillOverlap':
            int(profile.getProfileSettingFloat('fill_overlap')),
            'initialSpeedupLayers':
            int(4),
            'initialLayerSpeed':
            int(profile.getProfileSettingFloat('bottom_layer_speed')),
            'printSpeed':
            int(profile.getProfileSettingFloat('print_speed')),
            'infillSpeed':
            int(profile.getProfileSettingFloat('infill_speed')) if
            int(profile.getProfileSettingFloat('infill_speed')) > 0 else int(
                profile.getProfileSettingFloat('print_speed')),
            'inset0Speed':
            int(profile.getProfileSettingFloat('inset0_speed')) if
            int(profile.getProfileSettingFloat('inset0_speed')) > 0 else int(
                profile.getProfileSettingFloat('print_speed')),
            'insetXSpeed':
            int(profile.getProfileSettingFloat('insetx_speed')) if
            int(profile.getProfileSettingFloat('insetx_speed')) > 0 else int(
                profile.getProfileSettingFloat('print_speed')),
            'moveSpeed':
            int(profile.getProfileSettingFloat('travel_speed')),
            'fanSpeedMin':
            int(profile.getProfileSettingFloat('fan_speed'))
            if profile.getProfileSetting('fan_enabled') == 'True' else 0,
            'fanSpeedMax':
            int(profile.getProfileSettingFloat('fan_speed_max'))
            if profile.getProfileSetting('fan_enabled') == 'True' else 0,
            'supportAngle':
            int(-1) if profile.getProfileSetting('support') == 'None' else int(
                profile.getProfileSettingFloat('support_angle')),
            'supportEverywhere':
            int(1) if profile.getProfileSetting('support') == 'Everywhere' else
            int(0),
            'supportLineDistance':
            int(100 * profile.calculateEdgeWidth() * 1000 /
                profile.getProfileSettingFloat('support_fill_rate'))
            if profile.getProfileSettingFloat('support_fill_rate') > 0 else -1,
            'supportXYDistance':
            int(1000 * profile.getProfileSettingFloat('support_xy_distance')),
            'supportZDistance':
            int(1000 * profile.getProfileSettingFloat('support_z_distance')),
            'supportExtruder':
            0 if profile.getProfileSetting('support_dual_extrusion')
            == 'First extruder' else
            (1 if profile.getProfileSetting('support_dual_extrusion') ==
             'Second extruder' and profile.minimalExtruderCount() > 1 else -1),
            'retractionAmount':
            int(profile.getProfileSettingFloat('retraction_amount') * 1000)
            if profile.getProfileSetting('retraction_enable') == 'True' else 0,
            'retractionSpeed':
            int(profile.getProfileSettingFloat('retraction_speed')),
            'retractionMinimalDistance':
            int(
                profile.getProfileSettingFloat('retraction_min_travel') *
                1000),
            'retractionAmountExtruderSwitch':
            int(
                profile.getProfileSettingFloat('retraction_dual_amount') *
                1000),
            'retractionZHop':
            int(profile.getProfileSettingFloat('retraction_hop') * 1000),
            'minimalExtrusionBeforeRetraction':
            int(
                profile.getProfileSettingFloat('retraction_minimal_extrusion')
                * 1000),
            'enableCombing':
            1 if profile.getProfileSetting('retraction_combing') == 'True' else
            0,
            'multiVolumeOverlap':
            int(profile.getProfileSettingFloat('overlap_dual') * 1000),
            'objectSink':
            max(0, int(profile.getProfileSettingFloat('object_sink') * 1000)),
            'minimalLayerTime':
            int(profile.getProfileSettingFloat('cool_min_layer_time')),
            'minimalFeedrate':
            int(profile.getProfileSettingFloat('cool_min_feedrate')),
            'coolHeadLift':
            1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0,
            'startCode':
            profile.getAlterationFileContents('start.gcode', extruderCount),
            'endCode':
            profile.getAlterationFileContents('end.gcode', extruderCount),
            'relativeE':
            1 if profile.getMachineSetting('relative_extrusion') == 'True' else
            0,
            'perimInset':
            int(profile.getProfileSettingFloat('perimeter_inset') * 1000),
            'extruderOffset[1].X':
            int(profile.getMachineSettingFloat('extruder_offset_x1') * 1000),
            'extruderOffset[1].Y':
            int(profile.getMachineSettingFloat('extruder_offset_y1') * 1000),
            'extruderOffset[2].X':
            int(profile.getMachineSettingFloat('extruder_offset_x2') * 1000),
            'extruderOffset[2].Y':
            int(profile.getMachineSettingFloat('extruder_offset_y2') * 1000),
            'extruderOffset[3].X':
            int(profile.getMachineSettingFloat('extruder_offset_x3') * 1000),
            'extruderOffset[3].Y':
            int(profile.getMachineSettingFloat('extruder_offset_y3') * 1000),
            'fixHorrible':
            0,
        }
        fanFullHeight = int(
            profile.getProfileSettingFloat('fan_full_height') * 1000)
        settings['fanFullOnLayerNr'] = (fanFullHeight -
                                        settings['initialLayerThickness'] -
                                        1) / settings['layerThickness'] + 1
        if settings['fanFullOnLayerNr'] < 0:
            settings['fanFullOnLayerNr'] = 0
        if profile.getProfileSetting('support_type') == 'Lines':
            settings['supportType'] = 1

        if profile.getProfileSettingFloat('fill_density') == 0:
            settings['sparseInfillLineDistance'] = -1
        elif profile.getProfileSettingFloat('fill_density') == 100:
            settings['sparseInfillLineDistance'] = settings['extrusionWidth']
            #Set the up/down skins height to 10000 if we want a 100% filled object.
            # This gives better results then normal 100% infill as the sparse and up/down skin have some overlap.
            settings['downSkinCount'] = 10000
            settings['upSkinCount'] = 10000
        else:
            settings['sparseInfillLineDistance'] = int(
                100 * profile.calculateEdgeWidth() * 1000 /
                profile.getProfileSettingFloat('fill_density'))
        if profile.getProfileSetting('platform_adhesion') == 'Brim':
            settings['skirtDistance'] = 0
            settings['skirtLineCount'] = int(
                profile.getProfileSettingFloat('brim_line_count'))
        elif profile.getProfileSetting('platform_adhesion') == 'Raft':
            settings['skirtDistance'] = 0
            settings['skirtLineCount'] = 0
            settings['raftMargin'] = int(
                profile.getProfileSettingFloat('raft_margin') * 1000)
            settings['raftLineSpacing'] = int(
                profile.getProfileSettingFloat('raft_line_spacing') * 1000)
            settings['raftBaseThickness'] = int(
                profile.getProfileSettingFloat('raft_base_thickness') * 1000)
            settings['raftBaseLinewidth'] = int(
                profile.getProfileSettingFloat('raft_base_linewidth') * 1000)
            settings['raftInterfaceThickness'] = int(
                profile.getProfileSettingFloat('raft_interface_thickness') *
                1000)
            settings['raftInterfaceLinewidth'] = int(
                profile.getProfileSettingFloat('raft_interface_linewidth') *
                1000)
        else:
            settings['skirtDistance'] = int(
                profile.getProfileSettingFloat('skirt_gap') * 1000)
            settings['skirtLineCount'] = int(
                profile.getProfileSettingFloat('skirt_line_count'))
            settings['skirtMinLength'] = int(
                profile.getProfileSettingFloat('skirt_minimal_length') * 1000)

        if profile.getProfileSetting(
                'fix_horrible_union_all_type_a') == 'True':
            settings['fixHorrible'] |= 0x01
        if profile.getProfileSetting(
                'fix_horrible_union_all_type_b') == 'True':
            settings['fixHorrible'] |= 0x02
        if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True':
            settings['fixHorrible'] |= 0x10
        if profile.getProfileSetting(
                'fix_horrible_extensive_stitching') == 'True':
            settings['fixHorrible'] |= 0x04

        if settings['layerThickness'] <= 0:
            settings['layerThickness'] = 1000
        if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
            settings['gcodeFlavor'] = 1
        elif profile.getMachineSetting('gcode_flavor') == 'MakerBot':
            settings['gcodeFlavor'] = 2
        if profile.getProfileSetting('spiralize') == 'True':
            settings['spiralizeMode'] = 1
        if profile.getProfileSetting(
                'wipe_tower') == 'True' and extruderCount > 1:
            settings['wipeTowerSize'] = int(
                math.sqrt(
                    profile.getProfileSettingFloat('wipe_tower_volume') *
                    1000 * 1000 * 1000 / settings['layerThickness']))
        if profile.getProfileSetting('ooze_shield') == 'True':
            settings['enableOozeShield'] = 1
        return settings
Exemple #57
0
def main():
    parser = OptionParser(
        usage=
        "usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
    parser.add_option("-p",
                      "--profile",
                      action="store",
                      type="string",
                      dest="profile",
                      help="Encoded profile to use for the print")
    parser.add_option("-o",
                      "--output",
                      action="store",
                      type="string",
                      dest="output",
                      help="Output filename")
    (options, args) = parser.parse_args()
    if options.output is None:
        print 'Missing output filename'
        sys.exit(1)
    if options.profile is not None:
        profile.loadGlobalProfileFromString(options.profile)
    options.output = fixUTF8(options.output)

    clearZ = 0
    resultFile = open(options.output, "w")
    for idx in xrange(0, len(args), 2):
        position = map(float, args[idx].split(','))
        if len(position) < 9 + 2:
            position = position[0:2]
            position += [1, 0, 0]
            position += [0, 1, 0]
            position += [0, 0, 1]
        filenames = fixUTF8(args[idx + 1]).split('|')

        profile.setTempOverride('object_center_x', position[0])
        profile.setTempOverride('object_center_y', position[1])
        if idx == 0:
            resultFile.write(';TYPE:CUSTOM\n')
            resultFile.write(
                profile.getAlterationFileContents(
                    'start.gcode', len(filenames)).replace(
                        '?filename?',
                        ' '.join(filenames).encode('ascii', 'replace')))
        else:
            resultFile.write(';TYPE:CUSTOM\n')
            n = output[-1].rfind('Z') + 1
            zString = output[-1][n:n + 20]
            zString = zString[0:zString.find(' ')]
            clearZ = max(clearZ, float(zString) + 10)
            profile.setTempOverride('clear_z', clearZ)
            print position
            print profile.getAlterationFileContents('nextobject.gcode')
            resultFile.write(
                profile.getAlterationFileContents('nextobject.gcode').replace(
                    '?filename?',
                    ' '.join(filenames).encode('ascii', 'replace')))

        output = []
        for filename in filenames:
            extruderNr = filenames.index(filename)
            profile.resetTempOverride()
            if extruderNr > 0:
                profile.setTempOverride(
                    'object_center_x', position[0] -
                    profile.getPreferenceFloat('extruder_offset_x%d' %
                                               (extruderNr)))
                profile.setTempOverride(
                    'object_center_y', position[1] -
                    profile.getPreferenceFloat('extruder_offset_y%d' %
                                               (extruderNr)))
                profile.setTempOverride('fan_enabled', 'False')
                profile.setTempOverride('skirt_line_count', '0')
                profile.setTempOverride('alternative_center', filenames[0])
            else:
                profile.setTempOverride('object_center_x', position[0])
                profile.setTempOverride('object_center_y', position[1])
            profile.setTempOverride('object_matrix',
                                    ','.join(map(str, position[2:11])))
            if extruderNr > 0:
                if profile.getProfileSettingFloat('filament_diameter%d' %
                                                  (extruderNr + 1)) > 0:
                    profile.setTempOverride(
                        'filament_diameter',
                        profile.getProfileSetting('filament_diameter%d' %
                                                  (extruderNr + 1)))
            print extruderNr, profile.getPreferenceFloat(
                'extruder_offset_x%d' %
                (extruderNr)), profile.getPreferenceFloat(
                    'extruder_offset_y%d' % (extruderNr))
            output.append(export.getOutput(filename))
            profile.resetTempOverride()
        if len(output) == 1:
            resultFile.write(output[0])
        else:
            stitchMultiExtruder(output, resultFile)
    resultFile.write(';TYPE:CUSTOM\n')
    resultFile.write(profile.getAlterationFileContents('end.gcode'))
    resultFile.close()

    print "Running plugins"
    ret = profile.runPostProcessingPlugins(options.output)
    if ret is not None:
        print ret
    print "Finalizing %s" % (os.path.basename(options.output))
    if profile.getPreference('submit_slice_information') == 'True':
        filenames = fixUTF8(args[idx + 1]).split('|')
        for filename in filenames:
            m = hashlib.sha512()
            f = open(filename, "rb")
            while True:
                chunk = f.read(1024)
                if not chunk:
                    break
                m.update(chunk)
            f.close()
            data = {
                'processor': platform.processor(),
                'machine': platform.machine(),
                'platform': platform.platform(),
                'profile': profile.getGlobalProfileString(),
                'preferences': profile.getGlobalPreferencesString(),
                'modelhash': m.hexdigest(),
                'version': version.getVersion(),
            }
            try:
                f = urllib2.urlopen("http://platform.ultimaker.com/curastats/",
                                    data=urllib.urlencode(data),
                                    timeout=5)
                f.read()
                f.close()
            except:
                pass
Exemple #58
0
    def _load(self, gcodeFile):
        self.layerList = []
        pos = [0.0, 0.0, 0.0]
        posOffset = [0.0, 0.0, 0.0]
        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.0
        layerThickness = 0.1
        pathType = 'CUSTOM'
        currentLayer = []
        currentPath = gcodePath('move', pathType, layerThickness, pos[:])
        currentPath['extruder'] = currentExtruder

        currentLayer.append(currentPath)
        for line in gcodeFile:
            if type(line) is tuple:
                line = line[0]

            #Parse Cura_SF comments
            if line.startswith(';TYPE:'):
                pathType = line[6:].strip()

            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:'):
                    currentPath = gcodePath(moveType, pathType, layerThickness,
                                            currentPath['points'][-1])
                    currentPath['extruder'] = currentExtruder
                    for path in currentLayer:
                        path['points'] = numpy.array(path['points'],
                                                     numpy.float32)
                        path['extrusion'] = numpy.array(
                            path['extrusion'], numpy.float32)
                    self.layerList.append(currentLayer)
                    if self.progressCallback is not None:
                        if self.progressCallback(
                                float(gcodeFile.tell()) /
                                float(self._fileSize)):
                            #Abort the loading, we can safely return as the results here will be discarded
                            gcodeFile.close()
                            return
                    currentLayer = [currentPath]
                line = line[0:line.find(';')]
            T = getCodeInt(line, 'T')
            if T is not None:
                if currentExtruder > 0:
                    posOffset[0] -= profile.getPreferenceFloat(
                        'extruder_offset_x%d' % (currentExtruder))
                    posOffset[1] -= profile.getPreferenceFloat(
                        'extruder_offset_y%d' % (currentExtruder))
                currentExtruder = T
                if currentExtruder > 0:
                    posOffset[0] += profile.getPreferenceFloat(
                        'extruder_offset_x%d' % (currentExtruder))
                    posOffset[1] += profile.getPreferenceFloat(
                        'extruder_offset_y%d' % (currentExtruder))

            G = getCodeInt(line, 'G')
            if G is not None:
                if G == 0 or G == 1:  #Move
                    x = getCodeFloat(line, 'X')
                    y = getCodeFloat(line, 'Y')
                    z = getCodeFloat(line, 'Z')
                    e = getCodeFloat(line, 'E')
                    #f = getCodeFloat(line, 'F')
                    oldPos = pos[:]
                    if posAbs:
                        if x is not None:
                            pos[0] = x * scale + posOffset[0]
                        if y is not None:
                            pos[1] = y * scale + posOffset[1]
                        if z is not None:
                            pos[2] = z * scale + posOffset[2]
                    else:
                        if x is not None:
                            pos[0] += x * scale
                        if y is not None:
                            pos[1] += y * scale
                        if z is not None:
                            pos[2] += z * scale
                    #if f is not None:
                    #	feedRate = f
                    #if x is not None or y is not None or z is not None:
                    #	diffX = oldPos[0] - pos[0]
                    #	diffY = oldPos[1] - pos[1]
                    #	totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRate
                    moveType = 'move'
                    if e is not None:
                        if absoluteE:
                            e -= currentE
                        if e > 0.0:
                            moveType = 'extrude'
                        if e < 0.0:
                            moveType = 'retract'
                        totalExtrusion += e
                        currentE += e
                        if totalExtrusion > maxExtrusion:
                            maxExtrusion = totalExtrusion
                    else:
                        e = 0.0
                    if moveType == 'move' and oldPos[2] != pos[2]:
                        if oldPos[2] > pos[2] and abs(
                                oldPos[2] - pos[2]) > 5.0 and pos[2] < 1.0:
                            oldPos[2] = 0.0
                        layerThickness = abs(oldPos[2] - pos[2])
                    if currentPath['type'] != moveType or currentPath[
                            'pathType'] != pathType:
                        currentPath = gcodePath(moveType, pathType,
                                                layerThickness,
                                                currentPath['points'][-1])
                        currentPath['extruder'] = currentExtruder
                        currentLayer.append(currentPath)

                    currentPath['points'].append(pos[:])
                    currentPath['extrusion'].append(e * extrudeAmountMultiply)
                elif G == 4:  #Delay
                    S = getCodeFloat(line, 'S')
                    if S is not None:
                        totalMoveTimeMinute += S / 60.0
                    P = getCodeFloat(line, 'P')
                    if P is not None:
                        totalMoveTimeMinute += P / 60.0 / 1000.0
                elif G == 20:  #Units are inches
                    scale = 25.4
                elif G == 21:  #Units are mm
                    scale = 1.0
                elif G == 28:  #Home
                    x = getCodeFloat(line, 'X')
                    y = getCodeFloat(line, 'Y')
                    z = getCodeFloat(line, 'Z')
                    if profile.getPreference(
                            'machine_center_is_zero') == 'True':
                        center = [
                            profile.getProfileSettingFloat('machine_width') /
                            2,
                            profile.getProfileSettingFloat('machine_depth') /
                            2, 0.0
                        ]
                    else:
                        center = [0.0, 0.0, 0.0]
                    if x is None and y is None and z is None:
                        pos = center
                    else:
                        if x is not None:
                            pos[0] = center[0]
                        if y is not None:
                            pos[0] = center[1]
                        if z is not None:
                            pos[0] = center[2]
                elif G == 90:  #Absolute position
                    posAbs = True
                elif G == 91:  #Relative position
                    posAbs = False
                elif G == 92:
                    x = getCodeFloat(line, 'X')
                    y = getCodeFloat(line, 'Y')
                    z = getCodeFloat(line, 'Z')
                    e = getCodeFloat(line, 'E')
                    if e is not None:
                        currentE = e
                    if x is not None:
                        posOffset[0] = pos[0] - x
                    if y is not None:
                        posOffset[1] = pos[1] - y
                    if z is not None:
                        posOffset[2] = pos[2] - z
                else:
                    print "Unknown G code:" + str(G)
            else:
                M = getCodeInt(line, 'M')
                if M is not None:
                    if M == 0:  #Message with possible wait (ignored)
                        pass
                    elif 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 == 117:  #LCD message
                        pass
                    elif M == 140:  #Set bed temperature
                        pass
                    elif M == 190:  #Set bed temperature & wait
                        pass
                    elif M == 221:  #Extrude amount multiplier
                        s = getCodeFloat(line, 'S')
                        if s is not None:
                            extrudeAmountMultiply = s / 100.0
                    else:
                        print "Unknown M code:" + str(M)
        for path in currentLayer:
            path['points'] = numpy.array(path['points'], numpy.float32)
            path['extrusion'] = numpy.array(path['extrusion'], numpy.float32)
        self.layerList.append(currentLayer)
        if self.progressCallback is not None and self._fileSize > 0:
            self.progressCallback(
                float(gcodeFile.tell()) / float(self._fileSize))
        self.extrusionAmount = maxExtrusion
        self.totalMoveTimeMinute = totalMoveTimeMinute