=head NAME: DESCRIPTION: Signal线路挑选线性铜 PARAMETER: [ { name : 'step_filter', type : 'LineEdit', title : 'step过滤', pack : {row:0,column:1}, property:{tool_tip:'选择step时候的过滤器'}, }, { name : 'line_number_min', type : 'LineEdit', title : 'line转铜最小数量', pack : {row:0,column:1}, property:{tool_tip:'line转铜最小数量'}, }, { name : 'bak_layer_suf', type : 'LineEdit', title : '备份层后缀', pack : {row:0,column:1}, property:{tool_tip:'去铜丝参数'}, } ] VERSION_HISTORY: V1.00 2020-11-1 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->{line_number_min} = $PAR->{line_number_min} > 0 ? $PAR->{line_number_min} : 'max';#line转铜最小数量 $PAR->{bak_layer_suf} = $PAR->{bak_layer_suf} ? $PAR->{bak_layer_suf} : '++-bak-suface++'; 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 @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'); @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(); update_loading("挑选铜皮中...",0,position=>'n'); $GEN->COM("disp_off"); foreach my $layer (@work_layers){ my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>$layer,options=>'break_sr'); next unless @feat; my %line_info; foreach my $tmp (@feat){ if($tmp->{type} eq 'line' or $tmp->{type} eq 'arc'){ ++$line_info{$tmp->{symbol}}; } } next unless keys %line_info; my @tmp = sort {$line_info{$b} <=> $line_info{$a}} keys %line_info; #创建铜皮层 my $line_suface = 'tl++tmp+line+suf+++'; my $line_chek = 'tl++check+line++type++'; $GEN->createLayer(job=>$Job,layer=>$line_suface,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->createLayer(job=>$Job,layer=>$line_chek,context=>'misc',type=>'document',delete_exists=>'yes'); #备份层 my $bak_layer = $layer.$PAR->{bak_layer_suf}; $GEN->createLayer(job=>$Job,layer=>$bak_layer,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->affectedLayer(affected=>'yes',layer=>$layer,clear_before=>'yes'); $GEN->selCopyOther(target_layer=>$bak_layer,invert=>'no'); if($PAR->{line_number_min} eq 'max'){ select_line_suface(symbol_data=>$tmp[0],layer=>$layer,surface=>$line_suface,line_check=>$line_chek); }else{ foreach my $data (@tmp){ next if $line_info{$data} < $PAR->{line_number_min}; select_line_suface(symbol_data=>$data,layer=>$layer,surface=>$line_suface,line_check=>$line_chek); } } if(! $GEN->isLayerEmpty(job=>$Job,step=>$Step,layer=>$line_chek)){ update_loading("请确认 $line_chek 层挑选的线是否全部为线路层走线,请将需要转suface的走线选中...",0,position=>'n'); $GEN->COM("disp_on"); $GEN->clearLayers(); $GEN->affectedLayer( mode=>'all',affected=>'no' ); $GEN->workLayer(name=>$line_chek,display_number=>1,clear_before=>'yes'); $GEN->displayLayer(name=>$line_suface,number=>2); my $ans = $GEN->PAUSE("Please check line type!"); unless (defined $ans and $ans eq 'OK' ) { return 'Cancel'; }else{ $GEN->COM("disp_off"); $GEN->selMoveOther(target_layer=>$line_suface,invert=>'no') if ( $GEN->getSelectCount() > 0 ); $GEN->selMoveOther(target_layer=>$layer,invert=>'no'); $GEN->clearLayers(); $GEN->deleteLayer(job=>$Job,layer=>[$line_chek]); } }else{ $GEN->deleteLayer(job=>$Job,layer=>[$line_chek]); } if(! $GEN->isLayerEmpty(job=>$Job,step=>$Step,layer=>$line_suface)){ update_loading("请仔细检查 $line_suface 层挑选的线是否正确...",0,position=>'n'); $GEN->COM("disp_on"); $GEN->clearLayers(); $GEN->affectedLayer( mode=>'all',affected=>'no' ); $GEN->workLayer(name=>$line_suface,display_number=>1,clear_before=>'yes'); $GEN->displayLayer(name=>$layer,number=>2); my $ans = $GEN->PAUSE("Please check !"); unless (defined $ans and $ans eq 'OK' ) { return 'Cancel'; }else{ $GEN->COM("disp_off"); $GEN->selContourize(); $GEN->selMoveOther(target_layer=>$layer,invert=>'no'); # $GEN->affectedLayer(affected=>'yes',layer=>$layer,clear_before=>'yes'); # $GEN->COM('sel_drawn',type=>'mixed',therm_analyze=>'yes'); # $GEN->selContourize() if ( $GEN->getSelectCount() > 0 ); $GEN->clearLayers(); $GEN->deleteLayer(job=>$Job,layer=>[$line_suface]); } }else{ $GEN->deleteLayer(job=>$Job,layer=>[$line_suface]); $GEN->copyLayer(source_job=>$Job,source_step=>$Step,source_layer=>$bak_layer,dest_layer=>$layer,mode=>'replace',invert=>'no') ; } } $GUI->msgbox(-icon=>'info',-text=>'脚本运行完成请仔细检查!'); ###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->clearLayers(); $GEN->affectedLayer( mode=>'all',affected=>'no' ); $GEN->COM("disp_on"); }; =head 选择线路层 =cut 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 '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; } =head 挑选线性铜皮 symbol_data=>,layer=>,surface=> =cut sub select_line_suface { my %par = @_; $GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes'); #挑选最多D码的线 my $line_tmp = '++-+tl+tmp++line'; $GEN->createLayer(job=>$Job,layer=>$line_tmp,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selectByFilter(feat_types=>'line\;arc',polarity=>'positive',include_syms=>$par{symbol_data},profile=>'all'); $GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no') if ( $GEN->getSelectCount() > 0 ); #挑选PAD my $pad_tmp = '++-+tl+tmp++pad'; $GEN->createLayer(job=>$Job,layer=>$pad_tmp,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selectByFilter(feat_types=>'pad',polarity=>'positive',profile=>'all'); $GEN->selCopyOther(target_layer=>$pad_tmp,invert=>'no',size=>0); #删除cover的pad my $line_tmp2 = '++-+tl+tmp++line2'; $GEN->createLayer(job=>$Job,layer=>$line_tmp2,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes'); $GEN->selCopyOther(target_layer=>$line_tmp2,invert=>'no'); $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp2,clear_before=>'yes'); $GEN->selContourize(); $GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp,clear_before=>'yes'); $GEN->selRefFeat(layers=>$line_tmp2,use=>'filter',mode=>'cover'); $GEN->selDelete() if ( $GEN->getSelectCount() > 0 ); $GEN->COM('truncate_layer', layer =>$line_tmp2); #挑选与pad连接的线 $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes'); $GEN->selRefFeat(layers=>$pad_tmp,use=>'filter',mode=>'touch'); my $touch_pad_line = '++-+touch++pad++line'; if ( $GEN->getSelectCount() > 0 ){ $GEN->createLayer(job=>$Job,layer=>$touch_pad_line,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selMoveOther(target_layer=>$touch_pad_line,invert=>'no'); } #挑选单独的线移回工作层 $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes'); $GEN->selCopyOther(target_layer=>$line_tmp2,invert=>'no'); $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp2,clear_before=>'yes'); $GEN->selContourize(); my ($size) = $par{symbol_data} =~ /r(.*)/; $GEN->COM('sel_resize',size=>-($size+0.05),corner_ctl=>'no'); $GEN->COM(" sel_clean_surface,accuracy=0.25,clean_size=3,clean_mode=x_and_y,max_fold_len=0"); $GEN->COM('sel_resize',size=>$size+0.05,corner_ctl=>'no'); $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes'); $GEN->selRefFeat(layers=>$line_tmp2,use=>'filter',mode=>'disjoint'); $GEN->selMoveOther(target_layer=>$par{layer},invert=>'no') if ( $GEN->getSelectCount() > 0 ); if($GEN->isLayerExists(job=>$Job,layer=>$touch_pad_line)){ $GEN->affectedLayer(affected=>'yes',layer=>$touch_pad_line,clear_before=>'yes'); my $tmp_data = '+++-touch+pad+line+check'; $GEN->createLayer(job=>$Job,layer=>$tmp_data,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selCopyOther(target_layer=>$tmp_data,invert=>'no',size=>0); $GEN->selContourize(); #不与铜皮相连与PAD相连的移回线路层 $GEN->selRefFeat(layers=>$line_tmp,use=>'filter',mode=>'disjoint'); if ( $GEN->getSelectCount() > 0 ){ my $tmp_layer = '++++-tl++line+touch--+'; $GEN->createLayer(job=>$Job,layer=>$tmp_layer,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selMoveOther(target_layer=>$tmp_layer,invert=>'no'); $GEN->affectedLayer(affected=>'yes',layer=>$tmp_data,clear_before=>'yes'); $GEN->selRefFeat(layers=>$tmp_layer,use=>'filter',mode=>'touch'); $GEN->selMoveOther(target_layer=>$par{layer},invert=>'no'); $GEN->deleteLayer(job=>$Job,layer=>[$tmp_layer]); } $GEN->deleteLayer(job=>$Job,layer=>[$touch_pad_line]); #与铜皮和PAD相连 my $pad_tmp2 = '++pad+++tl++tmp'; $GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp,clear_before=>'yes'); $GEN->selRefFeat(layers=>$tmp_data,use=>'filter',mode=>'touch'); if ( $GEN->getSelectCount() > 0 ){ $GEN->createLayer(job=>$Job,layer=>$pad_tmp2,context=>'misc',type=>'document',delete_exists=>'yes'); $GEN->selMoveOther(target_layer=>$pad_tmp2,invert=>'no'); $GEN->COM('truncate_layer', layer =>$pad_tmp); my ($size) = $par{symbol_data} =~ /r(.*)/; my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>$pad_tmp2); my $idex = 1; foreach my $data (@feat){ my $pad_size; if ($data->{symbol} =~ /^s(\d.*)/) { $pad_size = $1; }elsif($data->{symbol} =~ /^r(\d.*)/){ $pad_size = $1; }elsif($data->{symbol} =~ /^rect(\d.*)x(\d.*)/){ $pad_size = $1 > $2 ? $2 : $1; }elsif($data->{symbol} =~ /^oval(\d.*)x(\d.*)/){ $pad_size = $1 > $2 ? $2 : $1; } $GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp2,clear_before=>'yes'); $GEN->COM('sel_layer_feat',operation=>'select',layer=>$pad_tmp2,index=>$idex); $GEN->selMoveOther(target_layer=>$pad_tmp,invert=>'no',dx=>0,dy=>0,size=>0); $GEN->affectedLayer(affected=>'yes',layer=>$tmp_data,clear_before=>'yes'); $GEN->selRefFeat(layers=>$pad_tmp,use=>'filter',mode=>'touch'); my $number = $GEN->getSelectCount(); if($number > 0){ if($number > 4){ if($number*$size / $pad_size > 0.5 ){ $GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no'); }else{ $GEN->selMoveOther(target_layer=>$par{line_check},invert=>'no'); } }else{ #4根以下算单根线的宽度 if($size / $pad_size > 0.5 ){ $GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no'); }else{ $GEN->selMoveOther(target_layer=>$par{line_check},invert=>'no'); } } } $idex++; } $GEN->deleteLayer(job=>$Job,layer=>[$pad_tmp2]); } $GEN->deleteLayer(job=>$Job,layer=>[$tmp_data]); } $GEN->deleteLayer(job=>$Job,layer=>[$pad_tmp,$line_tmp2]); $GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes'); if($GEN->isLayerExists(job=>$Job,layer=>$par{surface})){ $GEN->selMoveOther(target_layer=>$par{surface},invert=>'no'); $GEN->deleteLayer(job=>$Job,layer=>[$line_tmp]); } }