/*
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
}