pyedb 0.28.0__py3-none-any.whl → 0.29.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.
@@ -24,37 +24,93 @@ from pathlib import Path
24
24
 
25
25
 
26
26
  class CfgSParameterModel:
27
- def __init__(self, pdata, path_lib, sparam_dict):
28
- self._pedb = pdata._pedb
27
+ def __init__(self, **kwargs):
28
+ self.name = kwargs.get("name", "")
29
+ self.component_definition = kwargs.get("component_definition", "")
30
+ self.file_path = kwargs.get("file_path", "")
31
+ self.apply_to_all = kwargs.get("apply_to_all", False)
32
+ self.components = kwargs.get("components", [])
33
+ self.reference_net = kwargs.get("reference_net", "")
34
+ self.reference_net_per_component = kwargs.get("reference_net_per_component", {})
35
+ self.pin_order = kwargs.get("pin_order", None)
36
+
37
+
38
+ class CfgSParameters:
39
+ def __init__(self, pedb, data, path_lib=None):
40
+ self._pedb = pedb
29
41
  self.path_libraries = path_lib
30
- self._sparam_dict = sparam_dict
31
- self.name = self._sparam_dict.get("name", "")
32
- self.component_definition = self._sparam_dict.get("component_definition", "")
33
- self.file_path = self._sparam_dict.get("file_path", "")
34
- self.apply_to_all = self._sparam_dict.get("apply_to_all", False)
35
- self.components = self._sparam_dict.get("components", [])
36
- self.reference_net = self._sparam_dict.get("reference_net", "")
37
- self.reference_net_per_component = self._sparam_dict.get("reference_net_per_component", {})
42
+ self.s_parameters_models = [CfgSParameterModel(**i) for i in data]
38
43
 
39
44
  def apply(self):
40
- fpath = self.file_path
41
- if not Path(fpath).anchor:
42
- fpath = str(Path(self.path_libraries) / fpath)
43
- comp_def = self._pedb.definitions.component[self.component_definition]
44
- comp_def.add_n_port_model(fpath, self.name)
45
- comp_list = dict()
46
- if self.apply_to_all:
47
- comp_list.update(
48
- {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in self.components}
49
- )
50
- else:
51
- comp_list.update(
52
- {refdes: comp for refdes, comp in comp_def.components.items() if refdes in self.components}
53
- )
45
+ for s_param in self.s_parameters_models:
46
+ fpath = s_param.file_path
47
+ if not Path(fpath).anchor:
48
+ fpath = str(Path(self.path_libraries) / fpath)
49
+ comp_def = self._pedb.definitions.component[s_param.component_definition]
50
+ if s_param.pin_order:
51
+ comp_def.set_properties(pin_order=s_param.pin_order)
52
+ comp_def.add_n_port_model(fpath, s_param.name)
53
+ comp_list = dict()
54
+ if s_param.apply_to_all:
55
+ comp_list.update(
56
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes not in s_param.components}
57
+ )
58
+ else:
59
+ comp_list.update(
60
+ {refdes: comp for refdes, comp in comp_def.components.items() if refdes in s_param.components}
61
+ )
54
62
 
55
- for refdes, comp in comp_list.items():
56
- if refdes in self.reference_net_per_component:
57
- ref_net = self.reference_net_per_component[refdes]
63
+ for refdes, comp in comp_list.items():
64
+ if refdes in s_param.reference_net_per_component:
65
+ ref_net = s_param.reference_net_per_component[refdes]
66
+ else:
67
+ ref_net = s_param.reference_net
68
+ comp.use_s_parameter_model(s_param.name, reference_net=ref_net)
69
+
70
+ def get_data_from_db(self):
71
+ db_comp_def = self._pedb.definitions.component
72
+ for name, compdef_obj in db_comp_def.items():
73
+ nport_models = compdef_obj.component_models
74
+ if not nport_models:
75
+ continue
58
76
  else:
59
- ref_net = self.reference_net
60
- comp.use_s_parameter_model(self.name, reference_net=ref_net)
77
+ pin_order = compdef_obj.get_properties()["pin_order"]
78
+ temp_comps = compdef_obj.components
79
+ for model_name, model_obj in nport_models.items():
80
+ temp_comp_list = []
81
+ reference_net_per_component = {}
82
+ for i in temp_comps.values():
83
+ s_param_model = i.model_properties.get("s_parameter_model")
84
+ if s_param_model:
85
+ if s_param_model["model_name"] == model_name:
86
+ temp_comp_list.append(i.refdes)
87
+ reference_net_per_component[i.refdes] = s_param_model["reference_net"]
88
+ else:
89
+ continue
90
+
91
+ self.s_parameters_models.append(
92
+ CfgSParameterModel(
93
+ name=model_name,
94
+ component_definition=name,
95
+ file_path=model_obj.reference_file,
96
+ apply_to_all=False,
97
+ components=temp_comp_list,
98
+ reference_net_per_component=reference_net_per_component,
99
+ pin_order=pin_order,
100
+ )
101
+ )
102
+
103
+ data = []
104
+ for i in self.s_parameters_models:
105
+ data.append(
106
+ {
107
+ "name": i.name,
108
+ "component_definition": i.component_definition,
109
+ "file_path": i.file_path,
110
+ "apply_to_all": i.apply_to_all,
111
+ "components": i.components,
112
+ "reference_net_per_component": i.reference_net_per_component,
113
+ "pin_order": i.pin_order,
114
+ }
115
+ )
116
+ return data
@@ -117,10 +117,6 @@ class Configuration:
117
117
  # Configure components
118
118
  self.cfg_data.components.apply()
119
119
 
120
- # Configure padstacks
121
- if self.cfg_data.padstacks:
122
- self.cfg_data.padstacks.apply()
123
-
124
120
  # Configure pin groups
125
121
  self.cfg_data.pin_groups.apply()
126
122
 
@@ -145,9 +141,12 @@ class Configuration:
145
141
  else:
146
142
  self.cfg_data.stackup.apply()
147
143
 
144
+ # Configure padstacks
145
+ if self.cfg_data.padstacks:
146
+ self.cfg_data.padstacks.apply()
147
+
148
148
  # Configure S-parameter
149
- for s_parameter_model in self.cfg_data.s_parameters:
150
- s_parameter_model.apply()
149
+ self.cfg_data.s_parameters.apply()
151
150
 
152
151
  # Configure SPICE models
153
152
  for spice_model in self.cfg_data.spice_models:
@@ -293,6 +292,10 @@ class Configuration:
293
292
  data["operations"] = self.cfg_data.operations.get_data_from_db()
294
293
  if kwargs.get("padstacks", False):
295
294
  data["padstacks"] = self.cfg_data.padstacks.get_data_from_db()
295
+ if kwargs.get("s_parameters", False):
296
+ data["s_parameters"] = self.cfg_data.s_parameters.get_data_from_db()
297
+ if kwargs.get("boundaries", False):
298
+ data["boundaries"] = self.cfg_data.boundaries.get_data_from_db()
296
299
 
297
300
  return data
298
301
 
@@ -307,6 +310,10 @@ class Configuration:
307
310
  nets=True,
308
311
  pin_groups=True,
309
312
  operations=True,
313
+ components=True,
314
+ boundaries=True,
315
+ s_parameters=True,
316
+ padstacks=True,
310
317
  ):
311
318
  """Export the configuration data from layout to a file.
312
319
 
@@ -330,22 +337,39 @@ class Configuration:
330
337
  Whether to export pin groups.
331
338
  operations : bool
332
339
  Whether to export operations.
340
+ components : bool
341
+ Whether to export component.
342
+ boundaries : bool
343
+ Whether to export boundaries.
344
+ s_parameters : bool
345
+ Whether to export s_parameters.
346
+ padstacks : bool
347
+ Whether to export padstacks.
333
348
  Returns
334
349
  -------
335
350
  bool
336
351
  """
337
- file_path = file_path if isinstance(file_path, Path) else Path(file_path)
338
- file_path = file_path if file_path.suffix == ".json" else file_path.with_suffix(".json")
339
352
  data = self.get_data_from_db(
340
353
  stackup=stackup,
341
354
  package_definitions=package_definitions,
342
- setups=setups,
355
+ setups=False,
343
356
  sources=sources,
344
357
  ports=ports,
345
358
  nets=nets,
346
359
  pin_groups=pin_groups,
347
360
  operations=operations,
361
+ components=components,
362
+ boundaries=boundaries,
363
+ s_parameters=s_parameters,
364
+ padstacks=padstacks,
348
365
  )
366
+
367
+ file_path = file_path if isinstance(file_path, Path) else Path(file_path)
368
+ file_path = file_path.with_suffix(".json") if file_path.suffix == "" else file_path
369
+
349
370
  with open(file_path, "w") as f:
350
- json.dump(data, f, ensure_ascii=False, indent=4)
371
+ if file_path.suffix == ".json":
372
+ json.dump(data, f, ensure_ascii=False, indent=4)
373
+ else:
374
+ toml.dump(data, f)
351
375
  return True if os.path.isfile(file_path) else False
pyedb/dotnet/edb.py CHANGED
@@ -1630,6 +1630,14 @@ class Edb(Database):
1630
1630
  )
1631
1631
  else:
1632
1632
  obj_data = i.Expand(expansion_size, tolerance, round_corner, round_extension)
1633
+ if inlcude_voids_in_extents and "PolygonData" not in str(i) and i.has_voids and obj_data:
1634
+ for void in i.voids:
1635
+ void_data = void.primitive_object.GetPolygonData().Expand(
1636
+ -1 * expansion_size, tolerance, round_corner, round_extension
1637
+ )
1638
+ if void_data:
1639
+ for v in list(void_data):
1640
+ obj_data[0].AddHole(v)
1633
1641
  if obj_data:
1634
1642
  if not inlcude_voids_in_extents:
1635
1643
  unite_polys.extend(list(obj_data))
@@ -2209,9 +2217,9 @@ class Edb(Database):
2209
2217
  pins_to_preserve.extend([i.id for i in el.pins.values()])
2210
2218
  nets_to_preserve.extend(el.nets)
2211
2219
  if include_pingroups:
2212
- for reference in reference_list:
2213
- for pin in self.nets.nets[reference].padstack_instances:
2214
- if pin.pingroups:
2220
+ for pingroup in self.padstacks.pingroups:
2221
+ for pin in pingroup.pins.values():
2222
+ if pin.net_name in reference_list:
2215
2223
  pins_to_preserve.append(pin.id)
2216
2224
  if check_terminals:
2217
2225
  terms = [
@@ -2280,12 +2288,12 @@ class Edb(Database):
2280
2288
  if extent_type in ["Conforming", self.edb_api.geometry.extent_type.Conforming, 1]:
2281
2289
  if extent_defeature > 0:
2282
2290
  _poly = _poly.Defeature(extent_defeature)
2283
-
2284
2291
  _poly1 = _poly.CreateFromArcs(_poly.GetArcData(), True)
2285
2292
  if inlcude_voids_in_extents:
2286
2293
  for hole in list(_poly.Holes):
2287
2294
  if hole.Area() >= 0.05 * _poly1.Area():
2288
2295
  _poly1.AddHole(hole)
2296
+ self.logger.info(f"Number of voids included:{len(list(_poly1.Holes))}")
2289
2297
  _poly = _poly1
2290
2298
  if not _poly or _poly.IsNull():
2291
2299
  self._logger.error("Failed to create Extent.")
@@ -33,6 +33,7 @@ from pyedb.dotnet.edb_core.cell.hierarchy.s_parameter_model import SparamModel
33
33
  from pyedb.dotnet.edb_core.cell.hierarchy.spice_model import SpiceModel
34
34
  from pyedb.dotnet.edb_core.definition.package_def import PackageDef
35
35
  from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
36
+ from pyedb.dotnet.edb_core.general import pascal_to_snake, snake_to_pascal
36
37
 
37
38
  try:
38
39
  import numpy as np
@@ -1008,3 +1009,201 @@ class EDBComponent(Group):
1008
1009
  )
1009
1010
  void.is_negative = True
1010
1011
  return True
1012
+
1013
+ @property
1014
+ def model_properties(self):
1015
+ pp = {}
1016
+ c_p = self.component_property
1017
+ model = c_p.GetModel().Clone()
1018
+ netlist_model = {}
1019
+ pin_pair_model = []
1020
+ s_parameter_model = {}
1021
+ spice_model = {}
1022
+ if model.GetModelType().ToString() == "NetlistModel":
1023
+ netlist_model["netlist"] = model.GetNetlist()
1024
+ elif model.GetModelType().ToString() == "PinPairModel":
1025
+ temp = {}
1026
+ for i in model.PinPairs:
1027
+ temp["first_pin"] = i.FirstPin
1028
+ temp["second_pin"] = i.SecondPin
1029
+ rlc = model.GetPinPairRlc(i)
1030
+ temp["is_parallel"] = rlc.IsParallel
1031
+ temp["resistance"] = rlc.R.ToString()
1032
+ temp["resistance_enabled"] = rlc.REnabled
1033
+ temp["inductance"] = rlc.L.ToString()
1034
+ temp["inductance_enabled"] = rlc.LEnabled
1035
+ temp["capacitance"] = rlc.C.ToString()
1036
+ temp["capacitance_enabled"] = rlc.CEnabled
1037
+ pin_pair_model.append(temp)
1038
+ elif model.GetModelType().ToString() == "SParameterModel":
1039
+ s_parameter_model["reference_net"] = model.GetReferenceNet()
1040
+ s_parameter_model["model_name"] = model.GetComponentModelName()
1041
+ elif model.GetModelType().ToString() == "SPICEModel":
1042
+ spice_model["model_name"] = model.GetModelName()
1043
+ spice_model["model_path"] = model.GetModelPath()
1044
+ spice_model["sub_circuit"] = model.GetSubCkt()
1045
+ spice_model["terminal_pairs"] = [[i, j] for i, j in dict(model.GetTerminalPinPairs()).items()]
1046
+
1047
+ if netlist_model:
1048
+ pp["netlist_model"] = netlist_model
1049
+ if pin_pair_model:
1050
+ pp["pin_pair_model"] = pin_pair_model
1051
+ if s_parameter_model:
1052
+ pp["s_parameter_model"] = s_parameter_model
1053
+ if spice_model:
1054
+ pp["spice_model"] = spice_model
1055
+ return pp
1056
+
1057
+ @model_properties.setter
1058
+ def model_properties(self, kwargs):
1059
+ netlist_model = kwargs.get("netlist_model")
1060
+ pin_pair_model = kwargs.get("pin_pair_model")
1061
+ s_parameter_model = kwargs.get("s_parameter_model")
1062
+ spice_model = kwargs.get("spice_model")
1063
+
1064
+ c_p = self.component_property
1065
+ if netlist_model:
1066
+ m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
1067
+ m.SetNetlist(netlist_model["netlist"])
1068
+ c_p.SetModel(m)
1069
+ self.component_property = c_p
1070
+ elif pin_pair_model:
1071
+ m = self._pedb._edb.Cell.Hierarchy.PinPairModel()
1072
+ for i in pin_pair_model:
1073
+ p = self._pedb._edb.Utility.PinPair(str(i["first_pin"]), str(i["second_pin"]))
1074
+ rlc = self._pedb._edb.Utility.Rlc(
1075
+ self._pedb.edb_value(i["resistance"]),
1076
+ i["resistance_enabled"],
1077
+ self._pedb.edb_value(i["inductance"]),
1078
+ i["inductance_enabled"],
1079
+ self._pedb.edb_value(i["capacitance"]),
1080
+ i["capacitance_enabled"],
1081
+ i["is_parallel"],
1082
+ )
1083
+ m.SetPinPairRlc(p, rlc)
1084
+ c_p.SetModel(m)
1085
+ self.component_property = c_p
1086
+ elif s_parameter_model:
1087
+ m = self._pedb._edb.Cell.Hierarchy.SParameterModel()
1088
+ m.SetComponentModelName(s_parameter_model["model_name"])
1089
+ m.SetReferenceNet(s_parameter_model["reference_net"])
1090
+ c_p.SetModel(m)
1091
+ self.component_property = c_p
1092
+ elif spice_model:
1093
+ self.assign_spice_model(
1094
+ spice_model["model_path"],
1095
+ spice_model["model_name"],
1096
+ spice_model["sub_circuit"],
1097
+ spice_model["terminal_pairs"],
1098
+ )
1099
+
1100
+ @property
1101
+ def ic_die_properties(self):
1102
+ temp = dict()
1103
+ cp = self.component_property
1104
+ c_type = self.type.lower()
1105
+ if not c_type == "ic":
1106
+ return temp
1107
+ else:
1108
+ ic_die_prop = cp.GetDieProperty().Clone()
1109
+ die_type = pascal_to_snake(ic_die_prop.GetType().ToString())
1110
+ temp["type"] = die_type
1111
+ if not die_type == "no_die":
1112
+ temp["orientation"] = pascal_to_snake(ic_die_prop.GetOrientation())
1113
+ if die_type == "wire_bond":
1114
+ temp["height"] = ic_die_prop.GetHeightValue().ToString()
1115
+ return temp
1116
+
1117
+ @ic_die_properties.setter
1118
+ def ic_die_properties(self, kwargs):
1119
+ cp = self.component_property
1120
+ c_type = self.type.lower()
1121
+ if not c_type == "ic":
1122
+ return
1123
+ else:
1124
+ ic_die_prop = cp.GetDieProperty().Clone()
1125
+ die_type = kwargs.get("type")
1126
+ if not die_type == "no_die":
1127
+ orientation = kwargs.get("orientation")
1128
+ if orientation:
1129
+ ic_die_prop.SetOrientation(getattr(self._edb.definition.DieType, snake_to_pascal(die_type)))
1130
+ if die_type == "wire_bond":
1131
+ height = kwargs.get("height")
1132
+ if height:
1133
+ ic_die_prop.SetHeight(self._pedb.edb_value(height))
1134
+ cp.SetDieProperty(ic_die_prop)
1135
+ self.component_property = cp
1136
+
1137
+ @property
1138
+ def solder_ball_properties(self):
1139
+ temp = dict()
1140
+ cp = self.component_property
1141
+ c_type = self.type.lower()
1142
+ if c_type not in ["io", "other"]:
1143
+ return temp
1144
+ else:
1145
+ solder_ball_prop = cp.GetSolderBallProperty().Clone()
1146
+ _, diam, mid_diam = solder_ball_prop.GetDiameterValue()
1147
+ height = solder_ball_prop.GetHeightValue().ToString()
1148
+ shape = solder_ball_prop.GetShape().ToString()
1149
+ uses_solder_ball = solder_ball_prop.UsesSolderball()
1150
+ temp["uses_solder_ball"] = uses_solder_ball
1151
+ temp["shape"] = pascal_to_snake(shape)
1152
+ temp["diameter"] = diam.ToString()
1153
+ temp["mid_diameter"] = mid_diam.ToString()
1154
+ temp["height"] = height
1155
+ return temp
1156
+
1157
+ @solder_ball_properties.setter
1158
+ def solder_ball_properties(self, kwargs):
1159
+ cp = self.component_property
1160
+ solder_ball_prop = cp.GetSolderBallProperty().Clone()
1161
+ shape = kwargs.get("shape")
1162
+ if shape:
1163
+ solder_ball_prop.SetShape(getattr(self._edb.definition.SolderballShape, snake_to_pascal(shape)))
1164
+ if shape == "cylinder":
1165
+ diameter = kwargs["diameter"]
1166
+ solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(diameter))
1167
+ elif shape == "spheroid":
1168
+ diameter = kwargs["diameter"]
1169
+ mid_diameter = kwargs["mid_diameter"]
1170
+ solder_ball_prop.SetDiameter(self._pedb.edb_value(diameter), self._pedb.edb_value(mid_diameter))
1171
+ else:
1172
+ return
1173
+ solder_ball_prop.SetHeight(self._get_edb_value(kwargs["height"]))
1174
+ cp.SetSolderBallProperty(solder_ball_prop)
1175
+ self.component_property = cp
1176
+
1177
+ @property
1178
+ def port_properties(self):
1179
+ temp = dict()
1180
+ cp = self.component_property
1181
+ c_type = self.type.lower()
1182
+ if c_type not in ["ic", "io", "other"]:
1183
+ return temp
1184
+ else:
1185
+ port_prop = cp.GetPortProperty().Clone()
1186
+ reference_height = port_prop.GetReferenceHeightValue().ToString()
1187
+ reference_size_auto = port_prop.GetReferenceSizeAuto()
1188
+ _, reference_size_x, reference_size_y = port_prop.GetReferenceSize()
1189
+ temp["reference_height"] = reference_height
1190
+ temp["reference_size_auto"] = reference_size_auto
1191
+ temp["reference_size_x"] = str(reference_size_x)
1192
+ temp["reference_size_y"] = str(reference_size_y)
1193
+ return temp
1194
+
1195
+ @port_properties.setter
1196
+ def port_properties(self, kwargs):
1197
+ cp = self.component_property
1198
+ port_prop = cp.GetPortProperty().Clone()
1199
+ height = kwargs.get("reference_height")
1200
+ if height:
1201
+ port_prop.SetReferenceHeight(self._pedb.edb_value(height))
1202
+ reference_size_auto = kwargs.get("reference_size_auto")
1203
+ if reference_size_auto:
1204
+ port_prop.SetReferenceSizeAuto(reference_size_auto)
1205
+ reference_size_x = kwargs.get("reference_size_x", 0)
1206
+ reference_size_y = kwargs.get("reference_size_y", 0)
1207
+ port_prop.SetReferenceSize(self._pedb.edb_value(reference_size_x), self._pedb.edb_value(reference_size_y))
1208
+ cp.SetPortProperty(port_prop)
1209
+ self.component_property = cp
@@ -160,6 +160,8 @@ class Primitive(Connectable):
160
160
  -------
161
161
  float
162
162
  """
163
+ if "GetPolygonData" not in dir(self._edb_object):
164
+ return 0
163
165
  area = self._edb_object.GetPolygonData().Area()
164
166
  if include_voids:
165
167
  for el in self._edb_object.Voids:
@@ -223,9 +223,10 @@ class Terminal(Connectable):
223
223
  """Get reference terminal."""
224
224
 
225
225
  edb_terminal = self._edb_object.GetReferenceTerminal()
226
- terminal = self._pedb.terminals[edb_terminal.GetName()]
227
- if not terminal.is_null:
228
- return terminal
226
+ if not edb_terminal.IsNull():
227
+ return self._pedb.terminals[edb_terminal.GetName()]
228
+ else:
229
+ return None
229
230
 
230
231
  @ref_terminal.setter
231
232
  def ref_terminal(self, value):
@@ -23,6 +23,7 @@
23
23
  import os
24
24
 
25
25
  from pyedb.dotnet.edb_core.definition.component_model import NPortComponentModel
26
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
26
27
  from pyedb.dotnet.edb_core.utilities.obj_base import ObjBase
27
28
 
28
29
 
@@ -171,7 +172,7 @@ class EDBComponentDef(ObjBase):
171
172
  def component_models(self):
172
173
  temp = {}
173
174
  for i in list(self._edb_object.GetComponentModels()):
174
- temp_type = i.ToString().split(".")[0]
175
+ temp_type = i.ToString().split(".")[-1]
175
176
  if temp_type == "NPortComponentModel":
176
177
  edb_object = NPortComponentModel(self._pedb, i)
177
178
  temp[edb_object.name] = edb_object
@@ -197,3 +198,18 @@ class EDBComponentDef(ObjBase):
197
198
  footprint_cell = self._pedb._active_cell.cell.Create(self._pedb.active_db, cell_type, name)
198
199
  edb_object = self._pedb.edb_api.definition.ComponentDef.Create(self._pedb.active_db, name, footprint_cell)
199
200
  return EDBComponentDef(self._pedb, edb_object)
201
+
202
+ def get_properties(self):
203
+ data = {}
204
+ temp = []
205
+ for i in list(self._edb_object.ComponentDefPins):
206
+ temp.append(i.GetName())
207
+ data["pin_order"] = temp
208
+ return data
209
+
210
+ def set_properties(self, **kwargs):
211
+ pin_order = kwargs.get("pin_order")
212
+ if pin_order:
213
+ old = {i.GetName(): i for i in list(self._edb_object.ComponentDefPins)}
214
+ temp = convert_py_list_to_net_list([old[str(i)] for i in pin_order])
215
+ self._edb_object.ReorderPins(temp)
@@ -30,10 +30,6 @@ class ComponentModel(ObjBase):
30
30
  super().__init__(pedb, edb_object)
31
31
  self._model_type_mapping = {"PinPairModel": self._pedb.edb_api.cell}
32
32
 
33
- def name(self):
34
- """Name of the component model."""
35
- return self._edb_object.GetName()
36
-
37
33
 
38
34
  class NPortComponentModel(ComponentModel):
39
35
  """Class for n-port component models."""
@@ -22,7 +22,7 @@
22
22
 
23
23
  from pyedb.dotnet.edb_core.edb_data.edbvalue import EdbValue
24
24
  from pyedb.dotnet.edb_core.edb_data.primitives_data import cast
25
- from pyedb.dotnet.edb_core.general import convert_pytuple_to_nettuple
25
+ from pyedb.dotnet.edb_core.general import convert_pytuple_to_nettuple, pascal_to_snake
26
26
 
27
27
 
28
28
  class HfssExtentInfo:
@@ -192,7 +192,7 @@ class HfssExtentInfo:
192
192
  @property
193
193
  def dielectric_extent_type(self):
194
194
  """Dielectric extent type."""
195
- return self._edb_hfss_extent_info.DielectricExtentType.ToString().lower()
195
+ return pascal_to_snake(self._edb_hfss_extent_info.DielectricExtentType.ToString())
196
196
 
197
197
  @dielectric_extent_type.setter
198
198
  def dielectric_extent_type(self, value):
@@ -204,7 +204,7 @@ class HfssExtentInfo:
204
204
  @property
205
205
  def extent_type(self):
206
206
  """Extent type."""
207
- return self._edb_hfss_extent_info.ExtentType.ToString().lower()
207
+ return pascal_to_snake(self._edb_hfss_extent_info.ExtentType.ToString())
208
208
 
209
209
  @extent_type.setter
210
210
  def extent_type(self, value):
@@ -19,7 +19,6 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
-
23
22
  from pyedb.dotnet.edb_core.dotnet.database import (
24
23
  DifferentialPairDotNet,
25
24
  ExtendedNetDotNet,
@@ -58,7 +57,10 @@ class EDBNetsData(NetDotNet):
58
57
  -------
59
58
  list of :class:`pyedb.dotnet.edb_core.edb_data.primitives_data.EDBPrimitives`
60
59
  """
61
- return [self._app.layout.find_object_by_id(i.GetId()) for i in self.net_object.Primitives]
60
+ from pyedb.dotnet.edb_core.cell.layout import primitive_cast
61
+
62
+ return [primitive_cast(self._app, i) for i in self.net_object.Primitives]
63
+ # return [self._app.layout.find_object_by_id(i.GetId()) for i in self.net_object.Primitives]
62
64
 
63
65
  @property
64
66
  def padstack_instances(self):
@@ -67,10 +69,11 @@ class EDBNetsData(NetDotNet):
67
69
  Returns
68
70
  -------
69
71
  list of :class:`pyedb.dotnet.edb_core.edb_data.padstacks_data.EDBPadstackInstance`"""
70
- name = self.name
71
- return [
72
- EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances if i.GetNet().GetName() == name
73
- ]
72
+ # name = self.name
73
+ # return [
74
+ # EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances if i.GetNet().GetName() == name
75
+ # ]
76
+ return [EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances]
74
77
 
75
78
  @property
76
79
  def components(self):
@@ -133,7 +136,7 @@ class EDBNetsData(NetDotNet):
133
136
  Whether to show the plot or not. Default is `True`.
134
137
  """
135
138
 
136
- self._app.nets.plot(
139
+ return self._app.nets.plot(
137
140
  self.name,
138
141
  layers=layers,
139
142
  show_legend=show_legend,
@@ -1672,6 +1672,56 @@ class EDBPadstackInstance(Primitive):
1672
1672
  else:
1673
1673
  return
1674
1674
 
1675
+ @property
1676
+ def backdrill_parameters(self):
1677
+ data = {}
1678
+ flag, drill_to_layer, offset, diameter = self._edb_object.GetBackDrillParametersLayerValue(
1679
+ self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer),
1680
+ self._pedb.edb_value(0),
1681
+ self._pedb.edb_value(0.0),
1682
+ True,
1683
+ )
1684
+ if flag:
1685
+ if drill_to_layer.GetName():
1686
+ data["from_bottom"] = {
1687
+ "drill_to_layer": drill_to_layer.GetName(),
1688
+ "diameter": diameter.ToString(),
1689
+ "stub_length": offset.ToString(),
1690
+ }
1691
+ flag, drill_to_layer, offset, diameter = self._edb_object.GetBackDrillParametersLayerValue(
1692
+ self._pedb.edb_api.cell.layer("", self._pedb.edb_api.cell.layer_type.SignalLayer),
1693
+ self._pedb.edb_value(0),
1694
+ self._pedb.edb_value(0.0),
1695
+ False,
1696
+ )
1697
+ if flag:
1698
+ if drill_to_layer.GetName():
1699
+ data["from_top"] = {
1700
+ "drill_to_layer": drill_to_layer.GetName(),
1701
+ "diameter": diameter.ToString(),
1702
+ "stub_length": offset.ToString(),
1703
+ }
1704
+ return data
1705
+
1706
+ @backdrill_parameters.setter
1707
+ def backdrill_parameters(self, params):
1708
+ from_bottom = params.get("from_bottom")
1709
+ if from_bottom:
1710
+ self._edb_object.SetBackDrillParameters(
1711
+ self._pedb.stackup.layers[from_bottom.get("drill_to_layer")]._edb_object,
1712
+ self._pedb.edb_value(from_bottom.get("stub_length")),
1713
+ self._pedb.edb_value(from_bottom.get("diameter")),
1714
+ True,
1715
+ )
1716
+ from_top = params.get("from_top")
1717
+ if from_top:
1718
+ self._edb_object.SetBackDrillParameters(
1719
+ self._pedb.stackup.layers[from_top.get("drill_to_layer")]._edb_object,
1720
+ self._pedb.edb_value(from_top.get("stub_length")),
1721
+ self._pedb.edb_value(from_top.get("diameter")),
1722
+ False,
1723
+ )
1724
+
1675
1725
  def set_backdrill_bottom(self, drill_depth, drill_diameter, offset=0.0):
1676
1726
  """Set backdrill from bottom.
1677
1727