import Image, ImageDraw, ImageChops from GifImagePlugin import getheader, getdata # Get the entire text of a file. # @param filename name of the file # @return entire text of a file. def getFileText( filename ): file = open( filename, 'r' ) fileText = file.read() file.close() return fileText # Get the all the lines of text of a text. # @param text text # @return the lines of text of a text def getTextLines( text ): return text.replace( '\r', '\n' ).split( '\n' ) # Get the double value of the word after the first letter. # @param word string with value starting after the first letter # @return double value of the word after the first letter def getDoubleAfterFirstLetter( word ): return float( word[ 1 : ] ) # Get the double value of the word after the first occurence of the letter in the split line. def getDoubleForLetter( letter, splitLine ): return getDoubleAfterFirstLetter( splitLine[ indexOfStartingWithSecond( letter, splitLine ) ] ) # Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found def indexOfStartingWithSecond( letter, splitLine ): for wordIndex in range( 1, len( splitLine ) ): word = splitLine[ wordIndex ] firstLetter = word[ 0 ] if firstLetter == letter: return wordIndex return - 1 # straightforward delta encoding taken from gifmaker.py def makedelta(fp, sequence): """Convert list of image frames to a GIF animation file""" previous = None for im in sequence: if not previous: # global header for s in getheader(im) + getdata(im): fp.write(s) else: # delta frame delta = ImageChops.subtract_modulo(im, previous) bbox = delta.getbbox() if not bbox: bbox = (0,0, 1,1) # compress difference for s in getdata(im.crop(bbox), offset = bbox[:2]): fp.write(s) previous = im.copy() fp.write(";") class vec3: "A three dimensional vector class." def __init__( self ): self.x = 0.0 self.y = 0.0 self.z = 0.0 class g2gif: def __init__(self,filename, outfile): self.last_pos = vec3() self.last_pos.z = 999 self.do_move = 1 fileText = getFileText( filename ) textLines = getTextLines( fileText ) self.images = [] self.image = None for line in textLines: self.parseLine( line ) self.images.append(self.image) # write GIF animation fp = open(outfile, "wb") makedelta(fp, self.images) fp.close() def parseLine(self, line): splitLine = line.split( ' ' ) if len( splitLine ) < 1: return 0 firstWord = splitLine[ 0 ] if firstWord == 'G1': self.linearMove( splitLine ) if firstWord == 'M101': self.do_move = 1 # Set the feedrate to the gcode split line. def setFeedrate( self, splitLine ): indexOfF = indexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedrateMinute = getDoubleAfterFirstLetter( splitLine[ indexOfF ] ) # Set a point to the gcode split line. def setPointComponent( self, point, splitLine ): point.x = getDoubleForLetter( "X", splitLine ) point.y = getDoubleForLetter( "Y", splitLine ) indexOfZ = indexOfStartingWithSecond( "Z", splitLine ) if indexOfZ > 0: point.z = getDoubleAfterFirstLetter( splitLine[ indexOfZ ] ) def scale(self, x, y): return x * 5 + 150, -y * 5 + 100 def linearMove( self, splitLine ): location = vec3() self.setFeedrate( splitLine ) self.setPointComponent( location, splitLine ) if location.z != self.last_pos.z: if self.image: for i in range(10): self.images.append(self.image) self.image = Image.new('P', (300, 200), 255) palette = [] for red in range(8): for green in range(8): for blue in range(4): palette.extend((red * 255 / 7, green * 255 / 7, blue * 255 / 3)) self.image.putpalette(palette) self.segment = 0 else: if self.do_move: draw = ImageDraw.Draw(self.image) draw.line((self.scale(self.last_pos.x, self.last_pos.y), self.scale(location.x, location.y)), fill = 192) self.segment = self.segment + 1 else: draw = ImageDraw.Draw(self.image) draw.line((self.scale(self.last_pos.x, self.last_pos.y), self.scale(location.x, location.y)), fill = self.segment) self.last_pos = location self.do_move = 0