=head NAME: DESCRIPTION: 自动转PAD PARAMETER: [ { name : 'step_filter', type : 'LineEdit', title : 'step过滤', pack : {row:0,column:1}, property:{tool_tip:'选择step时候的过滤器'}, }, { name : 'max_pad_size', type : 'LineEdit', title : 'PAD最大尺寸(mil)', pack : {row:0,column:1}, property:{tool_tip:'PAD最大尺寸(mil)'}, }, { name : 'tolerance', type : 'LineEdit', title : '公差(mil)', pack : {row:0,column:1}, property:{tool_tip:'公差(mil)'}, }, { name : 'bak_layer_pad', type : 'LineEdit', title : '备份层后缀', pack : {row:0,column:1}, property:{tool_tip:'去铜丝参数'}, } ] VERSION_HISTORY: V1.00 2020-10-12 Super 1.新版本 HELP:

功能简介

DFM优化


参数配置

● 无

注意事项

● 无


=cut use strict; use utf8; use Data::Dump 'dump'; my ($Job,$Step)=($JOB,undef); my $Report = 'done'; my @work_layers; $PAR->{max_pad_size} = $PAR->{max_pad_size} ? $PAR->{max_pad_size} : 500; $PAR->{tolerance} = $PAR->{tolerance} ? $PAR->{tolerance} : 1; $PAR->{bak_layer_pad} = $PAR->{bak_layer_pad} ? $PAR->{bak_layer_pad} : '++-bak-pad++'; try { ###检查Genesis料号是否存在并打开 show_loading("检查${Job}是否存在..",0,position=>'n'); if (! $GEN->isJobExists(job=>$Job) ){ $GUI->msgbox(-icon=>'error',-text=>"料号 $Job 在Genesis中不存在, 请检查!"); return 'Error'; } update_loading("正在打开料号 ${Job} ...",0,position=>'n'); $GEN->openJob(job=>$Job) unless ($GEN->isJobOpen(job=>$Job)); my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash'); my @steps = $GEN->getStepList(job=>$Job); if ( @steps == 0 ) { $GUI->msgbox(-icon=>'error',-text=>'在料号中没有Step存在,你将退出!'); return 'Error'; } elsif (@steps != 1){ my $srep_filter = $PAR->{step_filter} ? $PAR->{step_filter} : '.*'; my @tmp_steps = grep(/$srep_filter/,@steps); if ( @tmp_steps == 0 ) { $GUI->msgbox(-icon=>'error',-text=>'在料号中没有过滤器中的step存在,你将退出!'); return 'Error'; } elsif ( @tmp_steps == 1 ) { $Step = $tmp_steps[0]; } else { $Step = $GUI->select_step(-title=>'请选择工作Step', -steplist=>\@tmp_steps, -selectmode=>'single'); return 'Cancel' unless ($Step); } } else { $Step = $steps[0]; } ## update_loading("过滤层别...",0,position=>'n'); my @work_layers = get_work_layer(); return 'Cancel' if grep /^Cancel$/,@work_layers; ###打开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=>'inch'); $GEN->zoomHome(); #优化参数 my $itm_info = { 'ref' => {action=>'valor_cleanup_ref_subst',erf=>'STD',params=>{pp_layer=>'.affected',pp_tol=>$PAR->{tolerance}}}, 'auto' => {action=>'valor_cleanup_auto_subst',erf=>'STD'}, }; #冒泡排序一次优先转阻焊层 for(my $i = 0; $i < @work_layers; $i++){ for(my $k = 0; $k < @work_layers - $i; $k++){ if ($matrix{$work_layers[$k]}{layer_type} ne 'solder_mask' and $matrix{$work_layers[$k+1]}{layer_type} eq 'solder_mask'){ my $tmp = $work_layers[$k]; $work_layers[$k] = $work_layers[$k+1]; $work_layers[$k+1] = $tmp; } } } foreach my $layer (@work_layers) { #备份层 my $bak_layer = $layer.$PAR->{bak_layer_pad}; $GEN->createLayer(job=>$Job,layer=>$bak_layer,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->copyLayer(source_job=>$Job,source_step=>$Step,source_layer=>$layer,dest_layer=>$bak_layer,mode=>'replace',invert=>'no'); #外层要参考阻焊层转PAD my $mask_tmp_layer; if($matrix{$layer}{tl_type} eq 'outer'){ foreach my $lay (sort {$matrix{$a}{row} <=> $matrix{$b}{row}} keys %matrix) { if($matrix{$lay}{tl_type} eq 'solder_mask' and $matrix{$lay}{side} eq $matrix{$layer}{side}){ $mask_tmp_layer = $lay; } } if(defined($mask_tmp_layer)){ $GEN->affectedLayer(affected=>'yes',layer=>$mask_tmp_layer,clear_before=>'yes'); $GEN->selectByFilter(feat_types=>'line\;arc',min_len=>0.004,max_len=>$PAR->{max_pad_size}/1000,polarity=>'positive',profile=>'all'); if($GEN->getSelectCount() > 0){ $GEN->displayLayer(name=>$mask_tmp_layer,number=>1); $GUI->msgbox(-icon=>'info',-text=>"阻焊层 $mask_tmp_layer 中含有规则物件!会影响 $layer 层转PAD效果,请确认。。。"); $GEN->PAUSE('Please,Check Layer Features!'); $GEN->COM('sel_clear_feat'); } } } $GEN->affectedLayer(affected=>'yes',layer=>$layer,clear_before=>'yes'); if($matrix{$layer}{tl_type} eq 'outer'){ $GEN->runSingleDfm( chklist => $itm_info->{auto}{action}, erf => $itm_info->{auto}{erf}, show_res=> 'no', params => { pp_layer =>'.affected', pp_in_selected=>'All', pp_min_smd=>0.001, pp_max_smd=>$PAR->{max_pad_size}, pp_tol =>$PAR->{tolerance},pp_ref_sm=>$mask_tmp_layer, pp_auto_ref=>'Auto Ref.', pp_sm_margin=>0, pp_drill_margin=>0, pp_work=>'Features', pp_construct=>'No' } ); }else{ $GEN->runSingleDfm( chklist => $itm_info->{auto}{action}, erf => $itm_info->{auto}{erf}, show_res=> 'no', params => { pp_layer =>'.affected', pp_in_selected=>'All', pp_min_smd=>0.004, pp_max_smd=>$PAR->{max_pad_size}, pp_tol =>$PAR->{tolerance},pp_ref_sm=>'', pp_auto_ref=>'', pp_sm_margin=>0, pp_drill_margin=>0, pp_work=>'Features', pp_construct=>'No', } ); } #全部是PAD的时候不需要手动操作 $GEN->selectByFilter(polarity=>'positive',profile=>'all'); $GEN->selectByFilter(feat_types=>'pad',operation=>'unselect'); next unless ($GEN->getSelectCount()); $GEN->COM('sel_clear_feat'); $GEN->workLayer(name=>$layer,display_number=>1,clear_before=>'yes'); $GEN->highlightByFilter(feat_types=>'pad',polarity=>'positive',profile=>'all'); update_loading("请仔细检查 $layer 当前PAD,框选需要转PAD的物件,无需转PAD时框选空白结束...",0,position=>'n'); while(1){ my %mouse_area = $GEN->MOUSE(type=>'r',text=>'Please Select The Construct Pad Feature'); $GEN->selectRectangle(x1=>$mouse_area{x1},y1=>$mouse_area{y1},x2=>$mouse_area{x2},y2=>$mouse_area{y2}); unless ($GEN->getSelectCount()){ $GEN->clearHighlight(); last ; }else{ $GEN->runSingleDfm( chklist => $itm_info->{ref}{action}, erf => $itm_info->{ref}{erf}, params => $itm_info->{ref}{params}, show_res => 'no' ); $GEN->clearHighlight(); $GEN->highlightByFilter(feat_types=>'pad',polarity=>'positive',profile=>'all'); } } } ###output and return status, if genesis error, it will output genesis error command unless ($GEN->{STATUS}){ return $Report; } else{ $GUI->msgbox(-icon=>'error',-text=>join("\n",@{$GEN->{STATUS}})); addFlowNotes(-notes=>" Genesis Error:\n ".join("\n ",@{$GEN->{STATUS}})); return 'Error'; } } catch Error::Simple with { my $error = shift; $GUI->msgbox(-icon=>'error',-text=>$error); return 'Error'; } finally{ $GEN->affectedLayer( mode=>'all',affected=>'no'); }; sub get_work_layer{ # 获取工作层 my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash'); foreach my $layer (sort {$matrix{$a}{row} <=> $matrix{$b}{row}} keys %matrix) { if(defined($matrix{$layer}{context}) and $matrix{$layer}{context} eq 'board' ){ if(defined($matrix{$layer}{layer_type}) and ($matrix{$layer}{layer_type} eq 'solder_mask' or $matrix{$layer}{layer_type} eq 'signal')){ push @work_layers,$layer; } } } ## my %tmp_matrix; foreach my $layer (@work_layers) { $tmp_matrix{$layer} = $matrix{$layer}; } if (@work_layers > 1) { @work_layers = $GUI->select_layer( -title=>'请选择工作层别', -layermatrix=>\%tmp_matrix, -selectmode => 'multiple');#single return 'Cancel' unless(@work_layers); } else { @work_layers = @work_layers; } return @work_layers; }