/* 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: <html><body bgcolor="#DDECFE"> <font size="3" color="#003DB2"><p>功能简介</p></font> <p> input原稿 </p> <br> <font size="3" color="#003DB2"><p>参数配置</p></font> <p> 资料路径 </p> <br> <font size="3" color="#003DB2"><p>注意事项</p></font> <p> 无 </p> <br> </body></html> */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// 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) }