-
Notifications
You must be signed in to change notification settings - Fork 0
/
Cutting_sphere_petal.html
198 lines (159 loc) · 9.06 KB
/
Cutting_sphere_petal.html
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laser Cutting Profile Generator</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
label, input, button {
display: block;
margin: 10px 0;
}
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Generate G-code for Laser Cutting with Profile Visualization</h1>
<label for="csvFile">Upload "Spherical_profile_data.csv" with half-profile data:</label>
<input type="file" id="csvFile" accept=".csv">
<label for="laserDiameter">Enter laser beam diameter (same units as profile):</label>
<input type="number" id="laserDiameter" placeholder="Enter beam diameter">
<label for="feedRate">Enter cutting speed (mm/min):</label>
<input type="number" id="feedRate" placeholder="Enter speed (default: 1000)" value="1000">
<label for="laserPower">Set laser power (%):</label>
<input type="range" id="laserPower" min="0" max="100" value="100">
<label for="laserHeight">Set laser lift height (mm):</label>
<input type="number" id="laserHeight" placeholder="Enter height (default: 5 mm)" value="5">
<label for="laserDelayStart">Set laser start delay (ms):</label>
<input type="number" id="laserDelayStart" placeholder="Enter delay (default: 0 ms)" value="0">
<label for="laserDelayEnd">Set laser end delay (ms):</label>
<input type="number" id="laserDelayEnd" placeholder="Enter delay (default: 0 ms)" value="0">
<label for="laserPasses">Enter number of passes:</label>
<input type="number" id="laserPasses" placeholder="Enter number of passes (default: 1)" value="1">
<button id="generateGCode">Generate G-code and Visualize Profile</button>
<h3>Profile Visualization:</h3>
<canvas id="profileCanvas" width="500" height="500"></canvas>
<!-- Placeholder for download link -->
<div id="downloadLink"></div>
<script>
document.getElementById('generateGCode').addEventListener('click', function() {
const csvFile = document.getElementById('csvFile').files[0];
const laserDiameter = parseFloat(document.getElementById('laserDiameter').value);
const feedRate = parseFloat(document.getElementById('feedRate').value);
const laserPower = parseFloat(document.getElementById('laserPower').value);
const laserHeight = parseFloat(document.getElementById('laserHeight').value);
const laserDelayStart = parseFloat(document.getElementById('laserDelayStart').value);
const laserDelayEnd = parseFloat(document.getElementById('laserDelayEnd').value);
const laserPasses = parseInt(document.getElementById('laserPasses').value);
if (!csvFile) {
alert('Please upload the "Spherical_profile_data.csv" file.');
return;
}
if (isNaN(laserDiameter) || laserDiameter <= 0) {
alert('Please enter a valid laser beam diameter.');
return;
}
if (isNaN(feedRate) || feedRate <= 0) {
alert('Please enter a valid feed rate.');
return;
}
if (isNaN(laserPasses) || laserPasses <= 0) {
alert('Please enter a valid number of passes.');
return;
}
const reader = new FileReader();
reader.onload = function(event) {
const csvData = event.target.result;
const lines = csvData.split('\n');
const xCoords = []; // 5th column (X axis)
const yCoords = []; // 6th column (Y axis)
// Parse the CSV data, skipping the header (first line)
for (let i = 1; i < lines.length; i++) { // Skip the header row
const columns = lines[i].split(',');
if (columns.length >= 6) { // Ensure there are enough columns
const x = parseFloat(columns[4]); // 5th column (index 4)
const y = parseFloat(columns[5]); // 6th column (index 5)
if (!isNaN(x) && !isNaN(y)) {
xCoords.push(x);
yCoords.push(y + laserDiameter / 2); // Compensate laser burn by adding half diameter
}
}
}
// Check if data is valid
if (xCoords.length === 0 || yCoords.length === 0) {
alert('No valid data found in the file.');
return;
}
// Create arrays for the full profile (including mirrored points)
const fullXCoords = [...xCoords];
const fullYCoords = [...yCoords];
// Mirror the profile by reflecting relative to X-axis (negate Y coordinates)
for (let i = xCoords.length - 1; i >= 0; i--) {
fullXCoords.push(xCoords[i]); // Keep X the same
fullYCoords.push(-yCoords[i]); // Reflect Y (negate Y)
}
// Connect the last point of the mirrored profile with the first point to close the profile
fullXCoords.push(fullXCoords[0]); // Closing the profile on X-axis
fullYCoords.push(fullYCoords[0]); // Closing the profile on Y-axis
// Calculate scaling factors to fit the profile into the canvas
const minX = Math.min(...fullXCoords);
const maxX = Math.max(...fullXCoords);
const minY = Math.min(...fullYCoords);
const maxY = Math.max(...fullYCoords);
const rangeX = maxX - minX;
const rangeY = maxY - minY;
const canvas = document.getElementById('profileCanvas');
const ctx = canvas.getContext('2d');
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Scale the profile to fit into the canvas (maintaining aspect ratio)
const scale = Math.min(canvas.width / rangeX, canvas.height / rangeY) * 0.95; // Adjust scale to fill canvas
const offsetX = canvas.width / 2 - ((maxX + minX) / 2) * scale;
const offsetY = canvas.height / 2 + ((maxY + minY) / 2) * scale;
// Draw the profile on the canvas
ctx.beginPath();
ctx.moveTo(offsetX + fullXCoords[0] * scale, offsetY - fullYCoords[0] * scale); // Start at the first point
for (let i = 1; i < fullXCoords.length; i++) {
ctx.lineTo(offsetX + fullXCoords[i] * scale, offsetY - fullYCoords[i] * scale); // Draw each segment
}
ctx.closePath(); // Close the path to complete the profile
ctx.stroke(); // Outline the profile
// Generate G-code
let gcode = "G21 ; Set units to mm\n";
gcode += `G90 ; Absolute positioning\n`;
gcode += `S${laserPower} ; Set laser power to ${laserPower}%\n`;
for (let pass = 0; pass < laserPasses; pass++) {
gcode += `G0 Z${laserHeight} ; Raise laser to ${laserHeight} mm\n`;
gcode += `G4 P${laserDelayStart} ; Start delay ${laserDelayStart} ms\n`;
gcode += `G0 X${fullXCoords[0].toFixed(4)} Y${fullYCoords[0].toFixed(4)} ; Move to starting point\n`;
gcode += "G1 Z0 ; Lower laser for cutting\n";
for (let i = 0; i < fullXCoords.length; i++) {
gcode += `G1 X${fullXCoords[i].toFixed(4)} Y${fullYCoords[i].toFixed(4)} F${feedRate} ; Cutting to (${fullXCoords[i].toFixed(4)}, ${fullYCoords[i].toFixed(4)})\n`;
}
gcode += `G4 P${laserDelayEnd} ; End delay ${laserDelayEnd} ms\n`;
gcode += "G0 Z5 ; Raise the laser\n"; // Finish pass
}
gcode += "M05 ; Turn off the laser\n";
gcode += "M30 ; End of program\n";
// Create a download link for the G-code file
const blob = new Blob([gcode], { type: "text/plain" });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'Full_sphere_profile_gcode.nc';
link.innerText = 'Download G-code';
// Replace existing link (if any)
const downloadLinkDiv = document.getElementById('downloadLink');
downloadLinkDiv.innerHTML = ''; // Clear previous link
downloadLinkDiv.appendChild(link);
};
reader.readAsText(csvFile);
});
</script>
</body>
</html>