2021年2月7日 星期日

分離bondwire腳本

以下腳本對單排的diepad可以適用。首先選擇Pin,執行腳本,落在其上的bondwires的Pt1會分離到不同的位置。可持續執行腳本直到到滿意的位置。將腳本連接到熱鍵可更快速的執行工作。目前只能確保2D平面直線不會交叉,因為立體結構,仍可能有交叉,仍需使用者肉眼判斷。

# -*- coding: utf-8 -*-
from itertools import combinations
from math import sqrt
import random


def ccw(A, B, C):
Ax, Ay = A
Bx, By = B
Cx, Cy = C
return (Cy - Ay) * (Bx - Ax) > (By - Ay) * (Cx - Ax)


def intersect(A, B, C, D):
return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(A, B, D)


def checkintersection(segments):
for (A, B), (C, D) in combinations(segments, 2):
if intersect(A, B, C, D):
return True
return False


import ScriptEnv

ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oDesktop.ClearMessages("", "", 2)
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oLayout = oDesign.GetActiveEditor()

sele = oLayout.GetSelections()
AddWarningMessage(str(sele))


def getPkgGrid(pin_name):
layer = oLayout.GetPropertyValue('BaseElementTab', pin_name, 'Start Layer')
x0, y0 = oLayout.GetPropertyValue('BaseElementTab', pin_name, 'Location').split(',')
x0, y0 = float(x0), float(y0)

grid = []
for i in range(-10, 11):
for j in range(-10, 11):
x = (x0 + 0.05 * i) * 1e-3
y = (y0 + 0.05 * j) * 1e-3
pt = oLayout.Point()
pt.Set(x, y)
if pin_name in oLayout.FindObjectsByPoint(pt, layer):
x = (x0 + 0.04 * i) * 1e-3
y = (y0 + 0.04 * j) * 1e-3
grid.append((x, y))
return grid


pkg = getPkgGrid(sele[0])
AddWarningMessage('Pkg Locations: {}'.format(len(pkg)))


def getDieGrid(pin_name):
layer = oLayout.GetPropertyValue('BaseElementTab', pin_name, 'Start Layer')
grid = {}
for i in oLayout.FindObjects('Type', 'bondwire'):
p1 = oLayout.Point()
x, y = oLayout.GetPropertyValue('BaseElementTab', i, 'Pt1').split(',')
pt = p1.Set(float(x) * 1e-3, float(y) * 1e-3)
obj = oLayout.FindObjectsByPoint(p1, layer)

if pin_name in oLayout.FindObjectsByPoint(pt, layer):
x, y = oLayout.GetPropertyValue('BaseElementTab', i, 'Pt0').split(',')
x, y = float(x) * 1e-3, float(y) * 1e-3
grid[(x, y)] = i
return grid


die = getDieGrid(sele[0])
AddWarningMessage('die Locations: {}'.format(len(die)))

pair = {}
N = 0
while (True):
N += 1
if N > 1000000:
AddWarningMessage('Failed')
segments = []
break
segments = []
random.shuffle(pkg)
for (pt0, pt1) in zip(die.keys(), pkg[0:len(die)]):
segments.append((pt0, pt1))
if checkintersection(segments) == False:
AddWarningMessage('Successful')
break

for pt0, pt1 in segments:
pair[die[pt0]] = pt1

AddWarningMessage(str(pair))
try:
for bw_name in pair:
x, y = pair[bw_name]
oLayout.ChangeProperty(
[
"NAME:AllTabs",
[
"NAME:BaseElementTab",
[
"NAME:PropServers",
bw_name
],
[
"NAME:ChangedProps",
[
"NAME:Pt1",
"X:=" , str(x),
"Y:=" , str(y)
]
]
]
])
except:
pass
oLayout.Select(sele[0])



沒有留言:

張貼留言