=head NAME: DESCRIPTION: 钻孔输出 PARAMETER: [ { name : 'step_filter', title : '工作step', type : 'LineEdit', property : {tool_tip : '过滤Step名称'}, }, { name : 'out_dir', title : '钻孔输出路径', type : 'LineEdit', property:{tool_tip:'例如: /output/drill'} }, { name : 'cool_spread', title : '跳钻距离(um)', type : 'LineEdit', property:{tool_tip:'例如: 350'} }, { name : 'reread_layer', type : 'RadioBox', title : '回读钻孔程式', property : {tool_tip:'未设定,则默认no', size_policy:'Expanding,Fixed',item_list:[{name:'yes',text:'Yes'},{name:'no',text:'No'}]}, pack : {row:1,column:1}, }, { name : 'is_select_lyr', type : 'RadioBox', title : '是否选择层别', property : {tool_tip:'未设定,则默认no', size_policy:'Expanding,Fixed',item_list:[{name:'yes',text:'Yes'},{name:'no',text:'No'}]}, pack : {row:1,column:1}, }, { name : 'save_job', title : '保存料号', type : 'RadioBox', property : { size_policy:'Expanding,Fixed', item_list:[ {name:'Yes',text:'Yes'}, {name:'No',text:'No'}, ], tool_tip:'脚本结束后自动保存料号,未设定,默认为No' }, pack : {row:1,column:1}, } ] VERSION_HISTORY: V1.00 2019-10-22 Super Zhang 1.新版本 V1.1 2020-03-11 Super Zhang 1.不同尺寸板子增加输出参数 V1.2 2020-03-12 Super 1.修改钻孔输出方式代码 V1.3 2020-03-23 Super 1.增加0.549的M97批号孔 V1.4 2020-3-25 Super 1.增加web server数据传输 V1.5 2020-03-27 Super 1.钻孔输出格式调整为3:3不省零 modal_coords=no V1.6 2020-3-30 Super 1.修改涨缩参数 V1.7 2020-04-01 Super 1.钻带表头增加料号和涨缩信息 2.涨缩中心点按原点移动后的数据从新计算 V1.8 2020-04-02 Super 1.涨缩中心按改变原点前的坐标计算 v1.9 2020-04-04 Super 1.angle = 270 v2.0 2020-04-15 Kurri 1.增加跳刀参数 V2.1 2020-04-21 Super 1.调整T99坐标位置 2.T02板框监视孔的数据放到T01前面 V2.2 2020-05-14 Kurri 1.vpg层也插入M97,${JOB} $S$I V2.3 2020-05-15 Kurri 1.修复涨缩小于1的程序没有正常输出的问题 V2.31 2020-06-09 Super 1.扩孔时不再增加G84代码 2.扩孔钻咀用3.151 3.修复ncset同名时钻孔无法输出 V2.32 2020-06-11 Super 1.输出命名更新 V2.33 2020-08-18 Super 1.读取map_info参数2.修复检测孔不是第二把刀的时候检测孔坐标乱刀序,3.双面3.054排序 V2.34 2020-10-13 Kurri 1.输出层别选择取消board属性限定 V2.35 2020-10-16 Kurri 1.增加程序上传的类型 V2.36 2020-10-16 Kurri 1.输出alp和alr时bottom层做mirror V2.37 2020-10-21 Kurri 1.取消测试版本T2.37 T2.38 2020-10-22 Super 1.增加短槽拉伸 2.调整*的M97/M98模式 T2.39 2020-10-29 Super 1.更新拉伸规则 2.706*603的M97/M98位置调整 V2.38 2020-11-03 Super 1.测试版本到正式版 2.取消槽孔角度旋转 3.输出参数增加single_sr V2.39 2020-11-06 Super 1.输出参数break_sr设置成yes HELP:

功能简介

钻孔输出


参数配置

● 无

注意事项

● 无


=cut use strict; use Encode; use utf8; use Data::Dump 'dump'; use File::Copy; use JSON; my $json = new JSON; # my $datum;#增加一个基准点数据 # my @drl_section_data;#监视孔范围数据 # my (@drl_section,$section_tool,$section_number);#监视孔坐标 use_module('TL_GenMath'); my ($Job,$Step)=($JOB,undef); my $units = 'mm'; # my $url = "http://10.87.66.216:9008/api/TOPMES6_SEC_V6/sec/sec-import_drill_program"; # my $server_data; # my $map_info = do($GEN->getJobPath(job=>$Job).'/user/PNL_map_info'); # my $new_name = get_new_layer_name("$Job"); ##host name为cody电脑名称,本地测试用本地目录 use Sys::Hostname; my $hostname = hostname; #$GUI->debug(dump($hostname)); if( $hostname eq 'DESKTOP-010QP68' ){ $PAR->{out_dir} = 'D:/tmp'; } if ($hostname eq 'g1kevnzhang'){ $PAR->{out_dir} = 'D:/tmp'; } $PAR->{spread} = 2000 unless $PAR->{spread}; $PAR->{reread_layer} = 'no' unless $PAR->{reread_layer}; $PAR->{is_select_lyr} = 'no' unless $PAR->{is_select_lyr}; $PAR->{save_job} = 'No' unless $PAR->{save_job}; $PAR->{cool_spread} = 350 unless $PAR->{cool_spread};#跳孔间距 unless( $PAR->{out_dir} ){ $GUI->msgbox(-icon=>'warning',-text=>'请在脚本参数中设定钻孔输出路径'); return 'Cancel'; } $PAR->{out_dir} = encode('gbk',$PAR->{out_dir}); ## unless( -d $PAR->{out_dir} ){ $GUI->msgbox(-icon=>'warning',-text=>"$PAR->{out_dir} 脚本参数设定的钻孔输出目录不存在,请确认!"); return 'Cancel'; } $PAR->{out_dir} .= '/'.lc($new_name); mkdir $PAR->{out_dir} unless ( -e $PAR->{out_dir}); my $info; try { show_loading("判断是否选择料号..",0,position=>'n'); unless( $Job){ $GUI->msgbox(-icon=>'error',-text=>"请先选择料号后再执行脚本!"); return 'Cancel'; } ##检查料号是否存在 update_loading("检查${Job}是否存在..",0,position=>'n'); unless ( $GEN->isJobExists(job=>$Job) ){ $GUI->msgbox(-icon=>'error',-text=>"料号 $Job 不存在,请确认。"); return 'Cancel'; } ## update_loading("正在打开料号${Job}...",0,position=>'n'); $GEN->openJob(job=>$Job) unless ($GEN->isJobOpen(job=>$Job)); ## update_loading("过滤工作step...",0,position=>'n'); my $ans = get_work_step(); return $ans if $ans; ##选择工作层 update_loading("过滤层别...",0,position=>'n'); my @work_layers = select_work_layer(); return 'Cancel' if $work_layers[0] eq 'Cancel'; ##确认涨缩信息 my $scale = get_scale_info(layers=>\@work_layers);#-----涨缩值信息确认 return $scale if $scale eq 'Cancel'; $PAR->{scale} = $scale; ## update_loading("正在打开料号$Step STEP...",0,position=>'n'); $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=>$units ); $GEN->zoomHome(); $PAR->{profile_limits} = $GEN->getProfileLimits(job=>$Job,step=>$Step,units=>'mm'); $PAR->{profile_limits}{xc} = $PAR->{profile_limits}{xsize}/2-abs($PAR->{profile_limits}{xmin}); $PAR->{profile_limits}{yc} = $PAR->{profile_limits}{ysize}/2-abs($PAR->{profile_limits}{ymin}); $PAR->{sr} = $GEN->getSRLimits(job=>$Job,step=>$Step,units=>'mm'); my $orgDrillToolInfo ; foreach my $layer (@work_layers) { ##钻孔输出 update_loading("$layer 层钻孔正在输出...",0,position=>'n'); my $output_layer = $Job.'-'.$layer.'-ori';#$Job.'-'.$layer.'-ori' my $ans = drill_out(layer=>$layer,output_layer=>$output_layer,scale_x=>$PAR->{scale}{$layer}{x},scale_y=>$PAR->{scale}{$layer}{y}); return $ans if $ans; ####钻孔程式编辑 my $new_layer; if($PAR->{scale}{$layer}{x} != 1 or $PAR->{scale}{$layer}{y} != 1){ $new_layer= $new_name.'.'.$layer.('X').($PAR->{scale}{$layer}{x}).('Y').($PAR->{scale}{$layer}{y}); }else{ $new_layer= $new_name.'.'.$layer; } my $new_file = $PAR->{out_dir}.'/'.$new_layer; update_loading("$layer 层钻孔程式正在编辑...",0,position=>'n'); $ans = edit_nc_file(layer=>$layer,output_file=>$PAR->{out_dir}.'/'.$output_layer,new_file=>$new_file,x=>$PAR->{scale}{$layer}{x},y=>$PAR->{scale}{$layer}{y});#drl_type=>$drl_type return $ans if $ans; ##删除钻孔输出的临时文件 unlink $PAR->{out_dir}.'/'.$output_layer; ##回读钻孔程式 if( $PAR->{reread_layer} =~ /yes/i){ update_loading("$layer 层钻孔程式回读中...",0,position=>'n'); my $new_layer_2 = $new_layer; input_drill_program(layer=>$layer,file=>$PAR->{out_dir}.'/'.$new_layer_2,new_layer=>$new_layer);#drl_type=>$drl_type,drl_side=>$drl_side } #传入web server数据 #if($layer =~ /(cdr|vpg|alp|alr|psp)/){ # update_loading("$layer 层web server数据上传中...",0,position=>'n'); # open(TMP,$new_file) || die "cannot open $PAR->{out_dir}/$new_layer"; # my @data = ; # close (TMP); # chomp(@data); # my $file_data; # $file_data = join("\n",@data); # $server_data->{data} = [{ # tooling_type=>"mech_drill", # tooling_name=>$new_layer, # partnumber=>$Job, # tooling_text_data=>$file_data, # }]; # #$GUI->debug(-text=>dump($server_data)); # my $result = sec_web_services($url,$server_data); # if($result){ # $GUI->msgbox(-icon=>'error',-text=>"Web services数据传输错误!"); # return 'Cancel'; # } #} } hide_loading(); ##保存料号 if( $PAR->{save_job} =~ /yes/i ){ show_loading("$Job 正在保存料号,请稍候...",0,position=>'n'); $GEN->checkInout(job=>$Job,mode=>'out'); $GEN->saveJob(job=>$Job); hide_loading(); } ###output and return status, if genesis error, it will output genesis error command unless ($GEN->{STATUS}){ return 'done'; } else{ $GUI->msgbox(-icon=>'error',-text=>join("\n",@{$GEN->{STATUS}})); return 'Error'; } } catch Error::Simple with { my $error = shift; $GUI->msgbox(-icon=>'error',-text=>$error); return 'Error'; } finally{ $GEN->COM('disp_on'); }; sub get_work_step { my @steps = $GEN->getStepList(job=>$Job); if ( @steps == 0 ) { $GUI->msgbox(-icon=>'error',-text=>'在料号中没有Step存在,请确认。'); return 'Cancel'; } elsif (@steps != 0){ $PAR->{step_filter} = '.*' unless $PAR->{step_filter}; my @tmp_steps = grep(/$PAR->{step_filter}/,@steps); if ( @tmp_steps == 0 ) { $GUI->msgbox(-icon=>'warning',-text=>'根据脚本参数过滤出来的step不存在,请检查资料或者脚本参数配置!'); return 'Cancel'; } elsif (@tmp_steps == 1) { $Step = $tmp_steps[0]; } else { $Step = $GUI->select_step(-title=>'请选择工作 Step', -steplist=>[@tmp_steps], -default=>[$tmp_steps[0]], -gen=>$GEN, -selectmode=>'single'); return 'Cancel' unless ($Step); } } return undef; } sub select_work_layer { my %par = @_; my @drill; my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash'); foreach my $layer (sort {$matrix{$a}{row} <=> $matrix{$b}{row}} keys %matrix) { next if $layer =~ /ddr/; if(defined($matrix{$layer}{layer_type}) and $matrix{$layer}{layer_type} eq 'drill'){ push @drill,$layer; } } unless( @drill ){ $GUI->msgbox(-icon=>'warning',-text=>'资料中无钻孔层,请确认!'); return 'Cancel'; } if ($PAR->{is_select_lyr} eq 'yes' and scalar @drill > 1) { my (%tmp_matrix); foreach my $layer (@drill) { $tmp_matrix{$layer} = $matrix{$layer}; } @drill = $GUI->select_layer( -title=>'请选择输出层别', -layermatrix=>\%tmp_matrix, -default => ['drl','md','bk','lp'], -selectmode => 'multiple');#single return 'Cancel' unless(@drill); } return @drill; } sub get_scale_info{ my %par = @_; my (%rows,$n); foreach my $layer (@{$par{layers}}){ $n ++; $rows{$layer}{sequence} = $n; $rows{$layer}{layer} = $layer; if($layer eq "md"){ $rows{$layer}{x} = 1.0004; $rows{$layer}{y} = 1.0004; } else{ $rows{$layer}{x} = 1.0000; $rows{$layer}{y} = 1.0000; } } my $scale_factor = $GUI->show_tableform ( -defaultsize=>[380,400],-title => '请确认涨缩值',-rows => \%rows, -showcheck => 1,-gen => $GEN, -columns => [ { column_name=>'layer', label=>'层名称', width=>70, type=>'label', }, { column_name=>'x', label=>'X涨缩值', width=>130, type=>'number', }, { column_name=>'y', label=>'Y涨缩值', width=>130, type=>'number', }, ], ); return 'Cancel' unless ($scale_factor); ## return $scale_factor; } =head drillmarge 输出 =cut sub drill_out { my %par = @_; my $nc_set = 'sec-jt'; my @ncsets = $GEN->getNcsetsList(job=>$Job,step=>$Step,layer=>$par{layer}); if( @ncsets ){ if (grep (/^($nc_set)$/,@ncsets)) { $GEN->COM('ncset_delete',name=>$nc_set); } } #钻带涨缩中心点 my $x_anchor = ($par{scale_x} != 1 or $par{scale_y} != 1) ? $PAR->{profile_limits}{xc} : 0; my $y_anchor = ($par{scale_x} != 1 or $par{scale_y} != 1) ? $PAR->{profile_limits}{yc} : 0; unlink if(-e $PAR->{out_dir}.'/'.$par{output_layer}); my ($org_x,$org_y,$angle); if($PAR->{profile_limits}{ysize} == 603 and $PAR->{profile_limits}{xsize} == 706){ $org_x = $PAR->{profile_limits}{yc};#- 15 $org_y = 5; $angle = 270; $datum->{x} = $PAR->{profile_limits}{xmax} - 5; $datum->{y} = $PAR->{profile_limits}{yc}; $datum->{angle} = 90; $datum->{type} = 1;#拼版类型 }elsif($PAR->{profile_limits}{ysize} == 603 and $PAR->{profile_limits}{xsize} == 606){ $datum->{x} = $org_x = $PAR->{profile_limits}{xc};#- 5 $datum->{y} = $org_y = 5; $datum->{angle} = $angle = 0; $datum->{type} = 0;#拼版类型 }else{ $datum->{x} = $org_x = $PAR->{profile_limits}{xc};#- 24 $datum->{y} = $org_y = 5; $datum->{angle} = $angle = 0; $datum->{type} = 0;#拼版类型 } # 铝片塞防焊和铝片塞树脂程序,bot面时需要mirror my $xmirror = 'no'; my $ymirror = 'no'; if ($par{layer} =~ /al[pr](\d\d)(\d\d)/) { my $start = $1 + 0; my $end = $2 + 0; if ($start > $end) { $xmirror = 'yes'; } } #获取@drl_section_data数据 if($par{layer} =~ /(cdr)/ and $GEN->getLayerCount(job=>$Job) >= 4){ my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>'pnl-map',units=>'mm'); my @data_tmp = grep($_->{attributes}->[0] =~ /(DRL_SECTION)/,@feat);#获取监视孔坐标 $section_tool = $map_info->{P}{min_drl} >= 1100 ? 1100 : $map_info->{P}{min_drl}; @drl_section_data = TL::GenMath->p_trans($datum,$datum->{angle},'no',-$datum->{x},-$datum->{y},@data_tmp); # if($datum->{angle} == 90){ # my @data_tmp = TL::GenMath->p_trans($datum,$datum->{angle},'no',0,0,@data_tmp);#坐标选择 # foreach my $data (@data_tmp){ # my $coorder_txt; # $coorder_txt = change_coode(data=>$data,datum=>$datum); # $drl_section_data->{$coorder_txt} = 1; # } # }else{ # foreach my $data (@data_tmp){ # my $coorder_txt; # $coorder_txt = change_coode(data=>{x=>$data->{x},y=>},datum=>$datum); # $drl_section_data->{$coorder_txt} = 1; # } # } } my $id = $nc_set; $GEN->COM('ncset_units',units=>'mm'); if($par{layer} =~ /(cdr)/){ $GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes'); $GEN->COM("adv_filter_reset"); $GEN->COM("reset_filter_criteria,filter_name=,criteria=all"); $GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*LDI_HOLE_Two*"}]); $GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*XRAY_HOLE*"}]); $GEN->COM("adv_filter_reset"); $GEN->COM("reset_filter_criteria,filter_name=,criteria=all"); $GEN->selChangeSym(symbol=>'r1') if $GEN->getSelectCount(); $GEN->affectedLayer( mode=>'all',affected=>'no' ); } #$GEN->COM('open_sets_manager',test_current=>'no'); $GEN->COM('nc_create',ncset=>$id,device=>'basic_excellon',lyrs=>$par{layer},thickness=>0); $GEN->COM('nc_set_advanced_params',layer=>$par{layer},ncset=>$id); $GEN->COM('nc_set_current',job=>$Job,step=>$Step,layer=>$par{layer},ncset=>$id); $GEN->COM('nc_set_file_params',single_sr=>'no',output_path=>$PAR->{out_dir},output_name=>$par{output_layer},zeroes=>'none',units=>'mm',tool_units=>'mm',nf1=>3,nf2=>3,decimal=>'no',modal_coords=>'no'); $GEN->COM('nc_register',angle=>$angle,xoff=>0,yoff=>0,version=>1,xorigin=>$org_x,yorigin=>$org_y,xscale=>$par{scale_x},yscale=>$par{scale_y},xscale_o=>$x_anchor,yscale_o=>$y_anchor,xmirror=>$xmirror,ymirror=>$ymirror); $GEN->COM('nc_set_optim',optimize=>'yes',iterations=>5,reduction_percent=>1,cool_spread=>$PAR->{cool_spread},break_sr=>'yes',xspeed=>2540,yspeed=>2540,diag_mode=>'45ort'); $GEN->COM('nc_cre_output',layer=>$par{layer},ncset=>$id); my $profile = $GEN->getProfileLimits(job=>$Job,step=>$Step,units=>'mm'); $GEN->origin(x=>$profile->{xmin},y=>$profile->{ymin}); if($par{layer} =~ /(cdr)/){ $GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes'); $GEN->COM("adv_filter_reset"); $GEN->COM("reset_filter_criteria,filter_name=,criteria=all"); $GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*LDI_HOLE_Two*"}]); $GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*XRAY_HOLE*"}]); $GEN->COM("adv_filter_reset"); $GEN->COM("reset_filter_criteria,filter_name=,criteria=all"); $GEN->selChangeSym(symbol=>'r3054') if $GEN->getSelectCount(); $GEN->affectedLayer( mode=>'all',affected=>'no'); } @ncsets = $GEN->getNcsetsList(job=>$Job,step=>$Step,layer=>$par{layer}); if( @ncsets ){ if (grep (/^($nc_set)$/,@ncsets)) { $GEN->COM('ncset_delete',name=>$nc_set); } } return undef; } sub edit_nc_file{ my %par = @_; open(TMP,"$par{output_file}") || die "cannot open $par{output_file}"; my @data = ; close (TMP); chomp @data; # my %data = split_program(data=>\@data); my $ans = convert_new_program(layer=>$par{layer},new_file=>$par{new_file},data=>\%data,x=>$par{x},y=>$par{y}); return $ans if $ans; return undef; } sub split_program{ my %par = @_; my $ui_info = $par{info}; my (%info); my ($flag,$router_flag) = ('start',undef); foreach my $line(@{$par{data}}){ if( $flag eq 'start' ){ if( $line eq 'M48' ){ $flag = 'overhead'; } } elsif( $flag eq 'overhead' ){ if( $line =~ /^T01C/i ){ $flag = 'head'; } } elsif( $flag eq 'head' ){ if( $line !~ /^T\d+/i ){ $flag = 'neck'; } } elsif( $flag eq 'neck' ){ if( $line =~ /^T01/i ){ $flag = 'body'; } } elsif( $flag eq 'body' ){ if( $line =~ /^M30$/i ){ $flag = 'end'; } } ## if( $flag eq 'overhead' ){ push @{$info{overhead}},$line; } elsif( $flag eq 'head' ){ if($line =~ /^T(\d+)C(.*)/){ if($2 - $section_tool/1000 < 0.0001){ $section_number = $1; } } push @{$info{head}},$line; } elsif( $flag eq 'neck' ){ push @{$info{neck}},$line; } elsif( $flag eq 'body' ){ if( $line =~ /^(T(\d+))$/i ){ $router_flag = $1; } if($router_flag){ my ($num) = $router_flag =~ /^T(\d+)$/; $info{body}{$router_flag}{num} = $num; #判断孔的范围 2020-04-21 # if($num - $section_number < 0.001 and $line !~ /^T/){ # my $point = change_coode_to_vale($line); # my $are_check = 0; # foreach my $symbol (@drl_section_data){ # my $dist = TL::GenMath->point2sym_dist($point,$symbol); # if($dist == 0){ # $are_check = 1; # last; # } # } # if($are_check){ # push @drl_section,$line; # }else{ # push @{$info{body}{$router_flag}{value}},$line; # } # }else{ push @{$info{body}{$router_flag}{value}},$line; # } } } elsif( $flag eq 'end' ){ push @{$info{end}},$line; } ## } if( wantarray ){ return %info; } else{ return \%info; } } sub convert_new_program{ my %par = @_; ## open(NEWMYFILE,">$par{new_file}"); my %data = %{$par{data}}; ##0.插入表头 # if($par{x} != 1 or $par{y} != 1){ # print NEWMYFILE 'M47,'.$Job.' '.'X:'.$par{x}.' '.'Y:'.$par{y},"\n"; # } ##1.头顶(刀径清单之前的)/overhead foreach my $line(@{$data{overhead}}){ print NEWMYFILE $line,"\n"; } ## ##2.程序头(router清单)/head my $tool_change = get_tool_change(layer=>$par{layer},data=>$par{data}); #$GUI->debug(dump($tool_change)); ###人工排序一次 # $tool_change = manual_sort_tool(layer=>$par{layer},data=>$par{data},info=>$tool_change); # return $tool_change if $tool_change eq 'Cancel'; ##目前扩孔后没有其它类型的孔 my $nibble_suffix = 1; my $check_nibble_tool = 0; foreach my $line(@{$data{head}}){ my ($tool,$suffix) = $line =~ /^(T\d+)C.*$/; next unless $tool; ##刀序顺序使用最新的 next unless $tool_change->{$tool}{new_tool}; foreach my $item(values %$tool_change){ if( $tool eq $item->{new_tool} ){ if($tool_change->{$item->{new_tool}}{size} > 6.35){ if(! $check_nibble_tool){ print NEWMYFILE $tool.'C'.(3.15 + $nibble_suffix/1000),"\n"; #$nibble_suffix++; $check_nibble_tool = 1; } }else{ print NEWMYFILE $item->{new_header},"\n"; } $PAR->{tool_num_count} = $item->{new_tool_num} unless ($PAR->{tool_num_count} and $PAR->{tool_num_count} > $item->{new_tool_num}); #$hole_exit = 1 if $item->{new_header} =~ /503$/; } } } # if($par{layer} =~ /(cdr|vpg|alp|alr|psp)/){ # print NEWMYFILE 'T99C0.549',"\n"; # } ##3.脖子(程序头和正式T序坐标之间)/neck foreach my $line(@{$data{neck}}){ next if $line =~ /g93/i; print NEWMYFILE $line,"\n"; } # if(@drl_section_data){ # print NEWMYFILE 'T'.$section_number,"\n"; # foreach my $tmp (@drl_section){ # print NEWMYFILE $tmp,"\n"; # } # } ##4.实际的每把T序/body my $nibble_tool_check = 0; foreach my $tool (sort{$data{body}{$a}{num}<=>$data{body}{$b}{num}} keys %{$data{body}}){ ##获取对应的新刀径 my $new_tool; my $check_drl_section = 0; foreach my $old_tool(keys %$tool_change){ if( $tool eq $tool_change->{$old_tool}{new_tool} ){ $new_tool = $old_tool; } } next unless $new_tool; foreach my $line(@{$data{body}{$new_tool}{value}}){ #if( abs($tool_change->{$new_tool}{size} - 3.175) < 0.001 ){ # if( $line =~ /^(T\d+)/ ){ # print NEWMYFILE '/',$tool,"\n"; # } # else{ # print NEWMYFILE '/',$line,"\n"; # } #} #else{ #if( $line =~ /^(T\d+)/ ){ # print NEWMYFILE $tool,"\n"; #} #else{ # print NEWMYFILE $line,"\n"; #} #} if( $tool_change->{$new_tool}{size} > 6.35 ){ if( $line =~ /^(T\d+)/ ){ if( !$nibble_tool_check ){ print NEWMYFILE $tool,"\n"; $nibble_tool_check = 1; } } else{ print NEWMYFILE $line,"\n";#'G84X'.$tool_change->{$new_tool}{size} } } else{ if( $line =~ /^(T\d+)/ ){ print NEWMYFILE $tool,"\n"; } else{ if( $line =~ /X.*Y.*G85X.*Y.*/ ){ my ($tmp1,$tmp2) = $line =~ /(X\-?\d*\.?\d*Y\-?\d*\.?\d*)G85(X\-?\d*\.?\d*Y\-?\d*\.?\d*)/; my $slot_star = change_coode_to_vale($tmp1); my $slot_end = change_coode_to_vale($tmp2); my $slot_size = $tool_change->{$new_tool}{size}; my $slot_length = $slot_size + TL::GenMath->line_length({xs=>$slot_star->{x},xe=>$slot_end->{x},ys=>$slot_star->{y},ye=>$slot_end->{y}}); my $slot_info = ger_short_slot_vale(slot_size=>$slot_size,slot_length=>$slot_length); #if($slot_info){ # my $angle = $slot_info->{angle}; # my $point = TL::GenMath->rotate_point($slot_star,$slot_end,$angle); # my $tmp_data = change_coode(data=>{x=>$point->{x},y=>$point->{y}},datum=>{x=>0,y=>0}); # my $tmp_line = $tmp1.'G85'.$tmp_data; # print NEWMYFILE $tmp_line,"\n"; #}else{ print NEWMYFILE $line,"\n"; #} }else{ print NEWMYFILE $line,"\n"; } } } } } #插入M97坐标 'X-214500Y000000' if($par{layer} =~ /(cdr|vpg|alp|alr|psp)/){ my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>'pnl-map',units=>'mm'); my @feat_M97 = grep($_->{attributes}->[0] =~ /(DRL_TXT_DRL)/,@feat); my $coordinate_txt; my $mode;#判断*的位置是横放还是竖放 1 代表横放 2代表竖放 if($feat_M97[0]->{x} >= $PAR->{sr}{xmin} and $feat_M97[0]->{x} <= $PAR->{sr}{xmax}){ $mode = 1; }else{ $mode = 2; } if($datum->{angle} == 90){ my @M97_tmp = TL::GenMath->p_trans($datum,$datum->{angle},'no',0,0,({x=>$feat_M97[0]->{x},y=>$feat_M97[0]->{y}}));#返回的是一个数组 if($mode == 1){ $coordinate_txt = change_coode(data=>{x=>$M97_tmp[0]->{x} + 2.5 - 0.275,y=>$M97_tmp[0]->{y} - 25 + 0.275},datum=>$datum); }else{ $coordinate_txt = change_coode(data=>{x=>$M97_tmp[0]->{x} - 25 + 0.275,y=>$M97_tmp[0]->{y} - 2.5 + 0.275},datum=>$datum); } }else{ if($mode == 1){ $coordinate_txt = change_coode(data=>{x=>$feat_M97[0]->{x} - 25 + 0.275,y=>$feat_M97[0]->{y} - 2.5 + 0.275},datum=>$datum); }else{ $coordinate_txt = change_coode(data=>{x=>$feat_M97[0]->{x} + 2.5 - 0.275,y=>$feat_M97[0]->{y} - 25 + 0.275},datum=>$datum); } } if($datum->{angle} == 90){ print NEWMYFILE 'T99',"\n"; if($mode == 1){ #$GEN->PAUSE('M98'); print NEWMYFILE 'M98,'.substr($Job,0,6).' $S$I',"\n"; }else{ #$GEN->PAUSE('M97'); print NEWMYFILE 'M97,'.substr($Job,0,6).' $S$I',"\n"; } print NEWMYFILE $coordinate_txt,"\n"; }else{ print NEWMYFILE 'T99',"\n"; if($mode == 1){ print NEWMYFILE 'M97,'.substr($Job,0,6).' $S$I',"\n" }else{ print NEWMYFILE 'M98,'.substr($Job,0,6).' $S$I',"\n"; } print NEWMYFILE $coordinate_txt,"\n"; } } ##5.结束/end foreach my $line(@{$data{end}}){ print NEWMYFILE $line,"\n"; } ## close (NEWMYFILE); return undef; } sub get_tool_change{ my %par = @_; my %info; my %data = %{$par{data}}; my $is_laser = $par{is_laser}; my $row_num = 0; ## my (%head,%special,$exist_2500); ##先判断有无3.054的刀径(排第1) foreach my $line(@{$data{head}}){ my ($tool,$size,$data) = $line =~ /^(T\d+)C(\d*\.?\d{3})(S?.*)$/; next unless $tool; $head{$tool}{data} = 'C'.$2; #### if( abs($size - 0.001) < 0.0001 ){ $head{$tool}{data} = 'C3.054'; $row_num++; $info{$tool}{new_tool_num} = $row_num; $info{$tool}{new_tool} = 'T'.sprintf("%02s",$row_num); $info{$tool}{size} = 3.054; $info{$tool}{new_header} = $info{$tool}{new_tool}.$head{$tool}{data}; } } foreach my $line(@{$data{head}}){ my ($tool,$size,$data) = $line =~ /^(T\d+)C(\d*\.?\d{3})(.*)$/; next unless $tool; next if(abs($size - 0.001) < 0.0001); $row_num++; $info{$tool}{size} = $size; $info{$tool}{new_tool_num} = $row_num; $info{$tool}{new_tool} = 'T'.sprintf("%02s",$row_num); $info{$tool}{new_header} = $info{$tool}{new_tool}.$head{$tool}{data}; } return \%info; } sub manual_sort_tool{ my %par = @_; my $data = $par{data}; my $tool_info = $par{info}; my @items; my ($slot_flag,@slot_size); foreach my $num(1..scalar(keys %{$data->{body}})){ my $tool = 'T'.sprintf("%02s",$num); next unless $tool_info->{$tool}{new_tool}; foreach my $old_tool(sort{$tool_info->{$a}{new_tool_num}<=>$tool_info->{$b}{new_tool_num}} keys %$tool_info){ if( $tool eq $tool_info->{$old_tool}{new_tool} ){ my $suffix; my $size = $tool_info->{$old_tool}{size}; push @items,{tool=>$old_tool,size=>$tool_info->{$old_tool}{size} >= 1 ? $tool_info->{$old_tool}{size} : '0'.$tool_info->{$old_tool}{size},suffix=>$suffix}; last; } } } update_loading("$par{layer} 层请确认钻刀排列顺序...",0,position=>'n'); my %form = $GUI->show_form( -title => "请确认钻孔刀径顺序", -defaultsize => [400,500], -columns => 2, -items => [ { name => 'table', type => 'treeview', label => '', label_position => 'top', expand=>1, scrolledwindow=>{}, property => { height_request=>200, tl_model_type => 'list', enable_grid_lines => 'none', tl_mapping =>['tool' => 'Glib::String','size' => 'Glib::String','suffix'=>'Glib::String'], tl_columns =>[ {title=>'原始刀序',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>0,background=>'#FCFBB6',foreground=>'#000000'},text=>'tool'}]}, {title=>'刀径',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>0,background=>'#FCFBB6',foreground=>'#000000'},text=>'size'}]}, {title=>'后缀(可编辑)',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>1,background=>'#C5DBF2',foreground=>'#000000'},text=>'suffix'}]}, ], }, value => \@items, get_value_func => sub{ my %par = @_; my $tvdata = $par{widget}->tl_get_model_data(); return $tvdata; }, set_value_func => sub{ my %par = @_; my $v = $par{value}; $par{widget}->tl_set_data($v); return 0; }, button_position=>'top', buttons => [ { name=>'top',label=>'置顶',stock=>'gtk-goto-top', command=>sub{ my %p = @_; my $widget = $p{formpanel}->get_widget('table'); $widget->set_property(reorderable=>1); $widget->tl_sel_moveto_top(); $widget->set_property(reorderable=>0); } }, { name=>'up',label=>'上移',stock=>'gtk-go-up', command=>sub{ my %p = @_; my $widget = $p{formpanel}->get_widget('table'); $widget->set_property(reorderable=>1); $widget->tl_sel_move_up(); $widget->set_property(reorderable=>0); } }, { name=>'down',label=>'下移',stock=>'gtk-go-down', command=>sub{ my %p = @_; my $widget = $p{formpanel}->get_widget('table'); $widget->set_property(reorderable=>1); $widget->tl_sel_move_down(); $widget->set_property(reorderable=>0); } }, { name=>'bottom',label=>'置底',stock=>'gtk-goto-bottom', command=>sub{ my %p = @_; my $widget = $p{formpanel}->get_widget('table'); $widget->set_property(reorderable=>1); $widget->tl_sel_moveto_bottom(); $widget->set_property(reorderable=>0); } }, ], }, ] ); return 'Cancel' unless %form; ##将界面确认的结果重新整理一遍 my %info; my @data = @{$form{table}}; my $row_num; foreach my $item(@data){ $row_num++; if( $item->{suffix} =~ /^\(w(\d+)\)$/i || $item->{suffix} =~ /^\(w(\d+)s\d+\)$/i || $item->{suffix} =~ /^\(s(\d+)\)$/i){ $info{$item->{tool}}{suffix} = $item->{suffix}; $info{$item->{tool}}{size} = $item->{size}; } elsif($item->{suffix} =~ /^(\d+)$/i ){ $info{$item->{tool}}{suffix} = $item->{suffix}+0; $info{$item->{tool}}{size} = $item->{size}; } else{ $info{$item->{tool}}{size} = $item->{size}; } $info{$item->{tool}}{new_tool_num} = $row_num; $info{$item->{tool}}{new_tool} = 'T'.sprintf("%02s",$row_num); if( $item->{suffix} =~ /^\((w|s)(\d+)\)$/i || $item->{suffix} =~ /^\(w(\d+)s(\d+)\)$/i){ $info{$item->{tool}}{new_header} = $info{$item->{tool}}{new_tool}.'C'.sprintf("%.3f",$info{$item->{tool}}{size}).$item->{suffix}; } else{ $info{$item->{tool}}{new_header} = $info{$item->{tool}}{new_tool}.'C'.sprintf("%.3f",$info{$item->{tool}}{size}); } } ## return \%info; } sub input_drill_program{ my %par = @_; $GEN->COM( "input_manual_reset"); $GEN->COM( "input_manual_set,path=$par{file},job=$Job,step=$Step,format=Excellon2,data_type=ascii, units=mm,coordinates=absolute,zeroes=none,nf1=3,nf2=3,decimal=no,separator=nl,tool_units=mm,layer=$par{new_layer},wheel=, wheel_template=,nf_comp=0,multiplier=1,text_line_width=0.0024,signed_coords=no,break_sr=yes,drill_only=no,merge_by_rule=no,threshold=200,resolution=3"); $GEN->COM( "input_manual,script_path="); $GEN->zoomHome(); return undef; } =head web server数据传输 =cut sub sec_web_services{ use LWP::UserAgent; use LWP; use HTTP::Headers; use HTTP::Response; use Encode; use JSON; use JSON qw(encode_json); my $url = shift; my $data = shift; my $json = JSON->new->allow_nonref; my $ua = LWP::UserAgent->new(); $ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0"); my $header = ['Content-Type' => 'application/json; charset=UTF-8']; my $body = encode('utf8', $json->encode($data)); my $request = HTTP::Request->new('POST', $url, $header, $body); my $res = $ua->request($request); #$GUI->debug(-text=>dump($res,'-----------------------------------------------------------------',$res->is_success)); if ($res->is_success) { return 0; }else{ return 1; } } =head 3:3 不省零 坐标转换 data=>{x=>,y=>} datum=>{x=>,y=>} =cut sub change_coode { my %par = @_; my ($check_x,$check_y); $par{data}->{x} = $par{data}->{x} - $par{datum}->{x}; $par{data}->{y} = $par{data}->{y} - $par{datum}->{y}; $check_x = $par{data}->{x} > 0 ? '': '-'; $check_y = $par{data}->{y} > 0 ? '': '-'; $par{data}->{x} = sprintf("%0.3f",$par{data}->{x}); $par{data}->{x} = sprintf("%06s",abs($par{data}->{x})*1000); $par{data}->{y} = sprintf("%0.3f",$par{data}->{y}); $par{data}->{y} = sprintf("%06s",abs($par{data}->{y})*1000); return 'X'.$check_x.($par{data}->{x}).'Y'.$check_y.($par{data}->{y}); } =head 坐标转换成数值 =cut sub change_coode_to_vale { my $string = shift; $string =~ /X(-?\w+)Y(-?\w+)/; my $x_data = sprintf("%0.3f",$1/1000); my $y_data = sprintf("%0.3f",$2/1000); return {x=>$x_data,y=>$y_data}; } sub _deleteLayer{ my %par = @_; foreach my $layer(@{$par{layer}}){ $GEN->deleteLayer(layer=>$layer) if ($GEN->isLayerExists(job=>$Job,layer=>$layer)); } } =head 输出层新命名 =cut sub get_new_layer_name { my $job = shift; my @tmp = split/\-/,$job; splice(@tmp,2,1); $tmp[2] =~ s/2//; unless($tmp[2]){ splice(@tmp,2,1); } my $new = join('-',@tmp); return $new; } =head 短槽拉伸值 slot_size=>,slot_length=> =cut sub ger_short_slot_vale { my %par = @_; my $info = { 1.5 =>[ {size_min=>0.4,size_max=>0.55,length=>0,angle=>0}, {size_min=>0.6,size_max=>0.65,length=>0.07,angle=>5}, {size_min=>0.7,size_max=>0.75,length=>0.0625,angle=>4}, {size_min=>0.8,size_max=>0.95,length=>0.05,angle=>2.5}, {size_min=>1.0,size_max=>1.25,length=>0.045,angle=>2}, {size_min=>1.3,size_max=>1.6,length=>0.0375,angle=>1}, {size_min=>1.65,size_max=>2.5,length=>0.0375,angle=>1}, {size_min=>2.55,size_max=>999,length=>0.03,angle=>0.5}, ], 1.75 =>[ {size_min=>0.4,size_max=>0.55,length=>0.055,angle=>4}, {size_min=>0.6,size_max=>0.65,length=>0.055,angle=>3}, {size_min=>0.7,size_max=>0.75,length=>0.05,angle=>2.5}, {size_min=>0.8,size_max=>0.95,length=>0.045,angle=>2}, {size_min=>1.0,size_max=>1.25,length=>0.0375,angle=>1}, {size_min=>1.3,size_max=>1.6,length=>0.03,angle=>0.5}, {size_min=>1.65,size_max=>2.5,length=>0.03,angle=>0.5}, {size_min=>2.55,size_max=>999,length=>0.025,angle=>0.5}, ], 2.0 =>[ {size_min=>0.4,size_max=>0.55,length=>0.045,angle=>3}, {size_min=>0.6,size_max=>0.65,length=>0.0375,angle=>2}, {size_min=>0.7,size_max=>0.75,length=>0.0375,angle=>1.5}, {size_min=>0.8,size_max=>0.95,length=>0.03,angle=>1}, {size_min=>1.0,size_max=>1.25,length=>0.03,angle=>1}, {size_min=>1.3,size_max=>1.6,length=>0.025,angle=>0.5}, {size_min=>1.65,size_max=>2.5,length=>0.02,angle=>0.5}, {size_min=>2.55,size_max=>999,length=>0.02,angle=>0}, ], }; my $type; if($par{slot_length}/$par{slot_size} <= 1.5){ $type = 1.5; }elsif($par{slot_length}/$par{slot_size} > 1.5 and $par{slot_length}/$par{slot_size} <= 1.75){ $type = 1.75; }elsif($par{slot_length}/$par{slot_size} > 1.75 and $par{slot_length}/$par{slot_size} <= 2){ $type = 2.0; }elsif($par{slot_length}/$par{slot_size} > 2){ return 0; } my $result; foreach my $tmp (@{$info->{$type}}){ if($par{slot_size} >= $tmp->{size_min} and $par{slot_size} <= $tmp->{size_max}){ $result = 1; return $tmp; } } unless ($result){ return 0; } } __END__