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.

Files changed (205) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/common/nets.py +53 -139
  3. pyedb/configuration/cfg_components.py +1 -1
  4. pyedb/configuration/cfg_general.py +4 -2
  5. pyedb/configuration/cfg_modeler.py +1 -1
  6. pyedb/configuration/cfg_package_definition.py +1 -1
  7. pyedb/configuration/cfg_padstacks.py +1 -1
  8. pyedb/configuration/cfg_ports_sources.py +56 -23
  9. pyedb/configuration/configuration.py +18 -1
  10. pyedb/dotnet/{application → database}/Variables.py +21 -21
  11. pyedb/dotnet/{edb_core → database}/cell/connectable.py +5 -5
  12. pyedb/dotnet/{edb_core → database}/cell/hierarchy/component.py +11 -11
  13. pyedb/dotnet/{edb_core → database}/cell/hierarchy/hierarchy_obj.py +1 -1
  14. pyedb/dotnet/{edb_core → database}/cell/hierarchy/model.py +1 -1
  15. pyedb/dotnet/{edb_core → database}/cell/layout.py +17 -17
  16. pyedb/dotnet/{edb_core → database}/cell/layout_obj.py +3 -3
  17. pyedb/dotnet/{edb_core → database}/cell/primitive/bondwire.py +1 -1
  18. pyedb/dotnet/{edb_core → database}/cell/primitive/path.py +4 -4
  19. pyedb/dotnet/{edb_core → database}/cell/primitive/primitive.py +14 -14
  20. pyedb/dotnet/{edb_core → database}/cell/terminal/bundle_terminal.py +2 -2
  21. pyedb/dotnet/{edb_core → database}/cell/terminal/edge_terminal.py +4 -4
  22. pyedb/dotnet/{edb_core → database}/cell/terminal/padstack_instance_terminal.py +2 -2
  23. pyedb/dotnet/{edb_core → database}/cell/terminal/pingroup_terminal.py +2 -2
  24. pyedb/dotnet/{edb_core → database}/cell/terminal/point_terminal.py +2 -2
  25. pyedb/dotnet/{edb_core → database}/cell/terminal/terminal.py +11 -11
  26. pyedb/dotnet/{edb_core → database}/cell/voltage_regulator.py +2 -2
  27. pyedb/dotnet/{edb_core → database}/components.py +101 -124
  28. pyedb/dotnet/{edb_core → database}/definition/component_def.py +5 -5
  29. pyedb/dotnet/{edb_core → database}/definition/component_model.py +1 -1
  30. pyedb/dotnet/{edb_core → database}/definition/definition_obj.py +1 -1
  31. pyedb/dotnet/{edb_core → database}/definition/definitions.py +2 -2
  32. pyedb/dotnet/{edb_core → database}/definition/package_def.py +4 -4
  33. pyedb/dotnet/{edb_core → database}/dotnet/database.py +8 -8
  34. pyedb/dotnet/{edb_core → database}/dotnet/primitive.py +9 -9
  35. pyedb/dotnet/{edb_core → database}/edb_data/control_file.py +12 -12
  36. pyedb/dotnet/{edb_core → database}/edb_data/hfss_extent_info.py +7 -7
  37. pyedb/dotnet/{edb_core → database}/edb_data/nets_data.py +10 -13
  38. pyedb/dotnet/{edb_core → database}/edb_data/padstacks_data.py +16 -16
  39. pyedb/dotnet/{edb_core → database}/edb_data/ports.py +4 -4
  40. pyedb/dotnet/{edb_core → database}/edb_data/primitives_data.py +5 -5
  41. pyedb/dotnet/{edb_core → database}/edb_data/raptor_x_simulation_setup_data.py +4 -4
  42. pyedb/dotnet/{edb_core → database}/edb_data/simulation_configuration.py +10 -10
  43. pyedb/dotnet/{edb_core → database}/edb_data/sources.py +4 -4
  44. pyedb/dotnet/{edb_core → database}/edb_data/variables.py +1 -1
  45. pyedb/dotnet/{edb_core → database}/geometry/polygon_data.py +4 -4
  46. pyedb/dotnet/{edb_core → database}/hfss.py +8 -8
  47. pyedb/dotnet/{edb_core → database}/layout_obj_instance.py +1 -1
  48. pyedb/dotnet/{edb_core → database}/layout_validation.py +2 -2
  49. pyedb/dotnet/{edb_core → database}/materials.py +23 -8
  50. pyedb/dotnet/{edb_core → database}/modeler.py +27 -27
  51. pyedb/dotnet/{edb_core → database}/net_class.py +8 -8
  52. pyedb/dotnet/{edb_core → database}/nets.py +12 -12
  53. pyedb/dotnet/{edb_core → database}/padstack.py +15 -15
  54. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/mesh_operation.py +1 -1
  55. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/settings.py +3 -3
  56. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sim_setup_info.py +2 -2
  57. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/simulation_settings.py +1 -1
  58. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/siw_dc_ir_settings.py +1 -1
  59. pyedb/dotnet/{edb_core → database}/sim_setup_data/data/sweep_data.py +1 -1
  60. pyedb/dotnet/{edb_core → database}/siwave.py +10 -10
  61. pyedb/dotnet/{edb_core → database}/stackup.py +12 -12
  62. pyedb/dotnet/{edb_core → database}/utilities/hfss_simulation_setup.py +15 -15
  63. pyedb/dotnet/{edb_core → database}/utilities/obj_base.py +1 -1
  64. pyedb/dotnet/{edb_core → database}/utilities/simulation_setup.py +3 -3
  65. pyedb/dotnet/{edb_core → database}/utilities/siwave_simulation_setup.py +6 -6
  66. pyedb/dotnet/edb.py +117 -112
  67. pyedb/generic/design_types.py +26 -19
  68. pyedb/generic/general_methods.py +1 -1
  69. pyedb/generic/plot.py +0 -2
  70. pyedb/grpc/database/__init__.py +1 -0
  71. pyedb/grpc/database/components.py +2354 -0
  72. pyedb/grpc/database/control_file.py +1277 -0
  73. pyedb/grpc/database/definition/component_def.py +218 -0
  74. pyedb/grpc/database/definition/component_model.py +39 -0
  75. pyedb/grpc/database/definition/component_pin.py +32 -0
  76. pyedb/grpc/database/definition/materials.py +1207 -0
  77. pyedb/grpc/database/definition/n_port_component_model.py +34 -0
  78. pyedb/grpc/database/definition/package_def.py +227 -0
  79. pyedb/grpc/database/definition/padstack_def.py +842 -0
  80. pyedb/grpc/database/definitions.py +70 -0
  81. pyedb/grpc/database/general.py +43 -0
  82. pyedb/grpc/database/geometry/__init__.py +0 -0
  83. pyedb/grpc/database/geometry/arc_data.py +93 -0
  84. pyedb/grpc/database/geometry/point_3d_data.py +79 -0
  85. pyedb/grpc/database/geometry/point_data.py +30 -0
  86. pyedb/grpc/database/geometry/polygon_data.py +133 -0
  87. pyedb/grpc/database/hfss.py +1279 -0
  88. pyedb/grpc/database/hierarchy/__init__.py +0 -0
  89. pyedb/grpc/database/hierarchy/component.py +1301 -0
  90. pyedb/grpc/database/hierarchy/model.py +31 -0
  91. pyedb/grpc/database/hierarchy/netlist_model.py +30 -0
  92. pyedb/grpc/database/hierarchy/pin_pair_model.py +128 -0
  93. pyedb/grpc/database/hierarchy/pingroup.py +245 -0
  94. pyedb/grpc/database/hierarchy/s_parameter_model.py +33 -0
  95. pyedb/grpc/database/hierarchy/spice_model.py +48 -0
  96. pyedb/grpc/database/layers/__init__.py +0 -0
  97. pyedb/grpc/database/layers/layer.py +57 -0
  98. pyedb/grpc/database/layers/stackup_layer.py +410 -0
  99. pyedb/grpc/database/layout/__init__.py +0 -0
  100. pyedb/grpc/database/layout/cell.py +30 -0
  101. pyedb/grpc/database/layout/layout.py +196 -0
  102. pyedb/grpc/database/layout/voltage_regulator.py +149 -0
  103. pyedb/grpc/database/layout_validation.py +319 -0
  104. pyedb/grpc/database/modeler.py +1468 -0
  105. pyedb/grpc/database/net/__init__.py +0 -0
  106. pyedb/grpc/database/net/differential_pair.py +138 -0
  107. pyedb/grpc/database/net/extended_net.py +340 -0
  108. pyedb/grpc/database/net/net.py +198 -0
  109. pyedb/grpc/database/net/net_class.py +93 -0
  110. pyedb/grpc/database/nets.py +633 -0
  111. pyedb/grpc/database/padstacks.py +1500 -0
  112. pyedb/grpc/database/ports/__init__.py +0 -0
  113. pyedb/grpc/database/ports/ports.py +396 -0
  114. pyedb/grpc/database/primitive/__init__.py +3 -0
  115. pyedb/grpc/database/primitive/bondwire.py +181 -0
  116. pyedb/grpc/database/primitive/circle.py +75 -0
  117. pyedb/grpc/database/primitive/padstack_instance.py +1116 -0
  118. pyedb/grpc/database/primitive/path.py +346 -0
  119. pyedb/grpc/database/primitive/polygon.py +276 -0
  120. pyedb/grpc/database/primitive/primitive.py +739 -0
  121. pyedb/grpc/database/primitive/rectangle.py +146 -0
  122. pyedb/grpc/database/simulation_setup/__init__.py +0 -0
  123. pyedb/grpc/database/simulation_setup/adaptive_frequency.py +33 -0
  124. pyedb/grpc/database/simulation_setup/hfss_advanced_meshing_settings.py +32 -0
  125. pyedb/grpc/database/simulation_setup/hfss_advanced_settings.py +59 -0
  126. pyedb/grpc/database/simulation_setup/hfss_dcr_settings.py +35 -0
  127. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +61 -0
  128. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +78 -0
  129. pyedb/grpc/database/simulation_setup/hfss_simulation_settings.py +118 -0
  130. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +355 -0
  131. pyedb/grpc/database/simulation_setup/hfss_solver_settings.py +34 -0
  132. pyedb/grpc/database/simulation_setup/mesh_operation.py +34 -0
  133. pyedb/grpc/database/simulation_setup/raptor_x_advanced_settings.py +34 -0
  134. pyedb/grpc/database/simulation_setup/raptor_x_general_settings.py +33 -0
  135. pyedb/grpc/database/simulation_setup/raptor_x_simulation_settings.py +64 -0
  136. pyedb/grpc/database/simulation_setup/raptor_x_simulation_setup.py +125 -0
  137. pyedb/grpc/database/simulation_setup/siwave_dcir_simulation_setup.py +34 -0
  138. pyedb/grpc/database/simulation_setup/siwave_simulation_setup.py +119 -0
  139. pyedb/grpc/database/simulation_setup/sweep_data.py +32 -0
  140. pyedb/grpc/database/siwave.py +1023 -0
  141. pyedb/grpc/database/source_excitations.py +2572 -0
  142. pyedb/grpc/database/stackup.py +2574 -0
  143. pyedb/grpc/database/terminal/__init__.py +0 -0
  144. pyedb/grpc/database/terminal/bundle_terminal.py +218 -0
  145. pyedb/grpc/database/terminal/edge_terminal.py +51 -0
  146. pyedb/grpc/database/terminal/padstack_instance_terminal.py +171 -0
  147. pyedb/grpc/database/terminal/pingroup_terminal.py +162 -0
  148. pyedb/grpc/database/terminal/point_terminal.py +99 -0
  149. pyedb/grpc/database/terminal/terminal.py +470 -0
  150. pyedb/grpc/database/utility/__init__.py +3 -0
  151. pyedb/grpc/database/utility/constants.py +25 -0
  152. pyedb/grpc/database/utility/heat_sink.py +124 -0
  153. pyedb/grpc/database/utility/hfss_extent_info.py +448 -0
  154. pyedb/grpc/database/utility/layout_statistics.py +277 -0
  155. pyedb/grpc/database/utility/rlc.py +80 -0
  156. pyedb/grpc/database/utility/simulation_configuration.py +3305 -0
  157. pyedb/grpc/database/utility/sources.py +388 -0
  158. pyedb/grpc/database/utility/sweep_data_distribution.py +83 -0
  159. pyedb/grpc/database/utility/xml_control_file.py +1277 -0
  160. pyedb/grpc/edb.py +4151 -0
  161. pyedb/grpc/edb_init.py +481 -0
  162. pyedb/grpc/rpc_session.py +177 -0
  163. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +3 -2
  164. pyedb/ipc2581/ecad/cad_data/feature.py +4 -3
  165. pyedb/ipc2581/ecad/cad_data/layer_feature.py +32 -20
  166. pyedb/ipc2581/ecad/cad_data/outline.py +3 -2
  167. pyedb/ipc2581/ecad/cad_data/package.py +4 -3
  168. pyedb/ipc2581/ecad/cad_data/path.py +82 -31
  169. pyedb/ipc2581/ecad/cad_data/polygon.py +122 -60
  170. pyedb/ipc2581/ecad/cad_data/profile.py +13 -12
  171. pyedb/ipc2581/ecad/cad_data/step.py +53 -21
  172. pyedb/ipc2581/ipc2581.py +47 -49
  173. pyedb/modeler/geometry_operators.py +1 -1
  174. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/METADATA +5 -2
  175. pyedb-0.39.0.dist-info/RECORD +288 -0
  176. pyedb-0.38.0.dist-info/RECORD +0 -195
  177. /pyedb/dotnet/{edb_core → database}/__init__.py +0 -0
  178. /pyedb/dotnet/{application → database/cell}/__init__.py +0 -0
  179. /pyedb/dotnet/{edb_core/cell → database/cell/hierarchy}/__init__.py +0 -0
  180. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/netlist_model.py +0 -0
  181. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/pin_pair_model.py +0 -0
  182. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/s_parameter_model.py +0 -0
  183. /pyedb/dotnet/{edb_core → database}/cell/hierarchy/spice_model.py +0 -0
  184. /pyedb/dotnet/{edb_core → database}/cell/primitive/__init__.py +0 -0
  185. /pyedb/dotnet/{edb_core/cell/hierarchy → database/cell/terminal}/__init__.py +0 -0
  186. /pyedb/dotnet/{edb_core/cell/terminal → database/definition}/__init__.py +0 -0
  187. /pyedb/dotnet/{edb_core/definition → database/dotnet}/__init__.py +0 -0
  188. /pyedb/dotnet/{edb_core/dotnet → database/edb_data}/__init__.py +0 -0
  189. /pyedb/dotnet/{edb_core → database}/edb_data/design_options.py +0 -0
  190. /pyedb/dotnet/{edb_core → database}/edb_data/edbvalue.py +0 -0
  191. /pyedb/dotnet/{edb_core → database}/edb_data/layer_data.py +0 -0
  192. /pyedb/dotnet/{edb_core → database}/edb_data/utilities.py +0 -0
  193. /pyedb/dotnet/{edb_core → database}/general.py +0 -0
  194. /pyedb/dotnet/{edb_core/edb_data → database/geometry}/__init__.py +0 -0
  195. /pyedb/dotnet/{edb_core → database}/geometry/point_data.py +0 -0
  196. /pyedb/dotnet/{edb_core → database}/sim_setup_data/__init__.py +0 -0
  197. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/__init__.py +0 -0
  198. /pyedb/dotnet/{edb_core → database}/sim_setup_data/data/adaptive_frequency_data.py +0 -0
  199. /pyedb/dotnet/{edb_core/geometry → database/sim_setup_data/io}/__init__.py +0 -0
  200. /pyedb/dotnet/{edb_core → database}/sim_setup_data/io/siwave.py +0 -0
  201. /pyedb/dotnet/{edb_core → database}/utilities/__init__.py +0 -0
  202. /pyedb/dotnet/{edb_core → database}/utilities/heatsink.py +0 -0
  203. /pyedb/{dotnet/edb_core/sim_setup_data/io → grpc/database/definition}/__init__.py +0 -0
  204. {pyedb-0.38.0.dist-info → pyedb-0.39.0.dist-info}/LICENSE +0 -0
  205. {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