/* NAME: DESCRIPTION: matrix改名和排序 PARAMETER: [ { name : 'customer', title : 'CUSTOMER 名', type : 'LineEdit', property : {tool_tip : '客户名称'} }, { name : 'job_name', title : '料号名', type : 'LineEdit', property : {tool_tip : '料号名'} } ] VERSION_HISTORY: V1.00 2020 3-30 Scott HELP: <html><body bgcolor="#DDECFE"> <font size="3" color="#003DB2"><p>功能简介</p></font> <p> matrix改名和排序</p> <br> <font size="3" color="#003DB2"><p>参数配置</p></font> <p> matrix改名和排序规则 </p> <font size="3" color="#003DB2"><p>注意事项</p></font> <p> ● 无 </p> <br> </body></html> */ // 引入模块 包 var $ = require('topcam.scriptfunc').argv(); var fs = require('fs'); var _ = require('lodash'); var IKM = $.ikm; var GEN = $.gen; var GUI = $.gui; var Job = $.job; try { var mode = "use" // develop var par = $.par; par = {job_name:"2", customer:"ats"} // !! tmp var cfg = JSON.parse(IKM.select_value({table:'pub_conf',field:'json_data',where:{path : 'cam/input_data'}})); // 读取配置文件 var useCfg = cfg[par.customer.toLowerCase()].formatData; if(!useCfg){throw "config error"} var job = par.job_name if(!GEN.isJobExists({job:job})){ throw "job "+ job+ " is not exist" } if(!GEN.isJobOpen({job:job})){GEN.openJob({job:job})} if(GEN.checkInout({job:job,mode:"test"}) != 0 && mode != "develop"){ throw "the job check" } GEN.checkInout({job:job,mode:"out"}); if(useCfg.hasOwnProperty("mergeDrill")){ // todo mergeDrill({job:job}) } if(mode=="develop"){ IKM.msg("rename")} if(useCfg.rename){ reName({job:job,rule:useCfg.rename}) } if(mode=="develop"){ IKM.msg("sort")} if(useCfg.sort){ var err = sortLayer({job:job, rule:useCfg.sort}); // 排序 if (err) {throw err} } if(mode=="develop"){ IKM.msg("setDrill")} if(useCfg.setDrill && /^yes$/.test(useCfg.setDrill.info)){ setDrill({job:job}); // 设置钻孔 } // finally if (/^yes$/ig.test(useCfg.autoSave)) { GEN.saveJob({ job: job }); } GEN.checkInout({job:job,mode:"in"}); GEN.closeJob({job:job}) return 'Done'; } catch (error) { GUI.msg(error); return 'Error'; } function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名的规则} var job = props.job if(Array.isArray(props.rule)){ props.rule = {rule: props.rule } } var matrix = GEN.getMatrix({job:job}); // 获取matrix var matrixNames = Object.keys(matrix) // 获取数组 matrix的name var signalCount = matrixNames.reduce(function(a,b){ if(matrix[b].context == "board" && matrix[b].layer_type=="signal"){ a++ } return a },0) var reNameList = []; // 记录匹配程度最高的改名结果 Object.keys(props.rule).forEach(function(key){ var rule = props.rule[key]; var renames = getRenameCount(matrixNames,rule, signalCount); // 根据规则 和 matrixNames 的到更改名称数据 if(renames.length > reNameList.length){ // 找到匹配规则最多的 reNameList = renames; } }) // 更改层名 reNameList.forEach(function(v){ if(v.orig_name !== v.new_name){ GEN.renameLayer({job:job,layer:v.orig_name,new_name:v.new_name}) } }); } function getRenameCount(names,rule,signalCount){ // 返回改名匹配结果 var res = names.reduce(function(res, name){ rule.map(function(rule){ if(rule.orig_name === name){ res.push({orig_name:name, new_name:rule.new_name}); } else if(eval("/^"+rule.orig_name+"$/ig.test(name)")) { if(/\(.*\)/ig.test(rule.orig_name)){ var exec = eval("/"+rule.orig_name+"/ig.exec(name)").slice(1) var new_name = rule.new_name; var index = 0; exec.forEach(function(v,i){ if(/(after)/.test(new_name)){ new_name = new_name.replace("(after)", Number(v)+1); } if(/(last)/.test(new_name)){ new_name = new_name.replace("(last)",signalCount); } new_name = new_name.replace("("+(i+1)+")", v); if(rule.tp && /\d+/.test(v)){ if(v==1){ new_name = "top" } index = v > index ? v : index } }) if(rule.tp){ res.push({orig_name:name, new_name:new_name, index:index}); }else{ res.push({orig_name:name, new_name:new_name}); } } else { res.push({orig_name:name, new_name:rule.new_name}); } } }) return res }, []) var tpIndex = {i: -1, value: 0}; res.forEach(function(v,i){ if(v.index && v.index > tpIndex.value){ tpIndex.i = i tpIndex.value = v.index } }) if(tpIndex.i >= 0){ res[tpIndex.i].new_name = "bottom" } return res } function sortLayer(props){ // 排序方法 {job:要排序的料号, rule: {要改名的规则} var job = props.job var matrix = GEN.getMatrix({job:job}); var matriNames = Object.keys(matrix) // 找出所有排序规则中契合度最高的 var ruleKey = {} Object.keys(props.rule).forEach(function(key){ var rule = props.rule[key] ruleKey[key] = 0 var regs = rule.map(function(item){ return new RegExp(item.name,'ig') }) matriNames.forEach(function(name){ var isSort = regs.reduce(function(a,b){ if(b.test(name)){a = true} return a}, false) if(isSort){ruleKey[key]++} }) }) var maxRule = {key:"", value: 0} Object.keys(ruleKey).forEach(function(key){ var value = ruleKey[key] if (value>=maxRule.value){ maxRule.key = key maxRule.value = value } }) if(props.rule[maxRule.key]){props.rule = props.rule[maxRule.key]}else{return "sort rule error"} var matriName = Object.keys(matrix).sort(function(a,b){return matrix[a].row - matrix[b].row}) var matrixFirst = matriName[0]; // 记录matrix中第一位 var sortNames = []; var miscName = matriName.filter(function(name){ // 找出需要排序的名称列表 var flag = true; props.rule.forEach(function(item,i){ var evalReg = "/^"+item.name+"$/ig.test(name)"; if(name == item.name || eval(evalReg)){ flag = false; if(name === item.name){ var _item = JSON.parse(JSON.stringify(item)); _item.value = i; sortNames.push(_item); } else { var _item = JSON.parse(JSON.stringify(item)); _item.value = i; var str = "/^"+ item.name +"$/ig.exec(name)" _item.value2 = eval(str)[1] - 0; _item.name = name; sortNames.push(_item); } } }); return flag; }) miscName.forEach(function(n){ if(matrix[n].context == 'board'){ GEN.matrixLayerAttr({job:job,layer:n,context:'misc'}) } }) sortNames = sortNames.sort(function(a,b){ return a.value - b.value || a.value2 - b.value2 }) // 排序 if(sortNames.length){ if(sortNames[0].name !== matrixFirst) { // 如果第一位和matrix中第一位不同,先把第一位插入到最前面 GEN.matrixMoveRow({ job:job,layer:sortNames[0].name,before:matrixFirst }) } sortNames.forEach(function(v,i,arr){ var layer = matrix[v.name]; if(i !== 0){ GEN.matrixMoveRow({ job:job,layer:v.name,after:arr[i-1].name }) } if(v.context !== layer.context || v.type !== layer.layer_type || v.polarity !== layer.polarity){ GEN.matrixLayerAttr({job:job,layer:v.name,context:v.context,type:v.type,polarity:v.polarity}); } }) } } function setDrill(props){ // 设置钻孔 var job = props.job var martrix = GEN.getMatrix({job:job}); // 获取所有的钻孔层 var drillLayer = Object.keys(martrix).filter(function(v){ return martrix[v].layer_type == "drill" && martrix[v].context == "board" }) // 获取所有single层 var signalLayer = Object.keys(martrix).sort(function(a,b){return Number(martrix[a].row) - Number(martrix[b].row)}).filter(function(v){ return martrix[v].layer_type == "signal" && martrix[v].context == "board" }) var layerCount = GEN.getLayerCount({job:job}) // findSignal 根据传入的数字找到对应的signal层 如 1 => top ; 2 => layer_2 function findSignal(num){ var res = signalLayer.filter(function(v){ var vnum = 0; if(/\d/.test(v)){ var tmp = /(\d+)/ig.exec(v); vnum = tmp? Number(tmp[1]) : 0; } return num === vnum }) return res[0]; } function doDrill(drills){ // 分析钻孔层 return drills.map(function(v){ if(v == "drill"){ return {start:signalLayer[0], end:signalLayer[signalLayer.length - 1], layer:v} } else { var tmp = /(\d+).(\d+)/ig.exec(v); if(tmp){ var start = Number(tmp[1]) === 1? 'top':findSignal(Number(tmp[1])); var end = Number(tmp[2]) === layerCount? 'bottom': findSignal(Number(tmp[2])); return {start:start, end:end, layer:v} } else { return 0; } } }) } var drillSetList = doDrill(drillLayer); // 分析得到钻孔设置结果 drillSetList = drillSetList.filter(function(v){return v!==0}) drillSetList.forEach(function(v){ GEN.matrixLayerDrill({job:job,layer:v.layer,start:v.start ,end:v.end}) }) } function mergeDrill(props){ // 合并钻孔 var newdrills = [] var job = props.job; var step = GEN.getStepList({job:job})[0]; var maxDrill = {name:"",value:0}; function getDrl(str){ var num = /(\d+)-(\d+)/ig.exec(str); // 匹配出 num-num var tmp = []; for(var i = Number(num[1]);i<num[2];i++){ if(i == 1){ maxDrill = Number(num[2]) > maxDrill.value? {name:str,value:Number(num[2])} : maxDrill; } tmp.push("L"+i+"-"+(i+1)); } return tmp; } var matrix = GEN.getMatrix({job:job}); GEN.openStep({job : job,name:step}); for(var key in matrix){ var val = matrix[key]; if(val.layer_type == "drill"){ var mergeTo = getDrl(val.name) // 要合并到的地方 mergeTo.forEach(function(layerName){ if(GEN.isLayerExists({job : job ,layer:layerName.toLowerCase()}) && newdrills.indexOf(layerName.toLowerCase()) < 0){ GEN.deleteLayer({job:job, layer:layerName.toLowerCase()}) } if(!GEN.isLayerExists({job : job ,layer:layerName.toLowerCase()})){ GEN.createLayer({job:job,layer:layerName.toLowerCase(),conext:'board',type:val.layer_type}); newdrills.push(layerName.toLowerCase()) } GEN.workLayer({name:layerName.toLowerCase(),display_number:1,clear_before:'yes'}); GEN.copyLayer({source_job:job ,mode:'append',source_step:step,source_layer:val.name,dest_layer:layerName.toLowerCase()}); }) } } // 合并到maxDrill独立合并 GEN.createLayer({job:job,layer:"b1-"+maxDrill.value,conext:'board',type:'drill'}); GEN.workLayer({name:"b1-"+maxDrill.value,display_number:1,clear_before:'yes'}); GEN.copyLayer({source_job:job ,mode:'append',source_step:step,source_layer:maxDrill.name,dest_layer:"b1-"+maxDrill.value}); GEN.affectedLayer({affected:"no",mode:"all"}); GEN.closeStep(); return this; }