=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__