pyedb 0.38.0__py3-none-any.whl → 0.39.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/common/nets.py +53 -139
- pyedb/configuration/cfg_components.py +1 -1
- pyedb/configuration/cfg_general.py +4 -2
- pyedb/configuration/cfg_modeler.py +1 -1
- pyedb/configuration/cfg_package_definition.py +1 -1
- pyedb/configuration/cfg_padstacks.py +1 -1
- pyedb/configuration/cfg_ports_sources.py +56 -23
- pyedb/configuration/configuration.py +18 -1
- pyedb/dotnet/{application → database}/Variables.py +21 -21
- pyedb/dotnet/{edb_core → database}/cell/connectable.py +5 -5
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/component.py +11 -11
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/hierarchy_obj.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/hierarchy/model.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/layout.py +17 -17
- pyedb/dotnet/{edb_core → database}/cell/layout_obj.py +3 -3
- pyedb/dotnet/{edb_core → database}/cell/primitive/bondwire.py +1 -1
- pyedb/dotnet/{edb_core → database}/cell/primitive/path.py +4 -4
- pyedb/dotnet/{edb_core → database}/cell/primitive/primitive.py +14 -14
- pyedb/dotnet/{edb_core → database}/cell/terminal/bundle_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/edge_terminal.py +4 -4
- pyedb/dotnet/{edb_core → database}/cell/terminal/padstack_instance_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/pingroup_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/point_terminal.py +2 -2
- pyedb/dotnet/{edb_core → database}/cell/terminal/terminal.py +11 -11
- pyedb/dotnet/{edb_core → database}/cell/voltage_regulator.py +2 -2
- pyedb/dotnet/{edb_core → database}/components.py +101 -124
- pyedb/dotnet/{edb_core → database}/definition/component_def.py +5 -5
- pyedb/dotnet/{edb_core → database}/definition/component_model.py +1 -1
- pyedb/dotnet/{edb_core → database}/definition/definition_obj.py +1 -1
- pyedb/dotnet/{edb_core → database}/definition/definitions.py +2 -2
- pyedb/dotnet/{edb_core → database}/definition/package_def.py +4 -4
- pyedb/dotnet/{edb_core → database}/dotnet/database.py +8 -8
- pyedb/dotnet/{edb_core → database}/dotnet/primitive.py +9 -9
- pyedb/dotnet/{edb_core → database}/edb_data/control_file.py +12 -12
- pyedb/dotnet/{edb_core → database}/edb_data/hfss_extent_info.py +7 -7
- pyedb/dotnet/{edb_core → database}/edb_data/nets_data.py +10 -13
- pyedb/dotnet/{edb_core → database}/edb_data/padstacks_data.py +16 -16
- pyedb/dotnet/{edb_core → database}/edb_data/ports.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/primitives_data.py +5 -5
- pyedb/dotnet/{edb_core → database}/edb_data/raptor_x_simulation_setup_data.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/simulation_configuration.py +10 -10
- pyedb/dotnet/{edb_core → database}/edb_data/sources.py +4 -4
- pyedb/dotnet/{edb_core → database}/edb_data/variables.py +1 -1
- pyedb/dotnet/{edb_core → database}/geometry/polygon_data.py +4 -4
- pyedb/dotnet/{edb_core → database}/hfss.py +8 -8
- pyedb/dotnet/{edb_core → database}/layout_obj_instance.py +1 -1
- pyedb/dotnet/{edb_core → database}/layout_validation.py +2 -2
- pyedb/dotnet/{edb_core → database}/materials.py +23 -8
- pyedb/dotnet/{edb_core → database}/modeler.py +27 -27
- pyedb/dotnet/{edb_core → database}/net_class.py +8 -8
- pyedb/dotnet/{edb_core → database}/nets.py +12 -12
- pyedb/dotnet/{edb_core → database}/padstack.py +15 -15
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/mesh_operation.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/settings.py +3 -3
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sim_setup_info.py +2 -2
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/simulation_settings.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/siw_dc_ir_settings.py +1 -1
- pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sweep_data.py +1 -1
- pyedb/dotnet/{edb_core → database}/siwave.py +10 -10
- pyedb/dotnet/{edb_core → database}/stackup.py +12 -12
- pyedb/dotnet/{edb_core → database}/utilities/hfss_simulation_setup.py +15 -15
- pyedb/dotnet/{edb_core → database}/utilities/obj_base.py +1 -1
- pyedb/dotnet/{edb_core → database}/utilities/simulation_setup.py +3 -3
- pyedb/dotnet/{edb_core → database}/utilities/siwave_simulation_setup.py +6 -6
- pyedb/dotnet/edb.py +117 -112
- pyedb/generic/design_types.py +26 -19
- pyedb/generic/general_methods.py +1 -1
- pyedb/generic/plot.py +0 -2
- pyedb/grpc/database/__init__.py +1 -0
- pyedb/grpc/database/components.py +2354 -0
- pyedb/grpc/database/control_file.py +1277 -0
- pyedb/grpc/database/definition/component_def.py +218 -0
- pyedb/grpc/database/definition/component_model.py +39 -0
- pyedb/grpc/database/definition/component_pin.py +32 -0
- pyedb/grpc/database/definition/materials.py +1207 -0
- pyedb/grpc/database/definition/n_port_component_model.py +34 -0
- pyedb/grpc/database/definition/package_def.py +227 -0
- pyedb/grpc/database/definition/padstack_def.py +842 -0
- pyedb/grpc/database/definitions.py +70 -0
- pyedb/grpc/database/general.py +43 -0
- pyedb/grpc/database/geometry/__init__.py +0 -0
- pyedb/grpc/database/geometry/arc_data.py +93 -0
- pyedb/grpc/database/geometry/point_3d_data.py +79 -0
- pyedb/grpc/database/geometry/point_data.py +30 -0
- pyedb/grpc/database/geometry/polygon_data.py +133 -0
- pyedb/grpc/database/hfss.py +1279 -0
- pyedb/grpc/database/hierarchy/__init__.py +0 -0
- pyedb/grpc/database/hierarchy/component.py +1301 -0
- pyedb/grpc/database/hierarchy/model.py +31 -0
- pyedb/grpc/database/hierarchy/netlist_model.py +30 -0
- pyedb/grpc/database/hierarchy/pin_pair_model.py +128 -0
- pyedb/grpc/database/hierarchy/pingroup.py +245 -0
- pyedb/grpc/database/hierarchy/s_parameter_model.py +33 -0
- pyedb/grpc/database/hierarchy/spice_model.py +48 -0
- pyedb/grpc/database/layers/__init__.py +0 -0
- pyedb/grpc/database/layers/layer.py +57 -0
- pyedb/grpc/database/layers/stackup_layer.py +410 -0
- pyedb/grpc/database/layout/__init__.py +0 -0
- pyedb/grpc/database/layout/cell.py +30 -0
- pyedb/grpc/database/layout/layout.py +196 -0
- pyedb/grpc/database/layout/voltage_regulator.py +149 -0
- pyedb/grpc/database/layout_validation.py +319 -0
- pyedb/grpc/database/modeler.py +1468 -0
- pyedb/grpc/database/net/__init__.py +0 -0
- pyedb/grpc/database/net/differential_pair.py +138 -0
- pyedb/grpc/database/net/extended_net.py +340 -0
- pyedb/grpc/database/net/net.py +198 -0
- pyedb/grpc/database/net/net_class.py +93 -0
- pyedb/grpc/database/nets.py +633 -0
- pyedb/grpc/database/padstacks.py +1500 -0
- pyedb/grpc/database/ports/__init__.py +0 -0
- pyedb/grpc/database/ports/ports.py +396 -0
- pyedb/grpc/database/primitive/__init__.py +3 -0
- pyedb/grpc/database/primitive/bondwire.py +181 -0
- pyedb/grpc/database/primitive/circle.py +75 -0
- pyedb/grpc/database/primitive/padstack_instance.py +1116 -0
- pyedb/grpc/database/primitive/path.py +346 -0
- pyedb/grpc/database/primitive/polygon.py +276 -0
- pyedb/grpc/database/primitive/primitive.py +739 -0
- pyedb/grpc/database/primitive/rectangle.py +146 -0
- pyedb/grpc/database/simulation_setup/__init__.py +0 -0
- pyedb/grpc/database/simulation_setup/adaptive_frequency.py +33 -0
- pyedb/grpc/database/simulation_setup/hfss_advanced_meshing_settings.py +32 -0
- pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +59 -0
- pyedb/grpc/database/simulation_setup/hfss_dcr_settings.py +35 -0
- pyedb/grpc/database/simulation_setup/hfss_general_settings.py +61 -0
- pyedb/grpc/database/simulation_setup/hfss_settings_options.py +78 -0
- pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +118 -0
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +355 -0
- pyedb/grpc/database/simulation_setup/hfss_solver_settings.py +34 -0
- pyedb/grpc/database/simulation_setup/mesh_operation.py +34 -0
- pyedb/grpc/database/simulation_setup/raptor_x_advanced_settings.py +34 -0
- pyedb/grpc/database/simulation_setup/raptor_x_general_settings.py +33 -0
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +64 -0
- pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +125 -0
- pyedb/grpc/database/simulation_setup/siwave_dcir_simulation_setup.py +34 -0
- pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +119 -0
- pyedb/grpc/database/simulation_setup/sweep_data.py +32 -0
- pyedb/grpc/database/siwave.py +1023 -0
- pyedb/grpc/database/source_excitations.py +2572 -0
- pyedb/grpc/database/stackup.py +2574 -0
- pyedb/grpc/database/terminal/__init__.py +0 -0
- pyedb/grpc/database/terminal/bundle_terminal.py +218 -0
- pyedb/grpc/database/terminal/edge_terminal.py +51 -0
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +171 -0
- pyedb/grpc/database/terminal/pingroup_terminal.py +162 -0
- pyedb/grpc/database/terminal/point_terminal.py +99 -0
- pyedb/grpc/database/terminal/terminal.py +470 -0
- pyedb/grpc/database/utility/__init__.py +3 -0
- pyedb/grpc/database/utility/constants.py +25 -0
- pyedb/grpc/database/utility/heat_sink.py +124 -0
- pyedb/grpc/database/utility/hfss_extent_info.py +448 -0
- pyedb/grpc/database/utility/layout_statistics.py +277 -0
- pyedb/grpc/database/utility/rlc.py +80 -0
- pyedb/grpc/database/utility/simulation_configuration.py +3305 -0
- pyedb/grpc/database/utility/sources.py +388 -0
- pyedb/grpc/database/utility/sweep_data_distribution.py +83 -0
- pyedb/grpc/database/utility/xml_control_file.py +1277 -0
- pyedb/grpc/edb.py +4151 -0
- pyedb/grpc/edb_init.py +481 -0
- pyedb/grpc/rpc_session.py +177 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +3 -2
- pyedb/ipc2581/ecad/cad_data/feature.py +4 -3
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +32 -20
- pyedb/ipc2581/ecad/cad_data/outline.py +3 -2
- pyedb/ipc2581/ecad/cad_data/package.py +4 -3
- pyedb/ipc2581/ecad/cad_data/path.py +82 -31
- pyedb/ipc2581/ecad/cad_data/polygon.py +122 -60
- pyedb/ipc2581/ecad/cad_data/profile.py +13 -12
- pyedb/ipc2581/ecad/cad_data/step.py +53 -21
- pyedb/ipc2581/ipc2581.py +47 -49
- pyedb/modeler/geometry_operators.py +1 -1
- {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/METADATA +5 -2
- pyedb-0.39.0.dist-info/RECORD +288 -0
- pyedb-0.38.0.dist-info/RECORD +0 -195
- /pyedb/dotnet/{edb_core → database}/__init__.py +0 -0
- /pyedb/dotnet/{application → database/cell}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell → database/cell/hierarchy}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/netlist_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/pin_pair_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/s_parameter_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/hierarchy/spice_model.py +0 -0
- /pyedb/dotnet/{edb_core → database}/cell/primitive/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell/hierarchy → database/cell/terminal}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/cell/terminal → database/definition}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/definition → database/dotnet}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core/dotnet → database/edb_data}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/design_options.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/edbvalue.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/layer_data.py +0 -0
- /pyedb/dotnet/{edb_core → database}/edb_data/utilities.py +0 -0
- /pyedb/dotnet/{edb_core → database}/general.py +0 -0
- /pyedb/dotnet/{edb_core/edb_data → database/geometry}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/geometry/point_data.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/adaptive_frequency_data.py +0 -0
- /pyedb/dotnet/{edb_core/geometry → database/sim_setup_data/io}/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/sim_setup_data/io/siwave.py +0 -0
- /pyedb/dotnet/{edb_core → database}/utilities/__init__.py +0 -0
- /pyedb/dotnet/{edb_core → database}/utilities/heatsink.py +0 -0
- /pyedb/{dotnet/edb_core/sim_setup_data/io → grpc/database/definition}/__init__.py +0 -0
- {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/LICENSE +0 -0
- {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,739 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from ansys.edb.core.database import ProductIdType as GrpcProductIdType
|
|
24
|
+
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
25
|
+
from ansys.edb.core.primitive.primitive import Circle as GrpcCircle
|
|
26
|
+
from ansys.edb.core.primitive.primitive import Primitive as GrpcPrimitive
|
|
27
|
+
|
|
28
|
+
from pyedb.misc.utilities import compute_arc_points
|
|
29
|
+
from pyedb.modeler.geometry_operators import GeometryOperators
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Primitive(GrpcPrimitive):
|
|
33
|
+
"""Manages EDB functionalities for a primitives.
|
|
34
|
+
It inherits EDB Object properties.
|
|
35
|
+
|
|
36
|
+
Examples
|
|
37
|
+
--------
|
|
38
|
+
>>> from pyedb import Edb
|
|
39
|
+
>>> edb = Edb(myedb, edbversion="2021.2")
|
|
40
|
+
>>> edb_prim = edb.modeler.primitives[0]
|
|
41
|
+
>>> edb_prim.is_void # Class Property
|
|
42
|
+
>>> edb_prim.IsVoid() # EDB Object Property
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, pedb, edb_object):
|
|
46
|
+
super().__init__(edb_object.msg)
|
|
47
|
+
self._pedb = pedb
|
|
48
|
+
self._edb_object = edb_object
|
|
49
|
+
self._core_stackup = pedb.stackup
|
|
50
|
+
self._core_net = pedb.nets
|
|
51
|
+
self._object_instance = None
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def type(self):
|
|
55
|
+
"""Type of the primitive.
|
|
56
|
+
|
|
57
|
+
Expected output is among ``"Circle"``, ``"Rectangle"``,``"Polygon"``,``"Path"`` or ``"Bondwire"``.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
str
|
|
62
|
+
"""
|
|
63
|
+
return super().primitive_type.name.lower()
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def polygon_data(self):
|
|
67
|
+
"""Polygon data.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
:class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
return self.cast().polygon_data
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def object_instance(self):
|
|
78
|
+
"""Layout object instance.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
:class:`LayoutObjInstance <ansys.edb.core.layout_instance.layout_obj_instance.LayoutObjInstance>`
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
if not self._object_instance:
|
|
86
|
+
self._object_instance = self.layout.layout_instance.get_layout_obj_instance_in_context(self, None)
|
|
87
|
+
return self._object_instance
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def net_name(self):
|
|
91
|
+
"""Net name.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
str
|
|
96
|
+
Net name.
|
|
97
|
+
|
|
98
|
+
"""
|
|
99
|
+
if not self.net.is_null:
|
|
100
|
+
return self.net.name
|
|
101
|
+
|
|
102
|
+
@net_name.setter
|
|
103
|
+
def net_name(self, value):
|
|
104
|
+
if value in self._pedb.nets.nets:
|
|
105
|
+
self.net = self._pedb.nets.nets[value]
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def layer_name(self):
|
|
109
|
+
"""Layer name.
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
113
|
+
str
|
|
114
|
+
Layer name.
|
|
115
|
+
"""
|
|
116
|
+
return self.layer.name
|
|
117
|
+
|
|
118
|
+
@layer_name.setter
|
|
119
|
+
def layer_name(self, value):
|
|
120
|
+
if value in self._pedb.stackup.layers:
|
|
121
|
+
self.layer = self._pedb.stackup.layers[value]
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def voids(self):
|
|
125
|
+
"""Primitive voids.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
List[:class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>`
|
|
130
|
+
|
|
131
|
+
"""
|
|
132
|
+
return [Primitive(self._pedb, prim) for prim in super().voids]
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def aedt_name(self):
|
|
136
|
+
"""Name to be visualized in AEDT.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
str
|
|
141
|
+
Name.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
name = self.get_product_property(GrpcProductIdType.DESIGNER, 1)
|
|
145
|
+
name = name.strip("'")
|
|
146
|
+
except:
|
|
147
|
+
name = ""
|
|
148
|
+
if not name:
|
|
149
|
+
if self.primitive_type.name.lower() == "path":
|
|
150
|
+
ptype = "line"
|
|
151
|
+
elif self.primitive_type.name.lower() == "rectangle":
|
|
152
|
+
ptype = "rect"
|
|
153
|
+
elif self.primitive_type.name.lower() == "polygon":
|
|
154
|
+
ptype = "poly"
|
|
155
|
+
elif self.primitive_type.name.lower() == "bondwire":
|
|
156
|
+
ptype = "bwr"
|
|
157
|
+
else:
|
|
158
|
+
ptype = self.primitive_type.name.lower()
|
|
159
|
+
name = "{}_{}".format(ptype, self.edb_uid)
|
|
160
|
+
self.aedt_name = name
|
|
161
|
+
return name
|
|
162
|
+
|
|
163
|
+
@aedt_name.setter
|
|
164
|
+
def aedt_name(self, value):
|
|
165
|
+
self.set_product_property(GrpcProductIdType.DESIGNER, 1, value)
|
|
166
|
+
|
|
167
|
+
def get_connected_objects(self):
|
|
168
|
+
"""Get connected objects.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
List[:class:`LayoutObjInstance <ansys.edb.core.layout_instance.layout_obj_instance.LayoutObjInstance>`]
|
|
173
|
+
|
|
174
|
+
"""
|
|
175
|
+
return self._pedb.get_connected_objects(self.object_instance)
|
|
176
|
+
|
|
177
|
+
def area(self, include_voids=True):
|
|
178
|
+
"""Return the total area.
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
include_voids : bool, optional
|
|
183
|
+
Either if the voids have to be included in computation.
|
|
184
|
+
The default value is ``True``.
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
float
|
|
189
|
+
"""
|
|
190
|
+
area = self.cast().polygon_data.area()
|
|
191
|
+
if include_voids:
|
|
192
|
+
for el in self.voids:
|
|
193
|
+
area -= el.polygon_data.area()
|
|
194
|
+
return area
|
|
195
|
+
|
|
196
|
+
def _get_points_for_plot(self, my_net_points, num):
|
|
197
|
+
"""
|
|
198
|
+
Get the points to be plotted.
|
|
199
|
+
"""
|
|
200
|
+
# fmt: off
|
|
201
|
+
x = []
|
|
202
|
+
y = []
|
|
203
|
+
for i, point in enumerate(my_net_points):
|
|
204
|
+
if not point.is_arc:
|
|
205
|
+
x.append(point.x.value)
|
|
206
|
+
y.append(point.y.value)
|
|
207
|
+
else:
|
|
208
|
+
arc_h = point.arc_height.value
|
|
209
|
+
p1 = [my_net_points[i - 1].x.value, my_net_points[i - 1].y.value]
|
|
210
|
+
if i + 1 < len(my_net_points):
|
|
211
|
+
p2 = [my_net_points[i + 1].x.value, my_net_points[i + 1].y.value]
|
|
212
|
+
else:
|
|
213
|
+
p2 = [my_net_points[0].x.value, my_net_points[0].y.value]
|
|
214
|
+
x_arc, y_arc = compute_arc_points(p1, p2, arc_h, num)
|
|
215
|
+
x.extend(x_arc)
|
|
216
|
+
y.extend(y_arc)
|
|
217
|
+
# fmt: on
|
|
218
|
+
return x, y
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def center(self):
|
|
222
|
+
"""Return the primitive bounding box center coordinate.
|
|
223
|
+
|
|
224
|
+
Returns
|
|
225
|
+
-------
|
|
226
|
+
List[float, float]
|
|
227
|
+
[x, y]
|
|
228
|
+
|
|
229
|
+
"""
|
|
230
|
+
center = self.cast().polygon_data.bounding_circle()[0]
|
|
231
|
+
return [center.x.value, center.y.value]
|
|
232
|
+
|
|
233
|
+
def get_connected_object_id_set(self):
|
|
234
|
+
"""Produce a list of all geometries physically connected to a given layout object.
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
List[int]
|
|
239
|
+
Found connected objects IDs with Layout object.
|
|
240
|
+
"""
|
|
241
|
+
layout_inst = self.layout.layout_instance
|
|
242
|
+
layout_obj_inst = layout_inst.get_layout_obj_instance_in_context(self._edb_object, None) # 2nd arg was []
|
|
243
|
+
return [loi.layout_obj.id for loi in layout_inst.get_connected_objects(layout_obj_inst)]
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def bbox(self):
|
|
247
|
+
"""Return the primitive bounding box points. Lower left corner, upper right corner.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
List[float, float, float, float]
|
|
252
|
+
[lower_left x, lower_left y, upper right x, upper right y]
|
|
253
|
+
|
|
254
|
+
"""
|
|
255
|
+
bbox = self.cast().polygon_data.bbox()
|
|
256
|
+
return [bbox[0].x.value, bbox[0].y.value, bbox[1].x.value, bbox[1].y.value]
|
|
257
|
+
|
|
258
|
+
def convert_to_polygon(self):
|
|
259
|
+
"""Convert path to polygon.
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
:class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>`
|
|
264
|
+
Polygon when successful, ``False`` when failed.
|
|
265
|
+
|
|
266
|
+
"""
|
|
267
|
+
if self.type == "path":
|
|
268
|
+
polygon = self._pedb.modeler.create_polygon(self.polygon_data, self.layer_name, [], self.net.name)
|
|
269
|
+
self.delete()
|
|
270
|
+
return polygon
|
|
271
|
+
else:
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
def intersection_type(self, primitive):
|
|
275
|
+
"""Get intersection type between actual primitive and another primitive or polygon data.
|
|
276
|
+
|
|
277
|
+
Parameters
|
|
278
|
+
----------
|
|
279
|
+
primitive : :class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>>` or `PolygonData`
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
int
|
|
284
|
+
Intersection type:
|
|
285
|
+
0 - objects do not intersect,
|
|
286
|
+
1 - this object fully inside other (no common contour points),
|
|
287
|
+
2 - other object fully inside this,
|
|
288
|
+
3 - common contour points,
|
|
289
|
+
4 - undefined intersection.
|
|
290
|
+
"""
|
|
291
|
+
if self.type in ["path, polygon"]:
|
|
292
|
+
poly = primitive.polygon_data
|
|
293
|
+
return self.polygon_data.intersection_type(poly).value
|
|
294
|
+
else:
|
|
295
|
+
return 4
|
|
296
|
+
|
|
297
|
+
def is_intersecting(self, primitive):
|
|
298
|
+
"""Check if actual primitive and another primitive or polygon data intesects.
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
primitive : :class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>>` or `PolygonData`
|
|
303
|
+
|
|
304
|
+
Returns
|
|
305
|
+
-------
|
|
306
|
+
bool
|
|
307
|
+
"""
|
|
308
|
+
return True if self.intersection_type(primitive) >= 1 else False
|
|
309
|
+
|
|
310
|
+
def get_closest_point(self, point):
|
|
311
|
+
"""Get the closest point of the primitive to the input data.
|
|
312
|
+
|
|
313
|
+
Parameters
|
|
314
|
+
----------
|
|
315
|
+
point : list of float or PointData
|
|
316
|
+
|
|
317
|
+
Returns
|
|
318
|
+
-------
|
|
319
|
+
List[float, float]
|
|
320
|
+
[x, y].
|
|
321
|
+
|
|
322
|
+
"""
|
|
323
|
+
if isinstance(point, (list, tuple)):
|
|
324
|
+
point = GrpcPointData(point)
|
|
325
|
+
|
|
326
|
+
p0 = self.cast().polygon_data.closest_point(point)
|
|
327
|
+
return [p0.x.value, p0.y.value]
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def arcs(self):
|
|
331
|
+
"""Get the Primitive Arc Data.
|
|
332
|
+
|
|
333
|
+
Returns
|
|
334
|
+
-------
|
|
335
|
+
:class:`ArcData <ansys.edb.core.geometry.arc_data.ArcData>`
|
|
336
|
+
"""
|
|
337
|
+
return self.polygon_data.arc_data
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def longest_arc(self):
|
|
341
|
+
"""Longest arc.
|
|
342
|
+
|
|
343
|
+
Returns
|
|
344
|
+
-------
|
|
345
|
+
float
|
|
346
|
+
Arc length.
|
|
347
|
+
"""
|
|
348
|
+
len = 0
|
|
349
|
+
arc = None
|
|
350
|
+
for i in self.arcs:
|
|
351
|
+
if i.is_segment and i.length > len:
|
|
352
|
+
arc = i
|
|
353
|
+
len = i.length
|
|
354
|
+
return arc
|
|
355
|
+
|
|
356
|
+
def subtract(self, primitives):
|
|
357
|
+
"""Subtract active primitive with one or more primitives.
|
|
358
|
+
|
|
359
|
+
Parameters
|
|
360
|
+
----------
|
|
361
|
+
primitives : :class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`
|
|
362
|
+
or: List[:class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
363
|
+
or: class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`
|
|
364
|
+
|
|
365
|
+
Returns
|
|
366
|
+
-------
|
|
367
|
+
List[:class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
368
|
+
List of Primitive objects.
|
|
369
|
+
|
|
370
|
+
"""
|
|
371
|
+
poly = self.cast().polygon_data
|
|
372
|
+
if not isinstance(primitives, list):
|
|
373
|
+
primitives = [primitives]
|
|
374
|
+
primi_polys = []
|
|
375
|
+
voids_of_prims = []
|
|
376
|
+
for prim in primitives:
|
|
377
|
+
if isinstance(prim, Primitive):
|
|
378
|
+
primi_polys.append(prim.cast().polygon_data)
|
|
379
|
+
for void in prim.voids:
|
|
380
|
+
voids_of_prims.append(void.cast().polygon_data)
|
|
381
|
+
else:
|
|
382
|
+
try:
|
|
383
|
+
primi_polys.append(prim.cast().polygon_data)
|
|
384
|
+
except:
|
|
385
|
+
primi_polys.append(prim)
|
|
386
|
+
for v in self.voids[:]:
|
|
387
|
+
primi_polys.append(v.cast().polygon_data)
|
|
388
|
+
primi_polys = poly.unite(primi_polys)
|
|
389
|
+
p_to_sub = poly.unite([poly] + voids_of_prims)
|
|
390
|
+
list_poly = poly.subtract(p_to_sub, primi_polys)
|
|
391
|
+
new_polys = []
|
|
392
|
+
if list_poly:
|
|
393
|
+
for p in list_poly:
|
|
394
|
+
if not p.points:
|
|
395
|
+
continue
|
|
396
|
+
new_polys.append(
|
|
397
|
+
self._pedb.modeler.create_polygon(p, self.layer_name, net_name=self.net.name, voids=[]),
|
|
398
|
+
)
|
|
399
|
+
self.delete()
|
|
400
|
+
for prim in primitives:
|
|
401
|
+
if isinstance(prim, Primitive):
|
|
402
|
+
prim.delete()
|
|
403
|
+
else:
|
|
404
|
+
try:
|
|
405
|
+
prim.Delete()
|
|
406
|
+
except AttributeError:
|
|
407
|
+
continue
|
|
408
|
+
return new_polys
|
|
409
|
+
|
|
410
|
+
def intersect(self, primitives):
|
|
411
|
+
"""Intersect active primitive with one or more primitives.
|
|
412
|
+
|
|
413
|
+
Parameters
|
|
414
|
+
----------
|
|
415
|
+
primitives :class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`
|
|
416
|
+
or: List[:class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
417
|
+
or: class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`
|
|
418
|
+
|
|
419
|
+
Returns
|
|
420
|
+
-------
|
|
421
|
+
List[:class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
422
|
+
List of Primitive objects.
|
|
423
|
+
|
|
424
|
+
"""
|
|
425
|
+
poly = self.cast().polygon_data
|
|
426
|
+
if not isinstance(primitives, list):
|
|
427
|
+
primitives = [primitives]
|
|
428
|
+
primi_polys = []
|
|
429
|
+
for prim in primitives:
|
|
430
|
+
prim = prim.cast()
|
|
431
|
+
if isinstance(prim, Primitive):
|
|
432
|
+
primi_polys.append(prim.polygon_data)
|
|
433
|
+
else:
|
|
434
|
+
if isinstance(prim, GrpcCircle):
|
|
435
|
+
primi_polys.append(prim.polygon_data)
|
|
436
|
+
else:
|
|
437
|
+
primi_polys.append(prim.polygon_data)
|
|
438
|
+
list_poly = poly.intersect([poly], primi_polys)
|
|
439
|
+
new_polys = []
|
|
440
|
+
if list_poly:
|
|
441
|
+
voids = self.voids
|
|
442
|
+
for p in list_poly:
|
|
443
|
+
if not p.points:
|
|
444
|
+
continue
|
|
445
|
+
list_void = []
|
|
446
|
+
void_to_subtract = []
|
|
447
|
+
if voids:
|
|
448
|
+
for void in voids:
|
|
449
|
+
void_pdata = void.polygon_data
|
|
450
|
+
int_data2 = p.intersection_type(void_pdata).value
|
|
451
|
+
if int_data2 > 2 or int_data2 == 1:
|
|
452
|
+
void_to_subtract.append(void_pdata)
|
|
453
|
+
elif int_data2 == 2:
|
|
454
|
+
list_void.append(void_pdata)
|
|
455
|
+
if void_to_subtract:
|
|
456
|
+
polys_cleans = p.subtract(p, void_to_subtract)
|
|
457
|
+
for polys_clean in polys_cleans:
|
|
458
|
+
if polys_clean.points:
|
|
459
|
+
void_to_append = [v for v in list_void if polys_clean.intersection_type(v) == 2]
|
|
460
|
+
new_polys.append(
|
|
461
|
+
self._pedb.modeler.create_polygon(
|
|
462
|
+
polys_clean, self.layer_name, net_name=self.net.name, voids=void_to_append
|
|
463
|
+
)
|
|
464
|
+
)
|
|
465
|
+
else:
|
|
466
|
+
new_polys.append(
|
|
467
|
+
self._pedb.modeler.create_polygon(
|
|
468
|
+
p, self.layer_name, net_name=self.net.name, voids=list_void
|
|
469
|
+
)
|
|
470
|
+
)
|
|
471
|
+
else:
|
|
472
|
+
new_polys.append(
|
|
473
|
+
self._pedb.modeler.create_polygon(p, self.layer_name, net_name=self.net.name, voids=list_void)
|
|
474
|
+
)
|
|
475
|
+
self.delete()
|
|
476
|
+
for prim in primitives:
|
|
477
|
+
prim.delete()
|
|
478
|
+
return new_polys
|
|
479
|
+
|
|
480
|
+
def unite(self, primitives):
|
|
481
|
+
"""Unite active primitive with one or more primitives.
|
|
482
|
+
|
|
483
|
+
Parameters
|
|
484
|
+
----------
|
|
485
|
+
primitives : :class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`
|
|
486
|
+
or: List[:class:`Primitives <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
487
|
+
or: class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`
|
|
488
|
+
|
|
489
|
+
Returns
|
|
490
|
+
-------
|
|
491
|
+
List[:class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>`]
|
|
492
|
+
List of Primitive objects.
|
|
493
|
+
|
|
494
|
+
"""
|
|
495
|
+
poly = self.polygon_data
|
|
496
|
+
if not isinstance(primitives, list):
|
|
497
|
+
primitives = [primitives]
|
|
498
|
+
primi_polys = []
|
|
499
|
+
for prim in primitives:
|
|
500
|
+
if isinstance(prim, Primitive):
|
|
501
|
+
primi_polys.append(prim.polygon_data)
|
|
502
|
+
else:
|
|
503
|
+
primi_polys.append(prim.polygon_data)
|
|
504
|
+
primi_polys.append(prim)
|
|
505
|
+
list_poly = poly.unite([poly] + primi_polys)
|
|
506
|
+
new_polys = []
|
|
507
|
+
if list_poly:
|
|
508
|
+
voids = self.voids
|
|
509
|
+
for p in list_poly:
|
|
510
|
+
if not p.points:
|
|
511
|
+
continue
|
|
512
|
+
list_void = []
|
|
513
|
+
if voids:
|
|
514
|
+
for void in voids:
|
|
515
|
+
void_pdata = void.polygon_data
|
|
516
|
+
int_data2 = p.intersection_type(void_pdata)
|
|
517
|
+
if int_data2 > 1:
|
|
518
|
+
list_void.append(void_pdata)
|
|
519
|
+
new_polys.append(
|
|
520
|
+
self._pedb.modeler.create_polygon(p, self.layer_name, net_name=self.net.name, voids=list_void),
|
|
521
|
+
)
|
|
522
|
+
self.delete()
|
|
523
|
+
for prim in primitives:
|
|
524
|
+
if isinstance(prim, Primitive):
|
|
525
|
+
prim.delete()
|
|
526
|
+
else:
|
|
527
|
+
try:
|
|
528
|
+
prim.delete()
|
|
529
|
+
except AttributeError:
|
|
530
|
+
continue
|
|
531
|
+
return new_polys
|
|
532
|
+
|
|
533
|
+
def get_closest_arc_midpoint(self, point):
|
|
534
|
+
"""Get the closest arc midpoint of the primitive to the input data.
|
|
535
|
+
|
|
536
|
+
Parameters
|
|
537
|
+
----------
|
|
538
|
+
point : List[float] or List[:class:`PointData <ansys.edb.core.geometry.point_data.PointData>`]
|
|
539
|
+
|
|
540
|
+
Returns
|
|
541
|
+
-------
|
|
542
|
+
LIst[float, float]
|
|
543
|
+
[x, y].
|
|
544
|
+
"""
|
|
545
|
+
|
|
546
|
+
if isinstance(point, GrpcPointData):
|
|
547
|
+
point = [point.x.value, point.y.value]
|
|
548
|
+
dist = 1e12
|
|
549
|
+
out = None
|
|
550
|
+
for arc in self.arcs:
|
|
551
|
+
mid_point = arc.midpoint
|
|
552
|
+
mid_point = [mid_point.x.value, mid_point.y.value]
|
|
553
|
+
if GeometryOperators.points_distance(mid_point, point) < dist:
|
|
554
|
+
out = arc.midpoint
|
|
555
|
+
dist = GeometryOperators.points_distance(mid_point, point)
|
|
556
|
+
return [out.x.value, out.y.value]
|
|
557
|
+
|
|
558
|
+
@property
|
|
559
|
+
def shortest_arc(self):
|
|
560
|
+
"""Longest arc.
|
|
561
|
+
|
|
562
|
+
Returns
|
|
563
|
+
-------
|
|
564
|
+
float
|
|
565
|
+
Arc length.
|
|
566
|
+
"""
|
|
567
|
+
len = 1e12
|
|
568
|
+
arc = None
|
|
569
|
+
for i in self.arcs:
|
|
570
|
+
if i.is_segment and i.length < len:
|
|
571
|
+
arc = i
|
|
572
|
+
len = i.length
|
|
573
|
+
return arc
|
|
574
|
+
|
|
575
|
+
def add_void(self, point_list):
|
|
576
|
+
"""Add a void to current primitive.
|
|
577
|
+
|
|
578
|
+
Parameters
|
|
579
|
+
----------
|
|
580
|
+
point_list : list or :class:`Primitive <pyedb.grpc.database.primitive.primitive.Primitive>` \
|
|
581
|
+
or point list in the format of `[[x1,y1], [x2,y2],..,[xn,yn]]`.
|
|
582
|
+
|
|
583
|
+
Returns
|
|
584
|
+
-------
|
|
585
|
+
bool
|
|
586
|
+
``True`` if successful, either ``False``.
|
|
587
|
+
"""
|
|
588
|
+
if isinstance(point_list, list):
|
|
589
|
+
plane = self._pedb.modeler.Shape("polygon", points=point_list)
|
|
590
|
+
_poly = self._pedb.modeler.shape_to_polygon_data(plane)
|
|
591
|
+
if _poly is None or _poly.is_null or _poly is False:
|
|
592
|
+
self._pedb.logger.error("Failed to create void polygon data")
|
|
593
|
+
return False
|
|
594
|
+
void_poly = self._pedb.modeler.create_polygon(_poly, layer_name=self.layer_name, net_name=self.net.name)
|
|
595
|
+
return self.add_void(void_poly)
|
|
596
|
+
|
|
597
|
+
def points(self, arc_segments=6):
|
|
598
|
+
"""Return the list of points with arcs converted to segments.
|
|
599
|
+
|
|
600
|
+
Parameters
|
|
601
|
+
----------
|
|
602
|
+
arc_segments : int
|
|
603
|
+
Number of facets to convert an arc. Default is `6`.
|
|
604
|
+
|
|
605
|
+
Returns
|
|
606
|
+
-------
|
|
607
|
+
tuple(float, float)
|
|
608
|
+
(X, Y).
|
|
609
|
+
"""
|
|
610
|
+
xt, yt = self._get_points_for_plot(self.polygon_data.points, arc_segments)
|
|
611
|
+
if not xt:
|
|
612
|
+
return []
|
|
613
|
+
x, y = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
|
|
614
|
+
return x, y
|
|
615
|
+
|
|
616
|
+
@property
|
|
617
|
+
def points_raw(self):
|
|
618
|
+
"""Return a list of Edb points.
|
|
619
|
+
|
|
620
|
+
Returns
|
|
621
|
+
-------
|
|
622
|
+
List[:class:`PointData <ansys.edb.core.geometry.point_data.PointData>`]
|
|
623
|
+
|
|
624
|
+
"""
|
|
625
|
+
|
|
626
|
+
return self.polygon_data.points
|
|
627
|
+
|
|
628
|
+
def expand(self, offset=0.001, tolerance=1e-12, round_corners=True, maximum_corner_extension=0.001):
|
|
629
|
+
"""Expand the polygon shape by an absolute value in all direction.
|
|
630
|
+
Offset can be negative for negative expansion.
|
|
631
|
+
|
|
632
|
+
Parameters
|
|
633
|
+
----------
|
|
634
|
+
offset : float, optional
|
|
635
|
+
Offset value in meters.
|
|
636
|
+
tolerance : float, optional
|
|
637
|
+
Tolerance in meters.
|
|
638
|
+
round_corners : bool, optional
|
|
639
|
+
Whether to round corners or not.
|
|
640
|
+
If True, use rounded corners in the expansion otherwise use straight edges (can be degenerate).
|
|
641
|
+
maximum_corner_extension : float, optional
|
|
642
|
+
The maximum corner extension (when round corners are not used) at which point the corner is clipped.
|
|
643
|
+
|
|
644
|
+
Return
|
|
645
|
+
------
|
|
646
|
+
List:[:class:`PolygonData <ansys.edb.core.geometry.polygon_data.PolygonData>`]
|
|
647
|
+
|
|
648
|
+
"""
|
|
649
|
+
return self.cast().polygon_data.expand(
|
|
650
|
+
offset=offset, round_corner=round_corners, max_corner_ext=maximum_corner_extension, tol=tolerance
|
|
651
|
+
)
|
|
652
|
+
|
|
653
|
+
def scale(self, factor, center=None):
|
|
654
|
+
"""Scales the polygon relative to a center point by a factor.
|
|
655
|
+
|
|
656
|
+
Parameters
|
|
657
|
+
----------
|
|
658
|
+
factor : float
|
|
659
|
+
Scaling factor.
|
|
660
|
+
center : List of float or str [x,y], optional
|
|
661
|
+
If None scaling is done from polygon center.
|
|
662
|
+
|
|
663
|
+
Returns
|
|
664
|
+
-------
|
|
665
|
+
bool
|
|
666
|
+
``True`` when successful, ``False`` when failed.
|
|
667
|
+
"""
|
|
668
|
+
if not isinstance(factor, str):
|
|
669
|
+
factor = float(factor)
|
|
670
|
+
from ansys.edb.core.geometry.polygon_data import (
|
|
671
|
+
PolygonData as GrpcPolygonData,
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
polygon_data = GrpcPolygonData(points=self.cast().polygon_data.points)
|
|
675
|
+
if not center:
|
|
676
|
+
center = polygon_data.bounding_circle()[0]
|
|
677
|
+
if center:
|
|
678
|
+
polygon_data.scale(factor, center)
|
|
679
|
+
self.cast().polygon_data = polygon_data
|
|
680
|
+
return True
|
|
681
|
+
else:
|
|
682
|
+
self._pedb.logger.error(f"Failed to evaluate center on primitive {self.id}")
|
|
683
|
+
elif isinstance(center, list) and len(center) == 2:
|
|
684
|
+
center = GrpcPointData(center)
|
|
685
|
+
polygon_data.scale(factor, center)
|
|
686
|
+
self.cast().polygon_data = polygon_data
|
|
687
|
+
return True
|
|
688
|
+
return False
|
|
689
|
+
|
|
690
|
+
def plot(self, plot_net=False, show=True, save_plot=None):
|
|
691
|
+
"""Plot the current polygon on matplotlib.
|
|
692
|
+
|
|
693
|
+
Parameters
|
|
694
|
+
----------
|
|
695
|
+
plot_net : bool, optional
|
|
696
|
+
Whether if plot the entire net or only the selected polygon. Default is ``False``.
|
|
697
|
+
show : bool, optional
|
|
698
|
+
Whether if show the plot or not. Default is ``True``.
|
|
699
|
+
save_plot : str, optional
|
|
700
|
+
Save the plot path.
|
|
701
|
+
|
|
702
|
+
Returns
|
|
703
|
+
-------
|
|
704
|
+
(ax, fig)
|
|
705
|
+
Matplotlib ax and figures.
|
|
706
|
+
"""
|
|
707
|
+
import matplotlib.pyplot as plt
|
|
708
|
+
from shapely.geometry import Polygon
|
|
709
|
+
from shapely.plotting import plot_polygon
|
|
710
|
+
|
|
711
|
+
dpi = 100.0
|
|
712
|
+
figsize = (2000 / dpi, 1000 / dpi)
|
|
713
|
+
if plot_net and self.net_name:
|
|
714
|
+
fig, ax = self._pedb.nets.plot([self.net_name], color_by_net=True, show=False, show_legend=False)
|
|
715
|
+
else:
|
|
716
|
+
fig = plt.figure(figsize=figsize)
|
|
717
|
+
ax = fig.add_subplot(1, 1, 1)
|
|
718
|
+
xt, yt = self.points()
|
|
719
|
+
p1 = [(i, j) for i, j in zip(xt[::-1], yt[::-1])]
|
|
720
|
+
|
|
721
|
+
holes = []
|
|
722
|
+
for void in self.voids:
|
|
723
|
+
xvt, yvt = void.points(arc_segments=3)
|
|
724
|
+
h1 = [(i, j) for i, j in zip(xvt, yvt)]
|
|
725
|
+
holes.append(h1)
|
|
726
|
+
poly = Polygon(p1, holes)
|
|
727
|
+
plot_polygon(poly, add_points=False, color=(1, 0, 0))
|
|
728
|
+
ax.grid(False)
|
|
729
|
+
ax.set_axis_off()
|
|
730
|
+
# Hide axes ticks
|
|
731
|
+
ax.set_xticks([])
|
|
732
|
+
ax.set_yticks([])
|
|
733
|
+
message = f"Polygon {self.id} on net {self.net_name}"
|
|
734
|
+
plt.title(message, size=20)
|
|
735
|
+
if save_plot:
|
|
736
|
+
plt.savefig(save_plot)
|
|
737
|
+
elif show:
|
|
738
|
+
plt.show()
|
|
739
|
+
return ax, fig
|