/*
NAME:
DESCRIPTION: ;
PARAMETER:
[
{
name : 'step',
title : '过滤Step',
type : 'LineEdit',
property : {tool_tip : '过滤Step'},
},
{
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-25 Scott Sun
1.新版本
HELP:
功能简介
sec drc 分析
参数配置
step信息
注意事项
无
*/
// 引入模块 包
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 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 = {
step: "drc",
auto_save: "No",
units: "mm"
}
for(var key in default_par){ if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] }}
var job = Job;
var Omatrix;
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 stepList = GEN.getStepList({job:job})
stepList = stepList.filter(function(v){
var reg = new RegExp(par.step,"ig")
return reg.test(v)
})
if(stepList.length == 0){throw "未找到step"}
// 上传matrix信息
var matrix = UPLOAD_LAYER_MATRIX({job:job}) // 分析matrix 获得分析后的matrix信息
var board_thickness = IKM.get_jobinfo({jobid:JobId,jobinfo:"board_thickness"}) || 0;
board_thickness *= 1000 ;
stepList.forEach(function (step) {
GEN.openStep({job:job,name:step});
GEN.clearLayers();
GEN.affectedLayer( {mode:'all',affected:'no'} );
GEN.COM( "sel_options,clear_mode=clear_after,display_mode=all_layers,area_inout=inside,area_select=select,select_mode=standard,area_touching_mode=exclude");
GEN.units( {type:par.units} );
GEN.zoomHome();
var check_list = 'pcb_analysis_jt01';
var signal = "", signals = [];
var pg_layer = "", pg_layers = [];
var drill = [];
var sm_layers = [] , ss_layer = "", ss_layers = [];
// var ($signal,@signal,@pg_layer,$pg_layer,@drill,@sm_layer,@ss_layer,$ss_layer);
var matrix = GEN.getMatrix({job:job});
for (var layer in matrix) {
var layerInfo = matrix[layer];
if(layerInfo.context == "board") {
if(layerInfo.layer_type == 'signal' && /(cil)|(col)/.test(layer)){
var lyr_paras = {};
if(layerInfo.side == 'top'){
lyr_paras.layer1 = layer;
lyr_paras.drills = 'yes';
lyr_paras.thickness = board_thickness/2;
}else if(layerInfo.side == 'bottom'){
lyr_paras.layer2 = layer;
lyr_paras.drills = 'yes';
lyr_paras.thickness = board_thickness/2;
}else{
lyr_paras.layer1 = layer;
lyr_paras.drills = 'no';
lyr_paras.thickness = 0;
}
var copperArea = GEN.copperArea(lyr_paras);
copperArea.area = Number(copperArea.area).toFixed(3) - 0;
copperArea.percent = parseInt(copperArea.percent)
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:layerInfo.tl_name,
layerinfohash:{copper_area_pcs:copperArea.area,
copper_area_ratio_pcs:copperArea.percent}
});
signals.push(layer)
layer += ';';
signal += layer;
}else if(layerInfo.layer_type == 'power_ground' && /(cil)/.test(layer)){
var lyr_paras = {
layer1 : layer,
drills : 'no',
thickness : 0
};
var copperArea = GEN.copperArea(lyr_paras);
copperArea.area = Number(copperArea.area).toFixed(3) - 0;
copperArea.percent = parseInt(copperArea.percent)
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:layerInfo.tl_name,
layerinfohash:{copper_area_pcs:copperArea.area,
copper_area_ratio_pcs:copperArea.percent}
});
pg_layers.push(layer)
layer += ';';
pg_layer += layer;
} else if(layerInfo.layer_type == 'drill'){
drill.push(layer)
} else if (layerInfo.layer_type == 'silk_screen' && /lpp/.test(layer)) {
var lyr_paras = {
layer1 : layer,
drills : 'no',
thickness : 0
};
var copperArea = GEN.copperArea(lyr_paras);
copperArea.area = Number(copperArea.area).toFixed(3) - 0;
copperArea.percent = parseInt(copperArea.percent)
var target_attrname = layerInfo.side == 'top' ? 'ss_area_pcs_top' : 'ss_area_pcs_bot';
var jobinfohash = {};
jobinfohash[target_attrname] = copperArea.area;
IKM.save_jobinfo({
jobid:JobId,
jobcategory:'work',
jobinfohash:jobinfohash
});
ss_layers.push(layer)
layer += ';';
ss_layer += layer;
}else if(layerInfo.layer_type == 'solder_mask' && /smf/.test(layer)){
sm_layers.push(layer)
}
}
}
var tmp_layer = 'tl+copper+tmp++';
GEN.createLayer({job:job,layer:'tl+copper+tmp++',context:'misc',type:'signal',delete_exists:'yes'});
GEN.affectedLayer({affected:'yes',layer:tmp_layer,clear_before:'yes'});
var profile_limits = GEN.getProfileLimits({job:job,step:step,units:par.units});
if(profile_limits.xsize == 0){
GEN.affectedLayer( {mode:'all',affected:'no'} );
GEN.deleteLayer({job:job,layer:tmp_layer,step:step});
throw 'Cancel';
}else{
GEN.srFill({layer:tmp_layer});
var lyr_paras = {};
lyr_paras.layer1 = tmp_layer;
lyr_paras.drills = 'no';
lyr_paras.thickness = 0;
var copperArea = GEN.copperArea(lyr_paras);
copperArea.area = Number(copperArea.area).toFixed(3) - 0;
copperArea.percent = parseInt(copperArea.percent)
GEN.affectedLayer( {mode:'all',affected:'no'} );
GEN.deleteLayer({job:job,layer:tmp_layer,step:step});
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:step,
layerinfohash:{board_area_pcs:copperArea.area,
board_area_ratio_pcs:copperArea.percent}
});
}
if(GEN.isChklistExists({job:job,step:step,chklist:check_list})){
GEN.COM('chklist_delete',{chklist:check_list});
}
GEN.COM("chklist_from_lib,chklist=" + check_list);
GEN.COM("chklist_open,chklist=" + check_list);
GEN.COM("chklist_show,chklist=" + check_list);
GEN.chklistSelectAct({job:job,step:step,chklist:check_list,nact:1,select:'yes',clear_before:'yes'});
if(pg_layers.length > 0){
GEN.COM('chklist_select_act',{chklist:check_list,nact:2,select:'yes'});//运行PG层分析
}
if(sm_layers.length > 0){
GEN.COM('chklist_select_act',{chklist:check_list,nact:3,select:'yes'});
}
if(ss_layers.length > 0){
GEN.COM('chklist_select_act',{chklist:check_list,nact:4,select:'yes'});
}
GEN.COM('chklist_select_act',{chklist:check_list,nact:5,select:'yes'});
GEN.chklistCupd({chklist:check_list,nact:1,params:{pp_layer:signal,pp_d2c:500,pp_tests:'Spacing\;Drill\;Size\;Rout\;SMD'}});
if(ss_layers.length > 0){
GEN.chklistCupd({chklist:check_list,nact:4,params:{pp_layers:ss_layer}});
}
if(pg_layers.length > 0){
GEN.chklistCupd({chklist:check_list,nact:2,params:{pp_layers:pg_layer,pp_tests:'Drill\;Rout'}});
}
GEN.chklistCupd({chklist:check_list,nact:5,params:{pp_tests:'Hole Separation\;NPTH to Rout'}});
GEN.chklistRun({chklist:check_list,nact:'s'});
// 分析取得结果插入数据库
var dirll_info = {},signal_info={},sm_info={};
for (var i in drill) {
var drl = drill[i];
var drill_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:5,units:par.units,layer:drl});
var same_net = drill_meas.filter(function(v){return /same/.test(v)})
var diff_net = drill_meas.filter(function(v){return /diff/.test(v)})
var drill_to_outline = drill_meas.filter(function(v){return /drill_to_outline/.test(v)})
var np_to_rout = drill_meas.filter(function(v){return /npth2rout/.test(v)})
dirll_info[drl] = {};
if(same_net.length > 0){
var tmp = same_net[0].split(/\s+/);
dirll_info[drl]["same_min"] = (tmp[2]/1000).toFixed(3);
}else{
dirll_info[drl]["same_min"] = '/';
}
if(diff_net.length > 0){
var tmp = diff_net[0].split(/\s+/);
dirll_info[drl]["diff_min"] = (tmp[2]/1000).toFixed(3);
}else{
dirll_info[drl]["diff_min"] = '/';
}
if(drill_to_outline.length > 0){
var tmp = drill_to_outline[0].split(/\s+/);
dirll_info[drl]["drill_to_outline"] = (tmp[2]/1000).toFixed(3);
}else{
dirll_info[drl]["drill_to_outline"] = '/';
}
if(np_to_rout.length > 0){
var tmp = np_to_rout[0].split(/\s+/);
dirll_info[drl]["np_to_rout"] = (tmp[2]/1000).toFixed(3);
}else{
dirll_info[drl]["np_to_rout"] = '/';
}
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:matrix[drl].tl_name,
layerinfohash:{h2h_min_same_layer:dirll_info[drl].same_min,
h2h_min_different_layer:dirll_info[drl].diff_min,
drill_to_rout:dirll_info[drl].drill_to_outline,
npth_to_rout:dirll_info[drl].np_to_rout
}
});
}
signals.forEach(function(layer){
var signal_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:1,units:par.units,layer:layer});
var line_to_line = signal_meas.filter(function(v){return /l2l/.test(v)})
var line_to_pad = signal_meas.filter(function(v){return /p2line/.test(v)}) // 线到pad
var pad_to_pad = signal_meas.filter(function(v){return /pth2pth|via2via/.test(v)}) // pad到pad
var hole_to_copper = signal_meas.filter(function(v){return /(via2l)|(via2c)|(pth2c)|(pth2l)/.test(v)}) // hole到copper
var min_ring = signal_meas.filter(function(v){return /(via_ar)|(pth_ar)/.test(v)}) // 最小ring
var min_line = signal_meas.filter(function(v){return /(line)|(arc)/.test(v)}) // 最小线宽
var smd_pitch = signal_meas.filter(function(v){return /smd_pitch/.test(v)}) // SMD_pith
var bga_pitch = signal_meas.filter(function(v){return /bga_pitch/.test(v)}) // BGA_pith
var rout_copper = signal_meas.filter(function(v){return /r2c/.test(v)}) // rout to copper
if(!signal_info[layer]){signal_info[layer] = {}}
if(line_to_line.length > 0){
var tmp = line_to_line[0].split(/\s+/)
signal_info[layer].line_to_line = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].line_to_line = '/';
}
if(line_to_pad.length > 0){
var tmp = line_to_pad[0].split(/\s+/)
signal_info[layer].line_to_pad = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].line_to_pad = '/';
}
if(pad_to_pad.length > 0){
var tmp = pad_to_pad[0].split(/\s+/)
signal_info[layer].pad_to_pad = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].pad_to_pad = '/';
}
if(hole_to_copper.length > 0){
var tmp = hole_to_copper[0].split(/\s+/)
signal_info[layer].hole_to_copper = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].hole_to_copper = '/';
}
if(min_ring.length > 0){
var tmp = min_ring[0].split(/\s+/)
signal_info[layer].min_ring = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].min_ring = '/';
}
if(min_line.length > 0){
var tmp = min_line[0].split(/\s+/)
signal_info[layer].min_line = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].min_line = '/';
}
if(smd_pitch.length > 0){
var tmp = smd_pitch[0].split(/\s+/)
signal_info[layer].smd_pitch = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].smd_pitch = '/';
}
if(bga_pitch.length > 0){
var tmp = bga_pitch[0].split(/\s+/)
signal_info[layer].bga_pitch = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].bga_pitch = '/';
}
if(rout_copper.length > 0){
var tmp = rout_copper[0].split(/\s+/)
signal_info[layer].rout_copper = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].rout_copper = '/';
}
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:matrix[layer].tl_name,
layerinfohash:{l2l_min:signal_info[layer].line_to_line,
l2p_min:signal_info[layer].line_to_pad,
p2p_min:signal_info[layer].pad_to_pad,
h2c_min:signal_info[layer].hole_to_copper,
annular_ring_min:signal_info[layer].min_ring,
org_line_width_min:signal_info[layer].min_line,
rout_to_copper:signal_info[layer].rout_copper,
smd_pitch:signal_info[layer].smd_pitch,
bga_pitch:signal_info[layer].bga_pitch,
}
});
})
pg_layers.forEach(function(layer){
var pg_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:2,units:par.units,layer:layer});
var hole_to_copper = pg_meas.filter(function(v){return /(via2l)|(via2c)|(pth2c)|(pth2l)/.test(v)}) // hole到copper
var min_ring = pg_meas.filter(function(v){return /(via2t)|(pth2t)/.test(v)}) // 最小ring
var rout_copper = pg_meas.filter(function(v){return /r2c/.test(v)}) // rout to copper
if(!signal_info[layer]){signal_info[layer] = {}}
if(hole_to_copper.length > 0){
var tmp = hole_to_copper[0].split(/\s+/)
signal_info[layer].hole_to_copper = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].hole_to_copper = '/';
}
if(min_ring.length > 0){
var tmp = min_ring[0].split(/\s+/)
signal_info[layer].min_ring = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].min_ring = '/';
}
if(rout_copper.length > 0){
var tmp = rout_copper[0].split(/\s+/)
signal_info[layer].rout_copper = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].rout_copper = '/';
}
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:matrix[layer].tl_name,
layerinfohash:{
h2c_min:signal_info[layer].hole_to_copper,
annular_ring_min:signal_info[layer].min_ring,
rout_to_copper:signal_info[layer].rout_copper,
}}
);
})
sm_layers.forEach(function(layer){
var sm_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:3,units:par.units,layer:layer});
var pad_ring = sm_meas.filter(function(v){return /ar_pad/.test(v)}) // ring
var pad_cover = sm_meas.filter(function(v){return /coverage/.test(v)}) // cover
var pad_bridge = sm_meas.filter(function(v){return /pad2pad_bridge/.test(v)}) // bridge
if(!signal_info[layer]){signal_info[layer] = {}}
if(pad_ring.length > 0){
var tmp = pad_ring[0].split(/\s+/)
signal_info[layer].pad_ring = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].pad_ring = '/';
}
if(pad_cover.length > 0){
var tmp = pad_cover[0].split(/\s+/)
signal_info[layer].pad_cover = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].pad_cover = '/';
}
if(pad_bridge.length > 0){
var tmp = pad_bridge[0].split(/\s+/)
signal_info[layer].pad_bridge = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].pad_bridge = '/';
}
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:matrix[layer].tl_name,
layerinfohash:{
sm_bridge:signal_info[layer].pad_bridge,
sm_cover:signal_info[layer].pad_cover,
sm_annular_ring:signal_info[layer].pad_ring,
}}
);
})
ss_layers.forEach(function(layer){
var ss_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:4,units:par.units,layer:layer});
var ss_line = ss_meas.filter(function(v){return /ss_line/.test(v)})
if(!signal_info[layer]){signal_info[layer] = {}}
if(ss_line.length > 0){
var tmp = ss_line[0].split(/\s+/)
signal_info[layer].ss_min_line = (tmp[2]/1000).toFixed(3);
}else{
signal_info[layer].ss_min_line = '/';
}
IKM.save_layerinfo({jobid:JobId,
jobcategory:'org',
tlname:matrix[layer].tl_name,
layerinfohash:{
ss_min_line:signal_info[layer].ss_min_line,
}}
);
})
var result = save_drill_info({job:job,step:step,step_type:'pcs',jobcategory:'mi'});
if (result){
throw result;
}
saveMeans({job:job,step:step,chklist:check_list})
GEN.clearLayers();
GEN.affectedLayer( {mode:'all',affected:'no'} );
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"})}
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 UPLOAD_LAYER_MATRIX(props){
var job = props.job
props.jobcategory = props.jobcategory || "work"
var matrix = ANALYSIS_STACKUP({job:job, jobcategory:props.jobcategory});
Omatrix = matrix
var layers = Object.keys(matrix).sort(function(a,b){return matrix[a]["row"] - matrix[b]["row"]})
var tableName = "pdm_job_" + props.jobcategory + "_layer";
console.log("===========>matrix upload");
var oLayers = db.query("",function(q){
return q.selectMapMap({
table:tableName,
field: ["odb_name", "release_status"],
where:{job_id:JobId},
uniquefield: "odb_name"
})
});
db.query("",function(q){
return q.deleteRow({
table:tableName,
where:{job_id:JobId},
})
});
var fieldLst = ["name", "odb_context", "odb_type", "odb_polarity", "odb_side", "drl_start", "drl_end",
"row_num", "type", "drl_start_num", "drl_end_num", "drl_from_num", "drl_to_num", "drl_connect_to",
"odb_name", "side", "stackup_num", "customer_field", "input_file_name", "odb_row_num"
];
layers.forEach(function(layer){
var layerInfo = matrix[layer];
var tmpData = {
"job_id": JobId,
"name": layerInfo["name"]
};
tmpData["release_status"] = (oLayers&&oLayers.hasOwnProperty(layerInfo["odb_name"])) ? oLayers[layerInfo["odb_name"]]["release_status"] : null;
for (n = 0; n < fieldLst.length; n++) {
tmpData[fieldLst[n]] = layerInfo[fieldLst[n]];
}
db.query("",function(q){
return q.insertRow({
table:tableName,
data: tmpData
})
});
})
return matrix
}
function ANALYSIS_STACKUP(props){
var job = props.job
if(!props.hasOwnProperty("jobcategory")){ props.jobcategory = 'work' }
var matrix = GEN.getMatrix({job:job})
var layer_count = GEN.getLayerCount({job:job}) // !
IKM.save_job_info({jobid:JobId,jobcategory:props.jobcategory,jobinfohash:{TL_layer_count:layer_count}})
_.values(matrix).sort(function(a,b){return a.row-b.row}).forEach(function(layer){
layer.odb_name = layer.name;
layer.name = layer.tl_name;
layer.odb_context = layer.context;
layer.odb_type = layer.layer_type;
layer.odb_polarity = layer.polarity;
layer.odb_side = layer.side;
layer.row_num = layer.tl_num;
layer.type = layer.tl_type;
layer.side = layer.enum_tl_side;
layer.input_file_name = layer.file_name;
layer.odb_row_num = layer.row;
if (layer.odb_name == 'ftdrill'){
layer.name = 'drill';
layer.drl_start_num = 1;
layer.drl_end_num = layer_count;
layer.drl_from_num = 1;
layer.drl_to_num = layer_count;
layer.type = 'main_drill';
}
else if (/^ftdrill(\d+)-(\d+)/.test(layer.odb_name)){ // /^d(\d+)\-(\d+)$/
var tmp = /^ftdrill(\d+)-(\d+)/.exec(layer.odb_name)
var drl_star = tmp[1];
var drl_end = tmp[2];
layer.drl_start_num = drl_star;
layer.drl_end_num = drl_end;
layer.drl_from_num = drl_star;
layer.drl_to_num = drl_end;
if(drl_end - drl_star == 1){
layer.name = 'laser' + drl_star + '-' + drl_end;
layer.type = 'laser_drill'; // 镭射
} else if( drl_star == 1 || drl_end == layer_count ){
layer.name = 'drill' + drl_star + '-' + drl_end;
layer.type = 'blind_drill'; // 埋孔
} else{
layer.name = 'drill' + drl_star + '-' + drl_end;
layer.type = 'bury_drill'; // 盲孔
}
}
else if (/\-a$/.test(layer.odb_name)){
layer.side = 'top';
if(!layer.name){
layer.name = '__'+layer.odb_name+'__'
}
if(!layer.type){
layer.type = 'other'
}
}
else if (/\-b$/.test(layer.odb_name)){
layer.side = 'bottom';
if(!layer.name){
layer.name = '__'+layer.odb_name+'__'
}
if(!layer.type){
layer.type = 'other'
}
}
else{
if(!layer.name){
layer.name = '__'+layer.odb_name+'__'
}
if(!layer.type){
layer.type = 'other'
}
}
})
return matrix;
}
function save_drill_info(props){
var job = props.job
var step = props.step
var matrix_ = GEN.getMatrix({job:job});
var drill = [];
// 获取工作层
for (var key in matrix_) {
if(matrix_[key].context == "board" && matrix_[key].tl_type=="drill") {
drill.push(key)
}
}
var matrix = ANALYSIS_STACKUP({job:job});
var orgDrills = [];
var miDrills = [];
drill.forEach(function(drl) {
if(drl) {
var tool = GEN.getTool({job:job,step:step,layer:drl,units:PAR.unit});
Object.keys(tool).sort(function(a,b){return tool[a].num - tool[b].num}).forEach(function(num){
var toolInfo = tool[num]
var orgDrillInfo = {
job_id : JobId,
step_name : step,
step_type : props.step_type,
std_layer_name : matrix[drl].name,
odb_layer_name : drl,
row_num : num,
drill_size : toolInfo.finish_size / 1000,
finish_size : toolInfo.finish_size / 1000,
drill_type : toolInfo.type2 != 'standard' ? toolInfo.type2 : toolInfo.type,
drill_shape : toolInfo.shape,
count : toolInfo.count,
slot_length : toolInfo.slot_len,
drill_size_lower_tol : toolInfo.min_tol,
drill_size_upper_tol : toolInfo.max_tol
}
var miDrillInfo = {
job_id : JobId,
step_name : step,
step_type : props.step_type,
std_layer_name : matrix[drl].name,
odb_layer_name : drl,
row_num : num,
drill_size : toolInfo.drill_size / 1000,
finish_size : toolInfo.finish_size / 1000,
drill_type : toolInfo.type2 != 'standard' ? toolInfo.type2 : toolInfo.type,
drill_shape : toolInfo.shape,
count : toolInfo.count,
slot_length : toolInfo.slot_len,
drill_size_lower_tol : toolInfo.min_tol,
drill_size_upper_tol : toolInfo.max_tol
};
orgDrills.push(orgDrillInfo);
miDrills.push(miDrillInfo);
})
}
})
var func = 'function(ARGV)\
{\
var jobId = ARGV["job_id"];\
var data = ARGV["data"];\
var midata = ARGV["midata"];\
var stepName = ARGV["step_name"];\
var tableName = "pdm_job_" + ARGV["jobcategory"] + "_drill";\
//GUI.msgbox({text: TDataParse.variant2JsonStr(tableName)});\
//GUI.msgbox({detail: _.toString(ARGV["data"])});\
var db = new TSqlQueryV2(T_SQLCNT_POOL.getSqlDatabase());\
db.begin();\
try{\
var miData = [];\
var orgUidList = [];\
_.each(data, function(h){\
h.uid = TDataParse.getUuid();\
orgUidList.push(h.uid);\
});\
var i = 0;\
_.each(midata, function(n){\
n.uid = TDataParse.getUuid();\
var miMap = _.pick(n, ["job_id","std_layer_name","odb_layer_name","step_name","step_type","drill_size","finish_size","drill_type","drill_shape","drill_size_lower_tol","drill_size_upper_tol","slot_length"])\
miMap.uid = TDataParse.getUuid();\
if (n.step_type == "pcs") miMap.pcs_count = n.count;\
if (n.step_type == "array") miMap.array_count = n.count;\
miMap.calc_drill_size = n.drill_size;\
miMap.org_size = n.finish_size;\
miMap.org_slot_length = n.org_slot_length;\
miMap.org_size_upper_tol = n.drill_size_upper_tol;\
miMap.org_size_lower_tol = n.drill_size_lower_tol;\
miMap.org_uids = [orgUidList[i]];\
miData.push(miMap);\
i++;\
});\
db.deleteRow({table: "pdm_job_org_drill", where: {job_id: jobId}});\
db.batchInsert("pdm_job_org_drill", ["uid","job_id","step_name","step_type","std_layer_name","odb_layer_name","row_num","drill_size",\
"drill_type","drill_shape","count","slot_length","drill_size_lower_tol","drill_size_upper_tol"], data);\
if (ARGV["jobcategory"] == "mi") {\
db.deleteRow({table: "pdm_job_mi_drill", where: {job_id: jobId, step_name: stepName}});\
db.batchInsert("pdm_job_mi_drill", db.getFieldList("pdm_job_mi_drill"), miData);\
}\
if (db.lastError().isValid()) throw db.lastError();\
db.commit();\
return new TDataResponse();\
}\
catch (err)\
{\
GUI.msgbox({text: "Error", detail: _.toString(err.text())});\
db.rollback();\
return new TDataResponse(err, "");\
}\
}';
var ret = IKM.command( func,{job_id :JobId, data:orgDrills,midata:miDrills,jobcategory:props.jobcategory,step_name:step}, 1); // --work属性
if (ret.errText) {
return {
jobcategory:props.jobcategory,
errText : ret.errText,
errCode : ret.errCode,
};
}
}
function mkPath(path, list) {
if (list.length) {
var newPath = path + '/' + list.shift()
if (!fs.dirExists(newPath)) {fs.mkdir(newPath)}
return mkPath(newPath, list)
} else {
return path
}
}
function saveMeans(props){
var job = props.job
var custstep = props.step
var chklist = props.chklist
var nact = props.nact
var jobpath = GEN.getJobPath({job: job})
var filter = props.filter
var afterPath = mkPath(jobpath, ["user", "opencam", "steps"])
var steps;
if (custstep) {
steps = [custstep]
} else {
steps = GEN.getStepList({job: job})
}
if(!steps || steps.length==0){
return
}
steps.forEach(function (step) {
var chkPath = mkPath(afterPath, [step, "chk"])
var chks
if (chklist) {chks = [chklist]}else {
chks = GEN.getChecklist({job: job,step: step})
}
if(chks && chks.length){
chks.forEach(function (item, i) {
var afterChkPath = mkPath(chkPath, [item])
var hdr = "{\n\
\"title\": \"" + item + "\",\n\
\"sequence\": " + (i + 1) + "\n\
}"
fs.writeFile(afterChkPath + "/hdr", _.toString(hdr))
var nacts = []
if (nact) {
nacts = [nact]
} else {
var nactCount = GEN.getChklistActCount({job:job,step:step,chklist:item})
for (var i = 0; i < nactCount; i++) {
nacts.push(i+1)
}
}
if(nacts.length > 0){
var actionPath = mkPath(afterChkPath, ["actions"])
nacts.forEach(function(index){
var titleFile = GEN.INFO({
entity_type: "check",
entity_path: job + "/" + step + "/" + item,
data_type: "TITLE",
options: "action=" + index,
parse:'no'
})
var title = fs.readFile(titleFile)
title = title.split("=")[1].trim()
title = title.substring(1, title.length-1)
var nackPath = mkPath(actionPath, [index+"-"+title])
fs.writeFile(nackPath + "/hdr", "{\n\
\"title\": \"" + (index + "-" + title) + "\",\n\
\"sequence\": " + index + ",\n\
\"dfm_name\": \"" + title + "\"\n\
}")
var displayFile = GEN.INFO({
entity_type: 'check',
entity_path: job + "/" + step + "/" + item,
data_type: 'MEAS_DISP_ID',
options: "action=" + index,
parse:'no'
});
fs.writeFile(nackPath + "/disp", fs.readFile(displayFile))
var measFile = GEN.INFO({entity_type:'check', entity_path:job+'/'+step+'/'+item, data_type:'MEAS', options:"index+action="+index, parse:'no'});
var means
if(filter){ // 处理过滤
var fileArray = []
var file = fs.openFile(measFile,'r');
while(!file.atEnd()) {
fileArray.push(file.readLine())
}
if(Array.isArray(filter)){
var nowFilter = filter.filter(function(item2){
for (var key in item2) {
var value = item2[key]
if (!Array.isArray(value)){
item2[key] = [value]
}
}
return item2.step.indexOf(step)>=0 && item2.chk.indexOf(item)>=0 && item2.nact.indexOf(index)>=0
})
if (nowFilter.length > 0){
var nowfilter = nowFilter.map(function(v){return v.filter}).reduce(function(a,b){
b.forEach(function(v2){
if (a.indexOf(v2)<0){
a.push(v2)
}
})
return a
},[])
fileArray = fileArray.filter(function(line){
var flag = false
nowfilter.forEach(function(f){
var reg = new RegExp(f, "ig")
if (reg.test(line)){
flag = true
}
})
return flag
})
}
} else if (typeof filter == "object") {
if (filter[step] && filter[step][item] && filter[step][item][String(index)]) {
var nowFilter = filter[step][item][String(index)]
if (!Array.isArray(nowFilter)){nowFilter = [nowFilter]}
fileArray = fileArray.filter(function(line){
var flag = false
nowFilter.forEach(function(f){
var reg = new RegExp(f, "ig")
if (reg.test(line)){
flag = true
}
})
return flag
})
}
}
means = fileArray.join("\n")
} else {
means = fs.readFile(measFile)
}
fs.writeFile(nackPath + "/meas", means)
})
}
})
}
})
}