def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line if self.layerIndex < 1: travelFeedRateMinute = self.repository.objectFirstLayerTravelSpeed.value * 60 if self.isSupportPath: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateEdgeMultiplier.value * 60 elif self.isEdgePath: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateEdgeMultiplier.value * 60 else: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateInfillMultiplier.value * 60 else: travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.isSupportPath: tempfeedRateMinute = self.repository.edgeFeedRateMultiplier.value * 60 elif self.isBridgeLayer: tempfeedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.edgeFeedRateMultiplier.value * 60 elif self.isEdgePath: tempfeedRateMinute = self.repository.edgeFeedRateMultiplier.value * 60 else: tempfeedRateMinute = 60.0 * self.feedRatePerSecond if self.isExtruderActive is True: feedRateMinute = tempfeedRateMinute self.addFlowRateLine() if not self.isExtruderActive: feedRateMinute = travelFeedRateMinute return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
def getLocationSetFeedRateToSplitLine( self, splitLine ): """Get location ans set feed rate to the plsit line.""" location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) indexOfF = gcodec.getIndexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedRateMinute = gcodec.getDoubleAfterFirstLetter( splitLine[indexOfF] ) return location
def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line tempfeedRateMinute = 60.0 * self.feedRatePerSecond travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.layerIndex <= 0: travelFeedRateMinute = self.repository.objectFirstLayerTravelSpeed.value * 60 if self.isEdgePath: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateEdgeMultiplier.value * 60 else: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateInfillMultiplier.value * 60 elif self.layerIndex > 0: travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.isEdgePath: tempfeedRateMinute = self.repository.edgeFeedRateMultiplier.value * 60 if self.isBridgeLayer: tempfeedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.edgeFeedRateMultiplier.value * 60 if self.isExtruderActive is True: feedRateMinute = tempfeedRateMinute self.addFlowRateLine() if not self.isExtruderActive: feedRateMinute = self.travelFeedRateMinute return self.distanceFeedRate.getLineWithFeedRate( feedRateMinute, line, splitLine)
def getLocationSetFeedRateToSplitLine( self, splitLine ): "Get location ans set feed rate to the plsit line." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) indexOfF = gcodec.getIndexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedRateMinute = gcodec.getDoubleAfterFirstLetter( splitLine[indexOfF] ) return location
def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line tempfeedRateMinute = 60.0 * self.feedRatePerSecond travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.layerIndex <= 0: travelFeedRateMinute = self.repository.objectFirstLayerTravelSpeed.value * 60 if self.isPerimeterPath: tempfeedRateMinute = self.repository.objectFirstLayerFeedRatePerimeterMultiplier.value * 60 else: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateInfillMultiplier.value * 60 elif self.layerIndex > 0: travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.isPerimeterPath: tempfeedRateMinute = self.repository.perimeterFeedRateMultiplier.value * 60 if self.isBridgeLayer: tempfeedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.perimeterFeedRateMultiplier.value * 60 if self.isExtruderActive is True: feedRateMinute = tempfeedRateMinute if self.isExtruderActive is False: feedRateMinute = travelFeedRateMinute self.addFlowRateLine() self.addAccelerationRateLine() return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line , splitLine)
def getSpeededLine(self, line, splitLine): "Get gcode line with feed rate." if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line feedRateMinute = 60.0 * self.feedRatePerSecond if self.isBridgeLayer: feedRateMinute *= self.repository.bridgeFeedRateMultiplier.value if self.isPerimeter: feedRateMinute *= self.repository.perimeterFeedRateOverOperatingFeedRate.value self.addFlowRateLineIfNecessary() if not self.isExtruderActive: feedRateMinute = self.travelFeedRatePerMinute return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
def helicalMove(self, isCounterclockwise, splitLine): "Get statistics for a helical move." if self.oldLocation == None: return location = self.getLocationSetFeedRateToSplitLine(splitLine) location += self.oldLocation center = self.oldLocation.copy() indexOfR = gcodec.getIndexOfStartingWithSecond("R", splitLine) if indexOfR > 0: radius = gcodec.getDoubleAfterFirstLetter(splitLine[indexOfR]) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.magnitude() centerMidpointDistanceSquared = radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength centerMidpointDistance = math.sqrt( max(centerMidpointDistanceSquared, 0.0)) centerMinusMidpoint = euclidean.getRotatedWiddershinsQuarterAroundZAxis( halfLocationMinusOld) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVector3(halfLocationMinusOld + centerMinusMidpoint) else: center.setToVector3(halfLocationMinusOld - centerMinusMidpoint) else: center.x = gcodec.getDoubleForLetter("I", splitLine) center.y = gcodec.getDoubleForLetter("J", splitLine) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment) absoluteDifferenceAngle = abs(afterCenterDifferenceAngle) steps = int( round(0.5 + max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.magnitude() / curveSection))) stepPlaneAngle = euclidean.getWiddershinsUnitPolar( afterCenterDifferenceAngle / steps) zIncrement = (afterCenterSegment.z - beforeCenterSegment.z) / float(steps) for step in xrange(1, steps): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.addToPath(arcPoint) self.addToPath(location)
def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line feedRateMinute = 60.0 * self.feedRatePerSecond if self.isBridgeLayer: feedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.perimeterFeedRateOverOperatingFeedRate.value * 60 # todo former reference to main feed now perimeter feed if self.isPerimeterPath: feedRateMinute = self.repository.perimeterFeedRateOverOperatingFeedRate.value * 60 if not self.isExtruderActive: feedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 self.addFlowRateLineIfNecessary() self.addAccelerationRateLineIfNecessary() return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line feedRateMinute = 60.0 * self.feedRatePerSecond if self.isBridgeLayer: feedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.perimeterFeedRateOverOperatingFeedRate.value * 60 # todo former reference to main feed now perimeter feed if self.isPerimeterPath: feedRateMinute = self.repository.perimeterFeedRateOverOperatingFeedRate.value * 60 if not self.isExtruderActive: feedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 self.addFlowRateLineIfNecessary() self.addAccelerationRateLineIfNecessary() return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line feedRateMinute = 60.0 * self.feedRatePerSecond if self.isBridgeLayer: feedRateMinute *= self.repository.bridgeFeedRateMultiplier.value if self.isEdgePath: feedRateMinute *= self.repository.perimeterFeedRateMultiplier.value if self.layerIndex == 0: if self.isEdgePath: feedRateMinute *= self.repository.objectFirstLayerFeedRatePerimeterMultiplier.value else: feedRateMinute *= self.repository.objectFirstLayerFeedRateInfillMultiplier.value self.addFlowRateLine() if not self.isExtruderActive: feedRateMinute = self.travelFeedRateMinute return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
def helicalMove( self, isCounterclockwise, splitLine ): """Get statistics for a helical move.""" if self.oldLocation is None: return location = self.getLocationSetFeedRateToSplitLine(splitLine) location += self.oldLocation center = self.oldLocation.copy() indexOfR = gcodec.getIndexOfStartingWithSecond( "R", splitLine ) if indexOfR > 0: radius = gcodec.getDoubleAfterFirstLetter( splitLine[ indexOfR ] ) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.magnitude() centerMidpointDistanceSquared = radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength centerMidpointDistance = math.sqrt( max( centerMidpointDistanceSquared, 0.0 ) ) centerMinusMidpoint = euclidean.getRotatedWiddershinsQuarterAroundZAxis( halfLocationMinusOld ) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVector3( halfLocationMinusOld + centerMinusMidpoint ) else: center.setToVector3( halfLocationMinusOld - centerMinusMidpoint ) else: center.x = gcodec.getDoubleForLetter( "I", splitLine ) center.y = gcodec.getDoubleForLetter( "J", splitLine ) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment ) absoluteDifferenceAngle = abs( afterCenterDifferenceAngle ) steps = int( round( 0.5 + max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.magnitude() / curveSection ) ) ) stepPlaneAngle = euclidean.getWiddershinsUnitPolar( afterCenterDifferenceAngle / steps ) zIncrement = ( afterCenterSegment.z - beforeCenterSegment.z ) / float( steps ) for step in xrange( 1, steps ): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment ) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.addToPath( arcPoint ) self.addToPath( location )
def getStringFromCharacterSplitLine( character, splitLine): "Get the string after the first occurence of the character in the split line." indexOfCharacter = gcodec.getIndexOfStartingWithSecond(character, splitLine) if indexOfCharacter < 0: return None return splitLine[indexOfCharacter][1 :]
def parseLine(self, line): """Parse a gcode line and add it to the reversal gcode. Overview: o Keep track of gcode state: current flowrate (self.flowrate), current position (self.newLocation/oldLocation) current feedrate (self.feedRateMinute) current logical extruder state (self.extruderOn) o Keep track of reversal state: (self.didReverse, self.reversalActive) o If early reversal is NOT active, it will insert a pause command at the end of each thread (G4). This will cause the extruder to move without XYZ. This is not recommended as it might cause some blobbing o If early reversal is active """ if DEBUG: self.distanceFeedRate.addLine("( line: " + line + " )") splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'M108': # If we didn't already rpmify the M108 commands, do this now line = line.replace( 'M108 S', 'M108 R' ) splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) # Keep track of current flowrate indexOfR = gcodec.getIndexOfStartingWithSecond('R', splitLine) if indexOfR > 0: self.flowrate = gcodec.getDoubleAfterFirstLetter(splitLine[indexOfR]) # Pick up all movement commands elif firstWord == 'G1': # Location at the start of this movement self.oldLocation = self.newLocation # Location at the end start of this movement self.newLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if self.activateEarlyReversal: # If we did reverse and we're not already pushing back if (not self.extruderOn and self.filamentState == ReversalSkein.FILAMENT_REVERSED and self.pushbackWorthy and not self.pushbackActive): # If this movement crosses the push-back point, this will # move us to where pushback starts and return true. if self.detectAndMoveToReversalEvent('M101', self.pushbackTime): if DEBUG: self.distanceFeedRate.addLine("( activating pushback: )") self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M101") self.pushbackActive = True self.filamentState = ReversalSkein.FILAMENT_READY # If we're going to reverse on next stop and we're not already reversing if (self.extruderOn and self.filamentState == ReversalSkein.FILAMENT_READY and self.reversalWorthy and not self.reversalActive): # If this movement crosses the reversal point, this will # move us to where reversal starts and return true. if self.detectAndMoveToReversalEvent('M103', self.reversalTime): if DEBUG: self.distanceFeedRate.addLine("( activating reverse: )") self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M102") self.reversalActive = True self.filamentState = ReversalSkein.FILAMENT_REVERSED # Note: We don't return here since the current G1 command will # keep moving to the end of the current movement thread with # reversal/push-back potentially active. # Detect extruder ON commands elif firstWord == 'M101': self.extruderOn = True self.reversalWorthy = self.isNextMovementReversalWorthy(self.reversalThreshold, 'M103', 'M101') if (not self.activateEarlyReversal and self.pushbackWorthy and self.filamentState == ReversalSkein.FILAMENT_REVERSED): self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M101") self.distanceFeedRate.addLine("G04 P" + str(self.reversalTime)) self.pushbackActive = True if self.pushbackActive: self.distanceFeedRate.addLine("M108 R" + str(self.flowrate)) self.pushbackActive = False self.filamentState = ReversalSkein.FILAMENT_READY if DEBUG: self.printState() return # Motor is already on - no need to emit the M101 # Detect extruder OFF commands elif firstWord == 'M103': self.extruderOn = False self.pushbackWorthy = self.isNextMovementReversalWorthy(self.reversalThreshold, 'M101', 'M103') if (not self.activateEarlyReversal and self.reversalWorthy and self.filamentState == ReversalSkein.FILAMENT_READY): self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M102") self.distanceFeedRate.addLine("G04 P" + str(self.pushbackTime)) self.filamentState = ReversalSkein.FILAMENT_REVERSED if self.reversalActive: self.reversalActive = False self.filamentState = ReversalSkein.FILAMENT_REVERSED # For safety, reset feedrate here. It's a known issue # that some other plugins keep track of flowrate state # and removed redundant settings, so we need to keep # the original state whenever we're done with an operation self.distanceFeedRate.addLine("M108 R" + str(self.flowrate)) # If someone else inserted a reverse command, detect this and update state # (e.g. end.gcode for Makerbots does this for retracting the filament) elif firstWord == 'M102': self.extruderOn = True self.filamentState = ReversalSkein.FILAMENT_REVERSED self.reversalActive = True if DEBUG: if firstWord == 'M101' or firstWord == 'M102' or firstWord == 'M103': self.printState() # The reversal may change the feedrate for the remaining reversal movements if (self.reversalActive or self.pushbackActive) and firstWord == 'G1': line = self.distanceFeedRate.getLineWithFeedRate(self.reversalFeedrate, line, splitLine) self.distanceFeedRate.addLine(line)
def parseLine(self, line): """Parse a gcode line and add it to the reversal gcode. Overview: o Keep track of gcode state: current flowrate (self.flowrate), current position (self.newLocation/oldLocation) current feedrate (self.feedRateMinute) current logical extruder state (self.extruderOn) o Keep track of reversal state: (self.didReverse, self.reversalActive) o If early reversal is NOT active, it will insert a pause command at the end of each thread (G4). This will cause the extruder to move without XYZ. This is not recommended as it might cause some blobbing o If early reversal is active """ if DEBUG: self.distanceFeedRate.addLine("( line: " + line + " )") splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'M108': # If we didn't already rpmify the M108 commands, do this now line = line.replace('M108 S', 'M108 R') splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) # Keep track of current flowrate indexOfR = gcodec.getIndexOfStartingWithSecond('R', splitLine) if indexOfR > 0: self.flowrate = gcodec.getDoubleAfterFirstLetter( splitLine[indexOfR]) # Pick up all movement commands elif firstWord == 'G1': # Location at the start of this movement self.oldLocation = self.newLocation # Location at the end start of this movement self.newLocation = gcodec.getLocationFromSplitLine( self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine) if self.activateEarlyReversal: # If we did reverse and we're not already pushing back if (not self.extruderOn and self.filamentState == ReversalSkein.FILAMENT_REVERSED and self.pushbackWorthy and not self.pushbackActive): # If this movement crosses the push-back point, this will # move us to where pushback starts and return true. if self.detectAndMoveToReversalEvent( 'M101', self.pushbackTime): if DEBUG: self.distanceFeedRate.addLine( "( activating pushback: )") self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M101") self.pushbackActive = True self.filamentState = ReversalSkein.FILAMENT_READY # If we're going to reverse on next stop and we're not already reversing if (self.extruderOn and self.filamentState == ReversalSkein.FILAMENT_READY and self.reversalWorthy and not self.reversalActive): # If this movement crosses the reversal point, this will # move us to where reversal starts and return true. if self.detectAndMoveToReversalEvent( 'M103', self.reversalTime): if DEBUG: self.distanceFeedRate.addLine( "( activating reverse: )") self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M102") self.reversalActive = True self.filamentState = ReversalSkein.FILAMENT_REVERSED # Note: We don't return here since the current G1 command will # keep moving to the end of the current movement thread with # reversal/push-back potentially active. # Detect extruder ON commands elif firstWord == 'M101': self.extruderOn = True self.reversalWorthy = self.isNextMovementReversalWorthy( self.reversalThreshold, 'M103', 'M101') if (not self.activateEarlyReversal and self.pushbackWorthy and self.filamentState == ReversalSkein.FILAMENT_REVERSED): self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M101") self.distanceFeedRate.addLine("G04 P" + str(self.reversalTime)) self.pushbackActive = True if self.pushbackActive: self.distanceFeedRate.addLine("M108 R" + str(self.flowrate)) self.pushbackActive = False self.filamentState = ReversalSkein.FILAMENT_READY if DEBUG: self.printState() return # Motor is already on - no need to emit the M101 # Detect extruder OFF commands elif firstWord == 'M103': self.extruderOn = False self.pushbackWorthy = self.isNextMovementReversalWorthy( self.reversalThreshold, 'M101', 'M103') if (not self.activateEarlyReversal and self.reversalWorthy and self.filamentState == ReversalSkein.FILAMENT_READY): self.distanceFeedRate.addLine("M108 R" + str(self.reversalRPM)) self.distanceFeedRate.addLine("M102") self.distanceFeedRate.addLine("G04 P" + str(self.pushbackTime)) self.filamentState = ReversalSkein.FILAMENT_REVERSED if self.reversalActive: self.reversalActive = False self.filamentState = ReversalSkein.FILAMENT_REVERSED # For safety, reset feedrate here. It's a known issue # that some other plugins keep track of flowrate state # and removed redundant settings, so we need to keep # the original state whenever we're done with an operation self.distanceFeedRate.addLine("M108 R" + str(self.flowrate)) # If someone else inserted a reverse command, detect this and update state # (e.g. end.gcode for Makerbots does this for retracting the filament) elif firstWord == 'M102': self.extruderOn = True self.filamentState = ReversalSkein.FILAMENT_REVERSED self.reversalActive = True if DEBUG: if firstWord == 'M101' or firstWord == 'M102' or firstWord == 'M103': self.printState() # The reversal may change the feedrate for the remaining reversal movements if (self.reversalActive or self.pushbackActive) and firstWord == 'G1': line = self.distanceFeedRate.getLineWithFeedRate( self.reversalFeedrate, line, splitLine) self.distanceFeedRate.addLine(line)
def Edist( self , splitLine ): return splitLine[gcodec.getIndexOfStartingWithSecond('E', splitLine)][1:]
def Edist( self , splitLine ): return splitLine[gcodec.getIndexOfStartingWithSecond('E', splitLine)][1:]