/* NAME: DESCRIPTION: ; PARAMETER: [ { name : 'step', title : 'step', type : 'LineEdit', property : {tool_tip : '目标step,默认是orig'}, }, { name : 'outline', title : 'outline', type : 'LineEdit', property : {tool_tip : '目标outline,默认是ol'}, }, { name : 'units', title : '单位', type : 'RadioBox', property : { size_policy:'Expanding,Fixed', item_list:[ {name:'inch',text:'INCH'}, {name:'mm',text:'MM'}, ], tool_tip:'工作单位,未设定,默认为INCH' }, pack : {row:1,column:1}, }, { name : 'cover_layer_suffix', title : '文字套层后缀', type : 'LineEdit', property : {tool_tip : ''}, }, { name : 'ss_to_sm', title : '文字距离阻焊', type : 'LineEdit', property : {tool_tip : ''}, }, { name : 'ss_to_smd', title : '文字距离SMD', type : 'LineEdit', property : {tool_tip : ''}, }, { name : 'ss_to_bga', title : '文字距离bga', type : 'LineEdit', property : {tool_tip : ''}, }, { name : 'select_lyr', title : '选择层别', type : 'RadioBox', property : { size_policy:'Expanding,Fixed', item_list:[ {name:'yes',text:'Yes'}, {name:'no',text:'No'}, ], tool_tip:'未设定,默认为Yes' }, pack : {row:1,column:1}, }, { name : 'auto_save', title : '自动保存', type : 'RadioBox', property : { item_list:[ {name:'yes',text:'YES'}, {name:'no',text:'NO'}, ], tool_tip:'是否自动保存料号开关' } } ] VERSION_HISTORY: V1.00 2020-09-01 Scott Sun 1.新版本 HELP:

功能简介

标题


参数配置

step信息


注意事项


*/ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// console.log("=============================:template"); // 引入模块 包 var $ = require('topcam.scriptfunc').argv(); var fs = require('fs'); var _ = require('lodash'); require("topsin.genmath") var genMath = new GenMath(); 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 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 = []; var par = PAR; var default_par = { units:"mm", ss_to_sm: 10, // 文字距离阻焊 ss_to_smd: 10, // 文字距离SMD ss_to_bga: 10, // 文字距离bga text_height: 1, // 文字最大高度 bk_suffix: "_bk", // 备份层后缀 silk_suffix: "_font", // 分离的文字层后缀 cover_layer_suffix: "_cover", tol: 1, select_lyr: "no", step: "unit", auto_save: "No", outline: "ol" } for(var key in default_par){ if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] }} var job = Job; var outline = par.outline var gui = new NewGUI(GUI); if(!par.outline_size){ par.outline_size = par.units == 'inch' ? 7.87 : 200; } try { if(_.isEmpty(job)){throw "参数job不存在"} else { 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" } else { GEN.checkInout({job:job,mode:"out"}) } } var workstep = getWorkStep() if(!Array.isArray(workstep)){throw "工作step错误"} createCoverLayer({workstep:workstep}) // 创建套层 // 保存 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"})} 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 createCoverLayer (props){ // 1. step过滤 var workstep = props.workstep; // 2.过滤工作层 var work_layer = getLayer({layer_type:"silk_screen", context: "board"}) if(/yes/ig.test(par.select_lyr)){ var matrix = GEN.getMatrix({job:job}); var layers = Object.keys(matrix).map(function(key){ var tmp ={}; tmp[key] = key; return tmp }) work_layer = gui.selectMultiple({title: "请先择工作层",list: layers,defaultvalue: work_layer,columns: 4,gen: GEN}) } if(work_layer.length == 0 ) {return "没有先择layer"} // 其他参数 var info = gui.showForm({ title : '请手动匹配以下信息', showcheck : 1,gen:GEN, defaultsize:[200,100], ui: { type: 'ScrollArea', property: { widget_resizable: true, frame_shape: 'NoFrame', align: 'Top' }, child: { type: 'VBoxLayout', property: { margin: 2, spacing: 5, align: 'Top' }, pack: { stretch: 0 }, child:[{ type: "FormGridLayout", property: { columns: 1, label_alignment: 'Top | Right', margin: 10, spacing: 20 }, pack: { stretch: 0 }, child:[{ name : 'ss_to_sm', pack: { label: '文字距离阻焊(单边)' }, type : 'LineEdit', units:par.units == 'inch' ? 'mil' : 'um', setter: function(obj){ obj.setText() }, property: { enabled: true, value:par.ss_to_sm } }, { name : 'ss_to_smd', pack: { label: '文字距离SMD(单边)' }, type : 'LineEdit', setter: function(obj){ obj.setText() }, units:par.units == 'inch' ? 'mil' : 'um', property: { value:par.ss_to_smd,enabled: true } }, { name : 'ss_to_bga', pack: { label: '文字距离BGA(单边)' }, setter: function(obj){ obj.setText() }, type : 'LineEdit', value:par.ss_to_bga, units:par.units == 'inch' ? 'mil' : 'um', property: {value:par.ss_to_smd, enabled: true } }, { type: "stretch" }] }] } } }); if(!info){throw "未填写参数"} info = JSON.parse(JSON.stringify(info)) var matrix = GEN.getMatrix({job:job}) workstep.forEach(function(step){ GEN.openStep({job:job,name:step}); GEN.clearLayers(); GEN.affectedLayer({ mode:'all',affected:'no' }); GEN.units({ type:par.units} ); GEN.zoomHome(); work_layer.forEach(function(layer){ var cover_lyr = layer + par.cover_layer_suffix ; var sm,outer ; if ( GEN.isLayerExists({job:job,layer:cover_lyr}) ) { GEN.deleteLayer({job:job,layer:[cover_lyr]}) } if (matrix[layer].side == 'top') { sm = getLayer({layer_type:"solder_mask", context:"board", side:"top"})[0]; outer = getLayer({layer_type:"signal", context:"board", side:"top"})[0]; GEN.createLayer({job:job,layer:cover_lyr,context:'board',type:'document',before:layer,delete_exists:'yes'}); }else{ sm = getLayer({layer_type:"solder_mask", context:"board", side:"bottom"})[0]; outer = getLayer({layer_type:"signal", context:"board", side:"bottom"})[0]; GEN.createLayer({job:job,layer:cover_lyr,context:'board',type:'document',before:layer,delete_exists:'yes'}); } if ( GEN.isLayerExists({job:job,layer:sm}) ) { GEN.affectedLayer({affected:'yes',layer:[sm],clear_before:'yes'}); GEN.selectByFilter({polarity:'positive',profile:'all'}); GEN.selCopyOther({dest:'layer_name',target_layer:cover_lyr,invert:'no',size:2*info.ss_to_sm}); } if ( GEN.isLayerExists({job:job,layer:outer}) ) { GEN.affectedLayer({affected:'yes',layer:[outer],clear_before:'yes'}); GEN.selectByFilter({attribute:['.smd'],profile:'all'}); if ( GEN.getSelectCount() > 0 ){GEN.selCopyOther({dest:'layer_name',target_layer:cover_lyr,invert:'no',size:2*info.ss_to_smd});} GEN.selectByFilter({attribute:['.bga'],profile:'all',}); if ( GEN.getSelectCount() > 0 ){GEN.selCopyOther({dest:'layer_name',target_layer:cover_lyr,invert:'no',size:2*info.ss_to_bga});} } if ( GEN.isLayerExists({job:job,layer:outline}) ) { var outline_tmp = outline + '_tmp_tl'; GEN.copyLayer({source_job:job,source_step:step,source_layer:outline,dest_layer:outline_tmp,mode:'replace',invert:'no'}) ; GEN.affectedLayer({affected:'yes',layer:[outline_tmp],clear_before:'yes'}); GEN.selectByFilter({feat_types:'line\;arc',polarity:'positive',profile:'all'}); if ( GEN.getSelectCount() > 0 ){ GEN.selChangeSym({symbol:'r'+par.outline_size}) } GEN.copyLayer({source_job:job,source_step:step,source_layer:outline_tmp,dest_layer:cover_lyr,mode:'append',invert:'no'}) GEN.deleteLayer({job:job,layer:[outline_tmp],step:step}); } }) }) GEN.affectedLayer({affected:'no',mode:'all'}) GEN.clearLayers() } function getLayer(props){ if(!props){return} if(!props.context){props.context = "board"} var matrix = GEN.getMatrix({job:job}) return Object.keys(matrix).reduce(function(a,b){ var info = matrix[b]; var ret = true; for (var key in props) { if(!Array.isArray(props[key])){props[key] = [props[key]]} if(info[key] && props[key].indexOf(info[key]) < 0){ ret = false } } if(ret){ a.push(props.res == "info"? info : b) } return a },[]) } function NewGUI (gui) { this.msgBox = function(props){ // title type content button props = props || {} return gui.msgBox(props.title || "title",props.type || "info",props.content || "content",props.button || ["ok", "cancel"]); } this.selectFromTreeview = gui.selectFromTreeview this.confirm = function(props) { props = props || {} return gui.confirm(props.content || "content",props.button || ["yes", "no"], props.type || "question"); } this.selectFile = function(props){ // "choose something", "*", true, "file", "/home/abby/fast_io" props = props || {} return gui.selectFile(props.title || "choose something",props.filter || "*",props.multiple || false, "file",""); } this.selectSingle = function(props) { props = props || {} return gui.selectSingle({ "title": props.title || "select", "list": props.list || [], "default": props["default"] || "", "columns": props.columns || 2, "gen":props.gen || GEN }); } this.selectMultiple = function(props) { props = props || {} return gui.selectMultiple({ "title": props.title || "select", "list": props.list || [], "defaultvalue": props["defaultvalue"] || [""], "defaultsize": props["defaultsize"] || [200, 100], "columns": props.columns || 2, "gen":props.gen || GEN }); } this.selectFromTable = gui.selectFromTable this.snapScreen = gui.snapScreen this.imageViewer = gui.imageViewer this.inputBox = gui.inputBox this.showForm = gui.showForm this.selectLayer = function(props){ props = props || {} return gui.selectLayer({ title: props.title || "请选择层", filter: props.filter || ".*", // regular expression selectmode: props.selectmode || "multiple", // single, multiple context: props.context || "all", // all, board, misc layertype: props.layertype || "signal", // default type of layertypelist defaultsize: props.defaultsize || [600, 400], // window size layermatrix: props.layermatrix || props.matrix, layertypelist: props.layertypelist || [ {name: "all", display_name: "all", filter: function(x) { return x }}, {name: "signal", display_name: "signal", filter: function(x) { return x["layer_type"] === "signal"; }}, {name: "power_ground", display_name: "power_ground", filter: function(x) { return x["layer_type"] === "power_ground"; }}, {name: "mixed", display_name: "mixed", filter: function(x) { return x["layer_type"] === "mixed"; }}, {name: "solder_mask", display_name: "solder_mask", filter: function(x) { return x["layer_type"] === "solder_mask"; }}, {name: "silk_screen", display_name: "silk_screen", filter: function(x) { return x["layer_type"] === "silk_screen"; }}, {name: "solder_paste", display_name: "solder_paste", filter: function(x) { return x["layer_type"] === "solder_paste"; }}, {name: "drill", display_name: "drill", filter: function(x) { return x["layer_type"] === "drill"; }}, {name: "rout", display_name: "rout", filter: function(x) { return x["layer_type"] === "rout"; }}, {name: "document", display_name: "document", filter: function(x) { return x["layer_type"] === "document"; }} ], gen: props.GEN || GEN }) } this.lockUnlockLayer = function(props){ props = props || {} var tmp = {} if (props.matrix) { for (var key in props.matrix) { var item = props.matrix[key] tmp[key] = { row : item.row, name : item.name } } } return gui.lockUnlockLayer({ title: props.title || "lockUnlockLayer", layermatrix:props.layermatrix || tmp }) } this.passwordBox = function(props){ props = props || {} return gui.passwordBox({title:props.title || "password", password:props.password || "1212"}) } this.selectJobLayer = function (props) { props = props || {} return gui.selectJobLayer({ layertypelist: props.layertypelist || [ {name: "all", display_name: "all", filter: function(x) { return x }}, {name: "signal", display_name: "signal", filter: function(x) { return x["layer_type"] === "signal"; }}, {name: "power_ground", display_name: "power_ground", filter: function(x) { return x["layer_type"] === "power_ground"; }}, {name: "mixed", display_name: "mixed", filter: function(x) { return x["layer_type"] === "mixed"; }}, {name: "solder_mask", display_name: "solder_mask", filter: function(x) { return x["layer_type"] === "solder_mask"; }}, {name: "silk_screen", display_name: "silk_screen", filter: function(x) { return x["layer_type"] === "silk_screen"; }}, {name: "solder_paste", display_name: "solder_paste", filter: function(x) { return x["layer_type"] === "solder_paste"; }}, {name: "drill", display_name: "drill", filter: function(x) { return x["layer_type"] === "drill"; }}, {name: "rout", display_name: "rout", filter: function(x) { return x["layer_type"] === "rout"; }}, {name: "document", display_name: "document", filter: function(x) { return x["layer_type"] === "document"; }} ], //defaultlayertype: "ha", joblist: props.joblist || [], defaultJob: props.defaultJob || [], // select by default steplist: props.steplist || [], // defaultstep: "step3", showstep: props.showstep || true, selectmode: props.selectmode || "multiple", // single/multiple layermatrix: props.layermatrix || { }, defaultlayer: props.defaultlayer || [] }) } } function getWorkStep(props){ var steplists = GEN.getStepList({job:job}); if(steplists.length == 0){return "该料号没有step"} var steps_tmp = steplists.filter(function(name){ var reg = new RegExp(par.step, "ig") return reg.test(name) }) if(steplists.length == 0){return "根据脚本参数过滤出来的step不存在,请检查资料或者脚本参数配置!"} var workstep = gui.selectMultiple({ title: "请先择工作step", size:[200,100], defaultsize:[200,100], list: steplists.map(function(v){ var tmp = {}; tmp[v] = v ;return tmp}), defaultvalue: steps_tmp, columns: 1, gen: GEN }) if(workstep.length == 0 ) {return "没有先择step"} return workstep }