/* NAME: DESCRIPTION: ; PARAMETER: [ { name : 'step_fliter', title : 'Step过滤', type : 'LineEdit', property : {tool_tip : 'unit'}, }, { name : 'erf', title : 'erf name', type : 'LineEdit', property : {tool_tip : 'erf'}, }, { name : 'layer_type', title : '工作层', type : 'ComboBox', property : {     size_policy:'Expanding,Fixed',     item_list:[         {name:'outer',text:'outer'},         {name:'inner',text:'inner'},         {name:'all',text:'all'}     ],     tool_tip:'分析模式必须设置,未设定则退出' }, pack : {row:1,column:1}, }, { name : 'del_backup', title : '删除TL备份层', type : 'RadioBox', property : { item_list:[ {name:'yes',text:'YES'}, {name:'no',text:'NO'}, ], 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-28 Scott Sun 1.新版本 HELP:

功能简介

补铜桥


参数配置

配置


注意事项


*/ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// console.log("==============================>JTG_PUB_pos_add_copper_bridge_aim"); // 引入模块 包 var $ = require('topcam.scriptfunc').argv(); var fs = require('fs'); var _ = require('lodash'); var mode = $.ikm ? "topcam" : "aimdfm"; var IKM = $.ikm; if (IKM==undefined ) { IKM = require('topcam.ikm6')($) } var GEN = $.gen; var GUI = $.gui || {}; var Job = $.job || $.job_name; var JobId = $.job_id; var db = $.db || IKM.db; var GenMath = require("topsin.genmath") var PAR = {} if ($.par) { PAR = $.par } else if ($.hasOwnProperty('script_parameter')){ PAR = JSON.parse($.script_parameter); } if (mode === "aimdfm") { var database = require("topsin.database"); database.addConnection($.conf.database_conf, "DFM"); var QDfm = database.query("DFM"); $.QDfm = QDfm; if ($.conf.product_type == "aimdfm") { QDfm.updateRow({ table: "pdm_aimdfm_task", data: { current_process_title: $.process_title }, where: { id: $.task_id } }); } } var Status = 'ok'; var resultData = []; try { var par = PAR; PAR.width = 10 PAR.length = 10 var default_par = { // par默认参数? step_fliter:"unit.+", step2:"unit", units: "inch", auto_save: "no" } for(var key in default_par){ // 设置默认属性 if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] } } // var par_props = ["ring_size","line_size"] // par的必填参数 // par_props.forEach(function(v){ // if(par[v] == ""){throw "par props "+v+" err"} // }) if(_.isEmpty(Job)){throw "参数Job不存在"} var job = Job.toLowerCase() // 料号验证 if(!GEN.isJobExists({job:job})){throw "料号"+job+"不存在"} if(!GEN.isJobOpen({job:job})){ GEN.openJob({job:job}) } if(mode == "aimdfm"){ if(GEN.checkInout({job:job,mode:"test"}) != 0){ throw "the job check" } GEN.checkInout({job:job,mode:"out"}); } // 脚本开始 var stepList = GEN.getStepList({job:job}) if(par.step_fliter != ""){ stepList = stepList.filter(function(v){ var step_reg = new RegExp(par.step_fliter) return step_reg.test(v)}) } if (stepList.length == 0 && par.step2) { stepList = GEN.getStepList({job: job}).filter(function (v) { var step_reg = new RegExp(par.step2) return step_reg.test(v) }) } var layer_config = { outer: {layer_type:"signal", side:"top|bottom", context:"board", polarity:"positive"}, inner: {layer_type:"signal", side:"inner", context:"board", polarity:"positive"}, all: {layer_type:"signal", context:"board", polarity:"positive"}, power_ground: {layer_type:"power_ground", side:"inner", context:"board", polarity:"negative"}, } var layer_cfg if(par.layer_type != ""){ layer_cfg = layer_config[par.layer_type] } var matrix = GEN.getMatrix({job:job}) var n_layers = Object.keys(matrix).sort(function(a,b){return matrix[a].row - matrix[b].row}) .filter(function(key){ var val = matrix[key] var flag = true if(!layer_cfg){ return false} for(var k in layer_cfg){ var tmp_reg = new RegExp(layer_cfg[k], "ig") if(!tmp_reg.test(val[k])){ flag = false } } return flag }) if(n_layers.length == 0){throw "can not find layer"} stepList.forEach(function(step){ GEN.openStep({job:job, name:step}) GEN.units({type:par.units}) GEN.affectedLayer({affected:'no',mode:'all'}) GEN.clearLayers() var profile_limits = GEN.getProfileLimits({job:job,step:step,units:par.units}); var ans_chk = create_checklist_and_run_analysis({layers:n_layers,aux:1, job:job, step:step}, par); GEN.COM("disp_off"); n_layers.forEach(function(layer){ var tmp = [] tmp.push(layer + '_tl+++tmp') GEN.copyLayer({source_job:job,source_step:step,source_layer:layer,dest_layer:layer+'_tl+++',mode:'replace',invert:'no'}); var length = par["length"]; var width = par["width"]; var line_chk = "tl_line_chk",line_ok="tl_line_ok", add_pad="tl_add_pad",touch_lyr="tl_touch_lyr" var tmp_layers = [line_chk,line_ok,add_pad,touch_lyr] //GEN.deleteLayer(job:job,layer:[line_chk,line_ok,add_pad,touch_lyr],step:step); tmp_layers.forEach(function(v){ if(GEN.isLayerExists({job:job, layer:v})){GEN.deleteLayer({job:job, layer:v})} GEN.createLayer({job:job,layer:v,conext:'misc',type:'document'}) }) var ms_layer = 'ms_1_'+layer var mk_layer='mk_1_'+layer if(GEN.isLayerExists({job:job,layer:ms_layer})){ var feature = GEN.getFeatures({job:job,step:step,layer:ms_layer,units:par["units"]}); // break_sr GEN.affectedLayer({affected:'yes',mode:'single',layer:line_chk,clear_before:'yes'}); if(feature && feature.length){ feature.forEach(function(feat){ if(feat.type == "line"){ var line = {xs:feat["xs"]-0,xe:feat["xe"]-0,ys:feat["ys"]-0,ye:feat["ye"]-0}; var tmpline = getLineParallel(line, length/ 2000) var line1 = tmpline.line1 var line2 = tmpline.line2 var point1 = get_line_center(line1); var point2 = get_line_center(line2); var line_new = {xs:point1["x"],ys:point1["y"],xe:point2["x"],ye:point2["y"]}; GEN.addLine({xs:line_new["xs"],ys:line_new["ys"],xe:line_new["xe"],ye:line_new["ye"],symbol:'r'+width}); } }) } } // 此处报错 ?? // var feature = GEN.getFeatures({job:job,step:step,layer:ms_layer,units:par["units"]}); //// break_sr // GEN.affectedLayer({affected:'yes',mode:'single',layer:line_chk,clear_before:'yes'}); // if(feature && feature.length){ // feature.forEach(function(feat){ // if(feat.type != "line"){ // var line = {xs:feat["xs"],xe:feat["xe"],ys:feat["ys"],ye:feat["ye"]}; // var line1 = GenMath.get_line_parallel(line,length/2000); // var line2 = GenMath.get_line_parallel(line,-length/2000); // var point1 = GenMath.get_line_center(line1); // var point2 = GenMath.get_line_center(line2); // var line_new = {xs:point1["x"],ys:point1["y"],xe:point2["x"],ye:point2["y"]}; // GEN.addLine({xs:line_new["xs"],ys:line_new["ys"],xe:line_new["xe"],ye:line_new["ye"],symbol:'r'+width}); // } // }) // } GEN.selClearFeature(); var feature_line = GEN.getFeatures({job:job,step:step,layer:line_chk,units:par["units"]}); // break_sr GEN.affectedLayer({affected:'yes',mode:'single',layer:add_pad,clear_before:'yes'}); if(feature_line && feature_line.length){ feature_line.forEach(function(feat){ if(feat.type != "line"){ GEN.addLine({xs:feat["xs"],ys:feat["ys"],xe:feat["xs"],ye:feat["ys"],symbol:'r'+width}); GEN.addLine({xs:feat["xe"],ys:feat["ye"],xe:feat["xe"],ye:feat["ye"],symbol:'r'+width}); } }) } GEN.affectedLayer({affected:'yes',mode:'single',layer:touch_lyr,clear_before:'yes'}); GEN.addRectangle({x1:profile_limits["xmin"],y1:profile_limits["ymin"],x2:profile_limits["xmax"],y2:profile_limits["ymax"]}); GEN.workLayer({name:layer,display_number:2,clear_before:'yes'}) GEN.selAllFeat() if (GEN.getSelectCount()>0){ GEN.selCopyOther({dest:'layer_name',target_layer:touch_lyr,invert:'yes',dx:0,dy:0,size:width+0.5}) }; GEN.affectedLayer({affected:'yes',mode:'single',layer:touch_lyr,clear_before:'yes'}); GEN.selContourize(); GEN.affectedLayer({affected:'yes',mode:'single',layer:line_chk,clear_before:'yes'}); GEN.selRefFeat({layers:touch_lyr,use:'filter',mode:'touch'}); if ( GEN.getSelectCount() > 0 ){GEN.selDelete()}; GEN.affectedLayer({affected:'yes',mode:'single',layer:add_pad,clear_before:'yes'}); GEN.selRefFeat({layers:layer,use:'filter',mode:'cover'}); GEN.selReverse(); if ( GEN.getSelectCount() > 0 ){GEN.selDelete()}; //// GEN.affectedLayer({affected:'yes',mode:'single',layer:[line_chk,add_pad],clear_before:'yes'}); GEN.selAllFeat() GEN.selChangeSym({symbol:'r0.1'}); GEN.workLayer({name:line_chk,display_number:1,clear_before:'yes'}); GEN.selRefFeat({layers:add_pad,use:'filter',mode:'touch'}); GEN.selAddAttr({attribute:[{attribute:'.string',text:'bridge'}]}); GEN.selAllFeat() GEN.selChangeSym({symbol:'r'+width}); GEN.selectByFilter({attribute:[{attribute:'.string',text:'bridge'}]}); if( GEN.getSelectCount()>0){GEN.selMoveOther({target_layer:line_ok,invert:'no',dx:0,dy:0,size:0}) }; GEN.selAddAttr({attribute:[{attribute:'.string',text:'bridge'}]}); GEN.affectedLayer({affected:'yes',mode:'single',layer:[line_ok,line_chk],clear_before:'yes'}); GEN.selRefFeat({layers:layer,use:'filter',mode:'touch',f_types:'line\;arc'}); if( GEN.getSelectCount()>0){GEN.selDelete() }; GEN.affectedLayer({ mode:'all',affected:'no' }); GEN.displayLayer({name:layer,number:2}); GEN.displayLayer({name:line_ok,number:3}); GEN.COM("disp_on"); GEN.COM("disp_off"); GEN.copyLayer({source_job:job,source_step:step,source_layer:line_ok,dest_layer:layer,mode:'append',invert:'no'}); GEN.copyLayer({source_job:job,source_step:step,source_layer:line_chk,dest_layer:layer,mode:'append',invert:'no'}); if(GEN.isLayerExists({job:job,layer:ms_layer})){ GEN.deleteLayer({job:job,layer:[ms_layer]}) } if(GEN.isLayerExists({job:job,layer:mk_layer})){ GEN.deleteLayer({job:job,layer:[mk_layer]}) } GEN.deleteLayer({job:job,layer:[line_chk,line_ok,add_pad,touch_lyr],step:step}); if (/yes/ig.test(par["del_backup"])){GEN.deleteLayer({job:job,layer:[layer+'_tl+++'],step:step})}; }) GEN.COM("disp_on"); var ans_chk_new = create_checklist_and_run_analysis({layers:n_layers,aux:0,job:job, step:step}, par); GEN.affectedLayer({mode:'all',affected:'no'}); GEN.clearLayers(); GEN.zoomHome(); }) // 保存 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"}) } console.log("======================== JTG_OUT_delete_individual_pad_aim end"); if (mode === "aimdfm") { $.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 }; } }else { return "Done" } } catch (e) { IKM.msg(_.join(GEN.STATUS, "\n")) IKM.msg(e) Status = 'error'; resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]}); return (mode === "aimdfm") ? {status: Status, result_data: resultData} : "Error"; } function create_checklist_and_run_analysis(obj, par){ var job = obj.job; var step = obj.step; var layers = obj.layers; var num = par["width"]; var nact = 1; var checklist = 'tmp_signal_analysis'; var params = {}, items = [] params["pp_layer"] = '.affected'; params["pp_tests"] = 'Bottleneck'; params["pp_selected"] = 'All'; // params["pp_selected"] = 'Selected'; items.push({ name:'tmp_signal_check', nact:nact, action:'valor_analysis_signal', erf:par.erf, mode:'regular', params:params, }) if(GEN.isChklistExists({job:job,step:step,chklist:checklist})){ GEN.COM("chklist_delete,chklist="+checklist) } GEN.createChklist({chklist:checklist,items:items}); GEN.affectedLayer({affected:'yes',layer:layers,clear_before:'yes'}); if (obj["aux"] == 1){ GEN.COM('filter_reset',{filter_name:'popup'}); GEN.selectByFilter({feat_types:'surface',polarity:'positive',profile:'all'}); GEN.COM('filter_reset',{filter_name:'popup'}); } GEN.COM('chklist_run',{chklist:checklist,nact:nact,area:'profile'}); GEN.chklistErfRange({ job:job,step:step,chklist:checklist,nact:nact,erf:par.erf,default_range:[0,0,0.1], range:{ conductor_width : [num,num+1,num+2], } }); if (obj["aux"] == 1) { // var meas = GEN.getCheckMeas({ // job: job, // step:step, // chklist:checklist, // nact:nact, // }) // var cflag = true; // meas.forEach(function(item){ // 结果存在 [""] 的情况,会继续导致下面的命令报错 // if(item.trim() == ''){ // cflag = false; // } // }) // if(meas.length > 0 && cflag){ // GEN.COM("chklist_create_lyrs,chklist="+checklist+",severity=0,suffix="); // } } else { GEN.chklistShow({chklist:checklist}); GEN.COM("chklist_res_show,chklist="+checklist+",nact="+nact+",x=0,y=0,w=0,h=0"); } } function get_line_center(line){ var xs = line.xs var ys = line.ys var xe = line.xe var ye = line.ye return {x:(xs+xe)/2,y:(ys+ye)/2} } function getLineParallel(line,length){ var xs = line.xs var ys = line.ys var xe = line.xe var ye = line.ye var linelength = Math.sqrt((xe-xs)*(xe-xs) + (ye-ys)*(ye-ys)) var ylengthq = Math.abs(xe - xs) / linelength * length var xlengthq = Math.abs(ye - ys) / linelength * length if((xe-xs)*(ye-ys) > 0){ return { line1: { xs: xs + xlengthq, xe: xe + xlengthq, ys: ys - ylengthq, ye: ye - ylengthq, }, line2: { xs: xs - xlengthq, xe: xe - xlengthq, ys: ys + ylengthq, ye: ye + ylengthq, } } } else if (ye == ys) { return { line1: { xs: xs, xe: xe, ys: ys - length, ye: ye - length, }, line2: { xs: xs, xe: xe, ys: ys + length, ye: ye + length, } } } else if (xe == xs) { return { line1: { xs: xs- length, xe: xe- length, ys: ys , ye: ye , }, line2: { xs: xs +length, xe: xe +length, ys: ys, ye: ye, } } } else { return { line1: { xs: xs + xlengthq, xe: xe + xlengthq, ys: ys + ylengthq, ye: ye + ylengthq, }, line2: { xs: xs - xlengthq, xe: xe - xlengthq, ys: ys - ylengthq, ye: ye - ylengthq, } } } };