pyedb 0.56.0__py3-none-any.whl → 0.58.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_data.py +3 -0
- pyedb/configuration/cfg_pin_groups.py +2 -0
- pyedb/configuration/cfg_terminals.py +232 -0
- pyedb/configuration/configuration.py +146 -3
- pyedb/dotnet/clr_module.py +1 -2
- pyedb/dotnet/database/Variables.py +30 -22
- pyedb/dotnet/database/cell/hierarchy/component.py +2 -8
- pyedb/dotnet/database/cell/layout.py +5 -1
- pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
- pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
- pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
- pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
- pyedb/dotnet/database/components.py +15 -19
- pyedb/dotnet/database/dotnet/database.py +1 -0
- pyedb/dotnet/database/edb_data/control_file.py +19 -8
- pyedb/dotnet/database/edb_data/nets_data.py +3 -3
- pyedb/dotnet/database/edb_data/padstacks_data.py +39 -14
- pyedb/dotnet/database/edb_data/ports.py +0 -25
- pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
- pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
- pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
- pyedb/dotnet/database/edb_data/sources.py +21 -2
- pyedb/dotnet/database/general.py +1 -6
- pyedb/dotnet/database/hfss.py +9 -8
- pyedb/dotnet/database/layout_validation.py +14 -3
- pyedb/dotnet/database/materials.py +1 -3
- pyedb/dotnet/database/modeler.py +7 -3
- pyedb/dotnet/database/nets.py +27 -19
- pyedb/dotnet/database/padstack.py +4 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +54 -1
- pyedb/dotnet/database/siwave.py +4 -3
- pyedb/dotnet/database/stackup.py +55 -58
- pyedb/dotnet/database/utilities/heatsink.py +0 -1
- pyedb/dotnet/database/utilities/hfss_simulation_setup.py +81 -0
- pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
- pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +264 -13
- pyedb/dotnet/edb.py +65 -47
- pyedb/exceptions.py +1 -2
- pyedb/extensions/create_cell_array.py +67 -49
- pyedb/generic/data_handlers.py +13 -23
- pyedb/generic/design_types.py +9 -35
- pyedb/generic/filesystem.py +4 -2
- pyedb/generic/general_methods.py +28 -41
- pyedb/generic/plot.py +8 -23
- pyedb/generic/process.py +78 -10
- pyedb/grpc/database/_typing.py +0 -0
- pyedb/grpc/database/components.py +14 -13
- pyedb/grpc/database/control_file.py +27 -40
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/package_def.py +6 -3
- pyedb/grpc/database/definition/padstack_def.py +14 -12
- pyedb/grpc/database/hfss.py +1 -4
- pyedb/grpc/database/hierarchy/component.py +5 -13
- pyedb/grpc/database/hierarchy/pingroup.py +16 -3
- pyedb/grpc/database/layers/layer.py +1 -2
- pyedb/grpc/database/layers/stackup_layer.py +42 -19
- pyedb/grpc/database/layout/layout.py +43 -27
- pyedb/grpc/database/layout/voltage_regulator.py +6 -1
- pyedb/grpc/database/layout_validation.py +5 -2
- pyedb/grpc/database/modeler.py +254 -252
- pyedb/grpc/database/net/differential_pair.py +9 -2
- pyedb/grpc/database/net/extended_net.py +24 -9
- pyedb/grpc/database/net/net.py +14 -5
- pyedb/grpc/database/net/net_class.py +24 -7
- pyedb/grpc/database/nets.py +11 -43
- pyedb/grpc/database/padstacks.py +67 -119
- pyedb/grpc/database/primitive/bondwire.py +3 -67
- pyedb/grpc/database/primitive/circle.py +42 -3
- pyedb/grpc/database/primitive/padstack_instance.py +58 -31
- pyedb/grpc/database/primitive/path.py +160 -11
- pyedb/grpc/database/primitive/polygon.py +73 -7
- pyedb/grpc/database/primitive/primitive.py +2 -2
- pyedb/grpc/database/primitive/rectangle.py +105 -4
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +79 -0
- pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
- pyedb/grpc/database/siwave.py +6 -13
- pyedb/grpc/database/source_excitations.py +46 -63
- pyedb/grpc/database/stackup.py +55 -60
- pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +9 -11
- pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
- pyedb/grpc/database/terminal/point_terminal.py +30 -0
- pyedb/grpc/database/terminal/terminal.py +35 -10
- pyedb/grpc/database/utility/heat_sink.py +0 -1
- pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
- pyedb/grpc/database/utility/xml_control_file.py +19 -8
- pyedb/grpc/edb.py +63 -32
- pyedb/grpc/edb_init.py +1 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
- pyedb/ipc2581/ecad/cad_data/step.py +1 -1
- pyedb/ipc2581/ipc2581.py +8 -7
- pyedb/libraries/common.py +3 -4
- pyedb/libraries/rf_libraries/base_functions.py +7 -16
- pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
- pyedb/misc/aedtlib_personalib_install.py +2 -2
- pyedb/misc/downloads.py +19 -3
- pyedb/misc/misc.py +5 -2
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +3 -2
- pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +0 -1
- pyedb/misc/utilities.py +0 -1
- pyedb/modeler/geometry_operators.py +3 -2
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/METADATA +6 -7
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/RECORD +110 -108
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/WHEEL +0 -0
- {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
from ansys.edb.core.primitive.bondwire import (
|
|
24
|
+
Bondwire as GrpcBondWire,
|
|
24
25
|
BondwireCrossSectionType as GrpcBondwireCrossSectionType,
|
|
26
|
+
BondwireType as GrpcBondWireType,
|
|
25
27
|
)
|
|
26
|
-
from ansys.edb.core.primitive.bondwire import Bondwire as GrpcBondWire
|
|
27
|
-
from ansys.edb.core.primitive.bondwire import BondwireType as GrpcBondWireType
|
|
28
28
|
|
|
29
29
|
from pyedb.grpc.database.utility.value import Value
|
|
30
30
|
|
|
@@ -36,6 +36,7 @@ class Bondwire(GrpcBondWire):
|
|
|
36
36
|
super().__init__(edb_object.msg)
|
|
37
37
|
self._pedb = _pedb
|
|
38
38
|
self._edb_object = edb_object
|
|
39
|
+
# TODO add create and delete methods to keep cache in sync
|
|
39
40
|
|
|
40
41
|
@property
|
|
41
42
|
def material(self):
|
|
@@ -53,25 +54,6 @@ class Bondwire(GrpcBondWire):
|
|
|
53
54
|
def material(self, value):
|
|
54
55
|
self.set_material(value)
|
|
55
56
|
|
|
56
|
-
# def __create(self, **kwargs):
|
|
57
|
-
# return Bondwire.create(
|
|
58
|
-
# self._pedb.layout,
|
|
59
|
-
# kwargs.get("net"),
|
|
60
|
-
# self._bondwire_type[kwargs.get("bondwire_type")],
|
|
61
|
-
# kwargs.get("definition_name"),
|
|
62
|
-
# kwargs.get("placement_layer"),
|
|
63
|
-
# kwargs.get("width"),
|
|
64
|
-
# kwargs.get("material"),
|
|
65
|
-
# kwargs.get("start_context"),
|
|
66
|
-
# kwargs.get("start_layer_name"),
|
|
67
|
-
# kwargs.get("start_x"),
|
|
68
|
-
# kwargs.get("start_y"),
|
|
69
|
-
# kwargs.get("end_context"),
|
|
70
|
-
# kwargs.get("end_layer_name"),
|
|
71
|
-
# kwargs.get("end_x"),
|
|
72
|
-
# kwargs.get("end_y"),
|
|
73
|
-
# )
|
|
74
|
-
|
|
75
57
|
@property
|
|
76
58
|
def type(self):
|
|
77
59
|
"""str: Bondwire-type of a bondwire object. Supported values for setter: `"apd"`, `"jedec4"`, `"jedec5"`,
|
|
@@ -120,28 +102,6 @@ class Bondwire(GrpcBondWire):
|
|
|
120
102
|
def cross_section_height(self, cross_section_height):
|
|
121
103
|
super(Bondwire, self.__class__).cross_section_height.__set__(self, Value(cross_section_height))
|
|
122
104
|
|
|
123
|
-
# @property
|
|
124
|
-
# def trajectory(self):
|
|
125
|
-
# """Get trajectory parameters of a bondwire object.
|
|
126
|
-
#
|
|
127
|
-
# Returns
|
|
128
|
-
# -------
|
|
129
|
-
# tuple[float, float, float, float]
|
|
130
|
-
#
|
|
131
|
-
# Returns a tuple of the following format:
|
|
132
|
-
# **(x1, y1, x2, y2)**
|
|
133
|
-
# **x1** : X value of the start point.
|
|
134
|
-
# **y1** : Y value of the start point.
|
|
135
|
-
# **x1** : X value of the end point.
|
|
136
|
-
# **y1** : Y value of the end point.
|
|
137
|
-
# """
|
|
138
|
-
# return [Value(i) for i in self.get_traj()]
|
|
139
|
-
#
|
|
140
|
-
# @trajectory.setter
|
|
141
|
-
# def trajectory(self, value):
|
|
142
|
-
# values = [Value(i) for i in value]
|
|
143
|
-
# self.set_traj(values[0], values[1], values[2], values[3])
|
|
144
|
-
|
|
145
105
|
@property
|
|
146
106
|
def width(self):
|
|
147
107
|
""":class:`Value <ansys.edb.utility.Value>`: Width of a bondwire object.
|
|
@@ -156,27 +116,3 @@ class Bondwire(GrpcBondWire):
|
|
|
156
116
|
@width.setter
|
|
157
117
|
def width(self, width):
|
|
158
118
|
super(Bondwire, self.__class__).width.__set__(self, Value(width))
|
|
159
|
-
|
|
160
|
-
# @property
|
|
161
|
-
# def start_elevation(self):
|
|
162
|
-
# layer = self.get_start_elevation(self._pedb.active_cell)
|
|
163
|
-
# return layer.name
|
|
164
|
-
#
|
|
165
|
-
# @start_elevation.setter
|
|
166
|
-
# def start_elevation(self, layer):
|
|
167
|
-
# if not layer in self._pedb.stackup.layers:
|
|
168
|
-
# return
|
|
169
|
-
# layer = self._pedb.stackup.layers[layer]
|
|
170
|
-
# self.set_start_elevation(self._pedb.active_cell, layer)
|
|
171
|
-
#
|
|
172
|
-
# @property
|
|
173
|
-
# def end_elevation(self):
|
|
174
|
-
# layer = self.get_end_elevation(self._pedb.active_cell)
|
|
175
|
-
# return layer.name
|
|
176
|
-
#
|
|
177
|
-
# @end_elevation.setter
|
|
178
|
-
# def end_elevation(self, layer):
|
|
179
|
-
# if not layer in self._pedb.stackup.layers:
|
|
180
|
-
# return
|
|
181
|
-
# layer = self._pedb.stackup.layers[layer]
|
|
182
|
-
# self.set_end_elevation(self._pedb.active_cell, layer)
|
|
@@ -21,18 +21,57 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
from typing import Union
|
|
25
|
+
|
|
24
26
|
from ansys.edb.core.primitive.circle import Circle as GrpcCircle
|
|
25
27
|
|
|
28
|
+
from pyedb.grpc.database.layers.layer import Layer
|
|
29
|
+
from pyedb.grpc.database.net.net import Net
|
|
26
30
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
27
31
|
from pyedb.grpc.database.utility.value import Value
|
|
28
32
|
|
|
29
33
|
|
|
30
34
|
class Circle(GrpcCircle, Primitive):
|
|
31
|
-
def __init__(self, pedb, edb_object):
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
def __init__(self, pedb, edb_object=None):
|
|
36
|
+
if edb_object:
|
|
37
|
+
GrpcCircle.__init__(self, edb_object.msg)
|
|
38
|
+
Primitive.__init__(self, pedb, edb_object)
|
|
34
39
|
self._pedb = pedb
|
|
35
40
|
|
|
41
|
+
def create(
|
|
42
|
+
self,
|
|
43
|
+
layout=None,
|
|
44
|
+
layer: Union[str, Layer] = None,
|
|
45
|
+
net: Union[str, Net, None] = None,
|
|
46
|
+
center_x: float = None,
|
|
47
|
+
center_y: float = None,
|
|
48
|
+
radius: float = 0.0,
|
|
49
|
+
):
|
|
50
|
+
if not layout:
|
|
51
|
+
layout = self._pedb.active_layout
|
|
52
|
+
if not layer:
|
|
53
|
+
raise ValueError("Layer must be provided to create a circle.")
|
|
54
|
+
if center_x is None or center_y is None:
|
|
55
|
+
raise ValueError("Center x and y values must be provided to create a circle.")
|
|
56
|
+
edb_object = GrpcCircle.create(
|
|
57
|
+
layout=layout,
|
|
58
|
+
layer=layer,
|
|
59
|
+
net=net,
|
|
60
|
+
center_x=Value(center_x),
|
|
61
|
+
center_y=Value(center_y),
|
|
62
|
+
radius=Value(radius),
|
|
63
|
+
)
|
|
64
|
+
new_circle = Circle(self._pedb, edb_object)
|
|
65
|
+
GrpcCircle.__init__(self, edb_object.msg)
|
|
66
|
+
Primitive.__init__(self, self._pedb, edb_object)
|
|
67
|
+
self._pedb.modeler._add_primitive(new_circle)
|
|
68
|
+
return new_circle
|
|
69
|
+
|
|
70
|
+
def delete(self):
|
|
71
|
+
"""Delete the circle from the layout."""
|
|
72
|
+
self._pedb.modeler._remove_primitive(self)
|
|
73
|
+
super().delete()
|
|
74
|
+
|
|
36
75
|
def get_parameters(self) -> tuple[float, float, float]:
|
|
37
76
|
"""Returns parameters.
|
|
38
77
|
|
|
@@ -28,8 +28,7 @@ from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
|
28
28
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
29
29
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
30
30
|
from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
|
|
31
|
-
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
|
|
32
|
-
from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
|
|
31
|
+
from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D
|
|
33
32
|
from ansys.edb.core.primitive.padstack_instance import (
|
|
34
33
|
PadstackInstance as GrpcPadstackInstance,
|
|
35
34
|
)
|
|
@@ -123,6 +122,47 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
123
122
|
term = PadstackInstanceTerminal(self._pedb, term)
|
|
124
123
|
return term if not term.is_null else None
|
|
125
124
|
|
|
125
|
+
@property
|
|
126
|
+
def side_number(self):
|
|
127
|
+
"""Return the number of sides meshed of the padstack instance.
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
int
|
|
131
|
+
Number of sides meshed of the padstack instance.
|
|
132
|
+
"""
|
|
133
|
+
side_value = self.get_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21)
|
|
134
|
+
if side_value:
|
|
135
|
+
return int(re.search(r"(?m)^\s*sid=(\d+)", side_value).group(1))
|
|
136
|
+
return 0
|
|
137
|
+
|
|
138
|
+
@side_number.setter
|
|
139
|
+
def side_number(self, value):
|
|
140
|
+
"""Set the number of sides meshed of the padstack instance.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
value : int
|
|
145
|
+
Number of sides to mesh the padstack instance.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
bool
|
|
150
|
+
True if successful, False otherwise.
|
|
151
|
+
"""
|
|
152
|
+
if isinstance(value, int) and 3 <= value <= 64:
|
|
153
|
+
prop_string = f"$begin ''\n\tsid={value}\n\tmat='copper'\n\tvs='Wirebond'\n$end ''\n"
|
|
154
|
+
self.set_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21, prop_string)
|
|
155
|
+
else:
|
|
156
|
+
raise ValueError("Number of sides must be an integer between 3 and 64")
|
|
157
|
+
|
|
158
|
+
def delete(self):
|
|
159
|
+
"""Delete the padstack instance."""
|
|
160
|
+
try:
|
|
161
|
+
self._pedb.padstacks._instances.pop(self.edb_uid, None)
|
|
162
|
+
except Exception:
|
|
163
|
+
self._pedb.padstacks.clear_instances_cache()
|
|
164
|
+
super().delete()
|
|
165
|
+
|
|
126
166
|
def set_backdrill_top(self, drill_depth, drill_diameter, offset=0.0):
|
|
127
167
|
"""Set backdrill from top.
|
|
128
168
|
|
|
@@ -144,7 +184,7 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
144
184
|
True if success, False otherwise.
|
|
145
185
|
"""
|
|
146
186
|
warnings.warn(
|
|
147
|
-
"`set_backdrill_top` is deprecated. Use `set_back_drill_by_depth` or
|
|
187
|
+
"`set_backdrill_top` is deprecated. Use `set_back_drill_by_depth` or `set_back_drill_by_layer` instead.",
|
|
148
188
|
DeprecationWarning,
|
|
149
189
|
)
|
|
150
190
|
if isinstance(drill_depth, str):
|
|
@@ -179,8 +219,7 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
179
219
|
True if success, False otherwise.
|
|
180
220
|
"""
|
|
181
221
|
warnings.warn(
|
|
182
|
-
"`set_backdrill_bottom` is deprecated. Use `set_back_drill_by_depth` or "
|
|
183
|
-
"`set_back_drill_by_layer` instead.",
|
|
222
|
+
"`set_backdrill_bottom` is deprecated. Use `set_back_drill_by_depth` or `set_back_drill_by_layer` instead.",
|
|
184
223
|
DeprecationWarning,
|
|
185
224
|
)
|
|
186
225
|
if isinstance(drill_depth, str):
|
|
@@ -761,18 +800,6 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
761
800
|
def aedt_name(self, value):
|
|
762
801
|
self.set_product_property(GrpcProductIdType.DESIGNER, 11, value)
|
|
763
802
|
|
|
764
|
-
@property
|
|
765
|
-
def side_number(self) -> int:
|
|
766
|
-
if not self._side_number:
|
|
767
|
-
prop_string = "$begin ''\n\tsid=3\n\tmat='copper'\n\tvs='Wirebond'\n$end ''\n"
|
|
768
|
-
self.set_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21, prop_string)
|
|
769
|
-
self._side_number = self.get_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21)
|
|
770
|
-
return self._side_number
|
|
771
|
-
|
|
772
|
-
@side_number.setter
|
|
773
|
-
def side_number(self, value):
|
|
774
|
-
self._side_number = self.set_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21, value)
|
|
775
|
-
|
|
776
803
|
def split(self) -> list:
|
|
777
804
|
"""Split padstack instance into multiple instances. The new instances only connect adjacent layers."""
|
|
778
805
|
pdef_name = self.padstack_definition
|
|
@@ -826,21 +853,21 @@ class PadstackInstance(GrpcPadstackInstance):
|
|
|
826
853
|
rad_l = rad_large
|
|
827
854
|
|
|
828
855
|
layout = self._pedb.active_layout
|
|
829
|
-
cloned_circle = Circle.create(
|
|
830
|
-
layout,
|
|
831
|
-
self.start_layer,
|
|
832
|
-
self.net,
|
|
833
|
-
Value(self.position[0]),
|
|
834
|
-
Value(self.position[1]),
|
|
835
|
-
Value(rad_u),
|
|
856
|
+
cloned_circle = Circle(self._pedb).create(
|
|
857
|
+
layout=layout,
|
|
858
|
+
layer=self.start_layer,
|
|
859
|
+
net=self.net,
|
|
860
|
+
center_x=Value(self.position[0]),
|
|
861
|
+
center_y=Value(self.position[1]),
|
|
862
|
+
radius=Value(rad_u),
|
|
836
863
|
)
|
|
837
|
-
cloned_circle2 = Circle.create(
|
|
838
|
-
layout,
|
|
839
|
-
self.stop_layer,
|
|
840
|
-
self.net,
|
|
841
|
-
Value(self.position[0]),
|
|
842
|
-
Value(self.position[1]),
|
|
843
|
-
Value(rad_l),
|
|
864
|
+
cloned_circle2 = Circle(self._pedb).create(
|
|
865
|
+
layout=layout,
|
|
866
|
+
layer=self.stop_layer,
|
|
867
|
+
net=self.net,
|
|
868
|
+
center_x=Value(self.position[0]),
|
|
869
|
+
center_y=Value(self.position[1]),
|
|
870
|
+
radius=Value(rad_l),
|
|
844
871
|
)
|
|
845
872
|
|
|
846
873
|
s3d = GrpcStructure3D.create(layout, generate_unique_name("via3d_" + self.aedt_name.replace("via_", ""), n=3))
|
|
@@ -20,19 +20,25 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
import math
|
|
23
|
+
from typing import Union
|
|
23
24
|
|
|
24
25
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
25
|
-
from ansys.edb.core.primitive.path import
|
|
26
|
-
|
|
26
|
+
from ansys.edb.core.primitive.path import (
|
|
27
|
+
Path as GrpcPath,
|
|
28
|
+
PathCornerType as GrpcPathCornerType,
|
|
29
|
+
PathEndCapType as GrpcPathEndCapType,
|
|
30
|
+
)
|
|
27
31
|
|
|
32
|
+
from pyedb.grpc.database.layers.layer import Layer
|
|
28
33
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
29
34
|
from pyedb.grpc.database.utility.value import Value
|
|
30
35
|
|
|
31
36
|
|
|
32
37
|
class Path(GrpcPath, Primitive):
|
|
33
|
-
def __init__(self, pedb, edb_object):
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
def __init__(self, pedb, edb_object=None):
|
|
39
|
+
if edb_object:
|
|
40
|
+
GrpcPath.__init__(self, edb_object.msg)
|
|
41
|
+
Primitive.__init__(self, pedb, edb_object)
|
|
36
42
|
self._edb_object = edb_object
|
|
37
43
|
self._pedb = pedb
|
|
38
44
|
|
|
@@ -72,6 +78,105 @@ class Path(GrpcPath, Primitive):
|
|
|
72
78
|
path_length += self.width / 2
|
|
73
79
|
return round(path_length, 9)
|
|
74
80
|
|
|
81
|
+
def create(
|
|
82
|
+
self,
|
|
83
|
+
layout=None,
|
|
84
|
+
layer: Union[str, Layer] = None,
|
|
85
|
+
net: Union[str, "Net"] = None,
|
|
86
|
+
width: float = 100e-6,
|
|
87
|
+
end_cap1: Union[str, GrpcPathEndCapType] = "flat",
|
|
88
|
+
end_cap2: Union[str, GrpcPathEndCapType] = "flat",
|
|
89
|
+
corner_style: Union[str, GrpcPathCornerType] = "sharp",
|
|
90
|
+
points: Union[list, GrpcPolygonData] = None,
|
|
91
|
+
):
|
|
92
|
+
"""
|
|
93
|
+
Create a path in the specified layout, layer, and net with the given parameters.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
layout : Layout, optional
|
|
98
|
+
The layout in which the path will be created. If not provided, the active layout of the `pedb` instance
|
|
99
|
+
will be used.
|
|
100
|
+
layer : Union[str, Layer], optional
|
|
101
|
+
The layer in which the path will be created. This parameter is required and must be specified.
|
|
102
|
+
net : Union[str, Net], optional
|
|
103
|
+
The net to which the path will belong. If not provided, the path will not be associated with a net.
|
|
104
|
+
width : float, optional
|
|
105
|
+
The width of the path in meters. The default value is `100e-6`.
|
|
106
|
+
end_cap1 : str, optional
|
|
107
|
+
The style of the first end cap. Options are `"flat"`, `"round"`, `"extended"`, and `"clipped"`.
|
|
108
|
+
The default value is `"flat"`.
|
|
109
|
+
end_cap2 : str, optional
|
|
110
|
+
The style of the second end cap. Options are `"flat"`, `"round"`, `"extended"`, and `"clipped"`.
|
|
111
|
+
The default value is `"flat"`.
|
|
112
|
+
corner_style : str, optional
|
|
113
|
+
The style of the path corners. Options are `"sharp"`, `"round"`, and `"mitter"`.
|
|
114
|
+
The default value is `"sharp"`.
|
|
115
|
+
points : Union[list, GrpcPolygonData], optional
|
|
116
|
+
The points defining the path. This can be a list of points or an instance of `GrpcPolygonData`.
|
|
117
|
+
This parameter is required and must be specified.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
:class:`Path <pyedb.grpc.database.primitive.path.Path>`
|
|
122
|
+
The created path object.
|
|
123
|
+
|
|
124
|
+
Raises
|
|
125
|
+
------
|
|
126
|
+
ValueError
|
|
127
|
+
If the `points` parameter is not provided.
|
|
128
|
+
|
|
129
|
+
Notes
|
|
130
|
+
-----
|
|
131
|
+
- If `points` is provided as a list, it will be converted to a `GrpcPolygonData` object.
|
|
132
|
+
- The created path is added to the modeler primitives of the `pedb` instance.
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
if layout is None:
|
|
136
|
+
layout = self._pedb.active_layout
|
|
137
|
+
end_cap_mapping = {
|
|
138
|
+
"flat": GrpcPathEndCapType.FLAT,
|
|
139
|
+
"round": GrpcPathEndCapType.ROUND,
|
|
140
|
+
"extended": GrpcPathEndCapType.EXTENDED,
|
|
141
|
+
"clipped": GrpcPathEndCapType.CLIPPED,
|
|
142
|
+
}
|
|
143
|
+
corner_style_mapping = {
|
|
144
|
+
"round": GrpcPathCornerType.ROUND,
|
|
145
|
+
"mitter": GrpcPathCornerType.MITER,
|
|
146
|
+
"sharp": GrpcPathCornerType.SHARP,
|
|
147
|
+
}
|
|
148
|
+
if isinstance(end_cap1, str):
|
|
149
|
+
end_cap1 = end_cap_mapping[end_cap1.lower()]
|
|
150
|
+
if isinstance(end_cap2, str):
|
|
151
|
+
end_cap2 = end_cap_mapping[end_cap2.lower()]
|
|
152
|
+
if isinstance(corner_style, str):
|
|
153
|
+
corner_style = corner_style_mapping[corner_style.lower()]
|
|
154
|
+
if not points:
|
|
155
|
+
raise ValueError("Points are required to create a path.")
|
|
156
|
+
if isinstance(points, list):
|
|
157
|
+
points = GrpcPolygonData(points=points)
|
|
158
|
+
self._edb_object = super().create(
|
|
159
|
+
layout=layout,
|
|
160
|
+
layer=layer,
|
|
161
|
+
net=net,
|
|
162
|
+
width=Value(width),
|
|
163
|
+
end_cap1=end_cap1,
|
|
164
|
+
end_cap2=end_cap2,
|
|
165
|
+
corner_style=corner_style,
|
|
166
|
+
points=points,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# keeping cache synced
|
|
170
|
+
new_path = Path(self._pedb, self._edb_object)
|
|
171
|
+
self._pedb.modeler._add_primitive(new_path)
|
|
172
|
+
return new_path
|
|
173
|
+
|
|
174
|
+
def delete(self):
|
|
175
|
+
"""Delete the path object."""
|
|
176
|
+
# keeping cache synced
|
|
177
|
+
self._pedb.modeler._remove_primitive(self)
|
|
178
|
+
super().delete()
|
|
179
|
+
|
|
75
180
|
def add_point(self, x, y, incremental=True) -> bool:
|
|
76
181
|
"""Add a point at the end of the path.
|
|
77
182
|
|
|
@@ -110,9 +215,9 @@ class Path(GrpcPath, Primitive):
|
|
|
110
215
|
``True`` when successful, ``False`` when failed.
|
|
111
216
|
"""
|
|
112
217
|
mapping = {
|
|
113
|
-
"round":
|
|
114
|
-
"mitter":
|
|
115
|
-
"sharp":
|
|
218
|
+
"round": GrpcPathCornerType.ROUND,
|
|
219
|
+
"mitter": GrpcPathCornerType.MITER,
|
|
220
|
+
"sharp": GrpcPathCornerType.SHARP,
|
|
116
221
|
}
|
|
117
222
|
|
|
118
223
|
cloned_path = GrpcPath.create(
|
|
@@ -339,8 +444,52 @@ class Path(GrpcPath, Primitive):
|
|
|
339
444
|
def corner_style(self, corner_type):
|
|
340
445
|
if isinstance(corner_type, str):
|
|
341
446
|
mapping = {
|
|
342
|
-
"round":
|
|
343
|
-
"mitter":
|
|
344
|
-
"sharp":
|
|
447
|
+
"round": GrpcPathCornerType.ROUND,
|
|
448
|
+
"mitter": GrpcPathCornerType.MITER,
|
|
449
|
+
"sharp": GrpcPathCornerType.SHARP,
|
|
345
450
|
}
|
|
346
451
|
self.corner_style = mapping[corner_type]
|
|
452
|
+
|
|
453
|
+
@property
|
|
454
|
+
def end_cap1(self) -> str:
|
|
455
|
+
"""Path's start style as string.
|
|
456
|
+
|
|
457
|
+
Returns
|
|
458
|
+
-------
|
|
459
|
+
str
|
|
460
|
+
Values supported for the setter `"flat"`, `"round"`, `"extended"`
|
|
461
|
+
|
|
462
|
+
"""
|
|
463
|
+
return self.get_end_cap_style()[0].name.lower()
|
|
464
|
+
|
|
465
|
+
@end_cap1.setter
|
|
466
|
+
def end_cap1(self, end_cap_style):
|
|
467
|
+
if isinstance(end_cap_style, str):
|
|
468
|
+
mapping = {
|
|
469
|
+
"flat": GrpcPathEndCapType.FLAT,
|
|
470
|
+
"round": GrpcPathEndCapType.ROUND,
|
|
471
|
+
"extended": GrpcPathEndCapType.EXTENDED,
|
|
472
|
+
}
|
|
473
|
+
self.set_end_cap_style(mapping[end_cap_style], self.get_end_cap_style()[1].value)
|
|
474
|
+
|
|
475
|
+
@property
|
|
476
|
+
def end_cap2(self) -> str:
|
|
477
|
+
"""Path's end style as string.
|
|
478
|
+
|
|
479
|
+
Returns
|
|
480
|
+
-------
|
|
481
|
+
str
|
|
482
|
+
Values supported for the setter `"flat"`, `"round"`, `"extended"`
|
|
483
|
+
|
|
484
|
+
"""
|
|
485
|
+
return self.get_end_cap_style()[1].name.lower()
|
|
486
|
+
|
|
487
|
+
@end_cap2.setter
|
|
488
|
+
def end_cap2(self, end_cap_style):
|
|
489
|
+
if isinstance(end_cap_style, str):
|
|
490
|
+
mapping = {
|
|
491
|
+
"flat": GrpcPathEndCapType.FLAT,
|
|
492
|
+
"round": GrpcPathEndCapType.ROUND,
|
|
493
|
+
"extended": GrpcPathEndCapType.EXTENDED,
|
|
494
|
+
}
|
|
495
|
+
self.set_end_cap_style(self.get_end_cap_style()[0].value, mapping[end_cap_style])
|
|
@@ -22,19 +22,23 @@
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
import math
|
|
25
|
+
from typing import Union
|
|
25
26
|
|
|
26
27
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
27
28
|
from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
|
|
28
29
|
from ansys.edb.core.primitive.polygon import Polygon as GrpcPolygon
|
|
29
30
|
|
|
31
|
+
from pyedb.grpc.database.layers.layer import Layer
|
|
32
|
+
from pyedb.grpc.database.layout.layout import Layout
|
|
30
33
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
31
34
|
from pyedb.grpc.database.utility.value import Value
|
|
32
35
|
|
|
33
36
|
|
|
34
37
|
class Polygon(GrpcPolygon, Primitive):
|
|
35
|
-
def __init__(self, pedb, edb_object):
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
def __init__(self, pedb, edb_object=None):
|
|
39
|
+
if edb_object:
|
|
40
|
+
GrpcPolygon.__init__(self, edb_object.msg)
|
|
41
|
+
Primitive.__init__(self, pedb, edb_object)
|
|
38
42
|
self._pedb = pedb
|
|
39
43
|
|
|
40
44
|
@property
|
|
@@ -59,6 +63,67 @@ class Polygon(GrpcPolygon, Primitive):
|
|
|
59
63
|
"""
|
|
60
64
|
return self.polygon_data.has_self_intersections()
|
|
61
65
|
|
|
66
|
+
def create(
|
|
67
|
+
self, layout: Layout = None, layer: Union[str, Layer] = None, net: Union[str, "Net"] = None, polygon_data=None
|
|
68
|
+
):
|
|
69
|
+
"""
|
|
70
|
+
Create a polygon in the specified layout, layer, and net using the provided polygon data.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
layout : Layout, optional
|
|
75
|
+
The layout in which the polygon will be created. If not provided, the active layout of the `pedb`
|
|
76
|
+
instance will be used.
|
|
77
|
+
layer : Union[str, Layer], optional
|
|
78
|
+
The layer in which the polygon will be created. This parameter is required and must be specified.
|
|
79
|
+
net : Union[str, Net], optional
|
|
80
|
+
The net to which the polygon will belong. If not provided, the polygon will not be associated with a
|
|
81
|
+
net.
|
|
82
|
+
polygon_data : list or GrpcPolygonData, optional
|
|
83
|
+
The data defining the polygon. This can be a list of points or an instance of `GrpcPolygonData`.
|
|
84
|
+
This parameter is required and must be specified.
|
|
85
|
+
|
|
86
|
+
Returns
|
|
87
|
+
-------
|
|
88
|
+
:class:`Polygon <ansys.edb.core.primitive.polygon.Polygon>`
|
|
89
|
+
The created polygon object.
|
|
90
|
+
|
|
91
|
+
Raises
|
|
92
|
+
------
|
|
93
|
+
ValueError
|
|
94
|
+
If the `layer` parameter is not provided.
|
|
95
|
+
ValueError
|
|
96
|
+
If the `polygon_data` parameter is not provided.
|
|
97
|
+
|
|
98
|
+
Notes
|
|
99
|
+
-----
|
|
100
|
+
- If `polygon_data` is provided as a list, it will be converted to a `GrpcPolygonData` object.
|
|
101
|
+
- The created polygon is added to the modeler primitives of the `pedb` instance.
|
|
102
|
+
|
|
103
|
+
"""
|
|
104
|
+
if not layout:
|
|
105
|
+
layout = self._pedb.active_layout
|
|
106
|
+
if not layer:
|
|
107
|
+
raise ValueError("Layer is required to create a polygon.")
|
|
108
|
+
if not polygon_data:
|
|
109
|
+
raise ValueError("Polygon data or point list is required to create a polygon.")
|
|
110
|
+
if isinstance(polygon_data, list):
|
|
111
|
+
polygon_data = GrpcPolygonData(polygon_data)
|
|
112
|
+
|
|
113
|
+
# call into the gRPC layer to actually create the polygon
|
|
114
|
+
edb_object = super().create(layout=layout, layer=layer, net=net, polygon_data=polygon_data)
|
|
115
|
+
new_polygon = Polygon(self._pedb, edb_object)
|
|
116
|
+
# keep modeler cache in sync
|
|
117
|
+
self._pedb.modeler._add_primitive(new_polygon)
|
|
118
|
+
|
|
119
|
+
return new_polygon
|
|
120
|
+
|
|
121
|
+
def delete(self):
|
|
122
|
+
"""Delete polygon from layout."""
|
|
123
|
+
# keeping cache in sync
|
|
124
|
+
self._pedb.modeler._remove_primitive(self)
|
|
125
|
+
super().delete()
|
|
126
|
+
|
|
62
127
|
def fix_self_intersections(self) -> list[any]:
|
|
63
128
|
"""Remove self intersections if they exist.
|
|
64
129
|
|
|
@@ -88,13 +153,14 @@ class Polygon(GrpcPolygon, Primitive):
|
|
|
88
153
|
Cloned polygon.
|
|
89
154
|
|
|
90
155
|
"""
|
|
156
|
+
voids = self.voids
|
|
91
157
|
polygon_data = self.polygon_data
|
|
92
|
-
|
|
158
|
+
cloned_polygon = self.create(
|
|
93
159
|
layout=self._pedb.active_layout, layer=self.layer, net=self.net, polygon_data=polygon_data
|
|
94
160
|
)
|
|
95
|
-
for void in
|
|
96
|
-
|
|
97
|
-
return
|
|
161
|
+
for void in voids:
|
|
162
|
+
cloned_polygon.add_void(void)
|
|
163
|
+
return cloned_polygon
|
|
98
164
|
|
|
99
165
|
def duplicate_across_layers(self, layers) -> bool:
|
|
100
166
|
"""Duplicate across layer a primitive object.
|
|
@@ -39,8 +39,8 @@ class Primitive(GrpcPrimitive):
|
|
|
39
39
|
>>> from pyedb import Edb
|
|
40
40
|
>>> edb = Edb(myedb, edbversion="2021.2")
|
|
41
41
|
>>> edb_prim = edb.modeler.primitives[0]
|
|
42
|
-
>>> edb_prim.is_void
|
|
43
|
-
>>> edb_prim.IsVoid()
|
|
42
|
+
>>> edb_prim.is_void # Class Property
|
|
43
|
+
>>> edb_prim.IsVoid() # EDB Object Property
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
def __init__(self, pedb, edb_object):
|