/* NAME: DESCRIPTION: 客户数据分析 PARAMETER: [ { name : 'step_filter', title : 'Step过滤', type : 'LineEdit', property : {tool_tip : '过滤step信息'} }, { name : 'erf', title : 'erf名称', type : 'LineEdit', property : {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 3-30 Scott HELP:

功能简介

客户数据分析


参数配置

客户参数

注意事项

● 无


*/ console.log("=============================================>anaysis_start"); // 引入模块 包 var $ = require('topcam.scriptfunc').argv(); var fs = require('fs'); var _ = require('lodash'); var JobId = $.job_id; var database = require("topsin.database"); database.addConnection($.conf.database_conf, "DFM"); var QDfm = database.query("DFM"); if ($.conf.product_type == "aimdfm") { QDfm.updateRow({ table: "pdm_aimdfm_task", data: { current_process_title: $.process_title }, where: { id: $.task_id } }); } var GEN = $.gen; var Job = $.job_name; var db = $.db; var Status = 'ok'; var resultData = []; var PAR = {}; if ($.hasOwnProperty('script_parameter')){ PAR = JSON.parse($.script_parameter); } try { var job = Job; var pcs_step = "cad", array_step = "stp"; var matrix = UPLOAD_LAYER_MATRIX({job:job}) // 分析matrix 获得分析后的matrix信息 console.log("===================================> 1matrix") var analysis_obj = analysis({job:job,jobId:JobId,pcs_step:pcs_step,array_step:array_step,matrix:matrix}) var config = { jobInfo: { layer_count: ["signal","power_ground"], // Board属性的signal或者power_ground层 vc_card_size_w: {api:"vc_card_size", props:"xsize"}, // card短边尺寸 // ? 保留小数 vc_card_size_l: {api:"vc_card_size", props:"ysize"}, // card长边尺寸 // ? 保留小数 vc_array_size_w: {api:"vc_array_size", props:"xsize"}, // ! array短边尺寸 需要arr_step // ? 保留小数 vc_array_size_l: {api:"vc_array_size", props:"ysize"}, // ! array长边尺寸 需要arr_step // ? 保留小数 vc_pcs_count_on_panel: true, // todo array中pcs的数量 ! 需要arr_step stack_vias_number: true, // via孔连续叠加的层数 stack_vias_more: {only_value:true}, // yes|no : 14层板以上时,Stack Vias >=12时,存yes // ! 需要分析完via连续叠加层数 depth_drilling: {api:"layer_exist", props:"depth_drill"}, // yes|no :存在depth_drill 层时 ,存yes depth_routing: {api:"layer_exist", props:"depth_routing"}, // tmp yes|no :存在depth_routing 层时,,存yes laser_via_on_buried_hole: true, // todo via孔在埋孔上时,存yes milling_bit_size: true, // todo 检查array中pcs的最小间距值 milling_length: true, // todo 检查array中铣切长度 vc_src_01005_pad_result: {api:"board_has_attr", props:".smd"}, // * yes|no:board 层中检查存在01005属性物件时,存yes 这里先拿.smd代替了 ATS_technology_25dc: {api:"layer_exist", props:"cavity"}, // yes|no:存在cavity层别时存yes ATS_technology_25dr: {api:"layer_exist", props:"cavity"}, // yes|no:存在cavity层别时存yes vc_src_EDGE_PLATING: true, // yes|no:检查线路外形是否存在物件,存在则存yes // !料号需要有rout层 edge_plating_length: true, // todo 检查线路外形处物件的长度 glod_finger: true, // todo yes|no:暂无逻辑 glod_finger_area: true, // todo 暂无逻辑 solder_mask_side: true, // top|bot|both:检查防焊层所在面次 silk_screen_side: true, // top|bot|both:检查文字层所在面次 min_drl_size: true, // todo 0.5mm 最小圆孔 max_pth_drl_size: true, // todo 3.5mm 最大pth圆孔 max_npth_drl_size: true, // todo 6.0mm 最大npth圆孔 min_slot_drl_size: true, // todo 0.8mm 最小槽孔 max_slot_drl_size: true, // todo 1.2mm 最大槽孔 max_slot_drl_length: true, // todo 2.0mm 最大槽孔 max_spec_slot_drl_size: true, // todo 2.1mm 最大异形槽孔 max_spec_slot_drl_length: true, // todo 3.0mm 最大异形槽孔 }, layerInfo: { } } console.log("===================================> 2analysis_obj") // 分析料号info var jobInfo = {} Object.keys(config.jobInfo).forEach(function(key){ var props = config.jobInfo[key]; if(props){ try { if(props.hasOwnProperty("api") && props.hasOwnProperty("props")){ jobInfo[key] = analysis_obj["analysis_"+props.api](props.props) } else if(props.only_value){ jobInfo[key] = analysis_obj.jobInfo[key] } else { jobInfo[key] = analysis_obj["analysis_"+key](props) } } catch (e) { console.log(e); jobInfo[key] = "_error" } } }) console.log("===================================> 3 jobinfo") // 过滤掉料号信息的 _todo 和 _error for (var key in jobInfo) { if(jobInfo[key] === "_todo" || jobInfo[key] === "_error"){ delete jobInfo[key] } } console.log("===================================> 4 save job info") // 上传jobInfo IKM版本 // IKM.save_job_info({ // jobid: JobId, // jobinfohash:jobInfo // }) // 上传jobInfo topjs3版本 save_job_info({ jobid: JobId, jobinfohash: jobInfo }) console.log("===================================> 5 save drill info") // todo 设置钻孔层孔属性,镭射孔via,无铜孔npth,其余孔pth // todo 上传钻孔信息 // 获取pcs_step 和 array_step的钻孔信息 var drill_info = {}; var drillLayers = analysis_obj.matrixInfo.mDrills; [pcs_step, array_step].forEach(function(step){ drill_info[step] = drill_info[step] || {}; drillLayers.forEach(function(layer){ var layer_tool_manager = GEN.getTool({job:job, step:step,layer:layer.name}) drill_info[step][layer.name] = layer_tool_manager }) }) var pcs_tool_manager = drill_info[pcs_step]; var array_tool_manager = drill_info[array_step]; Object.keys(pcs_tool_manager).forEach(function(layer){ Object.keys(pcs_tool_manager[layer]).forEach(function(key){ var tool = pcs_tool_manager[layer][key]; var array_count; if(array_tool_manager && array_tool_manager[layer] && array_tool_manager[layer][key]){array_count = array_tool_manager[layer][key].count} var data = { job_id: JobId, layer_name: layer, tool_num: key, tool_flag: key, tool_type: tool.shape, drill_type:tool.type, drill_size : tool.drill_size, drill_slot_length: tool.slot_len, finish_size : tool.finish_size, finish_slot_length: tool.slot_len, size_tol_lower: tool.min_tol, size_tol_upper: tool.max_tol, pcs_count: tool.count, array_count: array_count, // todo attr_data: {} // {"allowance": 2, "org_layer_name": "hhhh"} } if(!array_count){delete data.array_count} var id = db.query("",function(q){ return q.selectValue({ table:'pdm_job_cam_drill', field:"id", where:{job_id:JobId, layer_name: layer,tool_num: key} }) }); if(/done/ig.test(id)){ db.query("",function(q){ return q.insertRow({ table:'pdm_job_cam_drill', data:data, return_field:'id', }) }); }else{ db.query("",function(q){ return q.updateRow({ table:'pdm_job_cam_drill', where: {id:id}, data:data, update_policy:{tags:'array_append', attr_data:'json_merge'} }) }); } }) }) console.log("===================================> 6 layer info") // 分析layer info var stepList = [pcs_step]; var oChecklistName = "mychecklist" var signalLayers = analysis_obj.matrixInfo.mSignal.map(function(v){return v.name}) var drillLayers = analysis_obj.matrixInfo.mDrill.map(function(v){return v.name}) var info = { min_line_width: ["line"], min_line_spacing: ["l2l"], min_line2pad: ["p2line"], min_pad2pad: ["p2p", "smd2smd", "smd2pad"], min_ar: ["ar","pth_ar"] } stepList.forEach(function(step){ GEN.openStep({ job: job, name: step }) GEN.clearLayers() GEN.affectedLayer({ affected: 'no', mode: 'all' }) // 创建chklist并运行 如果chklist存在先删除 if (GEN.isChklistExists({ job: job, step: step, chklist: oChecklistName })) { GEN.COM("chklist_delete", { chklist: oChecklistName }) } createChklistAndRun({ // 创建checklist并运行 layers: signalLayers, items: [{ name: "signal_layer_checks", nact: 1, action: "valor_analysis_signal", erf: "S2_conductor_Check", params: { // ? pp_layer: ".affected", pp_spacing: 20, pp_selected: "All", pp_r2c: 10, pp_d2c: 15, pp_sliver: 8, pp_min_pad_overlap: 5, pp_check_missing_pads_for_drills: "Yes", pp_use_compensated_rout: "Skeleton", pp_sm_spacing: "Yes" } }] }) // signal层分析结果 var res = analysisChkAttr({layers:signalLayers, info:info, step:step, job:job, oChecklistName:oChecklistName}) // 铜面积 var copper_percent_pcs = signalLayers.map(function(v){ var tmp = {layer:v} tmp.copper_percent = GEN.copperArea({layer1:v}).percent + "%" return tmp }) // 钻孔 var drillToSignals = drillLayers.map(function(v){ // 获取到钻孔层对应的顶层和底层 var simbols = GEN.getLayerSymsHist({job:job,step:step,layer:v}) var symbol = _.values(simbols).sort(function(a,b){return Number(a.size)-Number(b.size)}) .reduce(function(a,b){ if(b.pad!="0"){ a.push(b.symbol) } return a },[])[0] return {layer:v,symbol:symbol,start:matrix[v]["drl_start"],end:matrix[v]["drl_end"]} }) var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果 // 数据入库 Object.keys(res).forEach(function(key){ var val = res[key] save_layerinfo({ jobid: JobId, layer: key, layerinfohash: val }) }) copper_percent_pcs.forEach(function(item){ save_layerinfo({ jobid: JobId, layer: item.layer, layerinfohash: { copper_percent: item.copper_percent } }) }) drillRes.forEach(function(item){ save_layerinfo({ jobid: JobId, layer: item.layer, layerinfohash: { drl_pad_top: item.drl_pad_top, drl_pad_bot: item.drl_pad_bot, } }) }) }) // smd var smdInfo = smdAnalysis({job:job,steplist:[pcs_step],layers:analysis_obj.matrixInfo.mOuters,attr:".smd"}) var save_info = [smdInfo, analysis_obj.jobInfo.laser_info]; // 保存 smd 和 bga数据 // 保存 console.log("===================================> save layer info") save_info.forEach(function(item){ Object.keys(item).forEach(function(key){ var val = item[key] save_layerinfo({ jobid: JobId, layer: key, layerinfohash: val }) }) }) 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 }; } } catch (e) { Status = 'error'; console.log("====================================>error"); console.log(_.toString(e)); resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]}); return {status: Status, result_data: resultData}; } function UPLOAD_LAYER_MATRIX(props){ var job = props.job props.jobcategory = props.jobcategory || "work" var matrix = ANALYSIS_STACKUP({job:job, jobcategory:props.jobcategory}); var func = 'function(ARGV)\ {\ var jobId = ARGV["job_id"];\ var tableName = "pdm_job_" + ARGV["jobcategory"] + "_layer";\ //GUI.msgbox({text: TDataParse.variant2JsonStr(tableName)});\ var db = new TSqlQueryV2(T_SQLCNT_POOL.getSqlDatabase());\ db.begin();\ try{\ var oLayers = db.selectMapMap({table:tableName, field:["odb_name","release_status"], where:{job_id:jobId}, uniquefield:"odb_name"});\ if (db.lastError().isValid()) throw db.lastError();\ //GUI.msgbox({text: TDataParse.variant2JsonStr(oLayers)});\ \ db.deleteRow({table:tableName, where:{job_id:jobId}});\ if (db.lastError().isValid()) throw db.lastError();\ \ 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"];\ \ for (var i=0;i0\ && ARGV["releasestatus"][layerInfo["odb_name"]] != undefined && ARGV["releasestatus"][layerInfo["odb_name"]] != null )\ {\ tmpData["release_status"] = ARGV["releasestatus"];\ }\ else\ {\ tmpData["release_status"] = 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]];\ }\ //GUI.msgbox({text: TDataParse.variant2JsonStr(tmpData)});\ db.insertRow({table:tableName, data:tmpData});\ if (db.lastError().isValid()) throw db.lastError();\ }\ db.commit();\ return new TDataResponse();\ }\ catch (err)\ {\ print(err.text());\ db.rollback();\ return new TDataResponse(err, "");\ }\ }'; // var ret = IKM.command( func, // ?? =========================> tmp // { job_id :JobId, // matrix:matrix, // layers: Object.keys(matrix).sort(function(a,b){return matrix[a]["row"] - matrix[b]["row"]}), // jobcategory:props.jobcategory}, 1); // if (ret.errText) { // return { // jobcategory:props.jobcategory, // errText :ret.errText, // errCode :ret.errCode, // }; // } 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 = IKM.get_jobinfo({jobname:JobId,jobcategory:props.jobcategory,jobinfo:'layer_count'}); if(!layer_count){ 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 == 'drill'){ 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 (/^d_(\d+)\-(\d+)$/.test(layer.odb_name)){ var tmp = /^d(\d+)\-(\d+)$/.exec(layer.odb_name) var drl_star = tmp[1]; var drl_end = tmp[2]; layer.name = 'drill' + drl_star + '-' + drl_end; 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_star == 1 || drl_end == layer_count ){ layer.type = 'blind_drill'; // 埋孔 } else{ layer.type = 'bury_drill'; // 盲孔 } } else if (/^d(\d+)\-(\d+)$/.test(layer.odb_name)){ var tmp = /^d(\d+)\-(\d+)$/.exec(layer.odb_name) var drl_star = tmp[1]; var drl_end = tmp[2]; layer.name = 'd'+drl_star+'-'+drl_end; layer.drl_start_num = drl_star; layer.drl_end_num = drl_end; layer.drl_from_num = drl_star; layer.drl_to_num = drl_end; layer.type = 'laser_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 getMatrixInfo(props){ // 获取matrix各种信息 var job = props.job var matrix = GEN.getMatrix({job:job}) var res = { matrix: matrix, // matrix matrixVal: [], // matrix 的 value数组 mSignal: {}, // board的signal层 {} mSignals: [], // board的signal层 [] mDrill: {}, // board的drill层 mDrills: [], // board的drill层 mSolderMask: {}, // 防焊层 mSolderMasks: [], // 防焊层 mOuters: [], // 外层和对于的防旱 mBoardLayer: [] // board层 } for (var key in matrix) { var value = matrix[key] res.matrixVal.push(value) if(value.context == "board"){ res.mBoardLayer.push(key) switch (value.layer_type) { case "signal": res.mSignal[key] = value res.mSignals.push(value) break; case "drill": res.mDrill[key] = value res.mDrills.push(value) break; case "solder_mask": res.mSolderMask[key] = value res.mSolderMasks.push(value) break; } } } res.matrixVal = res.matrixVal.sort(function(a,b){return Number(a.row) - Number(b.row)}) res.mSignals = res.mSignals.sort(function(a,b){return Number(a.row) - Number(b.row)}) res.mDrills = res.mDrills.sort(function(a,b){return Number(a.row) - Number(b.row)}) // 找出外层 以及外层对应的防焊层 [{signalL:"top", solderL:"smt"}] res.mOuters = res.mSignals.reduce(function(a,b){ if(b.tl_type == "outer"){ var solderLayers = res.mSolderMasks.filter(function(v){ return v.side == b.side }) a.push({ signalL: b.name, solderL: solderLayers.length >0 ? solderLayers[0]["name"] : null }) } return a },[]) return res } function selCopyLayer(props){ // 拷贝选择的到辅助层 var layer = props.layer var job = props.job if(GEN.isLayerExists({job:job,layer:layer})){ GEN.deleteLayer({job:job,layer:layer}) } GEN.selCopyOther({dest:'layer_name',target_layer:layer}) } function save_job_info(props){ // todo 保存料号信息 var jobid = props.jobid; var jobinfohash = props.jobinfohash; Object.keys(jobinfohash).forEach(function(key){ var val = jobinfohash[key]; db.query("",function(q){ return q.insertRow({ table:'sys_user', // todo data:{jobid:jobid, todo:key, value:val}, // todo return_field:'id', }) }); }) } function save_layerinfo(props){ // todo 保存层信息 var jobid = props.jobid; var layer = props.layer; var layerinfohash = props.layerinfohash; Object.keys(layerinfohash).forEach(function(key){ var val = layerinfohash[key]; db.query("",function(q){ return q.insertRow({ table:'sys_user', // todo data:{jobid:jobid, layer:layer,key:key , value:val}, // todo return_field:'id', }) }); }) } function analysis(props){ var job = props.job || Job; var jobId = props.jobId || JobId; var pcs_step = props.pcs_step || false; var array_step = props.array_step || false; var matrix = props.matrix; function T_m_p(props){ this.job = props.job; this.jobInfo = {}; this.jobId = props.jobId; if(props.pcs_step){ this.pcs_step = props.pcs_step; } if(props.matrix){ this.matrix = props.matrix; } if(props.array_step){ this.array_step = props.array_step; } this.matrixInfo = getMatrixInfo({job:this.job}) this.init(); } T_m_p.prototype.init = function(){ var init_checking = ["job", "jobId", "pcs_step", "matrix"]; var t = this; init_checking.forEach(function(v){ if(!t[v]){t.e(v+" is undefined")} }) } T_m_p.prototype.e = function(e){ // 处理error console.log(e) throw e } T_m_p.prototype.analysis_layer_count = function(props){ // 分析board属性的层数量 []string var matrix = this.matrixInfo.matrixVal; var res = matrix.filter(function(v){return v.context == "board" && props.indexOf(v.layer_type) >= 0 }) return res.length } T_m_p.prototype.analysis_vc_card_size = function(props){ // card短边尺寸 string return GEN.getProfileLimits({job:this.job,step:this.pcs_step})[props].toFixed(3) } T_m_p.prototype.analysis_vc_array_size = function(props){ // array长边尺寸 string if(!this.array_step){return "error"} return GEN.getProfileLimits({job:this.job,step:this.array_step})[props].toFixed(3) } T_m_p.prototype.analysis_vc_pcs_count_on_panel = function(props){ // return "_todo" } T_m_p.prototype.analysis_stack_vias_number = function(props){ // via孔连续叠加的层数 var t = this; var res; // 找出 镭射孔 var laser_layers = [] for (var key in t.matrix) { var val = t.matrix[key] if(val.type == "laser_drill"){ laser_layers.push(val) } } if(laser_layers.length == 0){return "error"} GEN.openStep({job:t.job,name:t.pcs_step}) laser_layers = laser_layers.sort(function(a,b){return Number(a.row)-Number(b.row)}) var laser_info = {} for(var i = 0; i < laser_layers.length-1; i++){ var start_layer = laser_layers[i].name var cover_layer = laser_layers[i+1].name GEN.workLayer({name:start_layer,display_number:2,clear_before:'yes'}) GEN.selClearFeature() GEN.selRefFeat({layers:cover_layer,use:'filter',mode:'cover'}) var count = GEN.getSelectCount() if(count>0){ if(!laser_info[start_layer]){ laser_info[start_layer] = {} } laser_info[start_layer].drill_connect_layer = cover_layer laser_info[start_layer].drill_connect_point = count } } // via孔连续叠加的层数 var via_vias_info = [] function analysis_via_number(layers){ if(layers.length < 2){return} var startlayer = layers[0].name + "_cover" GEN.selClearFeature() GEN.workLayer({name:layers[0].name,display_number:2,clear_before:'yes'}) GEN.selAllFeat() selCopyLayer({job:t.job,layer:startlayer}) var end_index = start_cover_next(startlayer,layers,0) via_vias_info.push(end_index+1) analysis_via_number(layers.slice(end_index)) } function start_cover_next(start, layers, end_index){ if(layers.length < 2){ GEN.deleteLayer({job:t.job,layer:start}) return end_index } layers = layers.slice(1) GEN.workLayer({name:start,display_number:2,clear_before:'yes'}) GEN.selClearFeature() GEN.selRefFeat({layers:layers[0].name,use:'filter',mode:'cover'}) var count = GEN.getSelectCount() if (count < 1) { GEN.deleteLayer({job:t.job,layer:start}) return ++end_index } var nextstartlayer = layers[0].name + "_cover" selCopyLayer({job:t.job,layer:nextstartlayer}) GEN.deleteLayer({job:t.job,layer:start}) return start_cover_next(nextstartlayer,layers,++end_index) } analysis_via_number(laser_layers.slice()) if (via_vias_info.length == 1){ res = via_vias_info[0] }else{ res = via_vias_info.reduce(function(a,b){return a-b>0?a :b}) } t.jobInfo.stack_vias_more = "no" if(GEN.getLayerCount({job:t.job}) > 14 && res >= 12){ t.jobInfo.stack_vias_more = "yes" } t.jobInfo.laser_info = laser_info; return res } T_m_p.prototype.analysis_layer_exist = function(props){ // 存在某某层? string return this.matrixInfo.matrix.hasOwnProperty(props) ? "yes" : "no" } T_m_p.prototype.analysis_laser_via_on_buried_hole = function(){ // todo return "_todo" } T_m_p.prototype.analysis_milling_bit_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_milling_length = function(){ // todo return "_todo" } T_m_p.prototype.analysis_board_has_attr = function(props){ // board层中检查存在01005属性物件时 GEN.openStep({job:this.job,name:this.pcs_step}) GEN.clearLayers() GEN.affectedLayer({affected:'yes',layer:this.matrixInfo.mBoardLayer,clear_before:'yes'}); GEN.selClearFeature() GEN.selectByFilter({attribute:props}) var res = GEN.getSelectCount() > 0? "yes" : "no" GEN.affectedLayer({affected:'no',mode:'all'}); GEN.selClearFeature() GEN.closeStep() return res } T_m_p.prototype.analysis_vc_src_EDGE_PLATING = function(props){ // ? 检查线路外形是否存在物件,存在则存yes var res = "no" var rout = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "rout"}) // 找rout层 if(rout.length == 0){ return "error:cant find rout layer" } GEN.openStep({job:this.job, name:this.pcs_step}) GEN.affectedLayer({affected:'no',mode:'all'}) try { this.matrixInfo.mSignals.forEach(function(v){ // 用线路层逐层与rout层touch 找得到说明存在 GEN.workLayer({name:v.name,display_number:2,clear_before:'yes'}) GEN.selClearFeature() GEN.selRefFeat({layers:rout[0].name,mode:"touch",use:"filter"}) if( GEN.getSelectCount()>0){ throw "yes" } GEN.clearLayers() }) } catch (msg) { res = msg GEN.affectedLayer({affected:'no',mode:'all'}) GEN.selClearFeature() } GEN.closeStep() return res } T_m_p.prototype.analysis_edge_plating_length = function(){ // todo return "_todo" } T_m_p.prototype.analysis_glod_finger = function(){ // todo return "_todo" } T_m_p.prototype.analysis_glod_finger_area = function(){ // todo return "_todo" } T_m_p.prototype.analysis_solder_mask_side = function(){ // 检查防焊层所在面次 var solder_paste_layers = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "solder_paste"}) var solder_paste_info= solder_paste_layers.map(function(v){return v.side}).reduce(function(a,b){ if(a.indexOf(b)<0){ a.push(b) } return a },[]) var res = "no" if(solder_paste_info.length == 0){ res = "no" } else if (solder_paste_info.length == 1) { res = /top/ig.test(solder_paste_info[0]) ? "top" : "bot" } else { res = "both" } return res } T_m_p.prototype.analysis_silk_screen_side = function(){ // 检查文字层所在面次 var solder_mask_layers = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "solder_mask"}) var solder_mask_info= solder_mask_layers.map(function(v){return v.side}).reduce(function(a,b){ if(a.indexOf(b)<0){ a.push(b) } return a },[]) var res = "no" if(solder_mask_info.length == 0){ res = "no" } else if (solder_mask_info.length == 1) { res = /top/ig.test(solder_mask_info[0]) ? "top" : "bot" } else { res = "both" } return res } T_m_p.prototype.analysis_min_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_pth_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_npth_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_min_slot_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_slot_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_slot_drl_length = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_spec_slot_drl_size = function(){ // todo return "_todo" } T_m_p.prototype.analysis_max_spec_slot_drl_length = function(){ // todo return "_todo" } return new T_m_p({job:job, jobId:jobId, pcs_step:pcs_step, array_step:array_step,matrix:matrix}) } function smdAnalysis(props){ var job = props.job var steplist = props.steplist var layers = props.layers var res = {} steplist.forEach(function(step){ GEN.openStep({job:job,step:step}) layers.forEach(function(layer){ // 计算开窗 数量 GEN.workLayer({name:layer.solderL,display_number:2,clear_before:'yes'}) if (!res.hasOwnProperty(layer.solderL)){ res[layer.solderL] = {} } GEN.selectByFilter({profile:'in'}) GEN.selAllFeat() res[layer.solderL].sm_opening_count = GEN.getSelectCount() GEN.selClearFeature() // 分析最小smd宽高 GEN.workLayer({name:layer.signalL,display_number:2,clear_before:'yes'}) GEN.selClearFeature() GEN.selectByFilter({attribute:props.attr}) var selCount = GEN.getSelectCount() if(selCount>0){ var tmp_layer = layer.signalL + "_tmp" selCopyLayer({job:job,layer:tmp_layer}) var symbols = GEN.getLayerSymsHist({job:job,layer:tmp_layer,step:step}) GEN.workLayer({name:tmp_layer,display_number:2,clear_before:'yes'}) var symbolInfo = symbolAnalysis({symbols:symbols,filterReg:/^rect/}) if (!res.hasOwnProperty(layer.signalL)){ res[layer.signalL] = {} } res[layer.signalL]["min_smd_width"] = symbolInfo["min_width"] res[layer.signalL]["min_smd_length"] = symbolInfo["min_length"] // 分析最小smd间距 // 创建一个checklist并且分析 var min_smd_pitch = smdPitch({job:job,step:step,layer:tmp_layer}) res[layer.signalL]["min_smd_pitch"] = min_smd_pitch // 分析开窗宽高 GEN.workLayer({name:layer.solderL,display_number:2,clear_before:'yes'}) GEN.selClearFeature() GEN.selRefFeat({layers:tmp_layer,use:'filter',mode:'include'}) GEN.selRefFeat({layers:tmp_layer,use:'filter',mode:'cover'}) var solderL_tmp = layer.solderL + "_tmp" selCopyLayer({job:job,layer:solderL_tmp}) GEN.selClearFeature() GEN.workLayer({name:solderL_tmp,display_number:2,clear_before:"yes"}) var symbols_solder = GEN.getLayerSymsHist({job:job,layer:solderL_tmp,step:step}) var symbolInfo_solder = symbolAnalysis({symbols:symbols_solder,filterReg:/^rect/}) res[layer.signalL].min_smd_opening_width = symbolInfo_solder["min_width"] res[layer.signalL].min_smd_opening_length = symbolInfo_solder["min_length"] GEN.deleteLayer({job:job,layer:solderL_tmp}) GEN.deleteLayer({job:job,layer:tmp_layer}) } }) GEN.closeStep() }) return res } function symbolAnalysis(props){ var symbols = Object.keys(props.symbols).reduce(function(a,b){ if(props.filterReg.test(b)){ var res = /^rect(\d+\.\d+|\d+)x(\d+\.\d+|\d+)/ig.exec(b).slice(1) var num1 = res[0], num2 = res[1] if(num1<=num2){ a.width.push(num1) a.length.push(num2) } else { a.width.push(num2) a.length.push(num1) } } return a },{width:[],length:[]}) return { min_width:symbols.width.reduce(function(a,b){return b-a > 0 ? a : b}), min_length:symbols.length.reduce(function(a,b){return b-a > 0 ? a : b}) } } function smdPitch(props){ var job = props.job var step = props.step var layer = props.layer var ck = "tmp_chk" if(GEN.isChklistExists({job:job,step:step,chklist:ck})){ GEN.COM("chklist_delete", { chklist: ck }) } // 创建并运行 GEN.createChklist({ // 创建checklist chklist: ck, items: [{ name: "smdPitch", nact: 1, action: "valor_analysis_signal", erf: "S2_conductor_Check", params: { pp_layer: ".affected", pp_spacing: 20, pp_selected: "All", pp_r2c: 10, pp_d2c: 15, pp_sliver: 8, pp_min_pad_overlap: 5, pp_check_missing_pads_for_drills: "Yes", pp_use_compensated_rout: "Skeleton", pp_sm_spacing: "Yes", pp_tests: "Spacing\\;SMD", pp_check_missing_pads_for_drills:"Yes" } }] }) GEN.chklistShow({ chklist: ck }) GEN.affectedLayer({ affected: "yes", layer: layer, clear_before: "yes" }) GEN.chklistRun({ chklist: ck, nact: 1, area: 'profile' }) var tmp_layer1 = "mk_1_"+layer+"_pitch" var tmp_layer2 = "ms_1_"+layer+"_pitch" if(GEN.isLayerExists({job:job,layer:tmp_layer1})){ GEN.deleteLayer({job:job,layer:tmp_layer1}) } if(GEN.isLayerExists({job:job,layer:tmp_layer2})){ GEN.deleteLayer({job:job,layer:tmp_layer2}) } GEN.COM("chklist_create_lyrs,chklist="+ck+",severity=3,suffix=pitch"); GEN.workLayer({name:tmp_layer2,display_number:1,clear_before:'yes'}); GEN.selectByFilter({attribute:[{attribute:".string",text:"smd_pitch"}]}) var tmp_layer = tmp_layer2 + "_tmp" selCopyLayer({job:job,layer:tmp_layer}) GEN.workLayer({name:tmp_layer,display_number:1,clear_before:'yes'}); var symbols = GEN.getLayerSymsHist({job:job,layer:tmp_layer,step:step}) // 获取最小smd间距 var res = _.values(symbols).sort(function(a,b){return Number(a.size)-Number(b.size)})[0].size GEN.deleteLayer({job:job,layer:tmp_layer}) GEN.deleteLayer({job:job,layer:tmp_layer1}) GEN.deleteLayer({job:job,layer:tmp_layer2}) return res } function createChklistAndRun(par) { var checkLayers = par.layers var items = par.items GEN.createChklist({ // 创建checklist chklist: oChecklistName, items: items }) GEN.chklistShow({ chklist: oChecklistName }) GEN.affectedLayer({ affected: "yes", layer: checkLayers, clear_before: "yes" }) items.forEach(function(v){ GEN.chklistRun({ chklist: oChecklistName, nact: v.nact, area: 'profile' }) }) } function analysisChkAttr(par) { var layers = par.layers; var hash = {}; var info = par.info; var job = par.job; var oChecklistName = par.oChecklistName layers.forEach(function (v) { hash[v] = {} Object.keys(info).forEach(function (key) { var val = info[key] hash[v][key] = val.reduce(function (a, type) { var tmp = GEN.getCheckAttr({ job: job, step: par.step, checklist: oChecklistName, nact: 1, attr: v + "_min_" + type }) if (a === "N/A" && /\d+/.test(tmp)) { a = tmp } if (/\d+/.test(a) && /\d+/.test(tmp) && Number(tmp) < Number(a)) { a = tmp } return a }, "N/A") }) }) return hash } function analysisDrill(par, step){ // {"layer":"d1-2","symbol":"r3.937","start":"top","end":"isl2"} var res = par.map(function(drill){ GEN.affectedLayer({affected:"yes",layer:drill.layer,clear_before:"yes",mode:"all"}) GEN.selClearFeature() GEN.selectByFilter({feat_types:"pad",include_syms:drill.symbol}) // 拷贝到_tmp var tmplayer = drill.layer + "_tmp" if(GEN.isLayerExists({job:Job,layer:tmplayer})){GEN.deleteLayer({job:Job,step:step,layer:tmplayer})} GEN.selCopyOther({dest:"layer_name",target_layer:tmplayer,invert:'no',dx:0,dy:0,size:0}) GEN.affectedLayer({affected:"no",mode:"all"}) GEN.selClearFeature(); [drill.start,drill.end].forEach(function(item, i){ GEN.workLayer({name:item,display_number:1,clear_before:"yes"}) GEN.selRefFeat({ layers: tmplayer, use: "filter", mode: "include", f_types: "pad", pads_as:"shape", polarity:"positive", include_syms:drill.symbol, filter: { feat_types:'pad' } }) var res = "" var pads = GEN.getFeatures({job:Job,step:step,layer:item,options:"select"}) if(pads && pads.length) { pads = pads.filter(function(item){ return /^r\d+/.test(item.symbol) }) pads = pads.sort(function(a,b){ return parseInt(a.symbol) - parseInt(b.symbol) }) res = pads[0].symbol.slice(1) } if ( i == 0) { drill.drl_pad_top = res } else if (i==1){ drill.drl_pad_bot = res } }) GEN.deleteLayer({job:Job,step:step,layer:tmplayer}) return drill }) return res } function tmp(){ return { "sst": { "row": "1","type": "solder_paste","name": "sp_fr","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": -1000,"tl_name": "sp_fr","tl_type": "solder_paste","odb_name": "sst","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "top", "row_num": -1000,"odb_row_num": "1" }, "spt": { "row": "2","type": "solder_paste","name": "sp_fr(2)","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": -999,"tl_name": "sp_fr(2)","tl_type": "solder_paste","odb_name": "spt","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "top", "row_num": -999,"odb_row_num": "2" }, "smt": { "row": "3","type": "solder_mask","name": "sm_fr","context": "board","layer_type": "solder_mask","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": -998,"tl_name": "sm_fr","tl_type": "solder_mask","odb_name": "smt","odb_context": "board","odb_type": "solder_mask","odb_polarity": "positive","odb_side": "top", "row_num": -998,"odb_row_num": "3" }, "top": { "row": "4","type": "outer","name": "top","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 1,"tl_name": "top","tl_type": "outer","odb_name": "top","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "top", "row_num": 1,"odb_row_num": "4" }, "isl2": { "row": "5","type": "inner","name": "l2","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 2,"tl_name": "l2","tl_type": "inner","odb_name": "isl2","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 2,"odb_row_num": "5" }, "isl3": { "row": "6","type": "inner","name": "l3","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 3,"tl_name": "l3","tl_type": "inner","odb_name": "isl3","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 3,"odb_row_num": "6" }, "isl4": { "row": "7","type": "inner","name": "l4","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 4,"tl_name": "l4","tl_type": "inner","odb_name": "isl4","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 4,"odb_row_num": "7" }, "isl5": { "row": "8","type": "inner","name": "l5","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 5,"tl_name": "l5","tl_type": "inner","odb_name": "isl5","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 5,"odb_row_num": "8" }, "isl6": { "row": "9","type": "inner","name": "l6","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 6,"tl_name": "l6","tl_type": "inner","odb_name": "isl6","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 6,"odb_row_num": "9" }, "isl7": { "row": "10","type": "inner","name": "l7","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 7,"tl_name": "l7","tl_type": "inner","odb_name": "isl7","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 7,"odb_row_num": "10" }, "isl8": { "row": "11","type": "inner","name": "l8","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 8,"tl_name": "l8","tl_type": "inner","odb_name": "isl8","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 8,"odb_row_num": "11" }, "isl9": { "row": "12","type": "inner","name": "l9","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 9,"tl_name": "l9","tl_type": "inner","odb_name": "isl9","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner", "row_num": 9,"odb_row_num": "12" }, "bottom": { "row": "13","type": "outer","name": "bottom","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 10,"tl_name": "bottom","tl_type": "outer","odb_name": "bottom","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "bottom", "row_num": 10,"odb_row_num": "13" }, "smb": { "row": "14","type": "solder_mask","name": "sm_ba","context": "board","layer_type": "solder_mask","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 1013,"tl_name": "sm_ba","tl_type": "solder_mask","odb_name": "smb","odb_context": "board","odb_type": "solder_mask","odb_polarity": "positive","odb_side": "bottom", "row_num": 1013,"odb_row_num": "14" }, "spb": { "row": "15","type": "solder_paste","name": "sp_ba","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 1014,"tl_name": "sp_ba","tl_type": "solder_paste","odb_name": "spb","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "bottom", "row_num": 1014,"odb_row_num": "15" }, "ssb": { "row": "16","type": "solder_paste","name": "sp_ba(2)","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 1015,"tl_name": "sp_ba(2)","tl_type": "solder_paste","odb_name": "ssb","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "bottom", "row_num": 1015,"odb_row_num": "16" }, "d1-2": { "row": "17","type": "laser_drill","name": "d1-2","context": "board","layer_type": "drill","polarity": "positive","drl_start": "top", "drl_end": "isl2","gdrl_start": "top","gdrl_end": "isl2","drl_start_num": "1","drl_end_num": "2","tl_name": "drill1-2","tl_type": "drill", "tl_num": 10016,"odb_name": "d1-2","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10016,"odb_row_num": "17","drl_from_num": "1","drl_to_num": "2" }, "d2-3": { "row": "18","type": "laser_drill","name": "d2-3","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl2","drl_end": "isl3","gdrl_start": "isl2","gdrl_end": "isl3","drl_start_num": "2","drl_end_num": "3","tl_name": "drill2-3","tl_type": "drill", "tl_num": 10017,"odb_name": "d2-3","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10017,"odb_row_num": "18","drl_from_num": "2","drl_to_num": "3" }, "d3-4": { "row": "19","type": "laser_drill","name": "d3-4","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl3","drl_end": "isl4","gdrl_start": "isl3","gdrl_end": "isl4","drl_start_num": "3","drl_end_num": "4","tl_name": "drill3-4","tl_type": "drill", "tl_num": 10018,"odb_name": "d3-4","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10018,"odb_row_num": "19","drl_from_num": "3","drl_to_num": "4" }, "d4-5": { "row": "20","type": "laser_drill","name": "d4-5","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl4","drl_end": "isl5","gdrl_start": "isl4","gdrl_end": "isl5","drl_start_num": "4","drl_end_num": "5","tl_name": "drill4-5","tl_type": "drill", "tl_num": 10019,"odb_name": "d4-5","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10019,"odb_row_num": "20","drl_from_num": "4","drl_to_num": "5" }, "d5-6": { "row": "21","type": "laser_drill","name": "d5-6","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl5","drl_end": "isl6","gdrl_start": "isl5","gdrl_end": "isl6","drl_start_num": "5","drl_end_num": "6","tl_name": "drill5-6","tl_type": "drill", "tl_num": 10020,"odb_name": "d5-6","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10020,"odb_row_num": "21","drl_from_num": "5","drl_to_num": "6" }, "d6-7": { "row": "22","type": "laser_drill","name": "d6-7","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl6","drl_end": "isl7","gdrl_start": "isl6","gdrl_end": "isl7","drl_start_num": "6","drl_end_num": "7","tl_name": "drill6-7","tl_type": "drill", "tl_num": 10021,"odb_name": "d6-7","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10021,"odb_row_num": "22","drl_from_num": "6","drl_to_num": "7" }, "d7-8": { "row": "23","type": "laser_drill","name": "d7-8","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl7","drl_end": "isl8","gdrl_start": "isl7","gdrl_end": "isl8","drl_start_num": "7","drl_end_num": "8","tl_name": "drill7-8","tl_type": "drill", "tl_num": 10022,"odb_name": "d7-8","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10022,"odb_row_num": "23","drl_from_num": "7","drl_to_num": "8" }, "d8-9": { "row": "24","type": "laser_drill","name": "d8-9","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl8","drl_end": "isl9","gdrl_start": "isl8","gdrl_end": "isl9","drl_start_num": "8","drl_end_num": "9","tl_name": "drill8-9","tl_type": "drill", "tl_num": 10023,"odb_name": "d8-9","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10023,"odb_row_num": "24","drl_from_num": "8","drl_to_num": "9" }, "d9-10": { "row": "25","type": "laser_drill","name": "d9-10","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl9","drl_end": "bottom","gdrl_start": "isl9","gdrl_end": "bottom","drl_start_num": "9","drl_end_num": "10","tl_name": "drill9-10","tl_type": "drill", "tl_num": 10024,"odb_name": "d9-10","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10024,"odb_row_num": "25","drl_from_num": "9","drl_to_num": "10" }, "drill": { "row": "26","type": "main_drill","name": "drill","context": "board","layer_type": "drill","polarity": "positive","drl_start": "top","drl_end": "bottom","gdrl_start": "top","gdrl_end": "bottom","drl_start_num": 1,"drl_end_num": 10,"tl_name": "drill","tl_type": "drill", "tl_num": 10025,"odb_name": "drill","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none", "row_num": 10025,"odb_row_num": "26","drl_from_num": 1,"drl_to_num": 10 }, "rout": { "row": "27","type": "other","name": "__rout__","context": "board","layer_type": "rout","polarity": "positive","drl_start": "top","drl_end": "bottom","gdrl_start": "top","gdrl_end": "bottom","odb_name": "rout","odb_context": "board","odb_type": "rout","odb_polarity": "positive","odb_side": "none","odb_row_num": "27" }, "nclegend-1-2": { "row": "28","type": "other","name": "__nclegend-1-2__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110027,"odb_name": "nclegend-1-2","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110027,"odb_row_num": "28" }, "nclegend-2-3": { "row": "29","type": "other","name": "__nclegend-2-3__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110028,"odb_name": "nclegend-2-3","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110028,"odb_row_num": "29" }, "nclegend-3-4": { "row": "30","type": "other","name": "__nclegend-3-4__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110029,"odb_name": "nclegend-3-4","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110029,"odb_row_num": "30" }, "nclegend-4-5": { "row": "31","type": "other","name": "__nclegend-4-5__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110030,"odb_name": "nclegend-4-5","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110030,"odb_row_num": "31" }, "nclegend-5-6": { "row": "32","type": "other","name": "__nclegend-5-6__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110031,"odb_name": "nclegend-5-6","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110031,"odb_row_num": "32" }, "nclegend-6-7": { "row": "33","type": "other","name": "__nclegend-6-7__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110032,"odb_name": "nclegend-6-7","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110032,"odb_row_num": "33" }, "nclegend-7-8": { "row": "34","type": "other","name": "__nclegend-7-8__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110033,"odb_name": "nclegend-7-8","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110033,"odb_row_num": "34" }, "nclegend-8-9": { "row": "35","type": "other","name": "__nclegend-8-9__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110034,"odb_name": "nclegend-8-9","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110034,"odb_row_num": "35" }, "nclegend-9-10": { "row": "36","type": "other","name": "__nclegend-9-10__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110035,"odb_name": "nclegend-9-10","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110035,"odb_row_num": "36" }, "nclegend-1-10": { "row": "37","type": "other","name": "__nclegend-1-10__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110036,"odb_name": "nclegend-1-10","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110036,"odb_row_num": "37" }, "outline": { "row": "38","type": "other","name": "__outline__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110037,"odb_name": "outline","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110037,"odb_row_num": "38" }, "top_assem": { "row": "39","type": "other","name": "__top_assem__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110038,"odb_name": "top_assem","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110038,"odb_row_num": "39" }, "bot_assem": { "row": "40","type": "other","name": "__bot_assem__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110039,"odb_name": "bot_assem","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110039,"odb_row_num": "40" }, "top_testpoint": { "row": "41","type": "other","name": "__top_testpoint__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110040,"odb_name": "top_testpoint","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110040,"odb_row_num": "41" }, "bot_testpoint": { "row": "42","type": "other","name": "__bot_testpoint__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110041,"odb_name": "bot_testpoint","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110041,"odb_row_num": "42" }, "top_osp": { "row": "43","type": "other","name": "__top_osp__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110042,"odb_name": "top_osp","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110042,"odb_row_num": "43" }, "bot_osp": { "row": "44","type": "other","name": "__bot_osp__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110043,"odb_name": "bot_osp","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110043,"odb_row_num": "44" }, "top_enig": { "row": "45","type": "other","name": "__top_enig__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110044,"odb_name": "top_enig","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110044,"odb_row_num": "45" }, "bot_enig": { "row": "46","type": "other","name": "__bot_enig__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110045,"odb_name": "bot_enig","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110045,"odb_row_num": "46" }, "fab_page2": { "row": "47","type": "other","name": "__fab_page2__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110046,"odb_name": "fab_page2","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none", "row_num": 110046,"odb_row_num": "47" }, "tmp_top_shorts": { "row": "48","type": "other","name": "__tmp_top_shorts__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110047,"odb_name": "tmp_top_shorts","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none", "row_num": 110047,"odb_row_num": "48" }, "tmp_bot_shorts": { "row": "49","type": "other","name": "__tmp_bot_shorts__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110048,"odb_name": "tmp_bot_shorts","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none", "row_num": 110048,"odb_row_num": "49" }, "bot_assy_mate": { "row": "50","type": "other","name": "__bot_assy_mate__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110049,"odb_name": "bot_assy_mate","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none", "row_num": 110049,"odb_row_num": "50" }, "outline+1": { "row": "51","type": "other","name": "__outline+1__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110050,"odb_name": "outline+1","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none", "row_num": 110050,"odb_row_num": "51" }, "top_assy_mate": { "row": "52","type": "other","name": "__top_assy_mate__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "", "tl_num": 110051,"odb_name": "top_assy_mate","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none", "row_num": 110051,"odb_row_num": "52" } } } function tmp_2(){ return { "cad": { "d1-2": { "1": { "count": "06896", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d2-3": { "1": { "count": "07430", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d3-4": { "1": { "count": "06866", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d4-5": { "1": { "count": "06413", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d5-6": { "1": { "count": "08938", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d6-7": { "1": { "count": "09057", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d7-8": { "1": { "count": "07818", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d8-9": { "1": { "count": "09126", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "d9-10": { "1": { "count": "08498", "num": "1", "type": "via", "min_tol": "2.756", "max_tol": "0.984", "finish_size": "2.756", "drill_size": "2.756", "slot_len": "0", "type2": "laser", "shape": "hole", "bit": 0 } }, "drill": { "1": { "count": "05", "num": "1", "type": "non_plated", "min_tol": "3.15", "max_tol": "3.15", "finish_size": "15.748", "drill_size": "15.748", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "2": { "count": "01", "num": "2", "type": "non_plated", "min_tol": "0", "max_tol": "1.969", "finish_size": "35.039", "drill_size": "35.039", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "3": { "count": "01", "num": "3", "type": "non_plated", "min_tol": "3.15", "max_tol": "3.15", "finish_size": "35.039", "drill_size": "35.039", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "4": { "count": "01", "num": "4", "type": "non_plated", "min_tol": "1.969", "max_tol": "1.969", "finish_size": "47.244", "drill_size": "47.244", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "5": { "count": "05", "num": "5", "type": "non_plated", "min_tol": "1.969", "max_tol": "1.969", "finish_size": "59.055", "drill_size": "59.055", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "6": { "count": "01", "num": "6", "type": "non_plated", "min_tol": "1.969", "max_tol": "1.969", "finish_size": "70.866", "drill_size": "70.866", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 }, "7": { "count": "01", "num": "7", "type": "non_plated", "min_tol": "1.969", "max_tol": "1.969", "finish_size": "74.803", "drill_size": "74.803", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 } } }, "stp": { "d1-2": {}, "d2-3": {}, "d3-4": {}, "d4-5": {}, "d5-6": {}, "d6-7": {}, "d7-8": {}, "d8-9": {}, "d9-10": {}, "drill": { "1": { "count": "08", "num": "1", "type": "non_plated", "min_tol": "0", "max_tol": "1.969", "finish_size": "118.11", "drill_size": "118.11", "slot_len": "0", "type2": "standard", "shape": "hole", "bit": 0 } } } } }