-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathGCodeGenerator.cs
More file actions
120 lines (97 loc) · 5.23 KB
/
Copy pathGCodeGenerator.cs
File metadata and controls
120 lines (97 loc) · 5.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
namespace ImageToGCode
{
class GCodeGenerator
{
private readonly double _Width;
private readonly double _Height;
private readonly double _LineStep;
private readonly double _PointStep = 0.1;
private readonly double _Freezone;
private readonly double _Feed;
private readonly bool _EngraveBothDirection;
private const int MAX_Intencity = 80;
public GCodeGenerator(double width, double height, double lineStep, double freezone, double feed, bool engraveBothDirection)
{
_Width = width;
_Height = height;
_LineStep = lineStep;
_Freezone = freezone;
_Feed = feed;
_EngraveBothDirection = engraveBothDirection;
}
const string feedMove = "G1 X{0:0.###} S{1:0.###}";
//const string engraveMove = "G1 X{0:0.###} S{1:0.###}";
//const string freeMove = "G1 X{0:0.###} M5";
const string fastMove = "G0 X{0:0.###} Y{1:0.###} S{2:0.###}";
public IEnumerable<string> Generate(Bitmap image)
{
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalSeparator = ".";
int iWidth = image.Width; //Ширина изображения
int iHeight = image.Height; //Высота изображения
double pixelWidth = _Width / iWidth; //Ширина пикселя
if (pixelWidth < _PointStep)
pixelWidth = _PointStep;
int xPixelSteps = 1; //Шаг выборки пикселей из изображения
if (pixelWidth < _LineStep)
xPixelSteps = (int)(_LineStep / pixelWidth);
int linesCount = (int)(_Height / _LineStep);
double linesPerPixel = (double)linesCount / (double)iHeight;
List<string> gCode = new List<string>();
gCode.Add(string.Format(nfi, "F{0:0.###}", _Feed));
for (int y = 0; y < linesCount; y++) //Шагаем по строкам
{
int yPixelCursor = (int)(y / linesPerPixel); //Вычисляем положение в картинке
int lastLaserState = 0; //Сбрасываем яркость лазера на последнем шаге
double lastX = 0.0; //Последнее положение
int firstDarkX = -1; //Поиск первого темного пикселя
for (int x = 0; x < iWidth; x++)
{
if (image.GetPixel(x, yPixelCursor).GetBrightness() < 1.0)
{
firstDarkX = x;
break;
}
}
if (firstDarkX == -1)
continue; //Пропускаем строки если они белые
//Холостой ход в начало строки с темными пикселями
gCode.Add(string.Format(nfi, fastMove, firstDarkX * pixelWidth - _Freezone, -y * _LineStep, 0.0));
//Подъезжаем на рабочей скорости к первой темной точке
//gCode.Add(string.Format(nfi, feedMove, firstDarkX * pixelWidth, 0));
float brightnessSum = 0;
//Перебор пикселей в строке
for (int x = firstDarkX; x < iWidth; x++)
{
if (x % xPixelSteps != 0)
{
brightnessSum += image.GetPixel(x, yPixelCursor).GetBrightness(); //суммируем яркости пикселей, между шагами головки
continue;
}
brightnessSum += image.GetPixel(x, yPixelCursor).GetBrightness(); //прибавляем текущий пиксель
int curLaserState = (int)(MAX_Intencity * (1.0 - brightnessSum / (double)xPixelSteps)); //вычисляем среднюю яркость
brightnessSum = 0; //Обнуляем яркость
if (lastLaserState == curLaserState) //не добавляем команд если строки не закрашены
continue;
lastX = x * pixelWidth; //координата точки с изменением цвета
gCode.Add(string.Format(nfi, feedMove, lastX, lastLaserState));
lastLaserState = curLaserState;
}
if (lastLaserState > 0.0)
{
lastX = _Width;
gCode.Add(string.Format(nfi, feedMove, _Width, lastLaserState)); //Завершаем строку и выключаем лазер
}
if (_Freezone > 0.0)
gCode.Add(string.Format(nfi, feedMove, lastX + _Freezone, 0)); //Холостой ход для торможения
}
return gCode;
}
}
}