public ColorSegment(int col, int len, bool rev, L2LConf c) { mColor = col; mLen = len / (c.vectorfilling ? c.fres : c.res); mReverse = rev; mConf = c; }
public void LoadImageL2L(Bitmap bmp, string filename, L2LConf c) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); long start = Tools.HiResTimer.TotalMilliseconds; list.Clear(); mRange.ResetRange(); //absolute list.Add(new GrblCommand("G90")); //use travel speed list.Add(new GrblCommand(String.Format("F{0}", c.travelSpeed))); //move fast to offset list.Add(new GrblCommand(String.Format("G0 X{0} Y{1}", formatnumber(c.oX), formatnumber(c.oY)))); if (c.pwm) { list.Add(new GrblCommand(String.Format("{0} S0", c.lOn))); //laser on and power to zero } else { list.Add(new GrblCommand(String.Format("{0} S255", c.lOff))); //laser off and power to maxpower } //set speed to markspeed list.Add(new GrblCommand(String.Format("G1 F{0}", c.markSpeed))); //relative list.Add(new GrblCommand("G91")); ImageLine2Line(bmp, c); //laser off list.Add(new GrblCommand(c.lOff)); //absolute list.Add(new GrblCommand("G90")); //move fast to origin list.Add(new GrblCommand("G0 X0 Y0")); Analyze(); long elapsed = Tools.HiResTimer.TotalMilliseconds - start; if (OnFileLoaded != null) { OnFileLoaded(elapsed, filename); } }
private void ImageLine2Line(Bitmap bmp, L2LConf c) { bool fast = false; List <ColorSegment> segments = GetSegments(bmp, c); List <GrblCommand> temp = new List <GrblCommand>(); foreach (ColorSegment seg in segments) { bool changespeed = (fast != seg.Fast); //se veloce != dafareveloce if (seg.IsSeparator && !fast) //fast = previous segment contains S0 color { if (c.pwm) { temp.Add(new GrblCommand("S0")); } else { temp.Add(new GrblCommand(c.lOff)); //laser off } } fast = seg.Fast; if (changespeed) { temp.Add(new GrblCommand(String.Format("{0} F{1} {2}", fast ? "G0" : "G1", fast ? c.travelSpeed : c.markSpeed, seg.ToString()))); } else { temp.Add(new GrblCommand(seg.ToString())); } //if (seg.IsSeparator) // list.Add(new GrblCommand(lOn)); } temp = OptimizeLine2Line(temp, c); list.AddRange(temp); }
private void ExtractSegment(Bitmap image, int x, int y, bool reverse, ref int len, ref int prevCol, List <ColorSegment> rv, L2LConf c) { len++; int col = GetColor(image, x, y, c.minPower, c.maxPower, c.pwm); if (prevCol == -1) { prevCol = col; } if (prevCol != col) { if (c.dir == RasterConverter.ImageProcessor.Direction.Horizontal) { rv.Add(new XSegment(prevCol, len, reverse, c)); } else if (c.dir == RasterConverter.ImageProcessor.Direction.Vertical) { rv.Add(new YSegment(prevCol, len, reverse, c)); } else if (c.dir == RasterConverter.ImageProcessor.Direction.Diagonal) { rv.Add(new DSegment(prevCol, len, reverse, c)); } len = 0; } prevCol = col; }
private List <ColorSegment> GetSegments(Bitmap bmp, L2LConf c) { bool uni = SettingsManager.Shared.UniDirectionalEngraving; List <ColorSegment> rv = new List <ColorSegment>(); if (c.dir == RasterConverter.ImageProcessor.Direction.Horizontal || c.dir == RasterConverter.ImageProcessor.Direction.Vertical) { bool h = (c.dir == RasterConverter.ImageProcessor.Direction.Horizontal); //horizontal/vertical for (int i = 0; i < (h ? bmp.Height : bmp.Width); i++) { bool d = uni || IsEven(i); //direct/reverse int prevCol = -1; int len = -1; for (int j = d ? 0 : (h ? bmp.Width - 1 : bmp.Height - 1); d ? (j < (h ? bmp.Width : bmp.Height)) : (j >= 0); j = (d ? j + 1 : j - 1)) { ExtractSegment(bmp, h ? j : i, h ? i : j, !d, ref len, ref prevCol, rv, c); //extract different segments } if (h) { rv.Add(new XSegment(prevCol, len + 1, !d, c)); //close last segment } else { rv.Add(new YSegment(prevCol, len + 1, !d, c)); //close last segment } if (uni) // add "go back" { if (h) { rv.Add(new XSegment(0, bmp.Width, true, c)); } else { rv.Add(new YSegment(0, bmp.Height, true, c)); } } if (i < (h ? bmp.Height - 1 : bmp.Width - 1)) { if (h) { rv.Add(new VSeparator(c)); //new line } else { rv.Add(new HSeparator(c)); //new line } } } } else if (c.dir == RasterConverter.ImageProcessor.Direction.Diagonal) { //based on: http://stackoverflow.com/questions/1779199/traverse-matrix-in-diagonal-strips //based on: http://stackoverflow.com/questions/2112832/traverse-rectangular-matrix-in-diagonal-strips /* * +------------+ | - | | - - | +-------+ | | - - | - | +-------+----+ | */ //the algorithm runs along the matrix for diagonal lines (slice index) //z1 and z2 contains the number of missing elements in the lower right and upper left //the length of the segment can be determined as "slice - z1 - z2" //my modified version of algorithm reverses travel direction each slice rv.Add(new VSeparator(c)); //new line int w = bmp.Width; int h = bmp.Height; for (int slice = 0; slice < w + h - 1; ++slice) { bool d = uni || IsEven(slice); //direct/reverse int prevCol = -1; int len = -1; int z1 = slice < h ? 0 : slice - h + 1; int z2 = slice < w ? 0 : slice - w + 1; for (int j = (d ? z1 : slice - z2); d?j <= slice - z2 : j >= z1; j = (d ? j + 1 : j - 1)) { ExtractSegment(bmp, j, slice - j, !d, ref len, ref prevCol, rv, c); //extract different segments } rv.Add(new DSegment(prevCol, len + 1, !d, c)); //close last segment //System.Diagnostics.Debug.WriteLine(String.Format("sl:{0} z1:{1} z2:{2}", slice, z1, z2)); if (uni) // add "go back" { int slen = (slice - z1 - z2) + 1; rv.Add(new DSegment(0, slen, true, c)); //System.Diagnostics.Debug.WriteLine(slen); } if (slice < Math.Min(w, h) - 1) //first part of the image { if (d && !uni) { rv.Add(new HSeparator(c)); //new line } else { rv.Add(new VSeparator(c)); //new line } } else if (slice >= Math.Max(w, h) - 1) //third part of image { if (d && !uni) { rv.Add(new VSeparator(c)); //new line } else { rv.Add(new HSeparator(c)); //new line } } else //central part of the image { if (w > h) { rv.Add(new HSeparator(c)); //new line } else { rv.Add(new VSeparator(c)); //new line } } } } return(rv); }
private List <GrblCommand> OptimizeLine2Line(List <GrblCommand> temp, L2LConf c) { List <GrblCommand> rv = new List <GrblCommand>(); decimal cumX = 0; decimal cumY = 0; bool cumulate = false; foreach (GrblCommand cmd in temp) { try { cmd.BuildHelper(); bool oldcumulate = cumulate; if (c.pwm) { if (cmd.S != null) //is S command { if (cmd.S.Number == 0) //is S command with zero power { cumulate = true; //begin cumulate } else { cumulate = false; //end cumulate } } } else { if (cmd.IsLaserOFF) { cumulate = true; //begin cumulate } else if (cmd.IsLaserON) { cumulate = false; //end cumulate } } if (oldcumulate && !cumulate) //cumulate down front -> flush { if (c.pwm) { rv.Add(new GrblCommand(string.Format("G0 X{0} Y{1} F{2} S0", formatnumber((double)cumX), formatnumber((double)cumY), c.travelSpeed))); } else { rv.Add(new GrblCommand(string.Format("G0 X{0} Y{1} F{2} {3}", formatnumber((double)cumX), formatnumber((double)cumY), c.travelSpeed, c.lOff))); } cumX = cumY = 0; } if (cumulate) //cumulate { if (cmd.IsMovement) { if (cmd.X != null) { cumX += cmd.X.Number; } if (cmd.Y != null) { cumY += cmd.Y.Number; } } else { rv.Add(cmd); } } else //emit line normally { rv.Add(cmd); } } catch (Exception ex) { throw ex; } finally { cmd.DeleteHelper(); } } return(rv); }
public void LoadImagePotrace(Bitmap bmp, string filename, bool UseSpotRemoval, int SpotRemoval, bool UseSmoothing, decimal Smoothing, bool UseOptimize, decimal Optimize, L2LConf c) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); long start = Tools.HiResTimer.TotalMilliseconds; list.Clear(); mRange.ResetRange(); Potrace.turdsize = (int)(UseSpotRemoval ? SpotRemoval : 2); Potrace.alphamax = UseSmoothing ? (double)Smoothing : 0.0; Potrace.opttolerance = UseOptimize ? (double)Optimize : 0.2; Potrace.curveoptimizing = UseOptimize; //optimize the path p, replacing sequences of Bezier segments by a single segment when possible. List <List <CsPotrace.Curve> > plist = Potrace.PotraceTrace(bmp); if (c.dir != RasterConverter.ImageProcessor.Direction.None) { using (Bitmap ptb = new Bitmap(bmp.Width, bmp.Height)) { using (Graphics g = Graphics.FromImage(ptb)) { //Potrace.Export2GDIPlus(plist, g, Brushes.Black, null, (Math.Max(c.res/c.fres, 1) + 1) / 2.0f); Potrace.Export2GDIPlus(plist, g, Brushes.Black, null, Math.Max(1, c.res / c.fres)); using (Bitmap resampled = RasterConverter.ImageTransform.ResizeImage(ptb, new Size((int)(bmp.Width * c.fres / c.res), (int)(bmp.Height * c.fres / c.res)), true, InterpolationMode.HighQualityBicubic)) { //absolute list.Add(new GrblCommand("G90")); //use travel speed list.Add(new GrblCommand(String.Format("F{0}", c.travelSpeed))); //move fast to offset list.Add(new GrblCommand(String.Format("G0 X{0} Y{1}", formatnumber(c.oX), formatnumber(c.oY)))); if (c.pwm) { list.Add(new GrblCommand(String.Format("{0} S0", c.lOn))); //laser on and power to zero } else { list.Add(new GrblCommand(String.Format("{0} S255", c.lOff))); //laser off and power to max power } //set speed to markspeed list.Add(new GrblCommand(String.Format("G1 F{0}", c.markSpeed))); //relative list.Add(new GrblCommand("G91")); c.vectorfilling = true; ImageLine2Line(resampled, c); //laser off list.Add(new GrblCommand(c.lOff)); } } } } //absolute list.Add(new GrblCommand("G90")); //use travel speed list.Add(new GrblCommand(String.Format("F{0}", c.travelSpeed))); //move fast to offset list.Add(new GrblCommand(String.Format("G0 X{0} Y{1}", formatnumber(c.oX), formatnumber(c.oY)))); //laser off and power to maxPower list.Add(new GrblCommand(String.Format("{0} S{1}", c.lOff, c.maxPower))); //set speed to borderspeed list.Add(new GrblCommand(String.Format("G1 F{0}", c.borderSpeed))); //trace borders List <string> gc = Potrace.Export2GCode(plist, c.oX, c.oY, c.res, c.lOn, c.lOff, bmp.Size); foreach (string code in gc) { list.Add(new GrblCommand(code)); } //laser off list.Add(new GrblCommand(String.Format("{0}", c.lOff))); //move fast to origin list.Add(new GrblCommand("G0 X0 Y0")); Analyze(); long elapsed = Tools.HiResTimer.TotalMilliseconds - start; if (OnFileLoaded != null) { OnFileLoaded(elapsed, filename); } }
public HSeparator(L2LConf c) : base(0, 1, false, c) { }
public DSegment(int col, int len, bool rev, L2LConf c) : base(col, len, rev, c) { }