/*
NAME:
DESCRIPTION: ;
PARAMETER:
[
{
name : 'path',
title : '资料路径',
type : 'LineEdit',
property : {tool_tip : '资料路径'},
},
{
name : 'auto_save',
title : '自动保存',
type : 'RadioBox',
property : {
item_list:[
{name:'yes',text:'YES'},
{name:'no',text:'NO'},
],
tool_tip:'是否自动保存料号开关'
}
}
]
VERSION_HISTORY:
V1.00 2020-04-20 Scott Sun
1.新版本
HELP:
功能简介
input原稿
参数配置
资料路径
注意事项
无
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
console.log("==============================>input原稿");
var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var database = require("topsin.database");
database.addConnection($.conf.database_conf, "DFM");
var QDfm = database.query("DFM");
if ($.conf.product_type == "aimdfm") {
QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
current_process_title: $.process_title
},
where: { id: $.task_id }
});
}
var GEN = $.gen;
var fs = require("fs");
var Job = $.job_name;
var db = $.db
var Status = 'ok';
var resultData = [];
var PAR = {};
if ($.hasOwnProperty('script_parameter')){
PAR = JSON.parse($.script_parameter);
}
if (!$.hasOwnProperty('auto_save')){
PAR.auto_save = "no"
}
// drill tool manage
var drill_toll_manage = {}
try {
var par = PAR;
var config = {
format: {
"Gerber274x_1": {
"nf1": 5,
"nf2": 5,
"units": "inch",
"zeroes": "leading",
"decimal": "no",
"nf_comp": 0,
"break_sr": "yes",
"data_type": "ascii",
"separator": "*",
"threshold": 200,
"drill_only": "no",
"multiplier": 1,
"resolution": 3,
"tool_units": "inch",
"coordinates": "absolute",
"merge_by_rule": "no",
"signed_coords": "no",
"text_line_width": 0.0024
},
"Excellon2_1": {
"nf1": 2,
"nf2": 3,
"units": "inch",
"zeroes": "none",
"decimal": "no",
"nf_comp": 0,
"break_sr": "yes",
"data_type": "ascii",
"separator": "nl",
"threshold": 200,
"drill_only": "no",
"multiplier": 1,
"resolution": 3,
"tool_units": "inch",
"coordinates": "absolute",
"merge_by_rule": "no",
"signed_coords": "no",
"text_line_width": 0.0024
}
},
odb: [{
vaild: function(item){
return /\.tgz$/ig.test(item.name) // 以.tgz结尾的
}
}],
gerber: [
{
vaild: function(item){
return /\.art$/ig.test(item.name) // 以.art结尾的
},
type: "Gerber274x",
format: "Gerber274x_1"
},
{
vaild: function(item){
return /\.drl$/ig.test(item.name) // 以.drl结尾的
},
type: "Excellon2",
format: "Excellon2_1"
}
]
}
if(!par.hasOwnProperty("path")){throw "缺少资料路径"}
if(_.isEmpty(Job)){throw "参数Job不存在"}
var job = Job.toLowerCase()
// 检查genesis中料号情况,存在则报警退出
if(GEN.isJobExists({job:job})){throw "料号已经:"+job+"已经存在"}
if(par.path[par.path.length-1]!=="/"){par.path = par.path + "/"}
var path = par.path + Job
// 检查待读入文件路径,路径不存在则报警退出
if(!fs.exists(path)){throw "路径:"+path+"不存在"}
// 检查文件格式,odb++或者gerber274,其中gerber存在一种特殊格式,其钻孔文件需要解析文件信息并更改文件内容才能读入(见特殊钻孔文件说明)
var inputInfo = getJobInfo({path:path, job:job,config:config})
if(inputInfo.type == "none"){throw "file error"}
// 读入gerber或者odb++ 判断读入方式
// 读入odb++
if(/odb/ig.test(inputInfo.type)){
importJob({db:"genesis",path:inputInfo.data.path,name:job})
}
// 读入gerber
if(/gerber/ig.test(inputInfo.type)){
// ? 处理特殊钻孔文件
inputInfo.data.forEach(function(file){
if(/\.drl$/ig.test(file.name)){
var backUpName = file.name+".backup"
// 备份
if(!fs.fileExists(file.dir+"/"+backUpName)){
fs.copyFile(file.path,file.dir+"/"+backUpName)
}
// 读取
var data = fs.readFile(file.path)
data = data.split("\n")
var head = getHead(data)
var body = data
// 解析head
var headData = head.filter(function(v){
return /Holesize.+Tolerance.+PLATED/ig.test(v)
})
headData.map(function(v){
var res = {
holesize: {},
tolerance: {},
attr: "",
unit: "",
quantity: 0
}
var holesize_tmp = /(Holesize.+)Tolerance/.exec(v)[1];
holesize_tmp = holesize_tmp.split("=")
res.holesize.key = holesize_tmp[0].trim()
res.holesize.value = holesize_tmp[1].trim()
var Tolerance_tmp = /(Tolerance.{23})/.exec(v)[1];
Tolerance_tmp = Tolerance_tmp.split("=")[1].split("/")
res.tolerance.top = Tolerance_tmp[0].trim()
res.tolerance.bot = Tolerance_tmp[1].trim()
res.attr = /NON_PLATED/ig.test(v) ? "non_plated" : "plated"
res.unit = /MILS/ig.test(v) ? "inch" : "mm"
res.quantity = parseInt(v.split("=").pop())
if(!drill_toll_manage.hasOwnProperty(file.name)){
drill_toll_manage[file.name] = {}
}
drill_toll_manage[file.name][/(\d+)/ig.exec(res.holesize.key)[1]] = res
})
// 给body添加刀
var count = 0
body = body.filter(function(v){
return !(/T\d+/ig.test(v))
})
body.forEach(function(v, i){
if(/^%$|^M00/ig.test(v)){
var k = "T" + getK(++count)
body[i] = v + "\n" + k
}
})
// 写入文件
var resStr = head.join("\n") + "\n" + body.join("\n")
fs.writeFile(file.path,resStr)
}
})
importGerber({job:job,step:"orig",db:"genesis",data:inputInfo.data})
var stepList = GEN.getStepList({job:job})
var matrix = GEN.getMatrix({job:job})
var drill_layers = Object.keys(matrix).filter(function(v){return matrix[v].layer_type=="drill"})
stepList.forEach(function(step){
GEN.openStep({job:job,name:step})
drill_layers.forEach(function(layer){
var drill_tool_manage_info = drill_toll_manage[layer]
var drill_tool_keys = Object.keys(drill_tool_manage_info).sort(function(a,b){return a-b})
GEN.COM("tools_tab_reset")
drill_tool_keys.forEach(function(key){
var val = drill_tool_manage_info[key]
GEN.COM("tools_tab_add", {
num: key,
type: /plated/ig.test(val.attr) ? "plate" : "nplate",
min_tol: Number(val.tolerance.top),
max_tol: Number(val.tolerance.bot),
finish_size: Number(val.holesize.value),
drill_size: Number(val.holesize.value)
})
})
GEN.COM("tools_set",{layer:layer,thickness:0,user_params:1,slots:"by_length"})
})
GEN.closeStep()
})
}
// 保存
if(/yes/ig.test(par.auto_save)){
GEN.checkInout({job:job,mode:"out"}) // 结束保存料号 关闭料号
GEN.saveJob({ job: job });
GEN.checkInout({job:job,mode:"in"})
GEN.closeJob({job:job})
} else {
GEN.checkInout({job:job,mode:"in"})
}
QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
progress: 33.33
},
where: { id: $.task_id }
});
if (GEN.hasError()) {
Status = 'error';
resultData.push({ type: "error", title: "GEN错误!", detail: [{ desc: _.join(GEN.STATUS, "\n") }] });
return {
status: Status,
result_data: resultData
};
} else {
resultData.push({ type: "info", title: "操作完成, 请注意检查!" });
return {
status: Status,
result_data: resultData
};
}
} catch (e) {
Status = 'error';
resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]});
return {status: Status, result_data: resultData};
}
function getJobInfo(props){
var path = props.path
var config = props.config
var job = props.job
var files = fs.listDir(path)
files = files.filter(function(v){return v.isFile}) // 过滤出文件
// 先判断是不是odb
var odbFiles = files.filter(function(file){ // 拿到odb文件
return config.odb.reduce(function(a,b){
if(b.vaild(file)){
a = true
}
return a
}, false)
})
if(odbFiles.length){
return {
type: "odb",
data: odbFiles[0]
}
}
var gerberFiles = files.filter(function(file){ // 拿到odb文件
return config.gerber.reduce(function(a,b){
if(b.vaild(file)){
file.gerber = config.format[b.format];
file.type = b.type;
a = true
}
return a
}, false)
})
if(gerberFiles.length){
return {
type: "gerber",
data: gerberFiles
}
}
return "none"
}
function importJob(props){
GEN.importJob(props);
}
function importGerber(props){ // job db step
var job = props.job
var step = props.step
var files = props.data
GEN.createJob({name:job,db:props.db})
GEN.createStep({job:job,name:props.step})
var gerberInfo = files.map(function(item){
var gerberCfg = JSON.parse(JSON.stringify(item.gerber));
gerberCfg.layer = item.name.toLowerCase()
gerberCfg.path = item.path
gerberCfg.format = item.type
gerberCfg.job = job
gerberCfg.step = step
return gerberCfg
})
GEN.COM("input_manual_reset")
gerberInfo.forEach(function(v){
GEN.COM("input_manual_set",v)
})
GEN.COM("input_manual")
}
function getHead(arr,head){
head = head || [];
if(arr[0] != "%"){
head.push(arr.shift())
return getHead(arr,head)
} else {
return head
}
}
function getK(count){
return count < 10 ? "0" + String(count) : String(count)
}