解析鑽孔(Excellon)格式前首先得了解此格式,這樣才能更好的解析呀。
一個鑽孔里面包含的基本信息如下:
1.單位:公式mm,英制inch
2.省零方式:前省零,后省零
3.坐標方式:絕對坐標,相對坐標
4.坐標位數:3:3,2:4
5.鑽孔刀徑信息
6.鑽孔坐標信息
更多EXCELLON格式詳見
https://wenku.baidu.com/view/4e9553b765ce0508763213e9.html
https://wenku.baidu.com/view/3a8f323b87c24028915fc309.html?rec_flag=default&sxts=1538927482555
一.數據結構信息
M48 鑽孔格式開始頭部 METRIC,TZ 公制 后省零
M72 單位英制 公制為M71 T01C0.0100 第1把刀0.0100 inch T02C0.0335 第2把刀0.0335 inch T03C0.0400 第3把刀0.0400 inch T04C0.1300 第4把刀0.1300 inch % 准備進入對應鑽孔坐標區域 T01 第一把刀 X14333Y7000 鑽孔XY坐標 X16333Y6500 鑽孔XY坐標
M30 鑽孔結束
此結構僅用於解析Excellon格式繪出鑽孔圖形,
后續改進點:
1.需增加G84,G85 擴孔;槽孔
2.需增加支持絕對坐標,
3.若要擴展用戶交互功能,需改進此結構,鑽孔目前是統一在一個集合中的,需改為按刀具大小分類存儲
4.鑽孔格式固定幾類格式3:3,2:4,無法智能匹配鑽孔格式,需改為依據板板尺寸或線路焊盤與鑽孔格式多次匹配最佳鑽孔格式
5.此為解析是基於常規鑽孔格式解析,特殊鑽孔格式是不支持的.所以此點需改進.
二.JS代碼實現:
function loadDrill(text) { text = text.replace(/^[\s%]*M48/, ''); text = text.replace(/[^\S\n]+/g, ''); function numVal(x) { if(x[0] == '+') return numVal(x.slice(1)); if(x[0] == '-') return -numVal(x.slice(1)); if(x == '0') return 0; if(g.omitLead) while(x.length < g.num) x = '0'+x; else while(x.length < g.num) x += '0'; return parseFloat(x.slice(0, g.int)+'.'+x.slice(g.int), 10); } var cmds = text.split('\n'); var g = {offA: 0, offB: 0, shapes: [], cmds: [], scale: 1}, shape, body = false, prevX = 0, prevY = 0; for(var i = 0; i < cmds.length; i++) { var d = cmds[i]; if(!body) { if(d[0] == 'T') { var r = /^T(\d+)[^C]*C([\d.]+)/.exec(d); // assert(r); g.shapes[parseInt(r[1], 10)] = ['C', +r[2]]; } else if(d == 'METRIC,LZ') g.scale = 1, g.omitLead = false, g.int = 3, g.dec = 3, g.num = 6; else if(d == 'METRIC,TZ' || d == 'M71') g.scale = 1, g.omitLead = true, g.int = 3, g.dec = 3, g.num = 6; else if(d == 'INCH,LZ') g.scale = 25.4, g.omitLead = false, g.int = 2, g.dec = 4, g.num = 6; else if(d == 'INCH,TZ' || d == 'M72') g.scale = 25.4, g.omitLead = true, g.int = 2, g.dec = 4, g.num = 6; else if(d == '%') body = true; } else { function getNum(offset) { var r = /^[-+\d]*/.exec(d = d.slice(offset)); // assert(r); d = d.slice(r[0].length); return numVal(r[0]); } if(d[0] == 'T') shape = parseInt(d.slice(1), 10); else if(d[0] == 'R') { var r = /^\d+/.exec(d = d.slice(1)); // assert(r); var nr = parseInt(r[0], 10), dx = 0, dy = 0; d = d.slice(r[0].length); if(d[0] == 'X') dx = getNum(1); if(d[0] == 'Y') dy = getNum(1); // assert(!d.length); for(var x = prevX, y = prevY, j = 0; j < nr; j++) x += dx, y += dy, g.cmds.push([(1<<2) | 3, shape, x, y]); prevX = x, prevY = y; } else { var x = prevX, y = prevY, coords = false; if(d[0] == 'X') x = getNum(1), coords = true; if(d[0] == 'Y') y = getNum(1), coords = true; if(coords) { g.cmds.push([(1<<2) | 3, shape, x, y]); prevX = x, prevY = y; } } } } return g; };
三.鑽孔解析繪圖Web效果圖
JS解析展示,無交互功能,雖然是在前端,但最佳作法解析動作放在后端,后端解析后的數據或圖像傳送到前端