Skip to content

Commit

Permalink
MAINT: integrate pyaedt PR 3759 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
SMoraisAnsys committed Nov 14, 2023
1 parent 4b03ea2 commit c0c90e6
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 1 deletion.
102 changes: 102 additions & 0 deletions src/pyedb/grpc/edb_core/edb_data/primitives_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,108 @@ def create_edge_port(
else:
return self._app.hfss.create_edge_port_vertical(self.id, pos, name, 50, reference_layer)

@pyedb_function_handler()
def create_via_fence(self, distance, gap, padstack_name):
"""Create via fences on both sides of the trace.
Parameters
----------
distance: str, float
Distance between via fence and trace center line.
gap: str, float
Gap between vias.
padstack_name: str
Name of the via padstack.
Returns
-------
"""

def getAngle(v1, v2): # pragma: no cover
v1_mag = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
v2_mag = math.sqrt(v2[0] ** 2 + v2[1] ** 2)
dotsum = v1[0] * v2[0] + v1[1] * v2[1]
if v1[0] * v2[1] - v1[1] * v2[0] > 0:
scale = 1
else:
scale = -1
dtheta = scale * math.acos(dotsum / (v1_mag * v2_mag))

return dtheta

def getLocations(line, gap): # pragma: no cover
location = [line[0]]
residual = 0

for n in range(len(line) - 1):
x0, y0 = line[n]
x1, y1 = line[n + 1]
length = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
dx, dy = (x1 - x0) / length, (y1 - y0) / length
x = x0 - dx * residual
y = y0 - dy * residual
length = length + residual
while length >= gap:
x += gap * dx
y += gap * dy
location.append((x, y))
length -= gap

residual = length
return location

def getParalletLines(pts, distance): # pragma: no cover
leftline = []
rightline = []

x0, y0 = pts[0]
x1, y1 = pts[1]
vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)

leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x0 + distance * math.cos(leftturn), y0 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x0 + distance * math.cos(righrturn), y0 + distance * math.sin(righrturn))
rightline.append(rightPt)

for n in range(1, len(pts) - 1):
x0, y0 = pts[n - 1]
x1, y1 = pts[n]
x2, y2 = pts[n + 1]

v1 = (x1 - x0, y1 - y0)
v2 = (x2 - x1, y2 - y1)
dtheta = getAngle(v1, v2)
orientation1 = getAngle((1, 0), v1)

leftturn = orientation1 + dtheta / 2 + math.pi / 2
righrturn = orientation1 + dtheta / 2 - math.pi / 2

distance2 = distance / math.sin((math.pi - dtheta) / 2)
leftPt = (x1 + distance2 * math.cos(leftturn), y1 + distance2 * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance2 * math.cos(righrturn), y1 + distance2 * math.sin(righrturn))
rightline.append(rightPt)

x0, y0 = pts[-2]
x1, y1 = pts[-1]

vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)
leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x1 + distance * math.cos(leftturn), y1 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance * math.cos(righrturn), y1 + distance * math.sin(righrturn))
rightline.append(rightPt)
return leftline, rightline

distance = self._pedb.edb_value(distance).ToDouble()
gap = self._pedb.edb_value(gap).ToDouble()
center_line = self.get_center_line()
leftline, rightline = getParalletLines(center_line, distance)
for x, y in getLocations(rightline, gap) + getLocations(leftline, gap):
self._pedb.padstacks.place([x, y], padstack_name)

class EdbRectangle(EDBPrimitives):
def __init__(self, raw_primitive, core_app):
Expand Down
104 changes: 103 additions & 1 deletion src/pyedb/legacy/edb_core/edb_data/primitives_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ def create_edge_port(
Examples
--------
>>> edbapp = legacy.Edb("myproject.aedb")
>>> edbapp = pyedb.legacy.Edb("myproject.aedb")
>>> sig = appedb.modeler.create_trace([[0, 0], ["9mm", 0]], "TOP", "1mm", "SIG", "Flat", "Flat")
>>> sig.create_edge_port("pcb_port", "end", "Wave", None, 8, 8)
Expand All @@ -834,6 +834,108 @@ def create_edge_port(
else:
return self._app.hfss.create_edge_port_vertical(self.id, pos, name, 50, reference_layer)

@pyedb_function_handler()
def create_via_fence(self, distance, gap, padstack_name):
"""Create via fences on both sides of the trace.
Parameters
----------
distance: str, float
Distance between via fence and trace center line.
gap: str, float
Gap between vias.
padstack_name: str
Name of the via padstack.
Returns
-------
"""

def getAngle(v1, v2): # pragma: no cover
v1_mag = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
v2_mag = math.sqrt(v2[0] ** 2 + v2[1] ** 2)
dotsum = v1[0] * v2[0] + v1[1] * v2[1]
if v1[0] * v2[1] - v1[1] * v2[0] > 0:
scale = 1
else:
scale = -1
dtheta = scale * math.acos(dotsum / (v1_mag * v2_mag))

return dtheta

def getLocations(line, gap): # pragma: no cover
location = [line[0]]
residual = 0

for n in range(len(line) - 1):
x0, y0 = line[n]
x1, y1 = line[n + 1]
length = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
dx, dy = (x1 - x0) / length, (y1 - y0) / length
x = x0 - dx * residual
y = y0 - dy * residual
length = length + residual
while length >= gap:
x += gap * dx
y += gap * dy
location.append((x, y))
length -= gap

residual = length
return location

def getParalletLines(pts, distance): # pragma: no cover
leftline = []
rightline = []

x0, y0 = pts[0]
x1, y1 = pts[1]
vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)

leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x0 + distance * math.cos(leftturn), y0 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x0 + distance * math.cos(righrturn), y0 + distance * math.sin(righrturn))
rightline.append(rightPt)

for n in range(1, len(pts) - 1):
x0, y0 = pts[n - 1]
x1, y1 = pts[n]
x2, y2 = pts[n + 1]

v1 = (x1 - x0, y1 - y0)
v2 = (x2 - x1, y2 - y1)
dtheta = getAngle(v1, v2)
orientation1 = getAngle((1, 0), v1)

leftturn = orientation1 + dtheta / 2 + math.pi / 2
righrturn = orientation1 + dtheta / 2 - math.pi / 2

distance2 = distance / math.sin((math.pi - dtheta) / 2)
leftPt = (x1 + distance2 * math.cos(leftturn), y1 + distance2 * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance2 * math.cos(righrturn), y1 + distance2 * math.sin(righrturn))
rightline.append(rightPt)

x0, y0 = pts[-2]
x1, y1 = pts[-1]

vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)
leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x1 + distance * math.cos(leftturn), y1 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance * math.cos(righrturn), y1 + distance * math.sin(righrturn))
rightline.append(rightPt)
return leftline, rightline

distance = self._pedb.edb_value(distance).ToDouble()
gap = self._pedb.edb_value(gap).ToDouble()
center_line = self.get_center_line()
leftline, rightline = getParalletLines(center_line, distance)
for x, y in getLocations(rightline, gap) + getLocations(leftline, gap):
self._pedb.padstacks.place([x, y], padstack_name)

class EdbRectangle(EDBPrimitives, RectangleDotNet):
def __init__(self, raw_primitive, core_app):
Expand Down
5 changes: 5 additions & 0 deletions tests/grpc/system/test_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,11 @@ def test_create_padstack_instance(self):
assert pad_instance3.dcir_equipotential_region
pad_instance3.dcir_equipotential_region = False
assert not pad_instance3.dcir_equipotential_region

trace = edb.modeler.create_trace([[0, 0], [0, 10e-3]], "1_Top", "0.1mm", "trace_with_via_fence")
edb.padstacks.create_padstack("via_0")
trace.create_via_fence("1mm", "1mm", "via_0")

edb.close()

def test_assign_hfss_extent_non_multiple_with_simconfig(self):
Expand Down
5 changes: 5 additions & 0 deletions tests/legacy/system/test_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,11 @@ def test_create_padstack_instance(self):
assert pad_instance3.dcir_equipotential_region
pad_instance3.dcir_equipotential_region = False
assert not pad_instance3.dcir_equipotential_region

trace = edb.modeler.create_trace([[0, 0], [0, 10e-3]], "1_Top", "0.1mm", "trace_with_via_fence")
edb.padstacks.create_padstack("via_0")
trace.create_via_fence("1mm", "1mm", "via_0")

edb.close()

def test_assign_hfss_extent_non_multiple_with_simconfig(self):
Expand Down

0 comments on commit c0c90e6

Please sign in to comment.