Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
Scott
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Scott Sun
Scott
Commits
cae41a62
Commit
cae41a62
authored
Dec 02, 2020
by
Scott Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scott
parent
f81d71c9
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
260 additions
and
1389 deletions
+260
-1389
ATS_AIM_checkin.js
ats/topcam/ATS_AIM_checkin.js
+19
-1
ATS_AIM_customer_data_analysis.js
ats/topcam/ATS_AIM_customer_data_analysis.js
+16
-17
ATS_AIM_data_input.js
ats/topcam/ATS_AIM_data_input.js
+33
-12
ATS_AIM_layer_rename_and_sort.js
ats/topcam/ATS_AIM_layer_rename_and_sort.js
+12
-7
config_ats.js
ats/topcam/config_ats.js
+3
-3
SEC_DRC_analysis.js
public_script/SEC_DRC_analysis.js
+1
-1
scotttest.js
public_script/scotttest.js
+176
-1348
No files found.
ats/topcam/ATS_AIM_checkin.js
View file @
cae41a62
...
...
@@ -72,6 +72,7 @@ if (mode === "aimdfm") {
var
Status
=
'ok'
;
var
resultData
=
[];
try
{
console
.
log
(
"=============================check in===================="
);
GEN
.
COM
(
"open_job,job="
+
Job
+
",open_win=no,disk_map=,job_map="
)
GEN
.
AUX
(
"set_group,group=99"
)
GEN
.
COM
(
"close_job,job="
+
Job
+
""
)
...
...
@@ -80,9 +81,26 @@ try {
GEN
.
COM
(
"disp_on"
)
GEN
.
COM
(
"origin_on"
)
GEN
.
COM
(
"checkin_closed_job,job="
+
Job
);
if
(
mode
===
"aimdfm"
)
{
if
(
GEN
.
hasError
())
{
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"GEN错误!"
,
detail
:
[{
desc
:
_
.
join
(
GEN
.
STATUS
,
"
\n
"
)
}]
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
else
{
resultData
.
push
({
type
:
"info"
,
title
:
"操作完成, 请注意检查!"
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
}
else
{
return
"Done"
}
}
catch
(
e
)
{
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"脚本执行出错!"
,
detail
:
[{
desc
:
_
.
toString
(
e
)}]});
return
(
mode
===
"aimdfm"
)
?
{
status
:
Status
,
result_data
:
resultData
}
:
"Error"
;
...
...
ats/topcam/ATS_AIM_customer_data_analysis.js
View file @
cae41a62
...
...
@@ -166,8 +166,10 @@ if(mailUserList && mailUserList.length) {
})
}
var
cam_workflow_info
=
IKM
.
get_jobinfo
({
jobid
:
JobId
,
jobinfo
:
"cam_workflow_info"
});
console
.
log
(
"==========cam_workflow_info===========:"
+
cam_workflow_info
);
try
{
if
(
cam_workflow_info
&&
cam_workflow_info
!=
""
){
console
.
log
(
"==========cam_workflow_info===========:"
+
cam_workflow_info
);
throw
cam_workflow_info
}
cam_workflow_info
=
"sendmail"
...
...
@@ -185,7 +187,7 @@ try {
// 检查料号是否能够check out
if
(
GEN
.
checkInout
({
job
:
job
,
mode
:
"test"
})
!=
0
&&
mode
==
"aimdfm"
){
throw
"the job check"
}
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
});
script_info
({
msg
:
"
analysis start
"
,
result_severity
:
"info"
})
script_info
({
msg
:
"
开始分析客户料号
"
,
result_severity
:
"info"
})
script_info
({
progress
:
65
})
var
pcs_step
=
par
.
pcs_step
==
""
?
"cad"
:
par
.
pcs_step
;
var
array_step
=
par
.
array_step
==
""
?
"stp"
:
par
.
array_step
;
...
...
@@ -197,7 +199,7 @@ try {
pcs_step
=
step_list
[
0
]
}
script_info
({
msg
:
"
analysis update_matrix_
info"
})
script_info
({
msg
:
"
分析上传matrix信息"
,
result_severity
:
"
info"
})
script_info
({
progress
:
65
})
var
matrix
=
UPLOAD_LAYER_MATRIX
({
job
:
job
})
// 分析matrix 获得分析后的matrix信息
GEN
.
openStep
({
job
:
job
,
name
:
pcs_step
})
...
...
@@ -253,7 +255,7 @@ try {
})
GEN
.
clearLayers
()
script_info
({
msg
:
"
analysis drill_stack
"
})
script_info
({
msg
:
"
分析钻孔叠构
"
})
script_info
({
progress
:
70
})
// * new 钻孔叠构
var
cam_drill_structure
=
[]
...
...
@@ -378,7 +380,7 @@ try {
var
analysis_obj
=
analysis
({
job
:
job
,
jobId
:
JobId
,
pcs_step
:
pcs_step
,
array_step
:
array_step
,
matrix
:
matrix
})
// 创建profile
var
tmp_matrix
=
GEN
.
getMatrix
({
job
:
job
})
script_info
({
msg
:
"
analysis panel_info
"
})
script_info
({
msg
:
"
分析profile
"
})
script_info
({
progress
:
70
})
// * profile 和 拼版
var
pandle_step
=
step_list
.
map
(
function
(
v
){
...
...
@@ -452,7 +454,7 @@ try {
}
ALL
.
gold_fingers
=
gold_fingers
GEN
.
closeStep
()
script_info
({
msg
:
"
analysis some_job_info
"
})
script_info
({
msg
:
"
分析料号信息
"
})
var
config
=
{
jobInfo
:
{
layer_count
:
[
"signal"
,
"power_ground"
],
// Board属性的signal或者power_ground层
...
...
@@ -532,7 +534,7 @@ try {
console
.
log
(
"=================================> 5 save drill info"
)
script_info
({
msg
:
"
analysis drill_info
"
})
script_info
({
msg
:
"
分析钻孔信息
"
})
script_info
({
progress
:
75
})
// * 获取pcs_step 和 array_step的钻孔信息
var
drill_tool_info
=
{};
...
...
@@ -657,7 +659,7 @@ try {
})
console
.
log
(
"=============================> 6 set smd bga"
)
script_info
({
msg
:
"
analysis smd&
bga"
})
script_info
({
msg
:
"
分析smd和
bga"
})
script_info
({
progress
:
80
});
step_list
.
forEach
(
function
(
step
){
GEN
.
openStep
({
job
:
job
,
name
:
step
})
...
...
@@ -808,7 +810,7 @@ try {
// jobpath = "/home/local_db/server_db/jobs/"+job
// }
mkPath
(
jobpath
,[
"user"
,
"opcam"
,
"steps"
])
script_info
({
msg
:
"
analysis signal
"
})
script_info
({
msg
:
"
分析线路
"
})
script_info
({
progress
:
85
})
stepList
.
forEach
(
function
(
step
){
GEN
.
openStep
({
job
:
job
,
name
:
step
})
...
...
@@ -961,7 +963,7 @@ try {
if
(
par
.
erf
){
tmpitem
.
erf
=
par
.
erf
}
script_info
({
msg
:
"
analysis run_signal_chk
"
})
script_info
({
msg
:
"
运行线路分析checklist
"
})
createChklistAndRun
({
// 创建checklist并运行
layers
:
signalLayers
,
items
:
[
tmpitem
]
...
...
@@ -987,7 +989,6 @@ try {
GEN
.
closeStep
()
})
mvOutProfile
({
job
:
job
,
step
:
pcs_step
})
IKM
.
msg
(
"end wait for save"
)
// 保存
...
...
@@ -1019,7 +1020,6 @@ try {
})
});
script_info
({
msg
:
"analysis export"
})
script_info
({
progress
:
95
})
// 导出
if
(
par
.
export_path
!=
""
&&
par
.
export_mode
!=
""
&&
par
.
export_submode
!=
""
){
...
...
@@ -1256,8 +1256,7 @@ function getMatrixInfo(props){ // 获取matrix各种信息
res
.
mBoardLayer
.
push
(
key
)
switch
(
value
.
layer_type
)
{
case
"signal"
:
s
.
mSignal
[
key
]
=
value
res
.
mSignal
[
key
]
=
value
res
.
mSignals
.
push
(
value
)
break
;
case
"drill"
:
...
...
ats/topcam/ATS_AIM_data_input.js
View file @
cae41a62
...
...
@@ -94,7 +94,7 @@ if(cam_workflow_info){
IKM
.
save_job_info
({
jobid
:
JobId
,
jobinfohash
:{
cam_workflow_info
:
""
}})
}
try
{
script_info
({
msg
:
"
import start
"
,
result_severity
:
"info"
})
script_info
({
msg
:
"
开始导入
"
,
result_severity
:
"info"
})
var
par
=
PAR
;
// var db_path = db.query("",function(q){
// return q.selectValue({
...
...
@@ -104,7 +104,9 @@ try {
// })
// });
// if(_.isEmpty(db_path)){throw "quote-data-upload error"}
if
(
!
par
.
path
||
par
.
path
==
""
)
{
throw
"path error"
}
if
(
!
par
.
path
||
par
.
path
==
""
)
{
script_info
({
msg
:
"资料路径不存在"
,
result_severity
:
"error"
});
throw
"path error"
}
if
(
!
par
.
hasOwnProperty
(
"config_path"
)
||
par
.
config_path
==
""
){
console
.
log
(
"===================cfg"
);
par
.
config_path
=
"cam/input_data"
...
...
@@ -120,7 +122,9 @@ try {
where
:{
id
:
JobId
}
})
});
if
(
_
.
isEmpty
(
db_customer
)){
throw
"customer error"
}
if
(
_
.
isEmpty
(
db_customer
)){
script_info
({
msg
:
"该料号客户不存在"
,
result_severity
:
"error"
});
throw
"customer error"
}
if
(
db_customer
&&
!
(
/^done$/ig
.
test
(
db_customer
))
&&
db_customer
!=
""
){
par
.
customer
=
db_customer
}
...
...
@@ -132,9 +136,13 @@ try {
where
:{
path
:
par
.
config_path
}
})
});
if
(
!
cfg
||
cfg
==
""
){
throw
"cfg can not find"
}
if
(
!
cfg
||
cfg
==
""
){
script_info
({
msg
:
"客户配置不存在"
,
result_severity
:
"error"
});
throw
"cfg can not find"
}
var
config
=
eval
(
cfg
);
if
(
!
config
.
hasOwnProperty
(
"customer"
)){
throw
"config error"
}
if
(
!
config
.
hasOwnProperty
(
"customer"
)){
script_info
({
msg
:
"客户配置不存在"
,
result_severity
:
"error"
});
throw
"config error"
}
var
job
=
Job
;
if
(
_
.
isEmpty
(
job
))
throw
"没有传入料号名!"
;
job
=
job
.
toLowerCase
()
...
...
@@ -146,7 +154,9 @@ try {
var
step
=
custCfg
.
step
.
toLowerCase
()
// 获取路径下文件信息
var
path
=
par
.
path
if
(
!
fs
.
exists
(
path
)){
throw
"path error"
}
if
(
!
fs
.
exists
(
path
)){
script_info
({
msg
:
"资料路径不存在"
,
result_severity
:
"error"
});
throw
"path error"
}
var
pathInfo
=
fs
.
listDir
(
path
+
"/"
+
db_customer
.
toLowerCase
(),
1
)
// 判断存不存在料号文件
// var vc_position = db.query("",function(q){
...
...
@@ -161,7 +171,9 @@ try {
// job_file_baseName = job_file_baseName + "_" + vc_position
// }
var
jobFile
=
pathInfo
.
filter
(
function
(
v
){
return
v
.
baseName
.
toLowerCase
()
==
job_file_baseName
})
if
(
jobFile
.
length
==
0
){
throw
"job file is not exist"
}
if
(
jobFile
.
length
==
0
){
script_info
({
msg
:
"资料路径不存在"
,
result_severity
:
"error"
});
throw
"job file is not exist"
}
var
jobFiles
=
[]
// 记录要分析的文件
if
(
!
jobFile
[
0
].
isDir
)
{
jobFiles
.
push
(
jobFile
[
0
])
...
...
@@ -197,7 +209,7 @@ try {
// 分析料号文件 得到料号导入信息 导入类型
var
jobInfo
=
analyJobFiles
({
jobFiles
:
jobFiles
.
filter
(
function
(
v
){
return
v
.
isFile
}),
custCfg
:
custCfg
,
config
:
config
,
job
:
job
})
if
(
jobInfo
.
data
.
length
==
0
){
script_info
({
msg
:
"
file error"
,
result_severity
:
"error"
})
script_info
({
msg
:
"
未找到料号文件"
,
result_severity
:
"error"
});
throw
"file error"
}
var
importOk
=
false
;
// 是否成功导入
...
...
@@ -288,15 +300,23 @@ try {
gerberCfg
.
step
=
step
return
gerberCfg
})
GEN
.
COM
(
"input_manual_reset"
)
gerberInfo
.
forEach
(
function
(
v
){
GEN
.
COM
(
"input_result_reset,step=,category=warnings,close_tab=yes"
)
GEN
.
COM
(
"input_create,path="
+
v
.
path
)
GEN
.
COM
(
"input_selected_reset"
)
GEN
.
COM
(
"input_selected_add,path="
+
v
.
path
)
GEN
.
COM
(
"input_identify_selected,path=,job="
+
job
+
",script_path=,gbr_ext=no,drl_ext=no,gbr_units=auto,drl_units=auto,unify=yes,break_sr=yes,gbr_wtp_filter=*,drl_wtp_filter=*,gbr_wtp_units=auto,drl_wtp_units=auto,wtp_dir=,have_wheels=yes,wheel=,gbr_consider_headlines=yes,drl_consider_headlines=yes,board_size_x=0,board_size_y=0"
)
GEN
.
COM
(
"input_manual_reset"
)
import_info
.
push
({
name
:
v
.
layer
,
type
:
"gerber274x"
,
date
:
now
(),
user
:
$
.
user_name
})
GEN
.
COM
(
"input_manual_set"
,
v
)
})
GEN
.
COM
(
"input_manual"
)
})
importOk
=
true
}
if
(
!
importOk
){
script_info
({
msg
:
"
import error
"
,
result_severity
:
"error"
});
throw
"import error"
}
if
(
!
importOk
){
script_info
({
msg
:
"
导入错误
"
,
result_severity
:
"error"
});
throw
"import error"
}
script_info
({
progress
:
20
})
reNameStep
(
job
)
if
(
/2171/
.
test
(
par
.
customer
)){
...
...
@@ -351,7 +371,7 @@ try {
import_html
+=
"</table>"
// name type date user
resultData
.
push
({
type
:
"info"
,
title
:
"导入资料列表"
,
detail
:
[{
desc
:
import_html
}]
})
script_info
({
msg
:
"
import ok
"
})
script_info
({
msg
:
"
导入资料成功
"
})
if
(
mode
===
"aimdfm"
)
{
$
.
QDfm
.
updateRow
({
table
:
"pdm_aimdfm_task"
,
...
...
@@ -458,6 +478,7 @@ function analyJobFiles(props){
}
}
}
function
importJob
(
props
,
delSameJob
){
var
name
=
props
.
name
if
(
GEN
.
isJobExists
({
job
:
name
}))
{
...
...
ats/topcam/ATS_AIM_
data_forma
t.js
→
ats/topcam/ATS_AIM_
layer_rename_and_sor
t.js
View file @
cae41a62
...
...
@@ -102,11 +102,11 @@ try {
if
(
cam_workflow_info
&&
cam_workflow_info
!=
""
){
throw
cam_workflow_info
}
script_info
({
msg
:
"
format start
"
,
result_severity
:
"info"
})
script_info
({
msg
:
"
料号标准化流程开始
"
,
result_severity
:
"info"
})
script_info
({
progress
:
35
})
var
par
=
PAR
;
if
(
!
par
.
hasOwnProperty
(
"config_path"
)
||
par
.
config_path
==
""
){
console
.
log
(
"==============cfg"
);
console
.
log
(
"===========
===cfg"
);
par
.
config_path
=
"cam/input_data"
};
var
db_customer
=
db
.
query
(
""
,
function
(
q
){
...
...
@@ -137,9 +137,13 @@ try {
var
custCfg
=
config
.
customer
[
par
.
customer
]
// 获取客户配置
if
(
!
custCfg
){
throw
"config error"
}
// 料号验证
if
(
!
GEN
.
isJobExists
({
job
:
job
})){
throw
"job "
+
job
+
" is not exist"
}
if
(
!
GEN
.
isJobExists
({
job
:
job
})){
script_info
({
msg
:
"料号"
+
job
+
"不存在"
,
result_severity
:
"error"
})
throw
"job "
+
job
+
" is not exist"
}
if
(
!
GEN
.
isJobOpen
({
job
:
job
})){
GEN
.
openJob
({
job
:
job
})}
if
(
GEN
.
checkInout
({
job
:
job
,
mode
:
"test"
})
!=
0
&&
mode
==
"aimdfm"
){
throw
"the job check"
}
if
(
GEN
.
checkInout
({
job
:
job
,
mode
:
"test"
})
!=
0
&&
mode
==
"aimdfm"
){
script_info
({
msg
:
"料号"
+
job
+
" check"
,
result_severity
:
"error"
})
throw
"the job check"
}
console
.
log
(
"Checkout====== ========================>"
)
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
});
console
.
log
(
"Checkout success==============================>"
)
...
...
@@ -260,7 +264,7 @@ try {
var
after_sort_matrix
=
ret
.
sortNames
// 改名
script_info
({
msg
:
"
format rename
"
,
result_severity
:
"info"
})
script_info
({
msg
:
"
开始改名
"
,
result_severity
:
"info"
})
script_info
({
progress
:
50
})
err
=
reName
({
job
:
job
,
matrix
:
after_sort_matrix
,
cfg
:
format_cfg
})
if
(
err
){
throw
err
}
...
...
@@ -383,7 +387,7 @@ try {
GEN
.
closeJob
({
job
:
job
});
GEN
.
COM
(
"open_job,job="
+
job
);
script_info
({
msg
:
"
format create
profile"
,
result_severity
:
"info"
})
script_info
({
msg
:
"
准备创建
profile"
,
result_severity
:
"info"
})
script_info
({
progress
:
55
})
var
all_layer
=
Object
.
keys
(
tmp_matrix
)
// 没有outline层
...
...
@@ -429,6 +433,8 @@ try {
}
}
script_info
({
msg
:
"料号标准化结束"
,
result_severity
:
"warn"
})
db
.
query
(
""
,
function
(
q
){
return
q
.
updateRow
({
table
:
'pdm_job'
,
...
...
@@ -482,7 +488,6 @@ catch (e) {
// subject:db_customer + ' / '+Job+ " format error",
// content:_.toString(e)
// })
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"脚本执行出错!"
,
detail
:
[{
desc
:
_
.
toString
(
e
)}]});
return
(
mode
===
"aimdfm"
)
?
{
status
:
Status
,
result_data
:
resultData
}
:
"Error"
;
...
...
ats/topcam/config_ats.js
View file @
cae41a62
...
...
@@ -68,9 +68,9 @@
},
"Gerber274x_4"
:
{
"nf1"
:
2
,
"nf2"
:
3
,
"nf2"
:
4
,
"units"
:
"mm"
,
"zeroes"
:
"
none
"
,
"zeroes"
:
"
leading
"
,
"decimal"
:
"no"
,
"nf_comp"
:
0
,
"break_sr"
:
"yes"
,
...
...
@@ -80,7 +80,7 @@
"drill_only"
:
"no"
,
"multiplier"
:
1
,
"resolution"
:
3
,
"tool_units"
:
"
mm
"
,
"tool_units"
:
"
inch
"
,
"coordinates"
:
"absolute"
,
"merge_by_rule"
:
"no"
,
"signed_coords"
:
"no"
,
...
...
public_script/SEC_DRC_analysis.js
View file @
cae41a62
...
...
@@ -109,7 +109,7 @@ try {
// var ($signal,@signal,@pg_layer,$pg_layer,@drill,@sm_layer,@ss_layer,$ss_layer);
var
matrix
=
GEN
.
getMatrix
({
job
:
job
});
for
(
var
layer
in
matrix
)
{
var
layerInfo
=
matrix
[
layer
]
var
layerInfo
=
matrix
[
layer
]
;
if
(
layerInfo
.
context
==
"board"
)
{
if
(
layerInfo
.
layer_type
==
'signal'
&&
/
(
cil
)
|
(
col
)
/
.
test
(
layer
)){
var
lyr_paras
=
{};
...
...
public_script/scotttest.js
View file @
cae41a62
...
...
@@ -11,73 +11,9 @@ PARAMETER:
},
{
name : 'outline',
title : '
outline
',
title : '
外形层
',
type : 'LineEdit',
property : {tool_tip : '目标outline,默认是ol'},
},
{
name : 'units',
title : '单位',
type : 'RadioBox',
property : {
size_policy:'Expanding,Fixed',
item_list:[
{name:'inch',text:'INCH'},
{name:'mm',text:'MM'},
],
tool_tip:'工作单位,未设定,默认为INCH'
},
pack : {row:1,column:1},
},
{
name : 'tmp_enlarge_ss',
title : '文字临时涨大辅助',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'cover_layer_suffix',
title : '文字套层后缀',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'silk_suffix',
title : '分离的文字层后缀',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'text_height',
title : '文字最大高度',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'ss_elarge_height',
title : '文字放大高度',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'bk_suffix',
title : '备份层后缀',
type : 'LineEdit',
property : {tool_tip : ''},
},
{
name : 'select_lyr',
title : '选择层别',
type : 'RadioBox',
property : {
size_policy:'Expanding,Fixed',
item_list:[
{name:'yes',text:'Yes'},
{name:'no',text:'No'},
],
tool_tip:'未设定,默认为Yes'
},
pack : {row:1,column:1},
property : {tool_tip : '支持正则匹配'},
},
{
name : 'auto_save',
...
...
@@ -100,7 +36,7 @@ PARAMETER:
HELP:
<html><body bgcolor="#DDECFE">
<font size="3" color="#003DB2"><p>功能简介</p></font>
<p>
标题
</p>
<p>
铺铜
</p>
<br>
<font size="3" color="#003DB2"><p>参数配置</p></font>
<p> step信息 </p>
...
...
@@ -112,14 +48,11 @@ PARAMETER:
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
console
.
log
(
"=============================
:
template"
);
console
.
log
(
"=============================
=>
template"
);
// 引入模块 包
var
$
=
require
(
'topcam.scriptfunc'
).
argv
();
var
fs
=
require
(
'fs'
);
const
{
padStart
}
=
require
(
'lodash'
);
var
_
=
require
(
'lodash'
);
require
(
"topsin.genmath"
)
var
genMath
=
new
GenMath
();
var
mode
=
$
.
ikm
?
"topcam"
:
"aimdfm"
;
var
IKM
=
$
.
ikm
;
if
(
IKM
==
undefined
)
{
IKM
=
require
(
'topcam.ikm6'
)(
$
)
}
...
...
@@ -127,1314 +60,209 @@ var GEN = $.gen;
var
GUI
=
$
.
gui
||
{};
var
Job
=
$
.
job
||
$
.
job_name
;
var
JobId
=
$
.
job_id
;
var
db
=
$
.
db
||
IKM
.
db
var
db
=
$
.
db
||
IKM
.
db
;
require
(
"topsin.genmath"
);
var
genMath
=
new
GenMath
();
var
PAR
=
{}
if
(
$
.
par
)
{
PAR
=
$
.
par
}
else
if
(
$
.
hasOwnProperty
(
'script_parameter'
)){
PAR
=
JSON
.
parse
(
$
.
script_parameter
);
}
if
(
$
.
par
)
{
PAR
=
$
.
par
}
else
if
(
$
.
hasOwnProperty
(
'script_parameter'
)){
PAR
=
JSON
.
parse
(
$
.
script_parameter
);
}
if
(
mode
===
"aimdfm"
)
{
var
database
=
require
(
"topsin.database"
);
database
.
addConnection
(
$
.
conf
.
database_conf
,
"DFM"
);
var
QDfm
=
database
.
query
(
"DFM"
);
$
.
QDfm
=
QDfm
;
if
(
$
.
conf
.
product_type
==
"aimdfm"
)
{
QDfm
.
updateRow
({
table
:
"pdm_aimdfm_task"
,
data
:
{
current_process_title
:
$
.
process_title
},
where
:
{
id
:
$
.
task_id
}
});
}
}
var
Status
=
'ok'
;
var
resultData
=
[];
var
par
=
PAR
;
var
default_par
=
{
units
:
"mm"
,
ss_to_sm
:
10
,
// 文字距离阻焊
ss_to_smd
:
10
,
// 文字距离SMD
ss_to_bga
:
10
,
// 文字距离bga
text_height
:
1
,
// 文字最大高度
bk_suffix
:
"_bk"
,
// 备份层后缀
silk_suffix
:
"_font"
,
// 分离的文字层后缀
cover_layer_suffix
:
"_cover_tmp"
,
tol
:
1
,
select_lyr
:
"no"
,
step
:
"unit"
,
ss_elarge_height
:
2000
,
tmp_enlarge_ss
:
700
,
auto_save
:
"No"
,
outline
:
"ol"
}
for
(
var
key
in
default_par
){
if
(
!
par
.
hasOwnProperty
(
key
)
||
par
[
key
]
==
""
){
par
[
key
]
=
default_par
[
key
]
}}
var
job
=
Job
;
var
outline
=
par
.
outline
var
gui
=
new
NewGUI
(
GUI
);
if
(
!
par
.
outline_size
){
par
.
outline_size
=
par
.
units
==
'inch'
?
7.87
:
200
;
}
try
{
if
(
_
.
isEmpty
(
job
)){
throw
"参数job不存在"
}
else
{
job
=
job
.
toLowerCase
()
}
if
(
!
GEN
.
isJobExists
({
job
:
job
})){
throw
"料号"
+
job
+
"不存在"
}
if
(
!
GEN
.
isJobOpen
({
job
:
job
})){
GEN
.
openJob
({
job
:
job
})
}
if
(
mode
==
"aimdfm"
){
if
(
GEN
.
checkInout
({
job
:
job
,
mode
:
"test"
})
!=
0
){
throw
"the job check"
}
else
{
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
})
}
}
var
workstep
=
getWorkStep
()
if
(
!
Array
.
isArray
(
workstep
)){
throw
"工作step错误"
}
var
err
=
slOptimize
({
workstep
:
workstep
})
// 文字优化
if
(
err
)
{
throw
err
}
// 保存
if
(
/yes/ig
.
test
(
par
.
auto_save
)){
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
});
GEN
.
saveJob
({
job
:
job
});
GEN
.
checkInout
({
job
:
job
,
mode
:
"in"
});
GEN
.
closeJob
({
job
:
job
});}
else
{
GEN
.
checkInout
({
job
:
job
,
mode
:
"in"
})}
if
(
mode
===
"aimdfm"
)
{
$
.
QDfm
.
updateRow
({
table
:
"pdm_aimdfm_task"
,
data
:
{
progress
:
33.33
},
where
:
{
id
:
$
.
task_id
}});
if
(
GEN
.
hasError
())
{
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"GEN错误!"
,
detail
:
[{
desc
:
_
.
join
(
GEN
.
STATUS
,
"
\n
"
)
}]
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
else
{
resultData
.
push
({
type
:
"info"
,
title
:
"操作完成, 请注意检查!"
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
}
else
{
return
"Done"
}
}
catch
(
e
)
{
IKM
.
msg
(
_
.
join
(
GEN
.
STATUS
,
"
\n
"
));
IKM
.
msg
(
e
);
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"脚本执行出错!"
,
detail
:
[{
desc
:
_
.
toString
(
e
)}]});
return
(
mode
===
"aimdfm"
)
?
{
status
:
Status
,
result_data
:
resultData
}
:
"Error"
;
}
// 创建套层
function
createCoverLayer
(
props
){
// 1. step过滤
var
workstep
=
props
.
workstep
;
// 2.过滤工作层
var
work_layer
=
getLayer
({
layer_type
:
"silk_screen"
,
context
:
"board"
})
if
(
/yes/ig
.
test
(
par
.
select_lyr
)){
var
matrix
=
GEN
.
getMatrix
({
job
:
job
});
var
layers
=
Object
.
keys
(
matrix
).
map
(
function
(
key
){
var
tmp
=
{};
tmp
[
key
]
=
key
;
return
tmp
})
work_layer
=
gui
.
selectMultiple
({
title
:
"请先择工作层"
,
list
:
layers
,
defaultvalue
:
work_layer
,
columns
:
4
,
gen
:
GEN
})
}
if
(
work_layer
.
length
==
0
)
{
return
"没有先择layer"
}
// 其他参数
var
info
=
gui
.
showForm
({
title
:
'请手动匹配以下信息'
,
showcheck
:
1
,
gen
:
GEN
,
defaultsize
:[
200
,
100
],
ui
:
{
type
:
'ScrollArea'
,
property
:
{
widget_resizable
:
true
,
frame_shape
:
'NoFrame'
,
align
:
'Top'
},
child
:
{
type
:
'VBoxLayout'
,
property
:
{
margin
:
2
,
spacing
:
5
,
align
:
'Top'
},
pack
:
{
stretch
:
0
},
child
:[{
type
:
"FormGridLayout"
,
property
:
{
columns
:
1
,
label_alignment
:
'Top | Right'
,
margin
:
10
,
spacing
:
20
},
pack
:
{
stretch
:
0
},
child
:[{
name
:
'ss_to_sm'
,
pack
:
{
label
:
'文字距离阻焊(单边)'
},
type
:
'LineEdit'
,
units
:
par
.
units
==
'inch'
?
'mil'
:
'um'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
property
:
{
enabled
:
true
,
value
:
par
.
ss_to_sm
}
},
{
name
:
'ss_to_smd'
,
pack
:
{
label
:
'文字距离SMD(单边)'
},
type
:
'LineEdit'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
units
:
par
.
units
==
'inch'
?
'mil'
:
'um'
,
property
:
{
value
:
par
.
ss_to_smd
,
enabled
:
true
}
QDfm
.
updateRow
({
table
:
"pdm_aimdfm_task"
,
data
:
{
current_process_title
:
$
.
process_title
},
{
name
:
'ss_to_bga'
,
pack
:
{
label
:
'文字距离BGA(单边)'
},
setter
:
function
(
obj
){
obj
.
setText
()
},
type
:
'LineEdit'
,
value
:
par
.
ss_to_bga
,
units
:
par
.
units
==
'inch'
?
'mil'
:
'um'
,
property
:
{
value
:
par
.
ss_to_smd
,
enabled
:
true
}
},
{
type
:
"stretch"
}]
}]
}
}
where
:
{
id
:
$
.
task_id
}
});
if
(
!
info
){
throw
"未填写参数"
}
info
=
JSON
.
parse
(
JSON
.
stringify
(
info
))
var
matrix
=
GEN
.
getMatrix
({
job
:
job
})
workstep
.
forEach
(
function
(
step
){
GEN
.
openStep
({
job
:
job
,
name
:
step
});
GEN
.
clearLayers
();
GEN
.
affectedLayer
({
mode
:
'all'
,
affected
:
'no'
});
GEN
.
units
({
type
:
par
.
units
}
);
GEN
.
zoomHome
();
work_layer
.
forEach
(
function
(
layer
){
var
cover_lyr
=
layer
+
par
.
cover_layer_suffix
;
var
sm
,
outer
;
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
cover_lyr
})
)
{
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
cover_lyr
]})
}
if
(
matrix
[
layer
].
side
==
'top'
)
{
sm
=
getLayer
({
layer_type
:
"solder_mask"
,
context
:
"board"
,
side
:
"top"
})[
0
];
outer
=
getLayer
({
layer_type
:
"signal"
,
context
:
"board"
,
side
:
"top"
})[
0
];
GEN
.
createLayer
({
job
:
job
,
layer
:
cover_lyr
,
context
:
'board'
,
type
:
'document'
,
before
:
layer
,
delete_exists
:
'yes'
});
}
else
{
sm
=
getLayer
({
layer_type
:
"solder_mask"
,
context
:
"board"
,
side
:
"bottom"
})[
0
];
outer
=
getLayer
({
layer_type
:
"signal"
,
context
:
"board"
,
side
:
"bottom"
})[
0
];
GEN
.
createLayer
({
job
:
job
,
layer
:
cover_lyr
,
context
:
'board'
,
type
:
'document'
,
before
:
layer
,
delete_exists
:
'yes'
});
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
sm
})
)
{
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
sm
],
clear_before
:
'yes'
});
GEN
.
selectByFilter
({
polarity
:
'positive'
,
profile
:
'all'
});
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
cover_lyr
,
invert
:
'no'
,
size
:
2
*
info
.
ss_to_sm
});
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
outer
})
)
{
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
outer
],
clear_before
:
'yes'
});
GEN
.
selectByFilter
({
attribute
:[
'.smd'
],
profile
:
'all'
});
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
cover_lyr
,
invert
:
'no'
,
size
:
2
*
info
.
ss_to_smd
});}
GEN
.
selectByFilter
({
attribute
:[
'.bga'
],
profile
:
'all'
,});
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
cover_lyr
,
invert
:
'no'
,
size
:
2
*
info
.
ss_to_bga
});}
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
outline
})
)
{
var
outline_tmp
=
outline
+
'_tmp_tl'
;
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
outline
,
dest_layer
:
outline_tmp
,
mode
:
'replace'
,
invert
:
'no'
})
;
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
outline_tmp
],
clear_before
:
'yes'
});
GEN
.
selectByFilter
({
feat_types
:
'line
\
;arc'
,
polarity
:
'positive'
,
profile
:
'all'
});
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selChangeSym
({
symbol
:
'r'
+
par
.
outline_size
})
}
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
outline_tmp
,
dest_layer
:
cover_lyr
,
mode
:
'append'
,
invert
:
'no'
})
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
outline_tmp
],
step
:
step
});
}
})
})
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
clearLayers
()
}
// 字符 和 文字框分开
function
ssFrameSeparate
(
props
)
{
// 1. step过滤
var
workstep
=
props
.
workstep
;
// 2.过滤工作层
var
work_layers
=
getLayer
({
layer_type
:
"silk_screen"
,
context
:
"board"
})
if
(
/yes/ig
.
test
(
par
.
select_lyr
)){
var
matrix
=
GEN
.
getMatrix
({
job
:
job
});
var
layers
=
Object
.
keys
(
matrix
).
map
(
function
(
key
){
var
tmp
=
{};
tmp
[
key
]
=
key
;
return
tmp
})
work_layers
=
gui
.
selectMultiple
({
defaultsize
:[
200
,
100
],
title
:
"请先择工作层"
,
list
:
layers
,
defaultvalue
:
work_layers
,
columns
:
4
,
gen
:
GEN
})
}
if
(
work_layers
.
length
==
0
)
{
return
"没有先择layer"
}
var
info
=
gui
.
showForm
({
title
:
'请手动匹配以下信息'
,
showcheck
:
1
,
gen
:
GEN
,
defaultsize
:[
500
,
250
],
ui
:
{
type
:
'ScrollArea'
,
property
:
{
widget_resizable
:
true
,
frame_shape
:
'NoFrame'
,
align
:
'Top'
},
child
:
{
type
:
'VBoxLayout'
,
property
:
{
margin
:
2
,
spacing
:
5
,
align
:
'Top'
},
pack
:
{
stretch
:
0
},
child
:[{
type
:
"FormGridLayout"
,
property
:
{
columns
:
1
,
label_alignment
:
'Top | Right'
,
margin
:
10
,
spacing
:
20
},
pack
:
{
stretch
:
0
},
child
:[{
name
:
'text_height'
,
pack
:
{
label
:
'文字最大高度'
},
type
:
'LineEdit'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
property
:
{
value
:
par
.
text_height
*
1000
,
enabled
:
true
},
units
:
par
.
units
==
'inch'
?
'mil'
:
'um'
},{
name
:
'type'
,
pack
:
{
label
:
'类型'
},
type
:
'RadioBox'
,
property
:
{
enabled
:
true
,
item_list
:[{
name
:
'separate'
,
text
:
'字框分离'
},{
name
:
"change"
,
text
:
"字框切换"
}]}
},
{
type
:
"stretch"
}]
}]
}
}
});
if
(
!
info
){
throw
"未填写参数"
}
info
=
JSON
.
parse
(
JSON
.
stringify
(
info
));
if
(
info
.
type
==
""
){
info
.
type
=
"separate"
}
var
matrix
=
GEN
.
getMatrix
({
job
:
job
})
workstep
.
forEach
(
function
(
step
){
GEN
.
openStep
({
job
:
job
,
name
:
step
});
GEN
.
clearLayers
();
GEN
.
affectedLayer
({
mode
:
'all'
,
affected
:
'no'
}
);
GEN
.
units
({
type
:
par
.
units
});
GEN
.
zoomHome
();
var
layer_count
=
GEN
.
getLayerCount
({
job
:
job
})
// IKM.get_jobinfo({jobid: JobId, jobinfo: "layer_count"})
GEN
.
COM
(
'disp_off'
);
if
(
info
[
"type"
]
==
'separate'
)
{
work_layers
.
forEach
(
function
(
layer
){
// 备份文字层
var
bk
=
layer
+
par
.
bk_suffix
;
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
layer
,
dest_layer
:
bk
,
mode
:
'replace'
,
invert
:
'no'
})
// 分离出的文字层
var
ss_text
=
layer
+
par
.
silk_suffix
;
if
(
matrix
[
layer
][
"side"
]
==
'top'
)
{
GEN
.
createLayer
({
job
:
job
,
layer
:
ss_text
,
context
:
'board'
,
type
:
'document'
,
before
:
layer
,
delete_exists
:
'yes'
});
}
else
{
GEN
.
createLayer
({
job
:
job
,
layer
:
ss_text
,
context
:
'board'
,
type
:
'document'
,
after
:
layer
,
delete_exists
:
'yes'
});
}
// 开始分离文字
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:
layer
,
clear_before
:
'yes'
});
GEN
.
COM
(
"filter_reset,filter_name=popup"
);
GEN
.
selectByFilter
({
feat_types
:
'line
\
;arc'
,
polarity
:
'positive'
,
profile
:
'all'
});
if
(
GEN
.
getSelectCount
()
>
0
){
var
ss_line_arc
=
layer
+
'_line_arc_tl_script'
;
selCopyOther
({
layer
:
ss_line_arc
,
delExist
:
true
})
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:
ss_line_arc
,
clear_before
:
'yes'
});
GEN
.
selChangeSym
({
symbol
:
'r0.2'
});
GEN
.
COM
(
"filter_reset,filter_name=popup"
);
GEN
.
selectByFilter
({
feat_types
:
'line'
,
polarity
:
'positive'
,
profile
:
'all'
});
//将直线固定角度分离去除
var
ss_line
=
layer
+
'_line_tl_script'
;
if
(
GEN
.
getSelectCount
()
>
0
){
selCopyOther
({
layer
:
ss_line
,
delExist
:
true
})
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:
ss_line
,
clear_before
:
'yes'
});
var
angle
=
[];
var
tol
=
0.2
;
if
(
GEN
.
GEN_TYPE
==
'genesis'
){
angle
=
[
-
180
,
-
135
,
-
90
,
-
45
,
0
,
45
,
90
,
135
];
}
else
{
angle
=
[
0
,
45
,
90
,
135
,
180
,
225
,
270
,
315
];
}
angle
.
forEach
(
function
(
angl
){
if
(
GEN
.
GEN_TYPE
==
'genesis'
){
var
min_angle
=
(
angl
-
tol
<
-
180
)
?
-
180
:
(
angl
-
tol
);
var
max_angle
=
(
angl
+
tol
>
180
)
?
180
:
(
angl
+
tol
);
GEN
.
COM
(
'filter_set'
,{
filter_name
:
'popup'
,
update_popup
:
'yes'
,
slot
:
'line'
,
slot_by
:
'angle'
,
min_angle
:
min_angle
,
max_angle
:
max_angle
});
}
else
{
GEN
.
COM
(
'set_filter_angle'
,{
direction
:
'ccw'
,
max_angle
:
angl
+
tol
,
min_angle
:
angl
-
tol
,
slot
:
'lines'
});
GEN
.
COM
(
"adv_filter_set,ccw_rotations=,filter_name=popup,mirror=any,bound_box=no,active=yes,srf_values=no,srf_area=no,limit_box=no"
);
}
GEN
.
COM
(
"filter_area_strt"
);
GEN
.
COM
(
"filter_area_end,filter_name=popup,operation=select"
);
})
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selDelete
()}
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
ss_line
})){
// 利用制作的套层
var
cover_lyr
=
layer
+
par
.
cover_layer_suffix
;
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
cover_lyr
],
clear_before
:
'yes'
});
GEN
.
COM
(
"filter_reset,filter_name=popup"
);
GEN
.
COM
(
"filter_set,filter_name=popup,update_popup=no,include_syms=r*"
);
GEN
.
COM
(
"filter_set,filter_name=popup,update_popup=no,exclude_syms=rect*"
);
GEN
.
COM
(
"filter_area_strt"
);
GEN
.
COM
(
"filter_area_end,filter_name=popup,layer=,operation=select,inside_area=no,intersect_area=no,area_type=none"
);
GEN
.
COM
(
"filter_reset,filter_name=popup"
);
GEN
.
COM
(
"sel_reverse"
);
var
cover_lyr_2
=
cover_lyr
+
'_tmp_tl'
;
var
Status
=
'ok'
;
var
resultData
=
[];
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
createLayer
({
job
:
job
,
layer
:
cover_lyr_2
,
delete_exists
:
'yes'
});
GEN
.
selCopyOther
({
target_layer
:
cover_lyr_2
,
invert
:
'no'
});
}
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
ss_line_arc
],
clear_before
:
'yes'
});
GEN
.
selContourize
();
if
(
GEN
.
GEN_TYPE
==
'incam'
){
GEN
.
COM
(
"reset_filter_criteria,filter_name=,criteria=all"
);
}
else
{
GEN
.
COM
(
"filter_atr_reset,filter_name=ref_select"
);
}
GEN
.
COM
(
"sel_ref_feat,pads_as=shape,mode=touch,exclude_syms=,include_syms=,use=filter,f_types=line
\
;pad
\
;surface
\
;arc
\
;text,polarity=positive
\
;negative,layers="
+
ss_line
);
var
layer_tmp1
=
layer
+
'_tmp1_tl'
;
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
createLayer
({
job
:
job
,
layer
:
layer_tmp1
,
delete_exists
:
'yes'
});
GEN
.
selMoveOther
({
target_layer
:
layer_tmp1
,
invert
:
'no'
});
}
if
(
GEN
.
GEN_TYPE
==
'incam'
){
GEN
.
COM
(
"reset_filter_criteria,filter_name=,criteria=all"
);
}
else
{
GEN
.
COM
(
"filter_atr_reset,filter_name=ref_select"
);
}
GEN
.
COM
(
"sel_ref_feat,pads_as=shape,mode=touch,exclude_syms=,include_syms=,use=filter,f_types=line
\
;pad
\
;surface
\
;arc
\
;text,polarity=positive
\
;negative,layers="
+
cover_lyr_2
);
var
layer_tmp2
=
layer
+
'_tmp2_tl'
;
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
createLayer
({
job
:
job
,
layer
:
layer_tmp2
,
delete_exists
:
'yes'
});
GEN
.
selCopyOther
({
target_layer
:
layer_tmp2
,
invert
:
'no'
});
}
GEN
.
COM
(
"sel_clean_surface,max_fold_len=0,clean_size="
+
info
.
text_height
+
",clean_mode=x_and_y,accuracy=0"
);
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
"layer_tmp2"
}))
{
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
layer_tmp2
],
clear_before
:
'yes'
});
if
(
GEN
.
GEN_TYPE
==
'incam'
){
GEN
.
COM
(
"reset_filter_criteria,filter_name=,criteria=all"
);
}
else
{
GEN
.
COM
(
"filter_atr_reset,filter_name=ref_select"
);
try
{
var
par
=
PAR
;
var
default_par
=
{
step
:
"unit.+"
,
step2
:
"unit"
,
auto_save
:
"No"
,
outline
:
"ol"
,
units
:
"mm"
}
GEN
.
COM
(
"sel_ref_feat,pads_as=shape,mode=disjoint,exclude_syms=,include_syms=,use=filter,f_types=line
\
;pad
\
;surface
\
;arc
\
;text,polarity=positive
\
;negative,layers="
+
ss_line_arc
);
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selMoveOther
({
target_layer
:
layer_tmp1
,
invert
:
'no'
});
var
jtg_inner_layer_avoid_copper
=
IKM
.
get_jobinfo
({
jobid
:
JobId
,
jobinfo
:
"jtg_inner_layer_avoid_copper"
})
*
2000
-
200
for
(
var
key
in
default_par
){
// 设置默认属性
if
(
!
par
.
hasOwnProperty
(
key
)
||
par
[
key
]
==
""
){
par
[
key
]
=
default_par
[
key
]
}
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
layer_tmp1
}))
{
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
layer_tmp1
],
clear_before
:
'yes'
});
if
(
GEN
.
GEN_TYPE
==
'incam'
){
GEN
.
COM
(
"reset_filter_criteria,filter_name=,criteria=all"
);
}
else
{
GEN
.
COM
(
"filter_atr_reset,filter_name=ref_select"
);
if
(
_
.
isEmpty
(
Job
)){
throw
"参数Job不存在"
}
var
job
=
Job
.
toLowerCase
()
if
(
!
GEN
.
isJobExists
({
job
:
job
})){
throw
"料号"
+
job
+
"不存在"
}
if
(
!
GEN
.
isJobOpen
({
job
:
job
})){
GEN
.
openJob
({
job
:
job
})
}
if
(
mode
==
"aimdfm"
){
if
(
GEN
.
checkInout
({
job
:
job
,
mode
:
"test"
})
!=
0
){
throw
"the job check"
}
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
});
}
GEN
.
COM
(
"sel_ref_feat,pads_as=shape,mode=touch,exclude_syms=,include_syms=,use=filter,f_types=line
\
;pad
\
;surface
\
;arc
\
;text,polarity=negative,layers="
+
layer
);
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selDelete
()
};
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
layer
],
clear_before
:
'yes'
});
if
(
GEN
.
GEN_TYPE
==
'incam'
){
GEN
.
COM
(
"reset_filter_criteria,filter_name=,criteria=all"
);
}
else
{
GEN
.
COM
(
"filter_atr_reset,filter_name=ref_select"
);
}
GEN
.
COM
(
"sel_ref_feat,pads_as=shape,mode=touch,exclude_syms=,include_syms=,use=filter,f_types=line
\
;pad
\
;surface
\
;arc
\
;text,polarity=positive
\
;negative,layers="
+
layer_tmp1
);
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selMoveOther
({
target_layer
:
ss_text
,
invert
:
'no'
});
}
}
// 将文字属性挑选
GEN
.
COM
(
"filter_reset,filter_name=popup"
);
GEN
.
selectByFilter
({
feat_types
:
'text'
}
);
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selMoveOther
({
target_layer
:
ss_text
,
invert
:
'no'
});
}
delLayer
([
ss_line_arc
,
ss_line
,
cover_lyr_2
,
layer_tmp1
,
layer_tmp2
]);
}
}
var
steplist
=
GEN
.
getStepList
({
job
:
job
})
steplist
=
steplist
.
filter
(
function
(
v
){
var
tmpreg
=
new
RegExp
(
par
.
step
,
"ig"
)
return
tmpreg
.
test
(
v
)
})
}
GEN
.
COM
(
"disp_on"
)
var
ref_layers
=
work_layers
.
filter
(
function
(
layer
){
return
GEN
.
isLayerExists
({
job
:
job
,
layer
:
layer
+
par
.
silk_suffix
})
}).
map
(
function
(
layer
){
return
{
work_layer
:
layer
,
ref_layer
:
layer
+
par
.
silk_suffix
}
if
(
steplist
.
length
==
0
&&
par
.
step2
)
{
steplist
=
GEN
.
getStepList
({
job
:
job
}).
filter
(
function
(
v
)
{
var
tmpreg
=
new
RegExp
(
par
.
step2
,
"ig"
);
return
tmpreg
.
test
(
v
);
})
if
(
ref_layers
.
length
>
0
)
{
ref_layers
.
forEach
(
function
(
layerInfo
){
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
clearLayers
()
var
work_layer
=
layerInfo
.
work_layer
;
var
ref_layer
=
layerInfo
.
ref_layer
;
IKM
.
msg
(
work_layer
+
"层字框分离"
);
GEN
.
workLayer
({
name
:
work_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
if
(
correct
(
work_layer
)){
var
tmp
=
work_layer
;
work_layer
=
ref_layer
,
ref_layer
=
tmp
;
}
GEN
.
displayLayer
({
name
:
ref_layer
,
number
:
2
});
var
flag
=
true
;
IKM
.
msg
(
"请选择需移动的文字或者的文字框,不需制作了请【左键框选空白处】"
)
while
(
flag
){
var
tmp_con
=
GEN
.
MOUSE
({
type
:
'r'
,
text
:
"Please Select"
});
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
if
(
GEN
.
getSelectCount
()
>
0
){
if
(
correct
(
work_layer
)){
var
tmp
=
work_layer
;
work_layer
=
ref_layer
,
ref_layer
=
tmp
;
}
GEN
.
selSubstitute
({
tol
:
1
,
mode
:
'select'
});
GEN
.
selMoveOther
({
target_layer
:
ref_layer
,
invert
:
'no'
});
}
else
{
flag
=
false
;
}
}
})
var
rout
=
"ol-tz"
;
if
(
!
GEN
.
isLayerExists
({
job
:
job
,
layer
:
rout
})){
rout
=
par
.
outline
}
})
}
// 文字框按阻焊扩大
function
slBoxOptimize
(
props
){
// 1. step过滤
var
workstep
=
props
.
workstep
;
// 2.过滤工作层
var
work_layers
=
getLayer
({
layer_type
:
"silk_screen"
,
context
:
"board"
})
if
(
/yes/ig
.
test
(
par
.
select_lyr
)){
var
matrix
=
GEN
.
getMatrix
({
job
:
job
});
var
layers
=
Object
.
keys
(
matrix
).
map
(
function
(
key
){
var
tmp
=
{};
tmp
[
key
]
=
key
;
return
tmp
})
work_layers
=
gui
.
selectMultiple
({
defaultsize
:[
200
,
100
],
title
:
"请先择工作层"
,
list
:
layers
,
defaultvalue
:
work_layers
,
columns
:
4
,
gen
:
GEN
})
var
tmp
=
rout
+
'_tmp'
if
(
!
GEN
.
isLayerExists
({
job
:
job
,
layer
:
tmp
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
]})
}
if
(
work_layers
.
length
==
0
)
{
return
"没有先择layer"
}
var
matrix
=
GEN
.
getMatrix
({
job
:
job
})
workstep
.
forEach
(
function
(
step
){
var
units
=
par
.
units
;
GEN
.
openStep
({
job
:
job
,
name
:
step
});
GEN
.
units
({
type
:
units
});
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
.
zoomHome
();
var
ref_layers
=
work_layers
.
filter
(
function
(
layer
){
return
GEN
.
isLayerExists
({
job
:
job
,
layer
:
layer
+
par
.
cover_layer_suffix
})
}).
map
(
function
(
layer
){
return
{
work_layer
:
layer
,
ref_layer
:
layer
+
par
.
cover_layer_suffix
}
})
if
(
ref_layers
.
length
>
0
)
{
ref_layers
.
forEach
(
function
(
layerInfo
){
// {"work_layer":"gto","ref_layer":"gto_cover"}
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
clearLayers
()
var
work_layer
=
layerInfo
.
work_layer
;
var
ref_layer
=
layerInfo
.
ref_layer
;
var
tmp1
=
'tl_script_tmp1'
,
tmp2
=
"tl_script_tmp2"
;
delLayer
([
tmp1
,
tmp2
]);
// 放大
var
ref_pad
=
"tmp_ref_pad"
;
delLayer
([
ref_pad
]);
GEN
.
createLayer
({
job
:
job
,
layer
:
ref_pad
,
context
:
'misc'
,
type
:
'document'
});
var
flag
=
true
;
IKM
.
msg
(
work_layer
+
"层:请选择需放大的文字框,不需制作了请【左键框选空白处】"
)
while
(
flag
){
GEN
.
workLayer
({
name
:
work_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
displayLayer
({
name
:
ref_layer
,
number
:
2
});
var
tmp_con
=
GEN
.
MOUSE
({
type
:
'r'
,
text
:
"Please Select"
});
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
if
(
GEN
.
getSelectCount
()
>
0
){
selCopyOther
({
layer
:
tmp1
})
// 判断特殊倾斜情况
var
layer_feature
=
GEN
.
getFeatures
({
job
:
job
,
step
:
step
,
layer
:
tmp1
})
// [{"type":"line","xs":"2.6998077","ys":"3.321854","xe":"2.6998077","ye":"3.4104367","symbol":"r7","polarity":"positive","attributes":[]},{"type":"line","xs":"2.6998077","ys":"3.321854","xe":"2.8912643","ye":"3.321854","symbol":"r7","polarity":"positive","attributes":[]},{"type":"line","xs":"2.6998077","ys":"3.4104367","xe":"2.8912643","ye":"3.4104367","symbol":"r7","polarity":"positive","attributes":[]},{"type":"line","xs":"2.8912643","ys":"3.321854","xe":"2.8912643","ye":"3.4104367","symbol":"r7","polarity":"positive","attributes":[]}]
// 1.算出最长边的角度
var
angle
=
getAngle
(
layer_feature
)
if
(
angle
%
90
==
0
)
{
angle
=
0
}
if
(
angle
<
0
){
angle
=
90
+
angle
}
// 求中心点
GEN
.
workLayer
({
name
:
ref_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
var
layer_limits_tmp1
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
tmp1
,
units
:
units
});
GEN
.
selectByFilter
({
area_rect
:{
x1
:
layer_limits_tmp1
.
xmin
-
0.01
,
y1
:
layer_limits_tmp1
.
ymin
-
0.01
,
x2
:
layer_limits_tmp1
.
xmax
+
0.01
,
y2
:
layer_limits_tmp1
.
ymax
+
0.01
}});
selCopyOther
({
layer
:
"tmp_center"
})
var
layer_limits_tmp
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
"tmp_center"
,
units
:
units
});
layer_limits_tmp
.
xc
=
layer_limits_tmp
.
xmin
-
0
+
layer_limits_tmp
.
xsize
/
2
;
layer_limits_tmp
.
yc
=
layer_limits_tmp
.
ymin
-
0
+
layer_limits_tmp
.
ysize
/
2
;
delLayer
(
"tmp_center"
)
GEN
.
clearLayers
()
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
work_layer
,
tmp1
]})
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
// 更具角度将其旋转
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
layer_limits_tmp
.
xc
,
y_anchor
:
layer_limits_tmp
.
yc
,
angle
:
angle
})
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
workLayer
({
name
:
ref_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
selectByFilter
({
area_rect
:{
x1
:
layer_limits_tmp1
.
xmin
-
0.01
,
y1
:
layer_limits_tmp1
.
ymin
-
0.01
,
x2
:
layer_limits_tmp1
.
xmax
+
0.01
,
y2
:
layer_limits_tmp1
.
ymax
+
0.01
}});
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
layer_limits_tmp
.
xc
,
y_anchor
:
layer_limits_tmp
.
yc
,
angle
:
angle
})
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
tmp1
,
dest_layer
:
tmp2
,
mode
:
'replace'
,
invert
:
'no'
});
var
text_tmp
=
'tl_tmp_text'
;
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
tmp1
,
dest_layer
:
text_tmp
,
mode
:
'replace'
,
invert
:
'no'
});
var
layer_limits
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
text_tmp
,
units
:
units
});
layer_limits
.
xc
=
layer_limits
.
xmin
-
0
+
layer_limits
.
xsize
/
2
;
layer_limits
.
yc
=
layer_limits
.
ymin
-
0
+
layer_limits
.
ysize
/
2
;
var
scalex
=
1
,
scaley
=
1
;
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
ref_layer
],
clear_before
:
'yes'
});
GEN
.
selectByFilter
({
area_rect
:{
x1
:
layer_limits
.
xmin
-
0.01
,
y1
:
layer_limits
.
ymin
-
0.01
,
x2
:
layer_limits
.
xmax
+
0.01
,
y2
:
layer_limits
.
ymax
+
0.01
}});
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selCopyOther
({
target_layer
:
ref_pad
,
invert
:
'no'
});
var
layer_limits_pad
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
ref_pad
,
units
:
units
});
var
feature
=
GEN
.
getFeatures
({
job
:
job
,
step
:
step
,
layer
:
tmp1
,
units
:
units
});
var
line_width
=
feature
[
0
].
symbol
.
slice
(
1
)
/
1000
;
var
tmp_ps
=
0.004
;
if
(
units
==
"mm"
){
tmp_ps
=
tmp_ps
*
25.4
}
// {"layer_limits_pad":{"xmin":"68.6901125","ymin":"84.4900925","xmax":"73.310115","ymax":"86.5100925",
// "xsize":4.620002499999998,"ysize":2.019999999999996},"line_width":0.1778,
// "layer_limits":{"xmin":"68.486215","ymin":"84.2861925","xmax":"73.527","ymax":"86.714",
// "xsize":5.040785,"ysize":2.4278075,"xc":71.0066075,"yc":85.50009625}}
scalex
=
(
Number
(
layer_limits_pad
.
xsize
)
+
line_width
*
2
+
tmp_ps
)
/
(
layer_limits
.
xsize
);
if
(
scalex
<
1
)
{
scalex
=
1
}
scaley
=
(
Number
(
layer_limits_pad
.
ysize
)
+
line_width
*
2
+
tmp_ps
)
/
(
layer_limits
.
ysize
);
if
(
scaley
<
1
)
{
scaley
=
1
}
}
delLayer
(
text_tmp
)
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
tmp1
],
clear_before
:
'yes'
});
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
'scale'
,
x_anchor
:
layer_limits_tmp
.
xc
,
y_anchor
:
layer_limits_tmp
.
yc
,
x_scale
:
scalex
,
y_scale
:
scaley
})
// {"mode":"anchor","oper":"scale","x_anchor":71.0066075,"y_anchor":85.50009625,"x_scale":1,"y_scale":1}
// 检查是否含单根线
// var tmp = 'tl-'+tmp1+'tmp1++';
// var _tmp2 = 'tl-'+tmp1+'tmp2++';
// var tmp3 = 'tl-'+tmp1+'-alone';
// var cale_x = scalex; // ?
// var cale_y = scaley; // ?
// GEN.createLayer({job:job,layer:tmp,context:'misc',type:'document',delete_exists:'yes'});
// GEN.createLayer({job:job,layer:tmp3,context:'misc',type:'document',delete_exists:'yes'});
// GEN.selCopyOther({target_layer:tmp,invert:'no'});
// GEN.affectedLayer({affected:'yes',mode:'single',layer:tmp,clear_before:'yes'});
// GEN.selContourize();
// GEN.DO_INFO("-t layer -e "+job+"/"+step+"/"+tmp+" -d FEAT_HIST");
// if (GEN.INFO_RESULT.gFEAT_HISTsurf > 0) {
// for(var i=1;i <= GEN.INFO_RESULT.gFEAT_HISTsurf;i++){
// GEN.createLayer({job:job,layer:_tmp2,context:'misc',type:'document',delete_exists:'yes'});
// GEN.affectedLayer({affected:'yes',mode:'single',layer:tmp,clear_before:'yes'});
// GEN.COM('sel_layer_feat',{operation:'select',layer:tmp,index:i});
// GEN.selCopyOther({target_layer:_tmp2,invert:'no'});
// GEN.affectedLayer({affected:'yes',mode:'single',layer:_tmp2,clear_before:'yes'});
// GEN.COM('sel_surf2outline',{width:1});
// GEN.COM('filter_reset',{filter_name:'popup'});
// GEN.selectByFilter({feat_types:'arc',polarity:'positive',profile:'all'});
// if (GEN.getSelectCount() > 0) {GEN.selDelete() } ;
// var feat = GEN.getFeatures({job:job,step:step,layer:_tmp2});
// var hash = {};
// for(var i=0;i < feat;i++){
// for(var k = i+1;k < feat.length; k++){
// if ((feat[i].xs == feat[k].xs && feat[i].ys == feat[k].ys) ||
// (feat[i].xs == feat[k].xe && feat[i].ys == feat[k].ye) ){
// if(!hash[i+'star']){hash[i+'star'] = {}}
// hash[i+'star'][x] = feat[i].xs;
// hash[i+'star'][y] = feat[i].ys;
// }
// if ((feat[i].xe == feat[k].xs && feat[i].ye == feat[k].ys) ||
// (feat[i].xe == feat[k].xe && feat[i].ye == feat[k].ye)) {
// if(!hash[i+'end']){hash[i+'end'] = {}}
// hash[i+'end'][x] = feat[i].xe;
// hash[i+'end'][y] = feat[i].ye;
// }
// }
// }
// if (Object.keys(hash).length == 0) {
// GEN.affectedLayer({affected:'yes',mode:'single',layer:tmp1,clear_before:'yes'});
// GEN.selRefFeat({layers:_tmp2,use:'filter',mode:'touch'});
// if ( GEN.getSelectCount() > 0 ){
// GEN.COM('sel_move_other',{target_layer:tmp3,invert:'no',dx:0,dy:0,size:0,x_anchor:0,y_anchor:0,rotation:0,mirror:'none'});
// var change_scal_x = (1 / cale_x).toFixed(3) - 0;
// var change_scal_y = (1 / cale_y).toFixed(3) - 0;
// GEN.affectedLayer({affected:'yes',mode:'single',layer:tmp3,clear_before:'yes'});
// GEN.selTransform({mode:'axis',oper:'scale',x_anchor:0,y_anchor:0,x_scale:change_scal_x,y_scale:change_scal_y});
// // {"mode":"axis","oper":"scale","x_anchor":0,"y_anchor":0,"x_scale":1,"y_scale":1}
// GEN.COM('sel_move_other',{target_layer:tmp1,invert:'no',dx:0,dy:0,size:0,x_anchor:0,y_anchor:0,rotation:0,mirror:'none'});
// GEN.deleteLayer({job:job,layer:tmp3,step:step});
// }
// }
// }
// GEN.deleteLayer({job:job,layer:_tmp2,step:step});
// GEN.deleteLayer({job:job,layer:tmp,step:step});
// }else{
// GEN.deleteLayer({job:job,layer:tmp,step:step});
// if (GEN.isLayerEmpty({job:job,step:step,layer:tmp3})) {
// GEN.deleteLayer({job:job,layer:tmp3,step:step});
// }
// }
// 转回去
GEN
.
clearLayers
()
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:[
work_layer
,
tmp1
,
tmp2
],
clear_before
:
"yes"
})
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
layer_limits_tmp
.
xc
,
y_anchor
:
layer_limits_tmp
.
yc
,
angle
:
360
-
angle
})
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
workLayer
({
name
:
ref_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
if
(
GEN
.
isLayerExists
({
job
:
job
,
step
:
step
,
layer
:
ref_pad
})){
GEN
.
affectedLayer
({
affected
:
'yes'
,
layer
:
ref_pad
})}
GEN
.
selectByFilter
({
area_rect
:{
x1
:
layer_limits_tmp1
.
xmin
-
0.01
,
y1
:
layer_limits_tmp1
.
ymin
-
0.01
,
x2
:
layer_limits_tmp1
.
xmax
+
0.01
,
y2
:
layer_limits_tmp1
.
ymax
+
0.01
}});
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
layer_limits_tmp
.
xc
,
y_anchor
:
layer_limits_tmp
.
yc
,
angle
:
360
-
angle
})
GEN
.
workLayer
({
name
:
tmp1
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
displayLayer
({
name
:
work_layer
,
number
:
2
});
if
(
!
GEN
.
isLayerEmpty
({
job
:
job
,
step
:
step
,
layer
:
ref_pad
})){
GEN
.
displayLayer
({
name
:
ref_layer
,
number
:
3
})}
GEN
.
COM
(
'disp_on'
);
if
(
GEN
.
isLayerExists
({
job
:
job
,
step
:
step
,
layer
:
ref_pad
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:
ref_pad
})}
var
ans
=
GEN
.
PAUSE
(
'Please Check...'
);
if
(
!
/ok/ig
.
test
(
ans
)){
throw
"cancel"
}
GEN
.
COM
(
'disp_off'
);
var
tmp_symbol
=
'tl_script_tmp'
;
GEN
.
workLayer
({
name
:
tmp1
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
COM
(
'sel_all_feat'
);
GEN
.
COM
(
"sel_create_sym,symbol="
+
tmp_symbol
+
",x_datum=0,y_datum=0,delete=no,fill_dx=0.1,fill_dy=0.1,attach_atr=no,retain_atr=no"
);
GEN
.
workLayer
({
name
:
work_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
selRefFeat
({
layers
:
tmp2
,
use
:
'filter'
,
mode
:
'cover'
});
GEN
.
COM
(
"sel_substitute,mode=substitute,symbol="
+
tmp_symbol
+
",tol="
+
par
.
tol
+
",x_datum=0,y_datum=0,dcode=0"
);
GEN
.
selectByFilter
({
include_syms
:
tmp_symbol
});
if
(
GEN
.
getSelectCount
()
>
0
){
GEN
.
selBreak
()};
GEN
.
COM
(
'disp_on'
);
GEN
.
COM
(
'truncate_layer'
,
{
layer
:
tmp1
});
GEN
.
COM
(
'truncate_layer'
,
{
layer
:
tmp2
});
GEN
.
COM
(
'disp_on'
);
GEN
.
COM
(
'sel_clear_feat'
);
GEN
.
units
({
type
:
units
});
}
else
{
flag
=
false
;
}
}
})
}
})
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
"tmp_ref_pad"
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
"tmp_ref_pad"
]})}
}
// 文字放大
function
slOptimize
(
props
)
{
var
info
=
gui
.
showForm
({
title
:
'请手动匹配以下信息'
,
showcheck
:
1
,
gen
:
GEN
,
defaultsize
:[
200
,
100
],
ui
:
{
type
:
'ScrollArea'
,
property
:
{
widget_resizable
:
true
,
frame_shape
:
'NoFrame'
,
align
:
'Top'
},
child
:
{
type
:
'VBoxLayout'
,
property
:
{
margin
:
2
,
spacing
:
5
,
align
:
'Top'
},
pack
:
{
stretch
:
0
},
child
:[{
type
:
"FormGridLayout"
,
property
:
{
columns
:
1
,
label_alignment
:
'Top | Right'
,
margin
:
10
,
spacing
:
20
},
pack
:
{
stretch
:
0
},
child
:[{
name
:
'font_symbol'
,
pack
:
{
label
:
'文字symbol'
},
type
:
'LineEdit'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
units
:
'um'
,
property
:
{
enabled
:
true
,
value
:
200
}
},
{
name
:
'tmp_enlarge_ss'
,
pack
:
{
label
:
'文字作为辅助临时扩大'
},
type
:
'LineEdit'
,
units
:
'um'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
property
:
{
value
:
par
.
tmp_enlarge_ss
,
enabled
:
true
}
},
{
name
:
'font_height'
,
pack
:
{
label
:
'字高(um)'
},
type
:
'LineEdit'
,
units
:
'um'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
property
:
{
value
:
par
.
ss_elarge_height
,
enabled
:
true
}
},
{
type
:
"stretch"
}]
}]
}
}
});
if
(
!
info
){
throw
"未填写参数"
}
info
=
JSON
.
parse
(
JSON
.
stringify
(
info
))
var
font_height
=
info
.
font_height
;
var
font_symbol
=
info
.
font_symbol
;
var
tmp_enlarge_ss
=
info
.
tmp_enlarge_ss
;
// 1. step过滤
var
workstep
=
props
.
workstep
;
// 2.过滤工作层
var
work_layers
=
getLayer
({
layer_type
:
"silk_screen"
,
context
:
"board"
})
if
(
/yes/ig
.
test
(
par
.
select_lyr
)){
var
matrix
=
GEN
.
getMatrix
({
job
:
job
});
var
layers
=
Object
.
keys
(
matrix
).
map
(
function
(
key
){
var
tmp
=
{};
tmp
[
key
]
=
key
;
return
tmp
var
work_layers
=
Object
.
keys
(
matrix
).
filter
(
function
(
v
)
{
var
layer_info
=
matrix
[
v
];
return
layer_info
.
context
==
"board"
&&
layer_info
.
layer_type
==
"signal"
&&
layer_info
.
side
==
"inner"
})
work_layers
=
gui
.
selectMultiple
({
defaultsize
:[
200
,
100
],
title
:
"请先择工作层"
,
list
:
layers
,
defaultvalue
:
work_layers
,
columns
:
4
,
gen
:
GEN
})
}
if
(
work_layers
.
length
==
0
)
{
return
"没有先择layer"
}
var
matrix
=
GEN
.
getMatrix
({
job
:
job
})
workstep
.
forEach
(
function
(
step
)
{
steplist
.
forEach
(
function
(
step
)
{
GEN
.
openStep
({
job
:
job
,
name
:
step
})
GEN
.
units
({
type
:
par
.
units
})
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
.
zoomHome
();
work_layers
.
forEach
(
function
(
layer
){
var
font_layer
=
layer
+
par
.
silk_suffix
;
GEN
.
workLayer
({
name
:
font_layer
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
selChangeSym
({
symbol
:
"r"
+
font_symbol
})
var
tmp1
=
font_layer
+
"_1"
;
var
tmp2
=
font_layer
+
"_2"
;
var
tmp3
=
font_layer
+
"_3"
;
var
bk
=
font_layer
+
"_bk"
;
var
bk2
=
font_layer
+
"_ok"
;
var
bk_tmp
=
font_layer
+
"_ok_tmp"
;
var
bk_ok2
=
font_layer
+
"_ok2"
;
[
tmp1
,
tmp2
,
tmp3
,
bk
,
bk2
,
bk_tmp
,
bk_ok2
].
forEach
(
function
(
v
){
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
v
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
v
]})}
})
// GEN.copyLayer({source_job:job,source_step:step,source_layer:font_layer,dest_layer:tmp1, mode:"replace"})
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
font_layer
,
dest_layer
:
tmp3
,
mode
:
"replace"
})
GEN
.
copyLayer
({
source_job
:
job
,
source_step
:
step
,
source_layer
:
font_layer
,
dest_layer
:
bk2
,
mode
:
"replace"
})
// GEN.copyLayer({source_job:job,source_step:step,source_layer:font_layer,dest_layer:bk, mode:"replace"})
GEN
.
affectedLayer
({
affected
:
'no'
,
mode
:
'all'
})
GEN
.
selClearFeature
()
// GEN.workLayer({name:tmp1,display_number:2,clear_before:'yes'})
// GEN.selChangeSym({symbol:"r0.1"})
// 利用tmp3 快速定位
GEN
.
workLayer
({
name
:
tmp3
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
units
({
type
:
"mm"
})
GEN
.
selChangeSym
({
symbol
:
"r"
+
tmp_enlarge_ss
})
// 转铜皮 获取每一个铜皮的limits信息
GEN
.
selContourize
()
var
fast_features
=
GEN
.
getFeatures
({
job
:
job
,
step
:
step
,
layer
:
tmp3
,
options
:
"feat_index"
,
surface
:
1
,
units
:
"mm"
})
fast_features
=
featsToLimits
(
fast_features
)
fast_features
.
forEach
(
function
(
item
){
if
(
item
.
limit
.
xsize
>
item
.
limit
.
ysize
)
{
var
k
=
font_height
/
(
item
.
limit
.
ysize
*
1000
)
item
.
x_scale
=
k
item
.
y_scale
=
k
}
else
{
var
k
=
font_height
/
(
item
.
limit
.
xsize
*
1000
)
item
.
y_scale
=
k
item
.
x_scale
=
k
}
})
fast_features
.
forEach
(
function
(
item
){
GEN
.
workLayer
({
name
:
bk2
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
item
.
limit
.
xmin
+
",y="
+
item
.
limit
.
ymin
)
GEN
.
COM
(
"filter_area_xy,x="
+
item
.
limit
.
xmax
+
",y="
+
item
.
limit
.
ymax
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=yes"
)
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
bk_tmp
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
GEN
.
workLayer
({
name
:
bk_tmp
,
display_number
:
2
,
clear_before
:
'yes'
})
var
tmp_limitbk
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
bk_tmp
,
units
:
'mm'
})
tmp_limitbk
.
xc
=
Number
(
tmp_limitbk
.
xmin
)
+
tmp_limitbk
.
xsize
/
2
tmp_limitbk
.
yc
=
Number
(
tmp_limitbk
.
ymin
)
+
tmp_limitbk
.
ysize
/
2
tmp_limitbk
.
xsize
=
Number
(
tmp_limitbk
.
xsize
)
tmp_limitbk
.
ysize
=
Number
(
tmp_limitbk
.
ysize
)
var
k
;
var
sym
=
0
;
var
syms
=
GEN
.
getLayerSymsHist
({
job
:
job
,
step
:
step
,
layer
:
bk_tmp
,
options
:
'break_sr'
,
units
:
'mm'
})
for
(
var
key
in
syms
)
{
var
symInfo
=
syms
[
key
];
if
(
symInfo
.
size
){
var
size
=
symInfo
.
size
;
if
(
sym
==
0
){
sym
=
size
}
else
{
sym
=
size
>
sym
?
sym
:
size
}
}
}
if
(
tmp_limitbk
.
xsize
>
tmp_limitbk
.
ysize
)
{
k
=
(
font_height
-
sym
)
/
(
tmp_limitbk
.
ysize
*
1000
-
sym
)
}
else
{
k
=
(
font_height
-
sym
)
/
(
tmp_limitbk
.
xsize
*
1000
-
sym
)
}
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
'scale'
,
x_anchor
:
tmp_limitbk
.
xc
,
y_anchor
:
tmp_limitbk
.
yc
,
x_scale
:
k
,
y_scale
:
k
})
GEN
.
selMoveOther
({
target_layer
:
bk_ok2
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
}
})
// 框选
var
flag
=
true
;
IKM
.
msg
(
font_layer
+
"层:请选择需放大的文字,不需制作了请【左键框选空白处】"
)
var
x_or_y
=
"x"
;
while
(
flag
){
var
bk2_tmp
=
bk2
+
"_tmp"
GEN
.
workLayer
({
name
:
bk_ok2
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
displayLayer
({
name
:
bk2
,
number
:
2
});
GEN
.
displayLayer
({
name
:
font_layer
,
number
:
2
});
var
tmp_con
=
GEN
.
MOUSE
({
type
:
'r'
,
text
:
"Please Select"
});
GEN
.
workLayer
({
name
:
font_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
if
(
GEN
.
getSelectCount
()
>
0
){
var
info2
=
gui
.
showForm
({
title
:
'请手动匹配以下信息'
,
showcheck
:
1
,
gen
:
GEN
,
defaultsize
:[
200
,
100
],
ui
:
{
type
:
'ScrollArea'
,
property
:
{
widget_resizable
:
true
,
frame_shape
:
'NoFrame'
,
align
:
'Top'
},
child
:
{
type
:
'VBoxLayout'
,
property
:
{
margin
:
2
,
spacing
:
5
,
align
:
'Top'
},
pack
:
{
stretch
:
0
},
child
:[{
type
:
"FormGridLayout"
,
property
:
{
columns
:
1
,
label_alignment
:
'Top | Right'
,
margin
:
10
,
spacing
:
20
},
pack
:
{
stretch
:
0
},
child
:[{
name
:
'font_symbol'
,
pack
:
{
label
:
'文字symbol'
},
type
:
'LineEdit'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
units
:
'um'
,
property
:
{
enabled
:
true
,
value
:
"200"
}
},
{
name
:
'x_or_y'
,
pack
:
{
label
:
'文字方向'
},
type
:
'LineEdit'
,
setter
:
function
(
obj
){
obj
.
setText
()
},
property
:
{
value
:
x_or_y
,
enabled
:
true
}
},
{
name
:
'font_height'
,
pack
:
{
label
:
'字高(um)'
},
type
:
'LineEdit'
,
units
:
'um'
,
setter
:
function
(
obj
)
{
obj
.
setText
()
},
property
:
{
value
:
par
.
ss_elarge_height
,
enabled
:
true
}
},
{
type
:
"stretch"
}]
}]
}
GEN
.
clearLayers
()
GEN
.
workLayer
({
name
:
rout
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
selectByFilter
({
profile
:
"in"
})
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
tmp
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
GEN
.
workLayer
({
name
:
tmp
,
display_number
:
2
,
clear_before
:
'yes'
});
(
function
(){
GEN
.
selRefFeat
({
layers
:
rout
,
use
:
"filter"
,
mode
:
"touch"
});
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
rout
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
arguments
.
callee
()
}
})();
// 过滤外形线
if
(
!
GEN
.
isLayerExists
({
job
:
job
,
layer
:
tmp
+
"2"
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"2"
]})
}
GEN
.
COM
(
"profile_to_rout,layer="
+
tmp
+
"2"
+
",width=1"
)
GEN
.
selRefFeat
({
layers
:
tmp
+
"2"
,
use
:
"filter"
,
mode
:
"touch"
});
(
function
(){
GEN
.
selRefFeat
({
layers
:
rout
,
use
:
"filter"
,
mode
:
"touch"
});
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
rout
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
arguments
.
callee
()
}
});
if
(
!
info2
){
throw
"未填写参数"
}
info2
=
JSON
.
parse
(
JSON
.
stringify
(
info2
))
x_or_y
=
info2
.
x_or_y
;
var
font_height2
=
info2
.
font_height
;
var
tmp_layer
=
font_layer
+
"_tmp"
;
selCopyOther
({
delExist
:
true
,
layer
:
tmp_layer
})
GEN
.
workLayer
({
name
:
tmp_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
})();
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"2"
]})
GEN
.
selAllFeat
()
selCopyOther
({
delExist
:
true
,
layer
:
bk2_tmp
})
GEN
.
workLayer
({
name
:
bk2
,
display_number
:
1
,
clear_before
:
'yes'
});
GEN
.
COM
(
"filter_area_strt"
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x1
+
",y="
+
tmp_con
.
y1
)
GEN
.
COM
(
"filter_area_xy,x="
+
tmp_con
.
x2
+
",y="
+
tmp_con
.
y2
)
GEN
.
COM
(
"filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"
)
if
(
GEN
.
getSelectCount
()
>
0
)
{
// 继续过滤
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
tmp
+
"_f"
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"_f"
]})
}
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
tmp
+
"_f"
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
GEN
.
workLayer
({
name
:
tmp
+
"_f"
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
COM
(
"sel_cut_data,det_tol=25.4,con_tol=25.4,rad_tol=0,filter_overlaps=no,delete_doubles=no,use_order=yes,ignore_width=yes,ignore_holes=none,start_positive=yes,polarity_of_touching=same"
)
GEN
.
selRefFeat
({
layers
:
"drl"
,
use
:
"filter"
,
mode
:
"touch"
})
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selDelete
()}
GEN
.
workLayer
({
name
:
tmp_layer
,
display_number
:
1
,
clear_before
:
'yes'
});
var
limits
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
tmp_layer
,
units
:
"mm"
})
for
(
var
key
in
limits
)
{
limits
[
key
]
=
limits
[
key
]
-
0
;
}
limits
.
xc
=
Number
(
limits
.
xmin
)
+
limits
.
xsize
/
2
limits
.
yc
=
Number
(
limits
.
ymin
)
+
limits
.
ysize
/
2
var
sym
=
0
;
var
syms
=
GEN
.
getLayerSymsHist
({
job
:
job
,
step
:
step
,
layer
:
tmp_layer
,
units
:
'mm'
})
for
(
var
key
in
syms
)
{
var
symInfo
=
syms
[
key
];
if
(
symInfo
.
size
){
var
size
=
symInfo
.
size
;
if
(
sym
==
0
){
sym
=
size
}
else
{
sym
=
size
>
sym
?
sym
:
size
}
}
}
// 获取里面有几个字母 每一个字母的limits信息
GEN
.
selChangeSym
({
symbol
:
"r1"
})
GEN
.
selContourize
()
var
feas
=
GEN
.
getFeatures
({
job
:
job
,
step
:
step
,
layer
:
tmp_layer
,
options
:
"feat_index"
,
units
:
"mm"
})
if
(
feas
.
length
==
1
)
{
GEN
.
workLayer
({
name
:
bk2_tmp
,
display_number
:
2
,
clear_before
:
'yes'
});
var
k
=
(
font_height2
-
sym
)
/
((
x_or_y
==
"y"
?
limits
.
xsize
:
limits
.
ysize
)
*
1000
-
sym
)
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
'scale'
,
x_anchor
:
limits
.
xc
,
y_anchor
:
limits
.
yc
,
x_scale
:
k
,
y_scale
:
k
})
GEN
.
selMoveOther
({
target_layer
:
bk2
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
}
else
if
(
feas
.
length
>
1
)
{
var
limits_info
=
[];
feas
.
forEach
(
function
(
item
)
{
var
index
=
item
.
index
;
GEN
.
selLayerFeat
({
layer
:
tmp_layer
,
index
:
index
,
operation
:
"select"
});
GEN
.
workLayer
({
name
:
tmp
,
display_number
:
2
,
clear_before
:
'yes'
});
GEN
.
selRefFeat
({
layers
:
tmp
+
"_f"
,
use
:
"filter"
,
mode
:
"touch"
})
GEN
.
selReverse
()
if
(
GEN
.
getSelectCount
()
>
0
)
{
var
tmp_l
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
tmp_layer
,
units
:
"mm"
,
options
:
"select"
})
for
(
var
key
in
tmp_l
)
{
tmp_l
[
key
]
=
tmp_l
[
key
]
-
0
;
}
tmp_l
.
xc
=
Number
(
tmp_l
.
xmin
)
+
tmp_l
.
xsize
/
2
tmp_l
.
yc
=
Number
(
tmp_l
.
ymin
)
+
tmp_l
.
ysize
/
2
limits_info
.
push
({
index
:
index
,
limits
:
tmp_l
})
GEN
.
selClearFeature
()
}
})
var
rodata
=
[]
limits_info
.
forEach
(
function
(
item
,
i
)
{
if
(
limits_info
[
i
+
1
]){
rodata
.
push
(
getRodate
({
xs
:
item
.
limits
.
xc
,
ys
:
item
.
limits
.
yc
,
xe
:
limits_info
[
i
+
1
].
limits
.
xc
,
ye
:
limits_info
[
i
+
1
].
limits
.
yc
}))
GEN
.
selMoveOther
({
target_layer
:
rout
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
}
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"_f"
]})
// 对单边>=20000um的闭合图形铺铜
// 将长度 >= 20000的线选出来 将跟此线xy坐标相同的线选出来拷贝到辅助层 cuttingdata 拷贝回去
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
tmp
+
"_2"
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"_2"
]})
}
var
feats
=
GEN
.
getFeatures
({
job
:
job
,
step
:
step
,
layer
:
tmp
,
units
:
"mm"
,
options
:
"feat_index"
})
feats
.
forEach
(
function
(
item
){
if
(
item
.
type
==
"line"
)
{
var
len
=
Math
.
sqrt
((
item
.
xe
-
item
.
xs
)
*
(
item
.
xe
-
item
.
xs
)
+
(
item
.
ye
-
item
.
ys
)
*
(
item
.
ye
-
item
.
ys
))
if
(
len
>=
20
)
{
GEN
.
selLayerFeat
({
layer
:
tmp
,
index
:
item
.
index
,
operation
:
"select"
})
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
tmp
+
"_2"
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})}
}
}
else
if
(
item
.
type
==
"arc"
)
{
var
len
=
genMath
.
arcLength
(
item
)
if
(
len
>=
20
)
{
GEN
.
selLayerFeat
({
layer
:
tmp
,
index
:
item
.
index
,
operation
:
"select"
})
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
tmp
+
"_2"
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})}
}
}
})
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
tmp
+
"_2"
})){
(
function
(){
GEN
.
workLayer
({
name
:
tmp
,
display_number
:
2
,
clear_before
:
'yes'
});
GEN
.
selRefFeat
({
layers
:
tmp
+
"_2"
,
use
:
"filter"
,
mode
:
"touch"
})
if
(
GEN
.
getSelectCount
()
>
0
)
{
GEN
.
selMoveOther
({
target_layer
:
tmp
+
"_2"
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
arguments
.
callee
()
}
})()
GEN
.
workLayer
({
name
:
tmp
+
"_2"
,
display_number
:
2
,
clear_before
:
'yes'
});
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
rout
,
invert
:
'no'
})
GEN
.
COM
(
"sel_cut_data,det_tol=25.4,con_tol=25.4,rad_tol=0,filter_overlaps=no,delete_doubles=no,use_order=yes,ignore_width=yes,ignore_holes=none,start_positive=yes,polarity_of_touching=same"
)
// 拷贝到负层
work_layers
.
forEach
(
function
(
l
){
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
l
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
-
500
})
})
var
angle
=
rodata
.
reduce
(
function
(
a
,
b
)
{
return
a
+
b
})
/
rodata
.
length
;
if
(
Math
.
abs
(
angle
)
<
10
)
{
angle
=
0
}
GEN
.
workLayer
({
name
:
bk2_tmp
,
display_number
:
2
,
clear_before
:
'yes'
});
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
limits
.
xc
,
y_anchor
:
limits
.
yc
,
angle
:
angle
})
// 按照中心放大
var
limits2
=
GEN
.
getLayerLimits
({
job
:
job
,
step
:
step
,
layer
:
tmp_layer
,
units
:
"mm"
})
for
(
var
key
in
limits
)
{
limits2
[
key
]
=
limits2
[
key
]
-
0
;
}
limits2
.
xc
=
limits2
.
xmin
+
limits2
.
xsize
/
2
limits2
.
yc
=
limits2
.
ymin
+
limits2
.
ysize
/
2
if
(
limits2
.
xsize
>
limits2
.
ysize
)
{
var
k
=
(
font_height2
-
sym
)
/
((
x_or_y
==
"y"
?
limits2
.
xsize
:
limits2
.
ysize
)
*
1000
-
sym
)
limits2
.
x_scale
=
k
limits2
.
y_scale
=
k
}
else
{
var
k
=
(
font_height2
-
sym
)
/
((
x_or_y
==
"y"
?
limits2
.
xsize
:
limits2
.
ysize
)
*
1000
-
sym
)
limits2
.
y_scale
=
k
limits2
.
x_scale
=
k
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
+
"_2"
]})
}
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
'scale'
,
x_anchor
:
limits2
.
xc
,
y_anchor
:
limits2
.
yc
,
x_scale
:
limits2
.
x_scale
,
y_scale
:
limits2
.
y_scale
})
GEN
.
selTransform
({
mode
:
'anchor'
,
oper
:
"rotate"
,
x_anchor
:
limits
.
xc
,
y_anchor
:
limits
.
yc
,
angle
:
360
-
angle
})
GEN
.
selMoveOther
({
target_layer
:
bk2
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
}
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp_layer
]})
}
else
{
flag
=
false
}
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
bk2_tmp
}))
{
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
bk2_tmp
]})
}
}
GEN
.
PAUSE
(
"check"
)
// 将ok的移动到文字层
GEN
.
clearLayers
()
GEN
.
workLayer
({
name
:
font_layer
,
display_number
:
2
,
clear_before
:
'yes'
});
GEN
.
selDelete
();
GEN
.
clearLayers
()
GEN
.
affectedLayer
({
affected
:
"yes"
,
layer
:[
bk2
,
bk_ok2
]})
GEN
.
selMoveOther
({
target_layer
:
layer
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
});
[
tmp1
,
tmp2
,
tmp3
,
bk
,
bk2
,
font_layer
,
bk_ok2
,
layer
+
cover_layer_suffix
].
forEach
(
function
(
v
){
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
v
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
v
]})}
})
})
})
}
function
selCopyOther
(
props
){
// {layer , invent, dx, dy , size}
if
(
GEN
.
getSelectCount
()
>
0
){
if
(
!
props
||
!
props
.
layer
){
return
}
if
(
props
.
delExist
){
if
(
GEN
.
isLayerExists
({
job
:
job
,
layer
:
props
.
layer
})){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
props
.
layer
]})}}
GEN
.
selCopyOther
({
dest
:
'layer_name'
,
target_layer
:
props
.
layer
,
invert
:
props
.
invert
||
'no'
,
dx
:
props
.
dx
||
0
,
dy
:
props
.
dy
||
0
,
size
:
props
.
size
||
0
})
}
}
function
getLayer
(
props
){
if
(
!
props
){
return
}
if
(
!
props
.
context
){
props
.
context
=
"board"
}
GEN
.
workLayer
({
name
:
tmp
,
display_number
:
2
,
clear_before
:
'yes'
})
GEN
.
selMoveOther
({
target_layer
:
rout
,
invert
:
'no'
,
dx
:
0
,
dy
:
0
,
size
:
0
})
GEN
.
displayLayer
({
name
:
rout
,
number
:
1
})
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
tmp
]})
// 删除+++
var
matrix
=
GEN
.
getMatrix
({
job
:
job
})
return
Object
.
keys
(
matrix
).
reduce
(
function
(
a
,
b
){
var
info
=
matrix
[
b
];
var
ret
=
true
;
for
(
var
key
in
props
)
{
if
(
!
Array
.
isArray
(
props
[
key
])){
props
[
key
]
=
[
props
[
key
]]}
if
(
info
[
key
]
&&
props
[
key
].
indexOf
(
info
[
key
])
<
0
){
ret
=
false
}
}
if
(
ret
){
a
.
push
(
props
.
res
==
"info"
?
info
:
b
)
}
return
a
},[])
}
function
NewGUI
(
gui
)
{
this
.
msgBox
=
function
(
props
){
// title type content button
props
=
props
||
{}
return
gui
.
msgBox
(
props
.
title
||
"title"
,
props
.
type
||
"info"
,
props
.
content
||
"content"
,
props
.
button
||
[
"ok"
,
"cancel"
]);
}
this
.
selectFromTreeview
=
gui
.
selectFromTreeview
this
.
confirm
=
function
(
props
)
{
props
=
props
||
{}
return
gui
.
confirm
(
props
.
content
||
"content"
,
props
.
button
||
[
"yes"
,
"no"
],
props
.
type
||
"question"
);
}
this
.
selectFile
=
function
(
props
){
// "choose something", "*", true, "file", "/home/abby/fast_io"
props
=
props
||
{}
return
gui
.
selectFile
(
props
.
title
||
"choose something"
,
props
.
filter
||
"*"
,
props
.
multiple
||
false
,
"file"
,
""
);
}
this
.
selectSingle
=
function
(
props
)
{
props
=
props
||
{}
return
gui
.
selectSingle
({
"title"
:
props
.
title
||
"select"
,
"list"
:
props
.
list
||
[],
"default"
:
props
[
"default"
]
||
""
,
"columns"
:
props
.
columns
||
2
,
"gen"
:
props
.
gen
||
GEN
});
}
this
.
selectMultiple
=
function
(
props
)
{
props
=
props
||
{}
return
gui
.
selectMultiple
({
"title"
:
props
.
title
||
"select"
,
"list"
:
props
.
list
||
[],
"defaultvalue"
:
props
[
"defaultvalue"
]
||
[
""
],
"defaultsize"
:
props
[
"defaultsize"
]
||
[
200
,
100
],
"columns"
:
props
.
columns
||
2
,
"gen"
:
props
.
gen
||
GEN
});
}
this
.
selectFromTable
=
gui
.
selectFromTable
this
.
snapScreen
=
gui
.
snapScreen
this
.
imageViewer
=
gui
.
imageViewer
this
.
inputBox
=
gui
.
inputBox
this
.
showForm
=
gui
.
showForm
this
.
selectLayer
=
function
(
props
){
props
=
props
||
{}
return
gui
.
selectLayer
({
title
:
props
.
title
||
"请选择层"
,
filter
:
props
.
filter
||
".*"
,
// regular expression
selectmode
:
props
.
selectmode
||
"multiple"
,
// single, multiple
context
:
props
.
context
||
"all"
,
// all, board, misc
layertype
:
props
.
layertype
||
"signal"
,
// default type of layertypelist
defaultsize
:
props
.
defaultsize
||
[
600
,
400
],
// window size
layermatrix
:
props
.
layermatrix
||
props
.
matrix
,
layertypelist
:
props
.
layertypelist
||
[
{
name
:
"all"
,
display_name
:
"all"
,
filter
:
function
(
x
)
{
return
x
}},
{
name
:
"signal"
,
display_name
:
"signal"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"signal"
;
}},
{
name
:
"power_ground"
,
display_name
:
"power_ground"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"power_ground"
;
}},
{
name
:
"mixed"
,
display_name
:
"mixed"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"mixed"
;
}},
{
name
:
"solder_mask"
,
display_name
:
"solder_mask"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"solder_mask"
;
}},
{
name
:
"silk_screen"
,
display_name
:
"silk_screen"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"silk_screen"
;
}},
{
name
:
"solder_paste"
,
display_name
:
"solder_paste"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"solder_paste"
;
}},
{
name
:
"drill"
,
display_name
:
"drill"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"drill"
;
}},
{
name
:
"rout"
,
display_name
:
"rout"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"rout"
;
}},
{
name
:
"document"
,
display_name
:
"document"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"document"
;
}}
],
gen
:
props
.
GEN
||
GEN
})
}
this
.
lockUnlockLayer
=
function
(
props
){
props
=
props
||
{}
var
tmp
=
{}
if
(
props
.
matrix
)
{
for
(
var
key
in
props
.
matrix
)
{
var
item
=
props
.
matrix
[
key
]
tmp
[
key
]
=
{
row
:
item
.
row
,
name
:
item
.
name
}
Object
.
keys
(
matrix
).
forEach
(
function
(
v
)
{
if
(
/
\+\+\+
$/
.
test
(
v
)){
GEN
.
deleteLayer
({
job
:
job
,
layer
:[
v
]})
}
}
return
gui
.
lockUnlockLayer
({
title
:
props
.
title
||
"lockUnlockLayer"
,
layermatrix
:
props
.
layermatrix
||
tmp
})
}
this
.
passwordBox
=
function
(
props
){
props
=
props
||
{}
return
gui
.
passwordBox
({
title
:
props
.
title
||
"password"
,
password
:
props
.
password
||
"1212"
})
}
this
.
selectJobLayer
=
function
(
props
)
{
props
=
props
||
{}
return
gui
.
selectJobLayer
({
layertypelist
:
props
.
layertypelist
||
[
{
name
:
"all"
,
display_name
:
"all"
,
filter
:
function
(
x
)
{
return
x
}},
{
name
:
"signal"
,
display_name
:
"signal"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"signal"
;
}},
{
name
:
"power_ground"
,
display_name
:
"power_ground"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"power_ground"
;
}},
{
name
:
"mixed"
,
display_name
:
"mixed"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"mixed"
;
}},
{
name
:
"solder_mask"
,
display_name
:
"solder_mask"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"solder_mask"
;
}},
{
name
:
"silk_screen"
,
display_name
:
"silk_screen"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"silk_screen"
;
}},
{
name
:
"solder_paste"
,
display_name
:
"solder_paste"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"solder_paste"
;
}},
{
name
:
"drill"
,
display_name
:
"drill"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"drill"
;
}},
{
name
:
"rout"
,
display_name
:
"rout"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"rout"
;
}},
{
name
:
"document"
,
display_name
:
"document"
,
filter
:
function
(
x
)
{
return
x
[
"layer_type"
]
===
"document"
;
}}
],
//defaultlayertype: "ha",
joblist
:
props
.
joblist
||
[],
defaultJob
:
props
.
defaultJob
||
[],
// select by default
steplist
:
props
.
steplist
||
[],
// defaultstep: "step3",
showstep
:
props
.
showstep
||
true
,
selectmode
:
props
.
selectmode
||
"multiple"
,
// single/multiple
layermatrix
:
props
.
layermatrix
||
{
},
defaultlayer
:
props
.
defaultlayer
||
[]
})
}
}
function
getWorkStep
(
props
){
var
steplists
=
GEN
.
getStepList
({
job
:
job
});
if
(
steplists
.
length
==
0
){
return
"该料号没有step"
}
var
steps_tmp
=
steplists
.
filter
(
function
(
name
){
var
reg
=
new
RegExp
(
par
.
step
,
"ig"
)
return
reg
.
test
(
name
)
})
if
(
steplists
.
length
==
0
){
return
"根据脚本参数过滤出来的step不存在,请检查资料或者脚本参数配置!"
}
var
workstep
=
gui
.
selectMultiple
({
title
:
"请先择工作step"
,
size
:[
200
,
100
],
defaultsize
:[
200
,
100
],
list
:
steplists
.
map
(
function
(
v
){
var
tmp
=
{};
tmp
[
v
]
=
v
;
return
tmp
}),
defaultvalue
:
steps_tmp
,
columns
:
1
,
gen
:
GEN
})
if
(
workstep
.
length
==
0
)
{
return
"没有先择step"
}
return
workstep
}
function
delLayer
(
layer
){
if
(
!
Array
.
isArray
(
layer
)){
layer
=
[
layer
]
}
layer
=
layer
.
filter
(
function
(
v
){
return
GEN
.
isLayerExists
({
job
:
job
,
layer
:
v
})})
if
(
layer
.
length
){
GEN
.
deleteLayer
({
job
:
job
,
layer
:
layer
})
}
}
function
correct
(
work_layer
){
var
tmp
=
GEN
.
getWorkLayer
();
return
tmp
!==
work_layer
;
}
function
getAngle
(
features
){
// 获取最长边的角度
features
.
sort
(
function
(
a
,
b
){
a
.
length
=
getLineLength
(
a
);
b
.
length
=
getLineLength
(
b
);
return
a
.
length
-
b
.
length
})
return
getRodate
(
features
[
features
.
length
-
1
])
}
function
getLineLength
(
line
){
if
(
line
.
type
!=
"line"
){
return
0
}
return
Math
.
sqrt
((
line
.
xe
-
line
.
xs
)
*
(
line
.
xe
-
line
.
xs
)
+
(
line
.
ye
-
line
.
ys
)
*
(
line
.
ye
-
line
.
ys
))
}
function
getRodate
(
props
){
var
xs
=
props
.
xs
;
var
ys
=
props
.
ys
;
var
xe
=
props
.
xe
;
var
ye
=
props
.
ye
;
var
y
=
ye
-
ys
;
var
x
=
xe
-
xs
;
var
r
=
Math
.
atan
(
y
/
x
)
return
r
*
180
/
Math
.
PI
}
function
sameDirection
(
xory
,
type
,
res
,
indexes
)
{
for
(
var
key
in
xory
)
{
var
current
=
-
1
;
var
data
=
xory
[
key
];
data
.
sort
(
function
(
a
,
b
){
return
a
[
type
]
-
b
[
type
]})
data
.
forEach
(
function
(
item
,
i
){
if
(
i
>
current
){
var
ret
=
[
item
];
current
=
searchFont
(
item
,
data
,
i
,
ret
,
type
)
if
(
ret
.
length
>
1
)
{
ret
.
forEach
(
function
(
item
)
{
indexes
=
indexes
.
filter
(
function
(
item2
){
return
item2
.
index
!=
item
.
index
})
})
res
.
push
(
ret
.
reduce
(
function
(
a
,
b
){
if
(
Number
(
b
.
limit
.
xmin
)
<
Number
(
a
.
xmin
)){
a
.
xmin
=
b
.
limit
.
xmin
}
if
(
Number
(
b
.
limit
.
ymin
)
<
Number
(
a
.
ymin
)){
a
.
ymin
=
b
.
limit
.
ymin
}
if
(
Number
(
b
.
limit
.
xmax
)
>
Number
(
a
.
xmax
)){
a
.
xmax
=
b
.
limit
.
xmax
}
if
(
Number
(
b
.
limit
.
ymax
)
>
Number
(
a
.
ymax
)){
a
.
ymax
=
b
.
limit
.
ymax
}
return
a
},{
xmin
:
item
.
limit
.
xmin
,
ymin
:
item
.
limit
.
ymin
,
xmax
:
item
.
limit
.
xmax
,
ymax
:
item
.
limit
.
ymax
}))
}
}
})
}
return
indexes
}
function
searchFont
(
l
,
arr
,
i
,
ret
,
type
){
if
(
arr
[
i
+
1
]){
var
len
=
Math
.
abs
(
l
[
type
]
-
arr
[
i
+
1
][
type
])
if
(
len
<=
1.5
){
ret
.
push
(
arr
[
i
+
1
])
return
searchFont
(
arr
[
i
+
1
],
arr
,
i
+
1
,
ret
,
type
)
}
else
{
return
i
}
// 保存
if
(
/yes/ig
.
test
(
par
.
auto_save
)){
GEN
.
checkInout
({
job
:
job
,
mode
:
"out"
})
// 结束保存料号 关闭料号
GEN
.
saveJob
({
job
:
job
});
GEN
.
checkInout
({
job
:
job
,
mode
:
"in"
})
GEN
.
closeJob
({
job
:
job
})
}
else
{
GEN
.
checkInout
({
job
:
job
,
mode
:
"in"
})
}
return
i
+
1
}
function
turnFix
(
data
)
{
return
parseFloat
(
data
).
toFixed
(
1
)
}
function
surfaceAnalysis
(
props
){
props
.
limit
.
xmin
=
props
.
limit
.
xmin
-
0
;
props
.
limit
.
ymin
=
props
.
limit
.
ymin
-
0
;
props
.
limit
.
xmax
=
props
.
limit
.
xmax
-
0
;
props
.
limit
.
ymax
=
props
.
limit
.
ymax
-
0
;
props
.
limit
.
xsize
=
props
.
limit
.
xsize
-
0
;
props
.
limit
.
ysize
=
props
.
limit
.
ysize
-
0
;
props
.
xc
=
props
.
limit
.
xsize
/
2
+
props
.
limit
.
xmin
props
.
yc
=
props
.
limit
.
ysize
/
2
+
props
.
limit
.
ymin
}
// function featsToLimits(feats) {
// feats.forEach(function(item) {
// if(item.feats) {
// var polygon = genMath.profile2Polygon(item.feats.join("\n"),0)
// var res = polygon.reduce(function(a,b){
// a.xmin = b.x > a.xmin ? a.xmin : b.x;
// a.ymin = b.y > a.ymin ? a.ymin : b.y;
// a.xmax = b.x < a.xmax ? a.xmax : b.x;
// a.ymax = b.y < a.ymax ? a.ymax : b.y;
// return a
// }, {
// xmin: polygon[0].x,
// ymin: polygon[0].y,
// xmax: polygon[0].x,
// ymax: polygon[0].y
// })
// res.xsize = Math.abs(res.xmax - res.xmin)
// res.ysize = Math.abs(res.ymax - res.ymin)
// res.xc = res.xmin + res.xsize/2
// res.yc = res.ymin + res.ysize/2
// item.limits = res
// item.limit = res
// }
// })
// return feats
// }
function
featsToLimits
(
feats
)
{
feats
.
forEach
(
function
(
item
)
{
if
(
item
.
feats
)
{
var
polygon
=
profile2Polygon
(
item
.
feats
)
var
res
=
polygon
.
reduce
(
function
(
a
,
b
){
a
.
xmin
=
b
.
x
>
a
.
xmin
?
a
.
xmin
:
b
.
x
;
a
.
ymin
=
b
.
y
>
a
.
ymin
?
a
.
ymin
:
b
.
y
;
a
.
xmax
=
b
.
x
<
a
.
xmax
?
a
.
xmax
:
b
.
x
;
a
.
ymax
=
b
.
y
<
a
.
ymax
?
a
.
ymax
:
b
.
y
;
return
a
},
{
xmin
:
polygon
[
0
].
x
,
ymin
:
polygon
[
0
].
y
,
xmax
:
polygon
[
0
].
x
,
ymax
:
polygon
[
0
].
y
})
res
.
xsize
=
Math
.
abs
(
res
.
xmax
-
res
.
xmin
)
res
.
ysize
=
Math
.
abs
(
res
.
ymax
-
res
.
ymin
)
res
.
xc
=
res
.
xmin
+
res
.
xsize
/
2
res
.
yc
=
res
.
ymin
+
res
.
ysize
/
2
item
.
limits
=
res
item
.
limit
=
res
if
(
mode
===
"aimdfm"
)
{
$
.
QDfm
.
updateRow
({
table
:
"pdm_aimdfm_task"
,
data
:
{
progress
:
33.33
},
where
:
{
id
:
$
.
task_id
}});
if
(
GEN
.
hasError
())
{
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"GEN错误!"
,
detail
:
[{
desc
:
_
.
join
(
GEN
.
STATUS
,
"
\n
"
)
}]
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
else
{
resultData
.
push
({
type
:
"info"
,
title
:
"操作完成, 请注意检查!"
});
return
{
status
:
Status
,
result_data
:
resultData
};
}
})
return
feats
}
function
profile2Polygon
(
feat
)
{
var
info
=
[];
feat
.
forEach
(
function
(
v
){
if
(
/^#O.
([\S]
+
)
([\S]
+
)
/
.
test
(
v
))
{
info
.
push
({
x
:
RegExp
.
$1
-
0
,
y
:
RegExp
.
$2
-
0
})
}
else
{
return
"Done"
}
})
return
info
}
catch
(
e
)
{
IKM
.
msg
(
_
.
join
(
GEN
.
STATUS
,
"
\n
"
))
IKM
.
msg
(
e
)
Status
=
'error'
;
resultData
.
push
({
type
:
"error"
,
title
:
"脚本执行出错!"
,
detail
:
[{
desc
:
_
.
toString
(
e
)}]});
return
(
mode
===
"aimdfm"
)
?
{
status
:
Status
,
result_data
:
resultData
}
:
"Error"
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment