pyedb 0.2.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 (128) hide show
  1. pyedb/__init__.py +17 -0
  2. pyedb/dotnet/__init__.py +0 -0
  3. pyedb/dotnet/application/Variables.py +2261 -0
  4. pyedb/dotnet/application/__init__.py +0 -0
  5. pyedb/dotnet/clr_module.py +103 -0
  6. pyedb/dotnet/edb.py +4237 -0
  7. pyedb/dotnet/edb_core/__init__.py +1 -0
  8. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  9. pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
  10. pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
  11. pyedb/dotnet/edb_core/components.py +2669 -0
  12. pyedb/dotnet/edb_core/configuration.py +423 -0
  13. pyedb/dotnet/edb_core/definition/__init__.py +0 -0
  14. pyedb/dotnet/edb_core/definition/component_def.py +166 -0
  15. pyedb/dotnet/edb_core/definition/component_model.py +30 -0
  16. pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
  17. pyedb/dotnet/edb_core/definition/definitions.py +12 -0
  18. pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
  19. pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
  20. pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
  21. pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
  22. pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
  24. pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
  25. pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
  26. pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
  27. pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
  28. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
  29. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
  30. pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
  31. pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
  32. pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
  33. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
  34. pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
  35. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
  36. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
  37. pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
  38. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
  39. pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
  40. pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
  41. pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
  42. pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
  43. pyedb/dotnet/edb_core/general.py +181 -0
  44. pyedb/dotnet/edb_core/hfss.py +1646 -0
  45. pyedb/dotnet/edb_core/layout.py +1244 -0
  46. pyedb/dotnet/edb_core/layout_validation.py +272 -0
  47. pyedb/dotnet/edb_core/materials.py +939 -0
  48. pyedb/dotnet/edb_core/net_class.py +335 -0
  49. pyedb/dotnet/edb_core/nets.py +1215 -0
  50. pyedb/dotnet/edb_core/padstack.py +1389 -0
  51. pyedb/dotnet/edb_core/siwave.py +1427 -0
  52. pyedb/dotnet/edb_core/stackup.py +2703 -0
  53. pyedb/edb_logger.py +396 -0
  54. pyedb/generic/__init__.py +0 -0
  55. pyedb/generic/constants.py +1063 -0
  56. pyedb/generic/data_handlers.py +320 -0
  57. pyedb/generic/design_types.py +104 -0
  58. pyedb/generic/filesystem.py +150 -0
  59. pyedb/generic/general_methods.py +1535 -0
  60. pyedb/generic/plot.py +1840 -0
  61. pyedb/generic/process.py +285 -0
  62. pyedb/generic/settings.py +224 -0
  63. pyedb/ipc2581/__init__.py +0 -0
  64. pyedb/ipc2581/bom/__init__.py +0 -0
  65. pyedb/ipc2581/bom/bom.py +21 -0
  66. pyedb/ipc2581/bom/bom_item.py +32 -0
  67. pyedb/ipc2581/bom/characteristics.py +37 -0
  68. pyedb/ipc2581/bom/refdes.py +16 -0
  69. pyedb/ipc2581/content/__init__.py +0 -0
  70. pyedb/ipc2581/content/color.py +38 -0
  71. pyedb/ipc2581/content/content.py +55 -0
  72. pyedb/ipc2581/content/dictionary_color.py +29 -0
  73. pyedb/ipc2581/content/dictionary_fill.py +28 -0
  74. pyedb/ipc2581/content/dictionary_line.py +30 -0
  75. pyedb/ipc2581/content/entry_color.py +13 -0
  76. pyedb/ipc2581/content/entry_line.py +14 -0
  77. pyedb/ipc2581/content/fill.py +15 -0
  78. pyedb/ipc2581/content/layer_ref.py +10 -0
  79. pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
  80. pyedb/ipc2581/ecad/__init__.py +0 -0
  81. pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
  82. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
  83. pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
  84. pyedb/ipc2581/ecad/cad_data/component.py +41 -0
  85. pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
  86. pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
  87. pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
  88. pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
  89. pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
  90. pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
  91. pyedb/ipc2581/ecad/cad_data/package.py +104 -0
  92. pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
  93. pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
  94. pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
  95. pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
  96. pyedb/ipc2581/ecad/cad_data/path.py +89 -0
  97. pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
  98. pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
  99. pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
  100. pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
  101. pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
  102. pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
  103. pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
  104. pyedb/ipc2581/ecad/cad_data/step.py +275 -0
  105. pyedb/ipc2581/ecad/cad_header.py +33 -0
  106. pyedb/ipc2581/ecad/ecad.py +19 -0
  107. pyedb/ipc2581/ecad/spec.py +46 -0
  108. pyedb/ipc2581/history_record.py +37 -0
  109. pyedb/ipc2581/ipc2581.py +387 -0
  110. pyedb/ipc2581/logistic_header.py +25 -0
  111. pyedb/misc/__init__.py +0 -0
  112. pyedb/misc/aedtlib_personalib_install.py +14 -0
  113. pyedb/misc/downloads.py +322 -0
  114. pyedb/misc/misc.py +67 -0
  115. pyedb/misc/pyedb.runtimeconfig.json +13 -0
  116. pyedb/misc/siw_feature_config/__init__.py +0 -0
  117. pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
  118. pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
  119. pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
  120. pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
  121. pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
  122. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
  123. pyedb/misc/utilities.py +27 -0
  124. pyedb/modeler/geometry_operators.py +2082 -0
  125. pyedb-0.2.0.dist-info/LICENSE +21 -0
  126. pyedb-0.2.0.dist-info/METADATA +208 -0
  127. pyedb-0.2.0.dist-info/RECORD +128 -0
  128. pyedb-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,169 @@
1
+ import math
2
+
3
+ from pyedb.generic.general_methods import ET, pyedb_function_handler
4
+
5
+
6
+ class Polygon(object):
7
+ def __init__(self, ipc):
8
+ self._ipc = ipc
9
+ self.is_void = False
10
+ self.poly_steps = []
11
+ self.solid_fill_id = ""
12
+ self.cutout = []
13
+
14
+ @pyedb_function_handler()
15
+ def add_poly_step(self, polygon=None): # pragma no cover
16
+ if polygon:
17
+ polygon_data = polygon.GetPolygonData()
18
+ if polygon_data.IsClosed():
19
+ arcs = polygon_data.GetArcData()
20
+ if not arcs:
21
+ return
22
+ # begin
23
+ new_segment_tep = PolyStep()
24
+ new_segment_tep.poly_type = PolyType.Segment
25
+ new_segment_tep.x = arcs[0].Start.X.ToDouble()
26
+ new_segment_tep.y = arcs[0].Start.Y.ToDouble()
27
+ self.poly_steps.append(new_segment_tep)
28
+ for arc in arcs:
29
+ if arc.Height == 0:
30
+ new_segment_tep = PolyStep()
31
+ new_segment_tep.poly_type = PolyType.Segment
32
+ new_segment_tep.x = arc.End.X.ToDouble()
33
+ new_segment_tep.y = arc.End.Y.ToDouble()
34
+ self.poly_steps.append(new_segment_tep)
35
+ else:
36
+ arc_center = arc.GetCenter()
37
+ new_poly_step = PolyStep()
38
+ new_poly_step.poly_type = PolyType.Curve
39
+ new_poly_step.center_X = arc_center.X.ToDouble()
40
+ new_poly_step.center_y = arc_center.Y.ToDouble()
41
+ new_poly_step.x = arc.End.X.ToDouble()
42
+ new_poly_step.y = arc.End.Y.ToDouble()
43
+ new_poly_step.clock_wise = not arc.IsCCW()
44
+ self.poly_steps.append(new_poly_step)
45
+ for void in polygon.voids:
46
+ void_polygon_data = void.GetPolygonData()
47
+ if void_polygon_data.IsClosed():
48
+ void_arcs = void_polygon_data.GetArcData()
49
+ if not void_arcs:
50
+ return
51
+ void_polygon = Cutout(self._ipc)
52
+ self.cutout.append(void_polygon)
53
+ # begin
54
+ new_segment_tep = PolyStep()
55
+ new_segment_tep.poly_type = PolyType.Segment
56
+ new_segment_tep.x = void_arcs[0].Start.X.ToDouble()
57
+ new_segment_tep.y = void_arcs[0].Start.Y.ToDouble()
58
+ void_polygon.poly_steps.append(new_segment_tep)
59
+ for void_arc in void_arcs:
60
+ if void_arc.Height == 0:
61
+ new_segment_tep = PolyStep()
62
+ new_segment_tep.poly_type = PolyType.Segment
63
+ new_segment_tep.x = void_arc.End.X.ToDouble()
64
+ new_segment_tep.y = void_arc.End.Y.ToDouble()
65
+ void_polygon.poly_steps.append(new_segment_tep)
66
+ else:
67
+ arc_center = void_arc.GetCenter()
68
+ new_poly_step = PolyStep()
69
+ new_poly_step.poly_type = PolyType.Curve
70
+ new_poly_step.center_X = arc_center.X.ToDouble()
71
+ new_poly_step.center_y = arc_center.Y.ToDouble()
72
+ new_poly_step.x = void_arc.End.X.ToDouble()
73
+ new_poly_step.y = void_arc.End.Y.ToDouble()
74
+ new_poly_step.clock_wise = not void_arc.IsCCW()
75
+ void_polygon.poly_steps.append(new_poly_step)
76
+
77
+ @pyedb_function_handler()
78
+ def add_cutout(self, cutout): # pragma no cover
79
+ if not isinstance(cutout, Cutout):
80
+ return False
81
+ self.cutout.append(cutout)
82
+
83
+ @pyedb_function_handler()
84
+ def write_xml(self, root_net): # pragma no cover
85
+ if not self.poly_steps:
86
+ return
87
+ feature = ET.SubElement(root_net, "Features")
88
+ location = ET.SubElement(feature, "Location")
89
+ location.set("x", str(0))
90
+ location.set("y", str(0))
91
+ contour = ET.SubElement(feature, "Contour")
92
+ polygon = ET.SubElement(contour, "Polygon")
93
+ polygon_begin = ET.SubElement(polygon, "PolyBegin")
94
+ polygon_begin.set("x", str(self._ipc.from_meter_to_units(self.poly_steps[0].x, self._ipc.units)))
95
+ polygon_begin.set("y", str(self._ipc.from_meter_to_units(self.poly_steps[0].y, self._ipc.units)))
96
+ for poly_step in self.poly_steps[1:]:
97
+ poly_step.write_xml(polygon, self._ipc)
98
+ for cutout in self.cutout:
99
+ cutout.write_xml(contour, self._ipc)
100
+
101
+
102
+ class Cutout(object):
103
+ def __init__(self, ipc):
104
+ self._ipc = ipc
105
+ self.poly_steps = []
106
+
107
+ @pyedb_function_handler()
108
+ def write_xml(self, contour, ipc): # pragma no cover
109
+ cutout = ET.SubElement(contour, "Cutout")
110
+ cutout_begin = ET.SubElement(cutout, "PolyBegin")
111
+ cutout_begin.set("x", str(ipc.from_meter_to_units(self.poly_steps[0].x, ipc.units)))
112
+ cutout_begin.set("y", str(ipc.from_meter_to_units(self.poly_steps[0].y, ipc.units)))
113
+ for poly_step in self.poly_steps[1:]:
114
+ if poly_step.poly_type == 0:
115
+ poly = ET.SubElement(cutout, "PolyStepSegment")
116
+ poly.set("x", str(ipc.from_meter_to_units(poly_step.x, ipc.units)))
117
+ poly.set("y", str(ipc.from_meter_to_units(poly_step.y, ipc.units)))
118
+ elif poly_step.poly_type == 1:
119
+ poly = ET.SubElement(cutout, "PolyStepCurve")
120
+ poly.set("x", str(ipc.from_meter_to_units(poly_step.x, ipc.units)))
121
+ poly.set("y", str(ipc.from_meter_to_units(poly_step.y, ipc.units)))
122
+ poly.set("centerX", str(ipc.from_meter_to_units(poly_step.center_X, ipc.units)))
123
+ poly.set("centerY", str(ipc.from_meter_to_units(poly_step.center_y, ipc.units)))
124
+ poly.set("clockwise", str(poly_step.clock_wise).lower())
125
+
126
+
127
+ class PolyStep(object):
128
+ def __init__(self):
129
+ self.poly_type = PolyType().Segment
130
+ self.x = 0.0
131
+ self.y = 0.0
132
+ self.center_X = 0.0
133
+ self.center_y = 0.0
134
+ self.clock_wise = False
135
+
136
+ @pyedb_function_handler()
137
+ def write_xml(self, polygon, ipc): # pragma no cover
138
+ if self.poly_type == 0:
139
+ poly = ET.SubElement(polygon, "PolyStepSegment")
140
+ poly.set("x", str(ipc.from_meter_to_units(self.x, ipc.units)))
141
+ poly.set("y", str(ipc.from_meter_to_units(self.y, ipc.units)))
142
+ elif self.poly_type == 1:
143
+ poly = ET.SubElement(polygon, "PolyStepCurve")
144
+ poly.set("x", str(ipc.from_meter_to_units(self.x, ipc.units)))
145
+ poly.set("y", str(ipc.from_meter_to_units(self.y, ipc.units)))
146
+ poly.set("centerX", str(ipc.from_meter_to_units(self.center_X, ipc.units)))
147
+ poly.set("centerY", str(ipc.from_meter_to_units(self.center_y, ipc.units)))
148
+ poly.set("clockwise", str(self.clock_wise).lower())
149
+
150
+
151
+ class PolyType(object):
152
+ (Segment, Curve) = range(0, 2)
153
+
154
+
155
+ class Curve(object):
156
+ def __init__(self):
157
+ self.center_X = 0.0
158
+ self.center_y = 0.0
159
+ self.clock_wise = False
160
+
161
+
162
+ class Arc(object):
163
+ @staticmethod
164
+ def get_arc_radius_angle(h, c): # pragma no cover
165
+ if not isinstance(h, float) and isinstance(c, float):
166
+ return False
167
+ r = h / 2 + math.pow(c, 2) / (8 * h)
168
+ theta = 2 * math.asin(c / (2 * r))
169
+ return r, theta
@@ -0,0 +1,40 @@
1
+ from pyedb.generic.general_methods import ET
2
+ from pyedb.ipc2581.ecad.cad_data.layer_feature import LayerFeature
3
+
4
+
5
+ class Profile(object):
6
+ def __init__(self, ipc):
7
+ self._profile = []
8
+ self._ipc = ipc
9
+
10
+ @property
11
+ def profile(self):
12
+ return self._profile
13
+
14
+ @profile.setter
15
+ def profile(self, value): # pragma no cover
16
+ if isinstance(value, list):
17
+ if len([poly for poly in value if isinstance(poly, LayerFeature)]) == len(value):
18
+ self._profile = value
19
+
20
+ def add_polygon(self, polygon): # pragma no cover
21
+ if isinstance(polygon, LayerFeature):
22
+ self._profile.append(polygon)
23
+
24
+ def xml_writer(self, step): # pragma no cover
25
+ profile = ET.SubElement(step, "Profile")
26
+ for poly in self.profile:
27
+ for feature in poly.features:
28
+ if feature.feature_type == 0:
29
+ polygon = ET.SubElement(profile, "Polygon")
30
+ polygon_begin = ET.SubElement(polygon, "PolyBegin")
31
+ polygon_begin.set(
32
+ "x", str(self._ipc.from_meter_to_units(feature.polygon.poly_steps[0].x, self._ipc.units))
33
+ )
34
+ polygon_begin.set(
35
+ "y", str(self._ipc.from_meter_to_units(feature.polygon.poly_steps[0].y, self._ipc.units))
36
+ )
37
+ for poly_step in feature.polygon.poly_steps[1:]:
38
+ poly_step.write_xml(polygon, self._ipc)
39
+ for cutout in feature.polygon.cutout:
40
+ cutout.write_xml(profile, self._ipc)
@@ -0,0 +1,31 @@
1
+ from pyedb.generic.general_methods import ET
2
+ from pyedb.ipc2581.ecad.cad_data.stackup_group import StackupGroup
3
+
4
+
5
+ class Stackup(object):
6
+ def __init__(self):
7
+ self.name = "PRIMARY"
8
+ self.total_thickness = 0.0
9
+ self.tol_plus = 0.0
10
+ self.tol_min = 0.0
11
+ self.where_measured = "METAL"
12
+ self._stackup_group = StackupGroup()
13
+
14
+ @property
15
+ def stackup_group(self):
16
+ return self._stackup_group
17
+
18
+ @stackup_group.setter
19
+ def stackup_group(self, value): # pragma no cover
20
+ if isinstance(value, list):
21
+ if len([stack_grp for stack_grp in value if isinstance(stack_grp, StackupGroup)]):
22
+ self._stackup_group = value
23
+
24
+ def write_xml(self, cad_data): # pragma no cover
25
+ stackup = ET.SubElement(cad_data, "Stackup")
26
+ stackup.set("name", self.name)
27
+ stackup.set("overallThickness", str(self.total_thickness))
28
+ stackup.set("tolPlus", str(self.tol_plus))
29
+ stackup.set("tolMinus", str(self.tol_min))
30
+ stackup.set("whereMeasured", self.where_measured)
31
+ self.stackup_group.write_xml(stackup)
@@ -0,0 +1,42 @@
1
+ from pyedb.generic.general_methods import ET
2
+ from pyedb.ipc2581.ecad.cad_data.layer import Layer
3
+ from pyedb.ipc2581.ecad.cad_data.stackup_layer import StackupLayer
4
+
5
+
6
+ class StackupGroup(object):
7
+ def __init__(self):
8
+ self.name = "GROUP_PRIMARY"
9
+ self.thickness = 0
10
+ self.tol_plus = 0
11
+ self.tol_minus = 0
12
+ self._stackup_layers = []
13
+
14
+ @property
15
+ def stackup_layers(self):
16
+ return self._stackup_layers
17
+
18
+ @stackup_layers.setter
19
+ def stackup_layers(self, value): # pragma no cover
20
+ if isinstance(value, list):
21
+ if len([lay for lay in value if isinstance(lay, Layer)]):
22
+ self._stackup_layers = value
23
+
24
+ def add_stackup_layer(
25
+ self, layer_name="", thickness="", tol_minus="0.0", tol_plus="0.0", sequence=""
26
+ ): # pragma no cover
27
+ stackup_layer = StackupLayer()
28
+ stackup_layer.layer_name = layer_name
29
+ stackup_layer.thickness = thickness
30
+ stackup_layer.tol_plus = tol_plus
31
+ stackup_layer.tol_minus = tol_minus
32
+ stackup_layer.sequence = sequence
33
+ self._stackup_layers.append(stackup_layer)
34
+
35
+ def write_xml(self, stackup): # pragma no cover
36
+ stackup_group = ET.SubElement(stackup, "StackupGroup")
37
+ stackup_group.set("name", "GROUP_PRIMARY")
38
+ stackup_group.set("thickness", str(self.thickness))
39
+ stackup_group.set("tolPlus", str(self.tol_plus))
40
+ stackup_group.set("tolMinus", str(self.tol_minus))
41
+ for layer in self.stackup_layers:
42
+ layer.write_xml(stackup_group)
@@ -0,0 +1,21 @@
1
+ from pyedb.generic.general_methods import ET
2
+
3
+
4
+ class StackupLayer(object):
5
+ def __init__(self):
6
+ self.layer_name = ""
7
+ self.thickness = 0
8
+ self.tol_minus = 0
9
+ self.tol_plus = 0
10
+ self.sequence = ""
11
+ self.spec_ref = "SPEC_{}".format(self.layer_name)
12
+
13
+ def write_xml(self, stackup_group): # pragma no cover
14
+ stackup_layer = ET.SubElement(stackup_group, "StackupLayer")
15
+ stackup_layer.set("layerOrGroupRef", self.layer_name)
16
+ stackup_layer.set("thickness", str(self.thickness))
17
+ stackup_layer.set("tolPlus", str(self.tol_plus))
18
+ stackup_layer.set("tolMinus", str(self.tol_minus))
19
+ stackup_layer.set("sequence", self.sequence)
20
+ spec_ref = ET.SubElement(stackup_layer, "SpecRef")
21
+ spec_ref.set("id", self.layer_name)
@@ -0,0 +1,275 @@
1
+ import math
2
+
3
+ from pyedb.generic.general_methods import ET, pyedb_function_handler
4
+ from pyedb.ipc2581.ecad.cad_data.component import Component
5
+ from pyedb.ipc2581.ecad.cad_data.layer_feature import LayerFeature
6
+ from pyedb.ipc2581.ecad.cad_data.logical_net import LogicalNet
7
+ from pyedb.ipc2581.ecad.cad_data.package import Package
8
+ from pyedb.ipc2581.ecad.cad_data.padstack_def import PadstackDef
9
+ from pyedb.ipc2581.ecad.cad_data.phy_net import PhyNet
10
+ from pyedb.ipc2581.ecad.cad_data.profile import Profile
11
+
12
+
13
+ class Step(object):
14
+ def __init__(self, caddata, edb, units, ipc):
15
+ self.design_name = caddata.design_name
16
+ self._pedb = edb
17
+ self._ipc = ipc
18
+ self.units = units
19
+ self._cad_data = caddata
20
+ self._padstack_defs = {}
21
+ self._profile = Profile(ipc)
22
+ self._packages = {}
23
+ self._components = []
24
+ self._logical_nets = []
25
+ self._physical_nets = []
26
+ self._layer_features = []
27
+
28
+ @property
29
+ def padstack_defs(self):
30
+ return self._padstack_defs
31
+
32
+ @padstack_defs.setter
33
+ def padstack_defs(self, value): # pragma no cover
34
+ if isinstance(value, list):
35
+ if len([pad for pad in value if isinstance(pad, PadstackDef)]) == len(value):
36
+ self._padstack_defs = value
37
+
38
+ @property
39
+ def packages(self):
40
+ return self._packages
41
+
42
+ @packages.setter
43
+ def packages(self, value): # pragma no cover
44
+ if isinstance(value, list):
45
+ if len([pkg for pkg in value if isinstance(pkg, Package)]) == len(value):
46
+ self._packages = value
47
+
48
+ @property
49
+ def profile(self):
50
+ return self._profile
51
+
52
+ @property
53
+ def components(self):
54
+ return self._components
55
+
56
+ @components.setter
57
+ def components(self, value): # pragma no cover
58
+ if isinstance(value, list):
59
+ if len([cmp for cmp in value if isinstance(cmp, Component)]) == len(value):
60
+ self._components = value
61
+
62
+ @property
63
+ def logical_nets(self):
64
+ return self._logical_nets
65
+
66
+ @pyedb_function_handler()
67
+ def add_logical_net(self, net=None): # pragma no cover
68
+ net_name = net.name
69
+ logical_net = LogicalNet()
70
+ logical_net.name = net_name
71
+ net_pins = list(net.PadstackInstances)
72
+ for pin in net_pins:
73
+ new_pin_ref = logical_net.get_pin_ref_def()
74
+ new_pin_ref.pin = pin.GetName()
75
+ new_pin_ref.component_ref = pin.GetComponent().GetName()
76
+ logical_net.pin_ref.append(new_pin_ref)
77
+ self.logical_nets.append(logical_net)
78
+
79
+ @property
80
+ def layer_features(self):
81
+ return self._layer_features
82
+
83
+ @layer_features.setter
84
+ def layer_features(self, value): # pragma no cover
85
+ if isinstance(value, list):
86
+ if len(
87
+ [
88
+ feat
89
+ for feat in value
90
+ if isinstance(
91
+ feat,
92
+ )
93
+ ]
94
+ ):
95
+ self._layer_features = value
96
+
97
+ @property
98
+ def physical_nets(self):
99
+ return self._physical_nets
100
+
101
+ @physical_nets.setter
102
+ def physical_nets(self, value): # pragma no cover
103
+ if isinstance(value, list):
104
+ if len([phy_net for phy_net in value if isinstance(phy_net, PhyNet)]) == len(value):
105
+ self._physical_nets = value
106
+
107
+ @pyedb_function_handler()
108
+ def add_physical_net(self, phy_net=None): # pragma no cover
109
+ if isinstance(phy_net, PhyNet):
110
+ self._physical_nets.append(phy_net)
111
+ return True
112
+ return False
113
+
114
+ @pyedb_function_handler()
115
+ def add_padstack_def(self, padstackdef=None): # pragma no cover
116
+ if isinstance(padstackdef, PadstackDef):
117
+ self._padstack_defs.append(padstackdef)
118
+
119
+ @pyedb_function_handler()
120
+ def add_component(self, component=None): # pragma no cover
121
+ # adding component add package in Step
122
+ if component:
123
+ if not component.part_name in self._packages:
124
+ package = Package(self._ipc)
125
+ package.add_component_outline(component)
126
+ package.name = component.part_name
127
+ package.height = ""
128
+ package.type = component.type
129
+ pin_number = 0
130
+ for _, pin in component.pins.items():
131
+ geometry_type, pad_parameters, pos_x, pos_y, rot = self._pedb.padstacks.get_pad_parameters(
132
+ pin._edb_padstackinstance, component.placement_layer, 0
133
+ )
134
+ if pad_parameters:
135
+ position = pin._position if pin._position else pin.position
136
+ pin_pos_x = self._ipc.from_meter_to_units(position[0], self.units)
137
+ pin_pos_y = self._ipc.from_meter_to_units(position[1], self.units)
138
+ primitive_ref = ""
139
+ if geometry_type == 1:
140
+ primitive_ref = "CIRC_{}".format(pad_parameters[0])
141
+ elif geometry_type == 2:
142
+ primitive_ref = "RECT_{}_{}".format(pad_parameters[0], pad_parameters[0])
143
+ elif geometry_type == 3:
144
+ primitive_ref = "RECT_{}_{}".format(pad_parameters[0], pad_parameters[1])
145
+ elif geometry_type == 4:
146
+ primitive_ref = "OVAL_{}_{}_{}".format(
147
+ pad_parameters[0], pad_parameters[1], pad_parameters[2]
148
+ )
149
+ if primitive_ref:
150
+ package.add_pin(
151
+ number=pin_number, x=pin_pos_x, y=pin_pos_y, rotation=rot, primitive_ref=primitive_ref
152
+ )
153
+ pin_number += 1
154
+ self.packages[package.name] = package
155
+ ipc_component = Component()
156
+ ipc_component.type = component.type
157
+ try:
158
+ ipc_component.value = component.value
159
+ except:
160
+ pass
161
+ ipc_component.refdes = component.refdes
162
+ center = component.center
163
+ ipc_component.location = [
164
+ self._ipc.from_meter_to_units(center[0], self.units),
165
+ self._ipc.from_meter_to_units(center[1], self.units),
166
+ ]
167
+ ipc_component.rotation = component.rotation * 180 / math.pi
168
+ ipc_component.part = ipc_component.package_ref = component.part_name
169
+ ipc_component.layer_ref = component.placement_layer
170
+ self.components.append(ipc_component)
171
+
172
+ def layer_ranges(
173
+ self,
174
+ start_layer,
175
+ stop_layer,
176
+ ): # pragma no cover
177
+ started = False
178
+ start_layer_name = start_layer.GetName()
179
+ stop_layer_name = stop_layer.GetName()
180
+ layer_list = []
181
+ for layer_name in self._ipc.layers_name:
182
+ if started:
183
+ layer_list.append(layer_name)
184
+ if layer_name == stop_layer_name or layer_name == start_layer_name:
185
+ break
186
+ elif layer_name == start_layer_name:
187
+ started = True
188
+ layer_list.append(layer_name)
189
+ if layer_name == stop_layer_name:
190
+ break
191
+ elif layer_name == stop_layer_name:
192
+ started = True
193
+ layer_list.append(layer_name)
194
+ if layer_name == start_layer_name:
195
+ break
196
+ return layer_list
197
+
198
+ @pyedb_function_handler()
199
+ def add_layer_feature(self, layer, polys): # pragma no cover
200
+ layer_name = layer.name
201
+ layer_feature = LayerFeature(self._ipc)
202
+ layer_feature.layer_name = layer_name
203
+ layer_feature.color = layer.color
204
+
205
+ for poly in polys:
206
+ if not poly.is_void:
207
+ layer_feature.add_feature(poly)
208
+ self._ipc.ecad.cad_data.cad_data_step.layer_features.append(layer_feature)
209
+
210
+ @pyedb_function_handler()
211
+ def add_profile(self, poly): # pragma no cover
212
+ profile = LayerFeature(self._ipc)
213
+ profile.layer_name = "profile"
214
+ if poly:
215
+ if not poly.is_void:
216
+ profile.add_feature(poly)
217
+ self.profile.add_polygon(profile)
218
+
219
+ @pyedb_function_handler()
220
+ def add_padstack_instances(self, padstack_instances, padstack_defs): # pragma no cover
221
+ top_bottom_layers = self._ipc.top_bottom_layers
222
+ layers = {j.layer_name: j for j in self._ipc.ecad.cad_data.cad_data_step.layer_features}
223
+
224
+ for padstack_instance in padstack_instances:
225
+ _, start_layer, stop_layer = padstack_instance._edb_padstackinstance.GetLayerRange()
226
+ for layer_name in self.layer_ranges(start_layer, stop_layer):
227
+ if layer_name not in layers:
228
+ layer_feature = LayerFeature(self._ipc)
229
+ layer_feature.layer_name = layer_name
230
+ layer_feature.color = self._ipc._pedb.stackup[layer_name].color
231
+ self._ipc.ecad.cad_data.cad_data_step.layer_features.append(layer_feature)
232
+ layers[layer_name] = self._ipc.ecad.cad_data.cad_data_step.layer_features[-1]
233
+ pdef_name = (
234
+ padstack_instance._pdef if padstack_instance._pdef else padstack_instance.padstack_definition
235
+ )
236
+ if pdef_name in padstack_defs:
237
+ padstack_def = padstack_defs[pdef_name]
238
+ comp_name = padstack_instance.GetComponent().GetName()
239
+ if padstack_instance.is_pin and comp_name:
240
+ component_inst = self._pedb.components.components[comp_name]
241
+ layers[layer_name].add_component_padstack_instance_feature(
242
+ component_inst, padstack_instance, top_bottom_layers, padstack_def
243
+ )
244
+ else:
245
+ layers[layer_name].add_via_instance_feature(padstack_instance, padstack_def, layer_name)
246
+
247
+ @pyedb_function_handler()
248
+ def add_drill_layer_feature(self, via_list=None, layer_feature_name=""): # pragma no cover
249
+ if via_list:
250
+ drill_layer_feature = LayerFeature(self._ipc)
251
+ drill_layer_feature.is_drill_feature = True
252
+ drill_layer_feature.layer_name = layer_feature_name
253
+ for via in via_list:
254
+ try:
255
+ via_diameter = via.pin.GetPadstackDef().GetData().GetHoleParameters()[2][0]
256
+ drill_layer_feature.add_drill_feature(via, via_diameter)
257
+ except:
258
+ pass
259
+ self.layer_features.append(drill_layer_feature)
260
+
261
+ @pyedb_function_handler()
262
+ def write_xml(self, cad_data): # pragma no cover
263
+ step = ET.SubElement(cad_data, "Step")
264
+ step.set("name", self._ipc.design_name)
265
+ for padsatck_def in list(self.padstack_defs.values()):
266
+ padsatck_def.write_xml(step)
267
+ self.profile.xml_writer(step)
268
+ for package in list(self.packages.values()):
269
+ package.write_xml(step)
270
+ for component in self.components:
271
+ component.write_xml(step)
272
+ for logical_net in self.logical_nets:
273
+ logical_net.write_xml(step)
274
+ for layer_feature in self.layer_features:
275
+ layer_feature.write_xml(step)
@@ -0,0 +1,33 @@
1
+ from pyedb.generic.general_methods import ET
2
+ from pyedb.ipc2581.ecad.spec import Spec
3
+
4
+
5
+ class CadHeader(object):
6
+ """Class describing a layer stackup."""
7
+
8
+ def __init__(self):
9
+ self._specs = []
10
+ self.units = ""
11
+
12
+ @property
13
+ def specs(self):
14
+ return self._specs
15
+
16
+ def add_spec(
17
+ self, name="", material="", layer_type="", conductivity="", dielectric_constant="", loss_tg="", embedded=""
18
+ ): # pragma no cover
19
+ spec = Spec()
20
+ spec.name = name
21
+ spec.material = material
22
+ spec.conductivity = conductivity
23
+ spec.dielectric_constant = dielectric_constant
24
+ spec.layer_type = layer_type
25
+ spec.loss_tangent = loss_tg
26
+ spec.embedded = embedded
27
+ self.specs.append(spec)
28
+
29
+ def write_xml(self, ecad): # pragma no cover
30
+ cad_header = ET.SubElement(ecad, "CadHeader")
31
+ cad_header.set("units", self.units)
32
+ for spec in self.specs:
33
+ spec.write_xml(cad_header)
@@ -0,0 +1,19 @@
1
+ from pyedb.generic.general_methods import ET
2
+ from pyedb.ipc2581.ecad.cad_data.cad_data import CadData
3
+ from pyedb.ipc2581.ecad.cad_header import CadHeader
4
+
5
+
6
+ class Ecad(object):
7
+ def __init__(self, ipc, edb, units):
8
+ self.design_name = "Design"
9
+ self.units = units
10
+ self.cad_header = CadHeader()
11
+ self._ipc = ipc
12
+ self.cad_data = CadData(self, edb, units, self._ipc)
13
+ self._pedb = edb
14
+
15
+ def write_xml(self, root): # pragma no cover
16
+ ecad = ET.SubElement(root, "Ecad")
17
+ ecad.set("name", self.design_name)
18
+ self.cad_header.write_xml(ecad)
19
+ self.cad_data.write_xml(ecad)
@@ -0,0 +1,46 @@
1
+ from pyedb.generic.general_methods import ET
2
+
3
+
4
+ class Spec(object):
5
+ """Class describing a layer."""
6
+
7
+ def __init__(self):
8
+ self.name = ""
9
+ self.material = ""
10
+ self.layer_type = ""
11
+ self.conductivity = ""
12
+ self.dielectric_constant = ""
13
+ self.loss_tangent = ""
14
+ self.embedded = ""
15
+
16
+ def write_xml(self, ecad_header): # pragma no cover
17
+ spec = ET.SubElement(ecad_header, "Spec")
18
+ spec.set("name", self.name)
19
+ material = ET.SubElement(spec, "General")
20
+ material.set("type", "MATERIAL")
21
+ material_set = ET.SubElement(material, "Property")
22
+ material_set.set("text", self.material)
23
+ layer_type = ET.SubElement(spec, "General")
24
+ layer_type.set("type", "OTHER")
25
+ layer_type.set("comment", "LAYER_TYPE")
26
+ layer_type_set = ET.SubElement(layer_type, "Property")
27
+ layer_type_set.set("text", self.layer_type)
28
+ conductivity = ET.SubElement(spec, "Conductor")
29
+ conductivity.set("type", "CONDUCTIVITY")
30
+ conductivity_set = ET.SubElement(conductivity, "Property")
31
+ conductivity_set.set("value", self.conductivity)
32
+ conductivity_set.set("unit", "MHO/CM")
33
+ dielectric = ET.SubElement(spec, "Dielectric")
34
+ dielectric.set("type", "DIELECTRIC_CONSTANT")
35
+ dielectric_set = ET.SubElement(dielectric, "Property")
36
+ dielectric_set.set("value", self.dielectric_constant)
37
+ loss_tg = ET.SubElement(spec, "Dielectric")
38
+ loss_tg.set("type", "LOSS_TANGENT")
39
+ loss_tg_set = ET.SubElement(loss_tg, "Property")
40
+ loss_tg_set.set("value", self.loss_tangent)
41
+ if self.layer_type == "CONDUCTOR":
42
+ embedded = ET.SubElement(spec, "General")
43
+ embedded.set("type", "OTHER")
44
+ embedded.set("comment", "LAYER_EMBEDDED_STATUS")
45
+ embedded_set = ET.SubElement(embedded, "Property")
46
+ embedded_set.set("text", self.embedded)