Skip to content

Commit

Permalink
FEAT: Add voids to extent (#619)
Browse files Browse the repository at this point in the history
* added an option in Edb.cutout method to include_voids_in_extents. this flag, used with conformal cutout, search for additional voids in the extent to reduce additionally the edb. The default is false

* added an option in Edb.cutout method to include_voids_in_extents. this flag, used with conformal cutout, search for additional voids in the extent to reduce additionally the edb. The default is false

* added an option in Edb.cutout method to include_voids_in_extents. this flag, used with conformal cutout, search for additional voids in the extent to reduce additionally the edb. The default is false

* MISC: Auto fixes from pre-commit.com hooks

For more information, see https://pre-commit.ci

---------

Co-authored-by: maxcapodi78 <Shark78>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
maxcapodi78 and pre-commit-ci[bot] authored Jun 28, 2024
1 parent ae34d16 commit 861d0f9
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 27 deletions.
117 changes: 90 additions & 27 deletions src/pyedb/dotnet/edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,7 @@ def _create_extent(
reference_list=[],
include_pingroups=True,
pins_to_preserve=None,
inlcude_voids_in_extents=False,
):
if extent_type in [
"Conforming",
Expand All @@ -1574,6 +1575,7 @@ def _create_extent(
smart_cut,
reference_list,
pins_to_preserve,
inlcude_voids_in_extents=inlcude_voids_in_extents,
)
else:
_poly = self.layout.expanded_extent(
Expand Down Expand Up @@ -1632,6 +1634,7 @@ def _create_conformal(
smart_cutout=False,
reference_list=[],
pins_to_preserve=None,
inlcude_voids_in_extents=False,
):
names = []
_polys = []
Expand All @@ -1649,7 +1652,7 @@ def _create_conformal(

for prim in self.modeler.primitives:
if prim is not None and prim.net_name in names:
_polys.append(prim.primitive_object.GetPolygonData())
_polys.append(prim)
if smart_cutout:
objs_data = self._smart_cut(reference_list, expansion_size)
_polys.extend(objs_data)
Expand All @@ -1658,9 +1661,33 @@ def _create_conformal(
while k < 10:
unite_polys = []
for i in _polys:
obj_data = i.Expand(expansion_size, tolerance, round_corner, round_extension)
if "PolygonData" not in str(i):
obj_data = i.primitive_object.GetPolygonData().Expand(
expansion_size, tolerance, round_corner, round_extension
)
else:
obj_data = i.Expand(expansion_size, tolerance, round_corner, round_extension)
if obj_data:
unite_polys.extend(list(obj_data))
if not inlcude_voids_in_extents:
unite_polys.extend(list(obj_data))
else:
voids_poly = []
try:
if i.HasVoids():
area = i.area()
for void in i.Voids:
void_polydata = void.GetPolygonData()
if void_polydata.Area() >= 0.05 * area:
voids_poly.append(void_polydata)
if voids_poly:
obj_data = obj_data[0].Subtract(
convert_py_list_to_net_list(list(obj_data)),
convert_py_list_to_net_list(voids_poly),
)
except:
pass
finally:
unite_polys.extend(list(obj_data))
_poly_unite = self.edb_api.geometry.polygon_data.unite(unite_polys)
if len(_poly_unite) == 1:
self.logger.info("Correctly computed Extension at first iteration.")
Expand Down Expand Up @@ -1761,6 +1788,7 @@ def cutout(
preserve_components_with_model=False,
simple_pad_check=True,
keep_lines_as_path=False,
include_voids_in_extents=False,
):
"""Create a cutout using an approach entirely based on PyAEDT.
This method replaces all legacy cutout methods in PyAEDT.
Expand Down Expand Up @@ -1837,6 +1865,11 @@ def cutout(
This feature works only in Electronics Desktop (3D Layout).
If the flag is set to ``True`` it can cause issues in SiWave once the Edb is imported.
Default is ``False`` to generate PolygonData of cut lines.
include_voids_in_extents : bool, optional
Whether to compute and include voids in pyaedt extent before the cutout. Cutout time can be affected.
It works only with Conforming cutout.
Default is ``False`` to generate extent without voids.
Returns
-------
Expand Down Expand Up @@ -1896,6 +1929,7 @@ def cutout(
use_pyaedt_extent_computing=use_pyaedt_extent_computing,
check_terminals=check_terminals,
include_pingroups=include_pingroups,
inlcude_voids_in_extents=include_voids_in_extents,
)
else:
legacy_path = self.edbpath
Expand Down Expand Up @@ -1929,6 +1963,7 @@ def cutout(
include_partial=include_partial_instances,
simple_pad_check=simple_pad_check,
keep_lines_as_path=keep_lines_as_path,
inlcude_voids_in_extents=include_voids_in_extents,
)
if self.are_port_reference_terminals_connected():
if output_aedb_path:
Expand Down Expand Up @@ -1969,6 +2004,7 @@ def cutout(
include_partial=include_partial_instances,
simple_pad_check=simple_pad_check,
keep_lines_as_path=keep_lines_as_path,
inlcude_voids_in_extents=include_voids_in_extents,
)
if result and not open_cutout_at_end and self.edbpath != legacy_path:
self.save_edb()
Expand All @@ -1990,6 +2026,7 @@ def _create_cutout_legacy(
remove_single_pin_components=False,
check_terminals=False,
include_pingroups=True,
inlcude_voids_in_extents=False,
):
expansion_size = self.edb_value(expansion_size).ToDouble()

Expand All @@ -2010,8 +2047,14 @@ def _create_cutout_legacy(
smart_cut=check_terminals,
reference_list=reference_list,
include_pingroups=include_pingroups,
inlcude_voids_in_extents=inlcude_voids_in_extents,
)

_poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
if inlcude_voids_in_extents:
for hole in list(_poly.Holes):
if hole.Area() >= 0.05 * _poly1.Area():
_poly1.AddHole(hole)
_poly = _poly1
# Create new cutout cell/design
included_nets_list = signal_list + reference_list
included_nets = convert_py_list_to_net_list(
Expand Down Expand Up @@ -2172,6 +2215,7 @@ def _create_cutout_multithread(
include_partial=False,
simple_pad_check=True,
keep_lines_as_path=False,
inlcude_voids_in_extents=False,
):
if is_ironpython: # pragma: no cover
self.logger.error("Method working only in Cpython")
Expand Down Expand Up @@ -2269,11 +2313,18 @@ def _create_cutout_multithread(
reference_list=reference_list,
include_pingroups=include_pingroups,
pins_to_preserve=pins_to_preserve,
inlcude_voids_in_extents=inlcude_voids_in_extents,
)
if extent_type in ["Conforming", self.edb_api.geometry.extent_type.Conforming, 1]:
if extent_defeature > 0:
_poly = _poly.Defeature(extent_defeature)
_poly = _poly.CreateFromArcs(_poly.GetArcData(), True)

_poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
if inlcude_voids_in_extents:
for hole in list(_poly.Holes):
if hole.Area() >= 0.05 * _poly1.Area():
_poly1.AddHole(hole)
_poly = _poly1
if not _poly or _poly.IsNull():
self._logger.error("Failed to create Extent.")
return []
Expand Down Expand Up @@ -2312,29 +2363,39 @@ def clean_prim(prim_1): # pragma: no cover
pdata = prim_1.polygon_data.edb_api
int_data = _poly.GetIntersectionType(pdata)
if int_data == 2:
return
if not inlcude_voids_in_extents:
return
skip = False
for hole in list(_poly.Holes):
if hole.GetIntersectionType(pdata) == 0:
prims_to_delete.append(prim_1)
return
elif hole.GetIntersectionType(pdata) == 1:
skip = True
if skip:
return
elif int_data == 0:
prims_to_delete.append(prim_1)
else:
list_poly = intersect(_poly, pdata)
if list_poly:
net = prim_1.net_name
voids = prim_1.voids
for p in list_poly:
if p.IsNull():
continue
# points = list(p.Points)
list_void = []
if voids:
voids_data = [void.polygon_data.edb_api for void in voids]
list_prims = subtract(p, voids_data)
for prim in list_prims:
if not prim.IsNull():
poly_to_create.append([prim, prim_1.layer.name, net, list_void])
else:
poly_to_create.append([p, prim_1.layer.name, net, list_void])
return
list_poly = intersect(_poly, pdata)
if list_poly:
net = prim_1.net_name
voids = prim_1.voids
for p in list_poly:
if p.IsNull():
continue
# points = list(p.Points)
list_void = []
if voids:
voids_data = [void.polygon_data.edb_api for void in voids]
list_prims = subtract(p, voids_data)
for prim in list_prims:
if not prim.IsNull():
poly_to_create.append([prim, prim_1.layer.name, net, list_void])
else:
poly_to_create.append([p, prim_1.layer.name, net, list_void])

prims_to_delete.append(prim_1)
prims_to_delete.append(prim_1)

def pins_clean(pinst):
if not pinst.in_polygon(_poly, include_partial=include_partial, simple_check=simple_pad_check):
Expand All @@ -2350,7 +2411,9 @@ def pins_clean(pinst):
for pin in pins_to_delete:
pin.delete()

self.logger.info_timer("Padstack Instances removal completed")
self.logger.info_timer(
"Padstack Instances removal completed. {} instances removed.".format(len(pins_to_delete))
)
self.logger.reset_timer()

# with ThreadPoolExecutor(number_of_threads) as pool:
Expand All @@ -2369,7 +2432,7 @@ def pins_clean(pinst):
for prim in prims_to_delete:
prim.delete()

self.logger.info_timer("Primitives cleanup completed")
self.logger.info_timer("Primitives cleanup completed. {} primitives deleted.".format(len(prims_to_delete)))
self.logger.reset_timer()

i = 0
Expand Down
1 change: 1 addition & 0 deletions tests/legacy/system/test_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ def test_create_custom_cutout_4(self):
use_pyaedt_extent_computing=True,
check_terminals=True,
expansion_factor=2,
include_voids_in_extents=True,
)
edbapp.close()
source_path = os.path.join(local_path, "example_models", test_subfolder, "Multizone_GroundVoids.aedb")
Expand Down

0 comments on commit 861d0f9

Please sign in to comment.