Paths, Traces, and Polygons
This examples shows different ways to add paths, traces, and polygons to your design
Adding a Path:
def adding_a_path(design: db_uu.Design) -> None:
from keysight.ads import de
# This example will add a path using the specified points directly
points = [(100.0, 0.0), (150.0, 0.0), (150.0, 50.0), (200.0, 50.0)]
# points_uu = [de.PointUU(point[0], point[1]) for point in points]
# ads_device:drawing for schematic, cond for layout
layer_id = db_uu.LayerId(231 if design.is_schematic is True else 1)
# TODO: Bend_style, cap_style, miter_radius, when supported
# When creating a path, a width must be specified
path = design.add_path(layer_id, points, 10.0)
assert path is not None
path_offset = 25.0 # Using an offset to easily adjust the placement of each path (for illustration purposes)
points_offset = [(point[0] - path_offset, point[1] + path_offset) for point in points]
# Paths may be added using a GenPolyline
polyline = de.GenPolyline(points_offset, 10.0, "Square", "Square", 0.0)
assert polyline.bend_style == de.db.BendStyle.SQUARE
assert polyline.cap_style == de.db.CapStyle.SQUARE
path = design.add_path(layer_id, polyline)
assert path is not None
path_offset = 50.0
points_offset = [(point[0] - path_offset, point[1] + path_offset) for point in points]
# Paths have different cap (end-points) and bend styles (corners)
# Mitered bend styles apply a miter cutoff percentage
polyline = de.GenPolyline(points_offset, 10.0, "Mitered", "Round", 30.0)
assert polyline.bend_style == de.db.BendStyle.MITERED
assert polyline.cap_style == de.db.CapStyle.ROUND
path = design.add_path(layer_id, polyline)
assert path is not None
path_offset = 75.0
points_offset = [(point[0] - path_offset, point[1] + path_offset) for point in points]
# Curved bend styles apply a miter radius
polyline = de.GenPolyline(points_offset, 10.0, "Curved", "Square", 45.0)
assert polyline.bend_style == de.db.BendStyle.CURVED
assert polyline.cap_style == de.db.CapStyle.SQUARE
path = design.add_path(layer_id, polyline)
assert path is not None
Adding a Trace:
def adding_a_trace(design: db_uu.Design) -> None:
from keysight.ads import de
transaction = de.db.Transaction(design, "Adding traces")
# This example will add a trace using the specified points directly
points = [(-100.0, 0.0), (-50.0, 0.0), (-50.0, 50.0), (0.0, 50.0)]
# ads_device:drawing for schematic, cond for layout
layer_id = db_uu.LayerId(231 if design.is_schematic is True else 1)
# TODO: Bend_style, cap_style, miter_radius, when supported
# When creating a trace, a width must be specified
path = design.add_trace(layer_id, points, 10.0)
assert path is not None
trace_offset = 25.0 # Using an offset to easily adjust the placement of each trace (for illustration purposes)
points_offset = [(point[0] - trace_offset, point[1] + trace_offset) for point in points]
# Traces may also be added using a GenPolyline
polyline = de.GenPolyline(points_offset, 10.0, de.BendStyle.SQUARE, de.CapStyle.SQUARE, 0.0)
path = design.add_trace(layer_id, polyline)
assert path is not None
trace_offset = 50.0
points_offset = [(point[0] - trace_offset, point[1] + trace_offset) for point in points]
# Traces have different cap (end-points) and bend styles (corners)
# Mitered bend styles apply a miter cutoff percentage
polyline = de.GenPolyline(points_offset, 10.0, de.BendStyle.MITERED, de.CapStyle.ROUND, 30.0)
path = design.add_trace(layer_id, polyline)
assert path is not None
trace_offset = 75.0
points_offset = [(point[0] - trace_offset, point[1] + trace_offset) for point in points]
# Curved bend styles apply a miter radius
polyline = de.GenPolyline(points_offset, 10.0, de.BendStyle.CURVED, de.CapStyle.SQUARE, 45.0)
path = design.add_trace(layer_id, polyline)
assert path is not None
transaction.commit()
Adding a Polygon:
def adding_a_polygon(design: db_uu.Design) -> None:
from keysight.ads import de
# This example will add a polygon using the specified points directly
points = [(15.0, -80.0), (35.0, -115.0), (75.0, -115.0), (95.0, -80.0), (75.0, -45.0), (35.0, -45.0)]
# Using a poly_offset to easily adjust the placement of each polygon (for illustration purposes)
poly_offset = 100.0
points_offset = [(point[0] + poly_offset, point[1]) for point in points]
# ads_device:drawing for schematic, cond for layout
layer_id = db_uu.LayerId(231 if design.is_schematic is True else 1)
polygon = design.add_polygon(layer_id, points_offset)
assert polygon is not None
points_offset = [(point[0] - poly_offset, point[1]) for point in points]
# Polygons may be added using a GenPolygon
gen_polygon = de.GenPolygon(points_offset)
polygon = design.add_polygon(layer_id, gen_polygon)
assert polygon is not None
# A polygon with holes may be added using a GenPolygonWithHoles
hole_points = [(40.0, -60.0), (70.0, -60.0), (80.0, -80.0), (70.0, -100.0), (40.0, -100.0), (30.0, -80.0)]
points_offset = [(point[0], point[1]) for point in points]
outer_boundary = de.GenPolygon(points_offset)
inner_boundary = de.GenPolygon(hole_points)
gen_polygon_with_holes = de.GenPolygonWithHoles(None, outer_boundary, [inner_boundary])
polygon = design.add_polygon(layer_id, gen_polygon_with_holes)
assert polygon is not None
Iterating over Shapes in a Design:
def iterating_over_shapes_in_design(design: db_uu.Design) -> None:
from keysight.ads.de.db import Transform
# For this example, clear the design to ensure its empty
design.clear_design()
# ads_device:drawing for schematic, cond for layout
layer_id = db_uu.LayerId(231 if design.is_schematic is True else 1)
# Let's add shapes
adding_a_path(design)
adding_a_trace(design)
adding_a_polygon(design)
# Create a ShapeIter to iterate over all shapes
shape_iter = db_uu.ShapeIter(design, layer_id)
# New shapes will be placed on a different layer
target_layer_id = db_uu.LayerId(229 if design.is_schematic is True else 2)
for shape in shape_iter:
shape_type = shape.type
# Paths, traces, and polygons added to a design are all Polygons
assert shape_type.is_oa_polygon
assert isinstance(shape, db_uu.Polygon)
# ApolloType may be used to distinguish the kind of component the Polygon represents
# Paths and traces have a centerline; other polygons do not.
if shape_type.is_ads_path:
# Use a transform to move the points of the existing path
path_line = shape.get_centerline()
transform = Transform()
transform.translate(dx=200.0, dy=0.0)
path_line.transform(transform)
# And then place the path onto a different layer
design.add_path(target_layer_id, path_line)
elif shape_type.is_trace:
# Use a transform to move the points and rotate an existing trace
trace_line = shape.get_centerline()
transform = Transform()
transform.rotate_degrees(45.0)
transform.translate(dx=-100.0, dy=200.0)
trace_line.transform(transform)
# And then place the trace onto a different layer
design.add_trace(target_layer_id, trace_line)
elif shape_type.is_ads_polygon:
# Use a transform to move the points of an existing polygon
transform = Transform()
transform.translate(dx=0.0, dy=-100.0)
polygon = shape.get_gen_polygon()
polygon.transform(transform, 0.0)
# Convert vertices to arcs and place the new shape in another layer
converted_polys = polygon.convert_vertices_to_arcs(15.0)
# Only one polygon will be returned when converting vertices to arcs on a simple shape
assert len(converted_polys) == 1
design.add_polygon(target_layer_id, converted_polys[0])
else:
raise RuntimeError("Unexpected shape present in design.")