def execute(self, app): if Image is None: app.setStatus(_("Halftone abort: This plugin requires PIL/Pillow to read image data")) return n = self["name"] if not n or n=="default": n="Halftone" #Calc desired size channel = self["Channel"] invert = self["Invert"] drawSize = self["DrawSize"] cellSize = self["CellSize"] dMax = self["DiameterMax"] dMin = self["DiameterMin"] angle = self["Angle"] drawBorder = self["DrawBorder"] depth = self["Depth"] conical = self["Conical"] #Check parameters if drawSize < 1: app.setStatus(_("Halftone abort: Size too small to draw anything!")) return if dMin > dMax: app.setStatus(_("Halftone abort: Minimum diameter must be minor then Maximum")) return if dMax < 1: app.setStatus(_("Halftone abort: Maximum diameter too small")) return if cellSize < 1: app.setStatus(_("Halftone abort: Cell size too small")) return tool = app.tools["EndMill"] tool_shape = tool["shape"] if conical: if tool_shape== "V-cutting": try: v_angle = float(tool["angle"]) except: app.setStatus(_("Halftone abort: Angle in V-Cutting end mill is missing")) return else: app.setStatus(_("Halftone abort: Conical path need V-Cutting end mill")) return #Open picture file fileName = self["File"] try: img = Image.open(fileName) except: app.setStatus(_("Halftone abort: Can't read image file")) return #Create a scaled image to work faster with big image and better with small ones squareNorm = True if channel == 'Blue(sqrt)': img = img.convert('RGB') img = img.split()[0] elif channel == 'Green(sqrt)': img = img.convert('RGB') img = img.split()[1] elif channel == 'Red(sqrt)': img = img.convert('RGB') img = img.split()[2] else: img = img.convert ('L') #to calculate luminance squareNorm = False #flip image to ouput correct coordinates img = img.transpose(Image.FLIP_TOP_BOTTOM) #Calc divisions for halftone divisions = drawSize / cellSize #Get image size self.imgWidth, self.imgHeight = img.size if (self.imgWidth > self.imgHeight): scale = drawSize / float(self.imgWidth) sample = int(self.imgWidth / divisions) else: scale = drawSize / float(self.imgHeight) sample = int(self.imgHeight / divisions) self.ratio = scale #Halftone circles = self.halftone(img, sample, scale, angle, squareNorm, invert) #Init blocks blocks = [] #Border block if drawBorder: block = Block("%s-border"%(self.name)) block.append(CNC.zsafe()) block.append(CNC.grapid(0,0)) block.append(CNC.zenter(depth)) block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])])) block.append(CNC.gline(self.imgWidth * self.ratio, 0)) block.append(CNC.gline(self.imgWidth * self.ratio, self.imgHeight*self.ratio)) block.append(CNC.gline(0, self.imgHeight*self.ratio)) block.append(CNC.gline(0,0)) blocks.append(block) #Draw block block = Block(self.name) #Change color if channel == 'Blue(sqrt)': block.color = "#0000ff" elif channel == 'Green(sqrt)': block.color = "#00ff00" elif channel == 'Red(sqrt)': block.color = "#ff0000" block.append("(Halftone size W=%d x H=%d x D=%d ,Total points:%i)" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))) block.append("(Channel = %s)" % channel) for c in circles: x,y,r = c r = min(dMax/2.0,r) if (r >= dMin/2.): block.append(CNC.zsafe()) block.append(CNC.grapid(x+r,y)) block.append(CNC.zenter(depth)) block.append(CNC.garc(CW,x+r,y,i=-r,)) block.append(CNC.zsafe()) if conical: block.enable = False blocks.append(block) if conical: blockCon = Block("%s-Conical"%(self.name)) for c in circles: x,y,r = c blockCon.append(CNC.zsafe()) blockCon.append(CNC.grapid(x,y)) dv = r / math.tan(math.radians(v_angle/2.)) blockCon.append(CNC.zenter(-dv)) blockCon.append(CNC.zsafe()) blocks.append(blockCon) #Gcode Zsafe active = app.activeBlock() app.gcode.insBlocks(active, blocks, "Halftone") app.refresh() app.setStatus(_("Generated Halftone size W=%d x H=%d x D=%d ,Total points:%i" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))))
def execute(self, app): if Image is None: app.setStatus( _("Halftone abort: This plugin requires PIL/Pillow to read image data" )) return n = self["name"] if not n or n == "default": n = "Halftone" # Calc desired size channel = self["Channel"] invert = self["Invert"] drawSize = self["DrawSize"] cellSize = self["CellSize"] dMax = self["DiameterMax"] dMin = self["DiameterMin"] angle = self["Angle"] drawBorder = self["DrawBorder"] depth = self["Depth"] conical = self["Conical"] # Check parameters if drawSize < 1: app.setStatus( _("Halftone abort: Size too small to draw anything!")) return if dMin > dMax: app.setStatus( _("Halftone abort: Minimum diameter must be minor then Maximum" )) return if dMax < 1: app.setStatus(_("Halftone abort: Maximum diameter too small")) return if cellSize < 1: app.setStatus(_("Halftone abort: Cell size too small")) return tool = app.tools["EndMill"] tool_shape = tool["shape"] if conical: if tool_shape == "V-cutting": try: v_angle = float(tool["angle"]) except: app.setStatus( _("Halftone abort: Angle in V-Cutting end mill is missing" )) return else: app.setStatus( _("Halftone abort: Conical path need V-Cutting end mill")) return # Open picture file fileName = self["File"] try: img = Image.open(fileName) except: app.setStatus(_("Halftone abort: Can't read image file")) return # Create a scaled image to work faster with big image and better with small ones squareNorm = True if channel == 'Blue(sqrt)': img = img.convert('RGB') img = img.split()[0] elif channel == 'Green(sqrt)': img = img.convert('RGB') img = img.split()[1] elif channel == 'Red(sqrt)': img = img.convert('RGB') img = img.split()[2] else: img = img.convert('L') # to calculate luminance squareNorm = False # flip image to ouput correct coordinates img = img.transpose(Image.FLIP_TOP_BOTTOM) # Calc divisions for halftone divisions = drawSize / cellSize # Get image size self.imgWidth, self.imgHeight = img.size if (self.imgWidth > self.imgHeight): scale = drawSize / float(self.imgWidth) sample = int(self.imgWidth / divisions) else: scale = drawSize / float(self.imgHeight) sample = int(self.imgHeight / divisions) self.ratio = scale # Halftone circles = self.halftone(img, sample, scale, angle, squareNorm, invert) # Init blocks blocks = [] # Border block if drawBorder: block = Block("%s-border" % (self.name)) block.append(CNC.zsafe()) block.append(CNC.grapid(0, 0)) block.append(CNC.zenter(depth)) block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])])) block.append(CNC.gline(self.imgWidth * self.ratio, 0)) block.append( CNC.gline(self.imgWidth * self.ratio, self.imgHeight * self.ratio)) block.append(CNC.gline(0, self.imgHeight * self.ratio)) block.append(CNC.gline(0, 0)) blocks.append(block) # Draw block block = Block(self.name) # Change color if channel == 'Blue(sqrt)': block.color = "#0000ff" elif channel == 'Green(sqrt)': block.color = "#00ff00" elif channel == 'Red(sqrt)': block.color = "#ff0000" block.append("(Halftone size W=%d x H=%d x D=%d ,Total points:%i)" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))) block.append("(Channel = %s)" % channel) for c in circles: x, y, r = c r = min(dMax / 2.0, r) if (r >= dMin / 2.): block.append(CNC.zsafe()) block.append(CNC.grapid(x + r, y)) block.append(CNC.zenter(depth)) block.append(CNC.garc( CW, x + r, y, i=-r, )) block.append(CNC.zsafe()) if conical: block.enable = False blocks.append(block) if conical: blockCon = Block("%s-Conical" % (self.name)) for c in circles: x, y, r = c blockCon.append(CNC.zsafe()) blockCon.append(CNC.grapid(x, y)) dv = r / math.tan(math.radians(v_angle / 2.)) blockCon.append(CNC.zenter(-dv)) blockCon.append(CNC.zsafe()) blocks.append(blockCon) # Gcode Zsafe active = app.activeBlock() app.gcode.insBlocks(active, blocks, "Halftone") app.refresh() app.setStatus( _("Generated Halftone size W=%d x H=%d x D=%d ,Total points:%i" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))))
def GetStitches(self, app, FileName ): try: from struct import * except: app.setStatus("Embroidery abort: no module named struct") return print(FileName) try: f = open(FileName,'rb') except: app.setStatus(" Embroidery abort: Can't read image file") return app.setStatus(" Embroidery: file %s sucsessfully opened"%f.name) #DST header struct checking - parsing format = "3s16sc3s7sc3s3sc3s5sc3s5sc3s5sc3s5sc3s6sc3s6sc" data=f.read(94) LAN,LA,C,STN,ST,C,CLN,CL,C,POSX,posx,C,NEGX,negx,C,POSY,posy,C,NEGY,negy,C,AX,ax,C,AY,ay,c=unpack(format, data) CL=int(CL) ST=int(ST) if (LAN !='LA:'): app.setStatus(" Embroidery abort: Not a DST") print (LA) print(" St count: %d color changes=%d"%(ST ,CL)) f.seek(512); coordX=0;coordY=0;#initial coordinates to start sewing cnt=0;#just counter color = 0;#color code format="1b1b1b"# 3 unsigned bytes from data field prevCol=self.color i=0 blocks = [] for ColorCycles in range (0 , CL+1): #color cycles block = Block(self.name) while prevCol==self.color: ff=f.read(3);#read 24 bits cnt+=1 if len(ff)<3: break b0,b1,b2=unpack(format, ff) #data field unpacked with "format" to b0 b1 b2 dx = decode_dx(b0, b1, b2) dy = decode_dy(b0, b1, b2) coordX+=dx coordY+=dy block.color = colors[self.color] block.append(self.decode_flags( b2)(coordX,coordY)) block.append(CNC.zsafe())#safe height prevCol = self.color print("Stitches read=: %d"%cnt)#counter blocks.append(block) try: dx = float(self["dx"]) except: dx = 0.0 try: dy = float(self["dy"]) except: dy = 0.0 return blocks