#!/usr/bin/env python3
#-*- coding:utf-8 -*-
import json
import argparse
import os, sys,shutil,datetime
import logging
import ezcam
from filelock import FileLock
import sys
import re
import time,zipfile
# resize = '0'
# jobpath= 'D:\AutoOutput'
# StartRun = True
# OperationMode = '導入-導出'
# DataFormat = 'ODB'
# def get_filelist(dir):
# Filelist = []
# for home, dirs, files in os.walk(dir):
# for filename in files:
# Filelist.append(os.path.join(home, filename).replace('\\','/'))
# return Filelist
def zipDir(dirpath,outFullName):
"""
压缩指定文件夹
:param dirpath: 目标文件夹路径
:param outFullName: 压缩文件保存路径+xxxx.zip
:return: 无
"""
zip = zipfile.ZipFile(outFullName,"w",zipfile.ZIP_DEFLATED)
for path,dirnames,filenames in os.walk(dirpath):
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
fpath = path.replace(dirpath,'')
for filename in filenames:
zip.write(os.path.join(path,filename),os.path.join(fpath,filename))
zip.close()
def del_file(filepath):
del_list = os.listdir(filepath)
for f in del_list:
file_path = os.path.join(filepath, f)
if os.path.isfile(file_path):
os.remove(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
class AutoOutput:
def __init__(self,InputJobPath,JobName,LayerType,DataFormat,OutputJobPath,InfoFileIsExist,resize=0,units='mm',AutoCompare=False):
# 文件的输入路径
self.InputJobPath = InputJobPath
# 输入的文件名
self.JobName = JobName
# 输入的格式
self.DataFormat = DataFormat
# 输出路径
self.OutputPath = OutputJobPath
# 输出文件路径
self.OutputJobPath = OutputJobPath
self.resize = resize
self.units = units
self.OutputLayertype = LayerType
self.AutoCompare = AutoCompare
# 默认的panelstepname
self.PanelStepName = ''
# 指定要输出的层
self.OutputLayers = []
# 指定要输出的层对应的极性
self.Polarity = []
#旋转类型
self.rotatetype = 0
# 缩放后输出的层
# self.ScaleOutputLayers = []
# 指定要输出的层的极性
self.Polarity = []
# 由InfoFileIsExist确定 若存在信息文档 则从信息文档中的aglin值确定 若没有 则由传递的LayerType参数确定
self.InfoFileIsExist = InfoFileIsExist
if InfoFileIsExist:
self.LayerType = ''
else:
if(LayerType == 'Inner'):
self.LayerType = 'inner'
elif(LayerType == 'Outer'):
self.LayerType = 'outer'
print(f'========== - InputJobPath={self.InputJobPath} - JobName={self.JobName} - DataFormat={self.DataFormat} - OutputJobPath={self.OutputJobPath} ==========')
def writeLog(self,msg):
f = open(f'{self.OutputJobPath}info.txt','a')
f.write(f'{msg}\n')
f.close()
def GetInfo(self):
InputPath = self.InputJobPath
# print("*********************"+InputPath+"********************")
FileName =self.JobName
# print("*********************"+FileName+"*********************")
InputInfoFilePath = InputPath +"\\\\" + FileName + ".txt"
# print("*********************"+InputInfoFilePath+"***********************")
with open(InputInfoFilePath,'r') as f:
str = f.read()
strings = str.split(' ')
for s in strings:
key = s.split('=')
if key[0] == 'Layerpair':
layers = key[1].split('/')
self.OutputLayers.append(layers[0])
self.OutputLayers.append(layers[1])
elif key[0] == 'Scale':
scale = key[1].split(',')
if float(scale[0]) != 0:
self.x_scale = scale[0]
if float(scale[1]) != 0:
self.y_scale = scale[1]
elif key[0] == 'Polarity':
polaritys = key[1].split('/')
self.Polarity.append(polaritys[0])
self.Polarity.append(polaritys[1])
elif key[0] == 'align':
if key[1] == 'inner':
self.LayerType = 'Inner'
elif key[1] == 'outer':
self.LayerType = 'Outer'
elif key[1] == 'soldermask':
self.LayerType = 'SolderMask'
def ImportJob(self):
print(f'========== Import 料號 - {self.InputJobPath} ==========')
if self.DataFormat == "ODB":
ezcam.COM('import_job', db='ezcam', path=f'{self.InputJobPath}\\{self.JobName}.tgz', name=self.JobName, analyze_surfaces='yes')
#import檢查
else:
#建立料號
ezcam.create_job(self.JobName)
cur_job = ezcam.get_job(self.JobName)
cur_job.open()
cur_job.create_step(self.org)
cur_step = cur_job.get_step(self.org)
# ezcam.VOF()
ezcam.COM('input_manual_reset')
ezcam.COM('input_manual_set',path=self.jobPath,job=self.JobName,step=self.org,format='Gerber274x',data_type='Ascii',units='inch',coordinates='absolute',zeroes='leading',nf1=2,nf2=6,decimal='no',separator='',tool_units='inch',layer=self.JobName,wheel='',wheel_template='',nf_comp=0,multiplier=1,text_line_width=0.0024,signed_coords='no',break_sr='no',drill_only='no',merge_by_rule='no',threshold=0,resolution=0)
ezcam.COM('input_manual',script_path='')
print('======================== input_manual_set =================================')
cur_step.open(skip_gui= True)
ezcam.COM('clipb_open_job',job=self.JobName,update_clipboard='view_job')
ezcam.set_def_units(self.units)
return 'ok'
def SetScale(self):
###如果宽大于高并且宽大于630,调换x,y的涨缩值
lay_info = ezcam.DO_INFO(args=f'-t step -e {self.JobName}/{self.PanelStepName} -d PROF_LIMITS -m json')
PanelWidth = lay_info['gPROF_LIMITSxmax'] - lay_info['gPROF_LIMITSxmin']
PanelHeight = lay_info['gPROF_LIMITSymax'] - lay_info['gPROF_LIMITSymin']
if(PanelWidth >= PanelHeight and PanelWidth > 630):
self.rotatetype = 90
elif(PanelWidth < PanelHeight and PanelHeight < 630):
self.rotatetype = 90
def JobStart(self):
#print(f'jobpath={self.jobPath},JobName={self.JobName},odbname={self.odbName}')
# InputInfoFilePath = self.InputJobPath +"\\\\" + self.JobName + ".txt"
if self.InfoFileIsExist:
#获取info文本中的有效信息
self.GetInfo()
#1. 确证输出路径是否存在,如果已经存在则删除重建
self.OutputJobPath = f'{self.OutputJobPath}\\{self.JobName}\\'
if os.path.exists(self.OutputJobPath): # 如果文件存在
del_file(self.OutputJobPath)
else:
os.makedirs(self.OutputJobPath)
#2. 数据库已有此料号,则删除
res = ezcam.DO_INFO(args = f'-t job -e {self.JobName} -d EXISTS -m json')['gEXISTS']
if res == True:
print('========== 刪除已存在的料号 ==========')
ezcam.COM('close_job',job=self.JobName)
ezcam.COM('delete_entity',job='',type='job',name=self.JobName)
#3. import job
res = self.ImportJob()
print('============================== import job ok ==================================')
#4. 确定输出哪个Step
self.SetPanelStepName() #默认 self.PanelStepName = 'panel',也可在SetPanelStepName中,根据不同的客户修改panel的step名称
print(f'========== - self.PanelStepName={self.PanelStepName} ==========')
#确定输出哪些层别
if len(self.OutputLayers) == 0:
self.SetOutputLayersByName()
#5. 对要输出的layer层进行x,y方向的缩涨
self.SetScale()
#6. 记录与Job相关的信息
self.InforJob()
self.InforLayer()
#7. 输出
self.Output()
#8. 压缩并删除原档
zipFile = f'{self.OutputPath}\\{self.JobName}.zip'
if os.path.exists(zipFile): # 如果文件存在
os.remove(zipFile)
zipDir(self.OutputJobPath, f'{self.OutputPath}\\{self.JobName}.zip')
def SetPanelStepName(self):
cur_job = ezcam.get_job(str(self.JobName))
with dblist_mutex:
cur_job.open()
ezcam.set_def_units('mm')
stepList = cur_job.get_steps_list()
print(stepList)
for i in range(len(stepList)):
if(stepList[i].split('.')[0]=='panel' and stepList[i].split('.')[1] == self.JobName):
self.PanelStepName = stepList[i]
print(self.PanelStepName)
return
elif(stepList[i].split('.')[0]=='panel-500'):
self.PanelStepName = stepList[i]
return
elif(stepList[i].split('.')[0]=='pnl' ):
self.PanelStepName = stepList[i]
return
def SetOutputLayersByName(self): ##根据层别名称来确定要输出的层
lyr_matrix = ezcam.DO_INFO(args =f'-t matrix -e {self.JobName}/matrix -d ROW -m json'.format(job={self.JobName}))
layList = lyr_matrix['gROWname']
layWise = lyr_matrix['gROWside']
layPolarity = lyr_matrix['gROWpolarity']
for i in range(len(layWise)):
if(layWise[i]==self.LayerType):
self.OutputLayers.append(layList[i])
self.Polarity.append(layPolarity[i])
'''if self.LayerType == 'Outer':
if 'cs' in layList:
self.OutputLayers.append('cs')
if 'ss' in layList:
self.OutputLayers.append('ss')
elif self.LayerType == 'Inner':
if 'in2' in layList:
self.OutputLayers.append('in2')
if 'in3' in layList:
self.OutputLayers.append('in3')
if 'in4' in layList:
self.OutputLayers.append('in4')
if 'in5' in layList:
self.OutputLayers.append('in5')
if 'in6' in layList:
self.OutputLayers.append('in6')
if 'in7' in layList:
self.OutputLayers.append('in7')
if 'in8' in layList:
self.OutputLayers.append('in8')
if 'in9' in layList:
self.OutputLayers.append('in9')
elif self.LayerType == 'SolderMask':
if 'cm' in layList:
self.OutputLayers.append('cm')
if 'sm' in layList:
self.OutputLayers.append('sm')
'''
def Contourse(self, step_name):
stp_sr = []
stp_sr = ezcam.DO_INFO(args=f'-t step -e {self.JobName}/{step_name} -d SR -m json')
print(len(stp_sr['gSRstep']))
if len(stp_sr['gSRstep']) == 0 and step_name not in self.AlreadDoStep:
self.AlreadDoStep.append(step_name)
ezcam.COM('open_entity', job=self.JobName, type='step', name=step_name,skip_gui='yes' )
ezcam.COM('units', type='Inch')
ezcam.COM('affected_layer', name='', mode='all', affected=False)
ezcam.COM('clear_layers')
for eachLay in self.OutputLayers:
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=True)
ezcam.COM('sel_contourize', accuracy=0.1, break_to_islands=True, clean_hole_size=3, clean_hole_mode='x_and_y')
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=False)
ezcam.COM('editor_page_close')
return
for each_step in stp_sr['gSRstep']:
self.Contourse(each_step)
def Output(self):
self.AlreadDoStep = []
print(self.PanelStepName)
self.Contourse(self.PanelStepName)
for index in range(len(self.OutputLayers)):
ezcam.COM('output_layer_reset')
ezcam.COM('output_layer_set', layer=self.OutputLayers[index], angle=0, mirror=False, x_scale=1, y_scale=1, comp=0, polarity='positive', setupfile='', setupfiletmp='', line_units='inch', gscl_file='', step_scale=False)
ezcam.COM('output', job=self.JobName, step=self.PanelStepName, format='Gerber274x', dir_path=self.OutputJobPath, prefix='', suffix='', x_anchor=0, y_anchor=0, x_offset=0, y_offset=0, line_units='inch', no_scale_attrs_file='', break_sr=False, break_symbols=False, break_arc=False, units='inch', scale_mode='all', surface_mode='contour', min_brush=2, surface_clean_hole_overlap=0.5, clip_profile=False, coordinates='absolute', decimal=False, zeroes='none', nf1=2, nf2=6, modal='', wheel='', film_size_cross_scan='', film_size_along_scan='', ds_model='')
def InforJob(self):
self.writeLog(f'JobName={self.JobName}')
self.writeLog(f'LayerType={self.OutputLayertype}')
tmpProfileInfo = ezcam.DO_INFO(args = f'-t step -e {self.JobName}/{self.PanelStepName} -d PROF_LIMITS -m json')
PanelWidth = tmpProfileInfo['gPROF_LIMITSxmax'] - tmpProfileInfo['gPROF_LIMITSxmin']
PanelHeight = tmpProfileInfo['gPROF_LIMITSymax'] - tmpProfileInfo['gPROF_LIMITSymin']
self.writeLog(f'Number=1000')
self.writeLog(f'PanelWidth={PanelWidth}')
self.writeLog(f'PanelHeight={PanelHeight}')
self.writeLog(f'Thick=0')
self.writeLog(f'Cols=1')
self.writeLog(f'Rows=1')
str ='0'
color = 'White'
if(self.LayerType=='Outer'):
str ='6'
color = 'Black'
self.writeLog(f'RiseFallType={str}')
filePath = f'D:\\ezcam\\fw\\jobs\\{self.JobName}\\steps\\{self.PanelStepName}\\layers\\{self.OutputLayers[0]}\\lpd'
with open(filePath,'r') as f:
iText = f.read()
aa = re.findall(f'.STRETCH.*',iText)
for scale in aa:
if(self.rotatetype=='0'):
if(scale.split('=')[0]=='XSTRETCH'):
stepscale = int(scale.split("=")[1])/100
self.writeLog(f'ScaleX={stepscale}')
elif(scale.split('=')[0]=='YSTRETCH'):
stepscale = int(scale.split("=")[1])/100
self.writeLog(f'ScaleY={stepscale}')
elif(self.rotatetype=='90'):
if(scale.split('=')[0]=='YSTRETCH'):
stepscale = int(scale.split("=")[1])/100
self.writeLog(f'ScaleX={stepscale}')
elif(scale.split('=')[0]=='XSTRETCH'):
stepscale = int(scale.split("=")[1])/100
self.writeLog(f'ScaleY={stepscale}')
#self.writeLog(f'ScaleY={scale.split("=")[1]/100}')
self.InforSideASideB('tzldi_side_a')
#self.InforSideASideB('tzldi_side_b')
self.writeLog(f'BackColor={color}')
self.writeLog(f'LayerCount={len(self.OutputLayers)}')
def InforSideASideB(self,side):
ezcam.COM('open_entity', job=self.JobName, type='step', name=self.PanelStepName,skip_gui='yes' )
ezcam.COM('units', type='mm')
ezcam.COM('affected_layer', name='', mode='all', affected=False)
i = int(0)
for eachLay in self.OutputLayers:
i = i + 1
tmpLay = f'Layer{i}'
ezcam.COM('delete_layer', layer='tzldi')
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=True)
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text=side, option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
ezcam.COM('get_select_count')
count=int(ezcam.COMANS())
if count > 0 :
ezcam.COM('sel_copy_other', dest='layer_name', target_layer='tzldi', invert=False, dx=0, dy=0, size=0, x_anchor=0, y_anchor=0, mirror='none', rotation=0)
tmpTargetInfor = ezcam.DO_INFO(args = f'-t layer -e {self.JobName}/{self.PanelStepName}/tzldi -d FEATURES -m json')
if len(tmpTargetInfor['gFEATURES']) > 0:
for item in tmpTargetInfor['gFEATURES']:
if item != '':
itemStr = json.dumps(item)
dict_json = json.loads(itemStr)
x = ''
y = ''
for key in dict_json:
if key == 'x':
x = dict_json[key]
if key =='y':
y = dict_json[key]
if x != '' and y != '':
if i == 1 and side == 'tzldi_side_a':
self.writeLog(f'{tmpLay}SideATargetX={x}')
self.writeLog(f'{tmpLay}SideATargetY={y}')
elif i == 2 and side == 'tzldi_side_b':
self.writeLog(f'{tmpLay}SideBTargetX={x}')
self.writeLog(f'{tmpLay}SideBTargetY={y}')
elif x != '' and y == '':
if i == 1 and side == 'tzldi_side_a':
self.writeLog(f'{tmpLay}SideATargetX={x}')
self.writeLog(f'{tmpLay}SideATargetY={0}')
elif i == 2 and side == 'tzldi_side_b':
self.writeLog(f'{tmpLay}SideBTargetX={x}')
self.writeLog(f'{tmpLay}SideBTargetY={0}')
elif x == '' and y != '':
if i == 1 and side == 'tzldi_side_a':
self.writeLog(f'{tmpLay}SideATargetX={0}')
self.writeLog(f'{tmpLay}SideATargetY={y}')
elif i == 2 and side == 'tzldi_side_b':
self.writeLog(f'{tmpLay}SideBTargetX={0}')
self.writeLog(f'{tmpLay}SideBTargetY={y}')
else:
if i == 1 and side == 'tzldi_side_a':
self.writeLog(f'{tmpLay}SideATargetX={0}')
self.writeLog(f'{tmpLay}SideATargetY={0}')
elif i == 2 and side == 'tzldi_side_b':
self.writeLog(f'{tmpLay}SideBTargetX={0}')
self.writeLog(f'{tmpLay}SideBTargetY={0}')
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=False)
else:
#if i%2 == 1 and side == 'tzldi_side_a':
#self.writeLog(f'{tmpLay}SideATargetX={0}')
#self.writeLog(f'{tmpLay}SideATargetY={0}')
#elif i%2 == 0 and side == 'tzldi_side_b':
#self.writeLog(f'{tmpLay}SideBTargetX={0}')
#self.writeLog(f'{tmpLay}SideBTargetY={0}')
if i%2 == 1 :
self.writeLog(f'{tmpLay}SideATargetX={0}')
self.writeLog(f'{tmpLay}SideATargetY={0}')
elif i%2 == 0 :
self.writeLog(f'{tmpLay}SideBTargetX={0}')
self.writeLog(f'{tmpLay}SideBTargetY={0}')
def InforLayer(self):
ezcam.COM('open_entity', job=self.JobName, type='step', name=self.PanelStepName,skip_gui='yes' )
ezcam.COM('units', type='mm')
ezcam.COM('affected_layer', name='', mode='all', affected=False)
i = int(0)
for eachLay in self.OutputLayers:
#tmpLay = eachLay.join( '(' )
#self.writeLog(eachLay + (eachLay.join( '{' )))
#self.writeLog(f'{')
i = i + 1
print(f'******************************i= {i}')
tmpLay = f'Layer{i}'
self.writeLog(f'{tmpLay}LayerName={eachLay}')
print(self.InputJobPath)
#filePath = f'D:\\ezcam\\fw\\jobs\\{self.JobName}\\steps\\panel.h10aa3037d1\\layers\\{eachLay}\\lpd'
#print(filePath)
#with open(filePath,'r') as f:
#iText = f.read()
#aa = re.findall(f'.STRETCH.*',iText)
#for scale in aa:
#if(self.rotatetype == 0):
#if(scale.split('=')[0]=='XSTRETCH'):
#self.writeLog(f'{tmpLay}ScaleX={scale.split("=")[1]}')
#elif(scale.split('=')[0]=='YSTRETCH'):
#self.writeLog(f'{tmpLay}ScaleY={scale.split("=")[1]}')
#elif(self.rotatetype == 90):
# if(scale.split('=')[0]=='YSTRETCH'):
# self.writeLog(f'{tmpLay}ScaleX={scale.split("=")[1]}')
# elif(scale.split('=')[0]=='XSTRETCH'):
# self.writeLog(f'{tmpLay}ScaleY={scale.split("=")[1]}')
#if self.InfoFileIsExist:
tmpSide=self.GetSideAB_ByLayerName_i(i)
#else:
#tmpSide=self.GetSideAB_ByLayerName(eachLay)
self.writeLog(f'{tmpLay}Side={tmpSide}')
groupId=self.GetGroupIdByLayerName(eachLay)
self.writeLog(f'{tmpLay}GroupId={groupId}')
self.writeLog(f'{tmpLay}Polarity={self.Polarity[i-1]}')
#旋转类型
self.writeLog(f'{tmpLay}Rotatetype={self.rotatetype}')
ezcam.COM('delete_layer', layer='tzldi')
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=True)
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='tzldi', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
ezcam.COM('sel_copy_other', dest='layer_name', target_layer='tzldi', invert=False, dx=0, dy=0, size=0, x_anchor=0, y_anchor=0, mirror='none', rotation=0)
tmpTargetInfor = ezcam.DO_INFO(args = f'-t layer -e {self.JobName}/{self.PanelStepName}/tzldi -d FEATURES -m json')
features = tmpTargetInfor['gFEATURES']
if(self.OutputLayertype=='Inner'):
self.writeLog(f'{tmpLay}TargetCount=0')
ezcam.COM('affected_layer', name=eachLay, mode='single', affected=False)
self.OutputSplitInfo(self.JobName,self.PanelStepName,eachLay,tmpLay)
#self.writeLog(f'{tmpLay}TextMoudleId=258')
self.writeLog(f'{tmpLay}TextMoudleX=-999999')
self.writeLog(f'{tmpLay}TextMoudleY=-999999')
self.writeLog(f'{tmpLay}TextMoudlevalid=no')
#self.writeLog('}')
def OutputSplitInfo(self,job_name,step_name,eachLay,tmpLay):
ezcam.COM('open_entity', job=job_name, type='step', name=step_name, iconic=False, skip_gui='yes')
ezcam.COM('units', type='mm')
ezcam.COM('affected_layer', name='', mode='all', affected=False)
ezcam.COM('clear_layers')
ezcam.COM('display_layer', name=eachLay, display=True, number=1)
ezcam.COM('work_layer', name=eachLay)
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='.trmh', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='.trmv', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.shared2', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.measure', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.shared4', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_logic', filter_name='popup', logic='or')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
selCount = int(ezcam.COMANS())
print(selCount,end="**************************************")
if selCount == 0:
self.writeLog(f'{tmpLay}SplitlinesCount=0')
else:
self.writeLog(f'{tmpLay}SplitlinesCount={selCount}')
# i用来记录分割线的条数
linecount = 1
# 写入垂直分割线的信息
ezcam.COM('sel_clear_feat')
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', condition=True, attribute='.fiducial_name', text='.trmv', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
trmvCount = int(ezcam.COMANS())
print(trmvCount,end="***********************************************")
if trmvCount > 0:
InfoTrmv = ezcam.DO_INFO(args = f'-t layer -e {job_name}/{step_name}/{eachLay} -d FEATURES -o select -m json'.format(job={job_name},step={step_name},layer={eachLay}))['gFEATURES']
for index in range(len(InfoTrmv)):
#print(f'*****************{InfoTrmv[index]['x']}***************')
#print(f'*****************{InfoTrmv[index]['y']}***************')
x = float(InfoTrmv[index]["x"]) * 25.4
y = float(InfoTrmv[index]["y"]) * 25.4
self.writeLog(f'{tmpLay}Splitlines{linecount}PosX=x')
self.writeLog(f'{tmpLay}Splitlines{linecount}PosY=y')
self.writeLog(f'{tmpLay}Splitlines{linecount}Flag=1')
linecount = linecount + 1
# 写入水平分割线的信息
ezcam.COM('sel_clear_feat')
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', condition=True, attribute='.fiducial_name', text='.trmh', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
trmhCount = int(ezcam.COMANS())
print(trmhCount,end="***********************************************")
if trmhCount > 0:
InfoTrmh = ezcam.DO_INFO(args = f'-t layer -e {job_name}/{step_name}/{eachLay} -d FEATURES -o select -m json'.format(job={job_name},step={step_name},layer={eachLay}))['gFEATURES']
for index in range(len(InfoTrmh)):
x = float(InfoTrmh[index]["x"]) * 25.4
y = float(InfoTrmh[index]["y"]) * 25.4
self.writeLog(f'{tmpLay}Splitlines{linecount}PosX=x')
self.writeLog(f'{tmpLay}Splitlines{linecount}PosY=y')
self.writeLog(f'{tmpLay}Splitlines{linecount}Flag=0')
linecount = linecount + 1
# 将分区点的信息写入临时文件中,处理后再写入SplitArea.txt中
ezcam.COM('sel_clear_feat')
ezcam.COM('filter_reset', filter_name='popup')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.measure', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.shared2', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_set', filter_name='popup', attribute='.fiducial_name', condition=True, text='*.shared4', option='', min_int_val='', max_int_val='', min_float_val='', max_float_val='')
ezcam.COM('filter_atr_logic', filter_name='popup', logic='or')
ezcam.COM('filter_area_strt')
ezcam.COM('filter_area_end', layer='', filter_name='popup', operation='select', area_type='none', inside_area=False, intersect_area=False, lines_only=False, ovals_only=False, min_len=0, max_len=100, min_angle=0, max_angle=0)
PointCount = int(ezcam.COMANS())
tempPointPath = "D:\\ezcam\\output\\"+job_name+"\\tempPointPath.txt"
print("************************"+tempPointPath+"************************")
if os.path.exists(tempPointPath):
shutil.rmtree(tempPointPath)
# os.mknod(tempPointPath)
with open(tempPointPath,'w') as f1:
# f1.write(job_name+" "+self.lyr_list[index])
if PointCount > 0 :
InfoPoint = ezcam.DO_INFO(args = f'-t layer -e {job_name}/{step_name}/{self.lyr_list[layIndex]} -d FEATURES -o select -m json '.format(job={job_name},step={step_name},layer={self.lyr_list[layIndex]}))['gFEATURES']
for index in range(len(InfoPoint)):
x = float(InfoPoint[index]["x"]) * 25.4
y = float(InfoPoint[index]["y"]) * 25.4
Count = InfoPoint[index]["attributes"][".fiducial_name"].split(".")[1]
# print("*************************"+Count+"**************************")
if Count == "measure":
f1.write(f'{x} {y} 1\n')
elif Count == "shared2":
f1.write(f'{x} {y} 2\n')
elif Count == "shared4":
f1.write(f'{x} {y} 4\n')
# 调用分区方法,文件中
self.SplitArea(tempPointPath,job_name,eachLay)
os.remove(tempPointPath)
# tempPointPath:临时存放所有分区点的信息的路径
# job_name:工程名
# layer_name:层名
def SplitArea(self,tempPointPath,job_name,layer_name):
print("********************************")
print("***********************"+tempPointPath+"****************")
print("***********************"+OutputSplitInfo+"********************")
print("***********************"+job_name+"**************************")
print("***********************"+layer_name+"***************************")
pointList = []
pointDict = {}
if os.path.exists(tempPointPath):
with open(tempPointPath,'r') as f:
lines = f.readlines()
for line in lines:
data = line.split(' ')
point = Point(data[0],data[1],data[2])
pointList.append(point)
pointList.sort()
pointList.reverse()
ipointList = len(pointList) - 1
while ipointList >= 3 :
print(f'******************{pointList[ipointList].getInfo()}********************')
#所有的点
outPoint = self.GetPoints(pointList[ipointList],pointList)
pointDict[pointList[ipointList]] = outPoint
pointList[ipointList].setCount(int(pointList[ipointList].getCount())-1)
for k in range(len(pointList)-1,-1,-1):
for point in outPoint:
if point == pointList[k]:
pointList[k].setCount(int(pointList[k].getCount())-1)
del_num = int(0)
for k in range(len(pointList)-1,-1,-1):
if int(pointList[k].getCount()) <=0 :
pointList.remove(pointList[k])
del_num = del_num + 1
if del_num != 1:
ipointList = ipointList - del_num + 1
ipointList = len(pointList) - 1
#exit()
resultDict = sorted(pointDict.items(),key=lambda x:int(x[0].getX()))
#print(sorted(pointDict.items(),key=lambda x:x[0].getX()))
for result in resultDict:
print(f'**{result[0].getInfo()}*****')
#exit()
j = int(1)
with open(OutputSplitInfo,mode='a+') as f:
for result in resultDict:
f.write('\n')
resultValues = result[1]
for i in range(len(resultValues)):
f.write(f'{layer_name} {resultValues[i].getInfo()} 分区{j}\n')
j = j + 1
def CalculateTargetSize(self,tmpLay,strSymbol,index):
print(f'***************strSymbol={strSymbol}***********************')
patternR = re.compile('r[0-9]')
tmpMatch = patternR.match(strSymbol)
if tmpMatch:
# print(f'**************************')
tmpSize = strSymbol.replace("r","")
tmpSize = 0.001 * float(tmpSize)
self.writeLog(f'{tmpLay}TargetWidth{index}={tmpSize}')
self.writeLog(f'{tmpLay}TargetHeight{index}={tmpSize}')
else:
self.writeLog(f'{tmpLay}TargetWidth{index}=0')
self.writeLog(f'{tmpLay}TargetHeight{index}=0')
def GetSideAB_ByLayerName_i(self,i):
if i%2 == 1:
return 'A'
if i%2 == 0:
return 'B'
return 'X'
def GetSideAB_ByLayerName(self,layName):
if layName == 'cs':
return "A"
if layName == 'ss':
return "B"
if layName == 'cm':
return "A"
if layName == 'sm':
return "B"
if layName == 'in2':
return "A"
if layName == 'in3':
return "A"
if layName == 'in4':
return "A"
if layName == 'in5':
return "B"
if layName == 'in6':
return "A"
if layName == 'in7':
return "B"
if layName == 'in8':
return "B"
if layName == 'in9':
return "B"
return "X"
def GetGroupIdByLayerName(self,layName):
if layName == 'l2':
return "1"
if layName == 'l3':
return "1"
if layName == 'l4':
return "2"
if layName == 'l5':
return "2"
if layName == 'l6':
return "3"
if layName == 'l7':
return "3"
if layName == 'l8':
return "4"
if layName == 'l9':
return "4"
return "1"
#辅助类Point
class Point:
def __init__(self,x,y,count):
self.x=x
self.y=y
self.count=count
def setX(self,x):
self.x= x
def getX(self):
return self.x
def setY(self,y):
self.y = y
def getY(self):
return self.y
def setCount(self,count):
self.count = count
def getCount(self):
return self.count
def getInfo(self):
#return "分区 "+self.x+" "+self.y+" "
return self.x+","+self.y
def __cmp__(self,other):
if self.__eq__(other):
return 0
elif self.__lt__(other):
return -1
elif self.__gt__(other):
return 1
def __eq__(self,other):
if not isinstance(other,Point):
print("can't cmp other type to Point")
return math.pow(float(self.x),2)+math.pow(float(self.y),2) == math.pow(float(other.x),2)+math.pow(float(other.y),2)
#return self.x == other.x and self.y == other.y
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5sms.py --script-param="D:\\AutoOutput\\Autojob\\h10aa3037d1-lngfy.tgz Inner D:\AutoOutput\AutoOutput ODB
#def __hash__(self):
#return hash(self.x+self.y)
def __lt__(self,other):
if not isinstance(other,Point):
print("can't cmp other type to Point")
if math.pow(float(self.x),2)+math.pow(float(self.y),2) < math.pow(float(other.x),2)+math.pow(float(other.y),2):
return True
else:
return False
def __gt__(self,other):
if not isinstance(other,Point):
print("can't cmp other type to Point")
if math.pow(float(self.x),2)+math.pow(float(self.y),2) > math.pow(float(other.x),2)+math.pow(float(other.y),2):
return True
else:
return False
# 辅助类Distencs
class Distence:
def __init__(self,dis,flag):
self.dis = dis
self.flag = flag
def setDis(self,dis):
self.dis = dis
def getDis(self):
return self.dis
def setFlag(self,flag):
self.flag = flag
def getFlag(self):
return self.flag
def __cmp__(self,other):
if self.__eq__(other):
return 0
elif self.__lt__(other):
return -1
elif self.__gt__(other):
return 1
def __eq__(self,other):
if not isinstance(other,Distence):
print("can't cmp other type to Distence")
return float(self.dis) == float(other.dis)
def __lt__(self,other):
if not isinstance(other,Distence):
print("can't cmp other type to Distence")
if float(self.dis) < float(other.dis):
return True
else:
return False
def __gt__(self,other):
if not isinstance(other,Distence):
print("can't cmp other type to Distence")
if float(self.dis) > float(other.dis):
return True
else:
return False
if __name__ == "__main__":
#python AutoOutput4.py --InputJobPath="D:\AutoOutput\autojob\bs20-1592ans-test2.tgz" --LayerType="Outer" --OutputJobPath="D:\AutoOutput" --DataFormat="ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput4.py --InputJobPath="D:\\AutoOutput\\autojob\\akf21681as2.tgz" --LayerType="Outer" --OutputJobPath="D:\\AutoOutput" --DataFormat="ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\ji30100ais-2x.tgz Outer D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\ji30100ais-2x.tgz SolderMask D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\ji30100ais-2x.tgz Inner D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\bs20-1592ans-test2.tgz Inner D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput4.py --InputJobPath="D:\\AutoOutput\\autojob\\bs20-1592ans-test2.tgz" --LayerType="Outer" --OutputJobPath="D:\\AutoOutput" --DataFormat="ODB"
#print(sys.argv)
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\bs20-1592ans-test2.tgz Inner D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\04ae30166a0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\bs20-1592ans-test2.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\04be30081a0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\04ae17573e0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\06ad28939dq.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\06ae30065a0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\04ad28618b0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob中文\\04ad28618b0.tgz D:\AutoOutput\AutoOutput ODB"
#D:\ezcam\1.1\ezcam.exe -u g -p g -m ezcam_di_starting -s AutoOutput5.py --script-param="D:\\AutoOutput\\autojob\\04ad28618b0.tgz Inner D:\AutoOutput\AutoOutput ODB"
# parser = argparse.ArgumentParser(description='manual to this script')
# parser.add_argument("--InputJobPath", type=str, default="D:\\AutoOutput\\autojob\\bs20-1592ans-test2.tgz")
# parser.add_argument("--LayerType", type=str, default="Outer")
# parser.add_argument("--OutputJobPath", type=str, default="D:\\AutoOutput")
# parser.add_argument("--DataFormat", type=str, default="ODB")
# args = parser.parse_args()
# print(script-param)
# print(args.InputJobPath)
# print(args.LayerType)
# print(args.OutputJobPath)
# print(args.DataFormat)
#print('###################################')
#print(sys.argv[4])
JobName='tmp_gerber274x' #当输入的格式为Gerber274x时,ezCAM中的临时料号名为:tmp_gerber274x
if sys.argv[4] == "ODB":
(path, filename) = os.path.split(sys.argv[1])
(file, ext) = os.path.splitext(filename)
InputJobPath=path
JobName=file
LayerType=sys.argv[2]
OutputJobPath=sys.argv[3]
DataFormat=sys.argv[4]
print(f'InputJobPath={InputJobPath}')
print(f'JobName={JobName}')
print(f'LayerType={LayerType}')
print(f'DataFormat={DataFormat}')
print(f'OutputJobPath={OutputJobPath}')
InputInfoFilePath = InputJobPath +"\\\\" + JobName + ".txt"
dblist_mutex = FileLock("dblist.lock")
InfoFileIsExist = os.path.exists(InputInfoFilePath)
job = AutoOutput(InputJobPath,JobName,LayerType,DataFormat,OutputJobPath,InfoFileIsExist)
job.JobStart()
ezcam.COM('close_toolkit',save_log='yes')
tmpPath=f'{OutputJobPath}\\{JobName}\\'
if os.path.exists(tmpPath): # 如果文件存在
del_file(tmpPath)
os.removedirs(tmpPath)
exit()
EZCAM脚本输出info信息以及分区信息
最新推荐文章于 2024-09-05 10:28:02 发布