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.
- pyedb/__init__.py +17 -0
- pyedb/dotnet/__init__.py +0 -0
- pyedb/dotnet/application/Variables.py +2261 -0
- pyedb/dotnet/application/__init__.py +0 -0
- pyedb/dotnet/clr_module.py +103 -0
- pyedb/dotnet/edb.py +4237 -0
- pyedb/dotnet/edb_core/__init__.py +1 -0
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
- pyedb/dotnet/edb_core/components.py +2669 -0
- pyedb/dotnet/edb_core/configuration.py +423 -0
- pyedb/dotnet/edb_core/definition/__init__.py +0 -0
- pyedb/dotnet/edb_core/definition/component_def.py +166 -0
- pyedb/dotnet/edb_core/definition/component_model.py +30 -0
- pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
- pyedb/dotnet/edb_core/definition/definitions.py +12 -0
- pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
- pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
- pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
- pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
- pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
- pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
- pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
- pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
- pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
- pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
- pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
- pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
- pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
- pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
- pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
- pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
- pyedb/dotnet/edb_core/general.py +181 -0
- pyedb/dotnet/edb_core/hfss.py +1646 -0
- pyedb/dotnet/edb_core/layout.py +1244 -0
- pyedb/dotnet/edb_core/layout_validation.py +272 -0
- pyedb/dotnet/edb_core/materials.py +939 -0
- pyedb/dotnet/edb_core/net_class.py +335 -0
- pyedb/dotnet/edb_core/nets.py +1215 -0
- pyedb/dotnet/edb_core/padstack.py +1389 -0
- pyedb/dotnet/edb_core/siwave.py +1427 -0
- pyedb/dotnet/edb_core/stackup.py +2703 -0
- pyedb/edb_logger.py +396 -0
- pyedb/generic/__init__.py +0 -0
- pyedb/generic/constants.py +1063 -0
- pyedb/generic/data_handlers.py +320 -0
- pyedb/generic/design_types.py +104 -0
- pyedb/generic/filesystem.py +150 -0
- pyedb/generic/general_methods.py +1535 -0
- pyedb/generic/plot.py +1840 -0
- pyedb/generic/process.py +285 -0
- pyedb/generic/settings.py +224 -0
- pyedb/ipc2581/__init__.py +0 -0
- pyedb/ipc2581/bom/__init__.py +0 -0
- pyedb/ipc2581/bom/bom.py +21 -0
- pyedb/ipc2581/bom/bom_item.py +32 -0
- pyedb/ipc2581/bom/characteristics.py +37 -0
- pyedb/ipc2581/bom/refdes.py +16 -0
- pyedb/ipc2581/content/__init__.py +0 -0
- pyedb/ipc2581/content/color.py +38 -0
- pyedb/ipc2581/content/content.py +55 -0
- pyedb/ipc2581/content/dictionary_color.py +29 -0
- pyedb/ipc2581/content/dictionary_fill.py +28 -0
- pyedb/ipc2581/content/dictionary_line.py +30 -0
- pyedb/ipc2581/content/entry_color.py +13 -0
- pyedb/ipc2581/content/entry_line.py +14 -0
- pyedb/ipc2581/content/fill.py +15 -0
- pyedb/ipc2581/content/layer_ref.py +10 -0
- pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
- pyedb/ipc2581/ecad/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
- pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
- pyedb/ipc2581/ecad/cad_data/component.py +41 -0
- pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
- pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
- pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
- pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
- pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
- pyedb/ipc2581/ecad/cad_data/package.py +104 -0
- pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
- pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
- pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
- pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
- pyedb/ipc2581/ecad/cad_data/path.py +89 -0
- pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
- pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
- pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
- pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
- pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
- pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
- pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
- pyedb/ipc2581/ecad/cad_data/step.py +275 -0
- pyedb/ipc2581/ecad/cad_header.py +33 -0
- pyedb/ipc2581/ecad/ecad.py +19 -0
- pyedb/ipc2581/ecad/spec.py +46 -0
- pyedb/ipc2581/history_record.py +37 -0
- pyedb/ipc2581/ipc2581.py +387 -0
- pyedb/ipc2581/logistic_header.py +25 -0
- pyedb/misc/__init__.py +0 -0
- pyedb/misc/aedtlib_personalib_install.py +14 -0
- pyedb/misc/downloads.py +322 -0
- pyedb/misc/misc.py +67 -0
- pyedb/misc/pyedb.runtimeconfig.json +13 -0
- pyedb/misc/siw_feature_config/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
- pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
- pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
- pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
- pyedb/misc/utilities.py +27 -0
- pyedb/modeler/geometry_operators.py +2082 -0
- pyedb-0.2.0.dist-info/LICENSE +21 -0
- pyedb-0.2.0.dist-info/METADATA +208 -0
- pyedb-0.2.0.dist-info/RECORD +128 -0
- pyedb-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.dictionary_color import DictionaryColor
|
|
3
|
+
from pyedb.ipc2581.content.dictionary_line import DictionaryLine
|
|
4
|
+
from pyedb.ipc2581.content.layer_ref import LayerRef
|
|
5
|
+
from pyedb.ipc2581.content.standard_geometries_dictionary import (
|
|
6
|
+
StandardGeometriesDictionary,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Content(object):
|
|
11
|
+
def __init__(self, ipc):
|
|
12
|
+
self.mode = self.Mode().Stackup
|
|
13
|
+
self.units = ipc.units
|
|
14
|
+
self.role_ref = "Owner"
|
|
15
|
+
self.function_mode = self.Mode().Stackup
|
|
16
|
+
self.step_ref = "Ansys_IPC2581"
|
|
17
|
+
self._layer_ref = []
|
|
18
|
+
self.dict_colors = DictionaryColor()
|
|
19
|
+
self.dict_line = DictionaryLine(self)
|
|
20
|
+
self.standard_geometries_dict = StandardGeometriesDictionary(self)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def layer_ref(self):
|
|
24
|
+
return self._layer_ref
|
|
25
|
+
|
|
26
|
+
@layer_ref.setter
|
|
27
|
+
def layer_ref(self, value): # pragma no cover
|
|
28
|
+
if isinstance(value, list):
|
|
29
|
+
if len([lay for lay in value if isinstance(lay, LayerRef)]) == len(value):
|
|
30
|
+
self._layer_ref = value
|
|
31
|
+
|
|
32
|
+
def add_layer_ref(self, layer_ref_name=None): # pragma no cover
|
|
33
|
+
if isinstance(layer_ref_name, str):
|
|
34
|
+
layer_ref = LayerRef()
|
|
35
|
+
layer_ref.name = layer_ref_name
|
|
36
|
+
self._layer_ref.append(layer_ref)
|
|
37
|
+
|
|
38
|
+
def write_wml(self, root=None): # pragma no cover
|
|
39
|
+
content = ET.SubElement(root, "Content")
|
|
40
|
+
content.set("roleRef", "Owner")
|
|
41
|
+
if self.mode == self.Mode.Stackup:
|
|
42
|
+
function_mode = ET.SubElement(content, "FunctionMode")
|
|
43
|
+
function_mode.set("mode", "USERDEF")
|
|
44
|
+
step_ref = ET.SubElement(content, "StepRef")
|
|
45
|
+
step_ref.set("name", self.step_ref)
|
|
46
|
+
for lay in self.layer_ref:
|
|
47
|
+
lay.write_xml(content)
|
|
48
|
+
self.dict_colors.write_xml(content)
|
|
49
|
+
self.dict_line.write_xml(content)
|
|
50
|
+
self.standard_geometries_dict.write_xml(content)
|
|
51
|
+
|
|
52
|
+
# skipping user defined geometries
|
|
53
|
+
|
|
54
|
+
class Mode(object):
|
|
55
|
+
(Stackup) = range(1)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.entry_color import EntryColor
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DictionaryColor(object):
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self._dict_colors = []
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def dict_colors(self):
|
|
11
|
+
return self._dict_colors
|
|
12
|
+
|
|
13
|
+
@dict_colors.setter
|
|
14
|
+
def dict_colors(self, value): # pragma no cover
|
|
15
|
+
if isinstance(value, list):
|
|
16
|
+
self._dict_colors = value
|
|
17
|
+
|
|
18
|
+
def add_color(self, name="", r=1, g=1, b=1): # pragma no cover
|
|
19
|
+
entry_color = EntryColor()
|
|
20
|
+
entry_color.name = name
|
|
21
|
+
entry_color.color.r = r
|
|
22
|
+
entry_color.color.g = g
|
|
23
|
+
entry_color.color.b = b
|
|
24
|
+
self._dict_colors.append(entry_color)
|
|
25
|
+
|
|
26
|
+
def write_xml(self, content=None): # pragma no cover
|
|
27
|
+
dict_color = ET.SubElement(content, "DictionaryColor")
|
|
28
|
+
for _color in self.dict_colors:
|
|
29
|
+
_color.write_xml(dict_color)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.content import Content
|
|
3
|
+
from pyedb.ipc2581.content.fill import FillDesc
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DictionaryFill(Content):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self._dict_fill = {}
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def dict_fill(self):
|
|
12
|
+
return self._dict_fill
|
|
13
|
+
|
|
14
|
+
@dict_fill.setter
|
|
15
|
+
def dict_fill(self, value): # pragma no cover
|
|
16
|
+
if isinstance(value, list):
|
|
17
|
+
self._dict_fill = value
|
|
18
|
+
|
|
19
|
+
def add_fill(self, value): # pragma no cover
|
|
20
|
+
if isinstance(value, FillDesc):
|
|
21
|
+
self._dict_fill.append(value)
|
|
22
|
+
|
|
23
|
+
def write_xml(self, content=None): # pragma no cover
|
|
24
|
+
if content:
|
|
25
|
+
dict_fill = ET.SubElement(content, "DictionaryFillDesc")
|
|
26
|
+
dict_fill.set("units", self.units)
|
|
27
|
+
for fill in self._dict_fill.keys():
|
|
28
|
+
self._dict_fill[fill].write_xml()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.entry_line import EntryLine
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DictionaryLine(object):
|
|
6
|
+
def __init__(self, content):
|
|
7
|
+
self._dict_lines = {}
|
|
8
|
+
self.units = content.units
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def dict_lines(self):
|
|
12
|
+
return self._dict_lines
|
|
13
|
+
|
|
14
|
+
@dict_lines.setter
|
|
15
|
+
def dict_lines(self, value): # pragma no cover
|
|
16
|
+
if isinstance(value, EntryLine):
|
|
17
|
+
self._dict_lines = value
|
|
18
|
+
|
|
19
|
+
def add_line(self, width=None): # pragma no cover
|
|
20
|
+
if width:
|
|
21
|
+
line = EntryLine()
|
|
22
|
+
line._line_width = width
|
|
23
|
+
if not "ROUND_{}".format(width) in self._dict_lines:
|
|
24
|
+
self._dict_lines["ROUND_{}".format(width)] = line
|
|
25
|
+
|
|
26
|
+
def write_xml(self, content=None): # pragma no cover
|
|
27
|
+
dict_line = ET.SubElement(content, "DictionaryLineDesc")
|
|
28
|
+
dict_line.set("units", self.units)
|
|
29
|
+
for line in list(self._dict_lines.values()):
|
|
30
|
+
line.write_xml(dict_line)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.color import Color
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class EntryColor(object):
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.name = ""
|
|
8
|
+
self.color = Color()
|
|
9
|
+
|
|
10
|
+
def write_xml(self, color=None): # pragma no cover
|
|
11
|
+
entry_color = ET.SubElement(color, "EntryColor")
|
|
12
|
+
entry_color.set("id", self.name)
|
|
13
|
+
self.color.write_xml(entry_color)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class EntryLine(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self._line_end = "ROUND"
|
|
7
|
+
self.line_width = ""
|
|
8
|
+
|
|
9
|
+
def write_xml(self, dictionnary_line): # pragma no cover
|
|
10
|
+
entry_line = ET.SubElement(dictionnary_line, "EntryLineDesc")
|
|
11
|
+
entry_line.set("id", "{}_{}".format(self._line_end, self.line_width))
|
|
12
|
+
line_desc = ET.SubElement(entry_line, "LineDesc")
|
|
13
|
+
line_desc.set("lineEnd", self._line_end)
|
|
14
|
+
line_desc.set("lineWidth", str(self.line_width))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.content.content import Content
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FillDesc(Content):
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.id = ""
|
|
8
|
+
self.fill_property = ""
|
|
9
|
+
|
|
10
|
+
def write_xml(self, dict_fill=None): # pragma no cover
|
|
11
|
+
if dict_fill:
|
|
12
|
+
fill = ET.SubElement(dict_fill, "EntryFillDesc")
|
|
13
|
+
fill.set("id", self.id)
|
|
14
|
+
fill_desc = ET.SubElement(fill, "FillDesc")
|
|
15
|
+
fill_desc.set("fillProperty", self.fill_property)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class StandardCircle(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.diameter = ""
|
|
7
|
+
self.fill_id = ""
|
|
8
|
+
|
|
9
|
+
def write_xml(self, entry_standard): # pragma no cover
|
|
10
|
+
standard_circle = ET.SubElement(entry_standard, "Circle")
|
|
11
|
+
standard_circle.set("diameter", self.diameter)
|
|
12
|
+
fill = ET.SubElement(standard_circle, "FillDescRef")
|
|
13
|
+
fill.set("id", self.fill_id)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RectangleDotNet(object):
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.width = ""
|
|
19
|
+
self.height = ""
|
|
20
|
+
self.fill_id = ""
|
|
21
|
+
|
|
22
|
+
def write_xml(self, entry_standard): # pragma no cover
|
|
23
|
+
standard_rectanlgle = ET.SubElement(entry_standard, "RectCenter")
|
|
24
|
+
standard_rectanlgle.set("width", self.width)
|
|
25
|
+
standard_rectanlgle.set("height", self.height)
|
|
26
|
+
fill = ET.SubElement(standard_rectanlgle, "FillDescRef")
|
|
27
|
+
fill.set("id", self.fill_id)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Oval(object):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Type(object):
|
|
35
|
+
(Circle, Rectangle) = range(0, 2)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class StandardGeometriesDictionary(object):
|
|
39
|
+
def __init__(self, content):
|
|
40
|
+
self.units = content.units
|
|
41
|
+
self.standard_circ_dict = {}
|
|
42
|
+
self.standard_rect_dict = {}
|
|
43
|
+
self.standard_oval_dict = {}
|
|
44
|
+
|
|
45
|
+
def write_xml(self, content_section=None): # pragma no cover
|
|
46
|
+
standard_dict = ET.SubElement(content_section, "DictionaryStandard")
|
|
47
|
+
standard_dict.set("units", self.units)
|
|
48
|
+
for standard_name, circle_val in self.standard_circ_dict.items():
|
|
49
|
+
if circle_val:
|
|
50
|
+
entry_standard = ET.SubElement(standard_dict, "EntryStandard")
|
|
51
|
+
entry_standard.set("id", standard_name)
|
|
52
|
+
circle = ET.SubElement(entry_standard, "Circle")
|
|
53
|
+
circle.set("diameter", str(circle_val))
|
|
54
|
+
fill_descref = ET.SubElement(circle, "FillDescRef")
|
|
55
|
+
fill_descref.set("id", "SOLID_FILL")
|
|
56
|
+
for standard_name, rect_val in self.standard_rect_dict.items():
|
|
57
|
+
if rect_val:
|
|
58
|
+
entry_standard = ET.SubElement(standard_dict, "EntryStandard")
|
|
59
|
+
entry_standard.set("id", standard_name)
|
|
60
|
+
rec_center = ET.SubElement(entry_standard, "RectCenter")
|
|
61
|
+
rec_center.set("width", str(rect_val[0]))
|
|
62
|
+
rec_center.set("height", str(rect_val[1]))
|
|
63
|
+
fill_descref = ET.SubElement(rec_center, "FillDescRef")
|
|
64
|
+
fill_descref.set("id", "SOLID_FILL")
|
|
65
|
+
|
|
66
|
+
def add_circle(self, diameter): # pragma no cover
|
|
67
|
+
circle = StandardCircle()
|
|
68
|
+
circle.diameter = diameter
|
|
69
|
+
circle.fill_id = "SOLID_FILL"
|
|
70
|
+
entry_key = "CIRCLE_{}".format(diameter[0])
|
|
71
|
+
if not entry_key in self.standard_circ_dict:
|
|
72
|
+
self.standard_circ_dict[entry_key] = str(diameter[0])
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.ecad.cad_data.polygon import Polygon
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AssemblyDrawing(object):
|
|
6
|
+
"""Class describing an IPC2581 assembly drawing."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, ipc):
|
|
9
|
+
self._ipc = ipc
|
|
10
|
+
self.polygon = Polygon(self._ipc)
|
|
11
|
+
self.line_ref = ""
|
|
12
|
+
|
|
13
|
+
def write_xml(self, package): # pragma no cover
|
|
14
|
+
assembly_drawing = ET.SubElement(package, "AssemblyDrawing")
|
|
15
|
+
outline = ET.SubElement(assembly_drawing, "Outline")
|
|
16
|
+
polygon = ET.SubElement(outline, "Polygon")
|
|
17
|
+
polygon_begin = ET.SubElement(polygon, "PolyBegin")
|
|
18
|
+
if self.polygon.poly_steps:
|
|
19
|
+
polygon_begin.set("x", str(self.polygon.poly_steps[0].x))
|
|
20
|
+
polygon_begin.set("y", str(self.polygon.poly_steps[0].y))
|
|
21
|
+
for poly_step in self.polygon.poly_steps[1:]:
|
|
22
|
+
polygon_segment = ET.SubElement(polygon, "PolyStepSegment")
|
|
23
|
+
polygon_segment.set("x", str(poly_step.x))
|
|
24
|
+
polygon_segment.set("y", str(poly_step.y))
|
|
25
|
+
line_desc_ref = ET.SubElement(outline, "LineDescRef")
|
|
26
|
+
line_desc_ref.set("id", self.line_ref)
|
|
@@ -0,0 +1,37 @@
|
|
|
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 import Stackup
|
|
4
|
+
from pyedb.ipc2581.ecad.cad_data.step import Step
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CadData(object):
|
|
8
|
+
def __init__(self, ecad, edb, units, ipc):
|
|
9
|
+
self.design_name = ecad.design_name
|
|
10
|
+
self._pedb = edb
|
|
11
|
+
self._ipc = ipc
|
|
12
|
+
self.units = units
|
|
13
|
+
self._layers = []
|
|
14
|
+
self.stackup = Stackup()
|
|
15
|
+
self.cad_data_step = Step(self, edb, self.units, self._ipc)
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def layers(self):
|
|
19
|
+
return self._layers
|
|
20
|
+
|
|
21
|
+
def add_layer(
|
|
22
|
+
self, layer_name="", layer_function="", layer_side="internal", polarity="positive"
|
|
23
|
+
): # pragma no cover
|
|
24
|
+
layer = Layer()
|
|
25
|
+
layer.name = layer_name
|
|
26
|
+
layer.layer_function = layer_function
|
|
27
|
+
layer.layer_side = layer_side
|
|
28
|
+
layer.layer_polarity = polarity
|
|
29
|
+
self.layers.append(layer)
|
|
30
|
+
|
|
31
|
+
def write_xml(self, ecad): # pragma no cover
|
|
32
|
+
self.design_name = self._pedb.cell_names[0]
|
|
33
|
+
cad_data = ET.SubElement(ecad, "CadData")
|
|
34
|
+
for layer in self.layers:
|
|
35
|
+
layer.write_xml(cad_data)
|
|
36
|
+
self.stackup.write_xml(cad_data)
|
|
37
|
+
self.cad_data_step.write_xml(cad_data)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Component(object):
|
|
5
|
+
"""Contains IPC2581 component information."""
|
|
6
|
+
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.refdes = ""
|
|
9
|
+
self.package_ref = ""
|
|
10
|
+
self.layer_ref = ""
|
|
11
|
+
self.part = ""
|
|
12
|
+
self.mount_type = "SMT"
|
|
13
|
+
self.stand_off = "0.0"
|
|
14
|
+
self.height = "0.0"
|
|
15
|
+
self.location = ["0.0", "0.0"]
|
|
16
|
+
self.rotation = "0.0"
|
|
17
|
+
self.type = Type().Rlc
|
|
18
|
+
self.value = ""
|
|
19
|
+
|
|
20
|
+
def write_xml(self, step): # pragma no cover
|
|
21
|
+
component = ET.SubElement(step, "Component")
|
|
22
|
+
component.set("refDes", self.refdes)
|
|
23
|
+
component.set("packageRef", self.package_ref)
|
|
24
|
+
component.set("layerRef", self.layer_ref)
|
|
25
|
+
component.set("part", self.package_ref)
|
|
26
|
+
component.set("mountType", self.mount_type)
|
|
27
|
+
component.set("standoff", self.stand_off)
|
|
28
|
+
component.set("height", self.height)
|
|
29
|
+
non_standard_attribute = ET.SubElement(component, "NonstandardAttribute")
|
|
30
|
+
non_standard_attribute.set("name", "VALUE")
|
|
31
|
+
non_standard_attribute.set("value", str(self.value))
|
|
32
|
+
non_standard_attribute.set("type", "STRING")
|
|
33
|
+
xform = ET.SubElement(component, "Xform")
|
|
34
|
+
xform.set("rotation", str(self.rotation))
|
|
35
|
+
location = ET.SubElement(component, "Location")
|
|
36
|
+
location.set("x", str(self.location[0]))
|
|
37
|
+
location.set("y", str(self.location[1]))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Type(object):
|
|
41
|
+
(Rlc, Discrete) = range(0, 2)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Drill(object):
|
|
5
|
+
"""Class describing an ICP2581 drill feature."""
|
|
6
|
+
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.net = ""
|
|
9
|
+
self.component = ""
|
|
10
|
+
self.geometry = "VIA"
|
|
11
|
+
self.hole_name = ""
|
|
12
|
+
self.diameter = ""
|
|
13
|
+
self.plating_status = "VIA"
|
|
14
|
+
self.plus_tol = "0.0"
|
|
15
|
+
self.min_tol = "0.0"
|
|
16
|
+
self.x = "0.0"
|
|
17
|
+
self.y = "0.0"
|
|
18
|
+
|
|
19
|
+
def write_xml(self, net): # pragma no cover
|
|
20
|
+
net.set("geometry", "VIA")
|
|
21
|
+
color_ref = ET.SubElement(net, "ColorRef")
|
|
22
|
+
color_ref.set("id", "")
|
|
23
|
+
hole = ET.SubElement(net, "Hole")
|
|
24
|
+
hole.set("name", self.hole_name)
|
|
25
|
+
hole.set("diameter", str(self.diameter))
|
|
26
|
+
hole.set("platingStatus", "VIA")
|
|
27
|
+
hole.set("plusTol", str(self.plus_tol))
|
|
28
|
+
hole.set("minusTol", str(self.min_tol))
|
|
29
|
+
hole.set("x", str(self.x))
|
|
30
|
+
hole.set("y", str(self.y))
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
from pyedb.ipc2581.ecad.cad_data.drill import Drill
|
|
3
|
+
from pyedb.ipc2581.ecad.cad_data.padstack_instance import PadstackInstance
|
|
4
|
+
from pyedb.ipc2581.ecad.cad_data.path import Path
|
|
5
|
+
from pyedb.ipc2581.ecad.cad_data.polygon import Polygon
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Feature(object):
|
|
9
|
+
"""Class describing IPC2581 features."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, ipc):
|
|
12
|
+
self._ipc = ipc
|
|
13
|
+
self.feature_type = FeatureType().Polygon
|
|
14
|
+
self.net = ""
|
|
15
|
+
self.x = 0.0
|
|
16
|
+
self.y = 0.0
|
|
17
|
+
self.polygon = Polygon(self._ipc)
|
|
18
|
+
self._cutouts = []
|
|
19
|
+
self.path = Path(self._ipc)
|
|
20
|
+
# self.pad = PadstackDef()
|
|
21
|
+
self.padstack_instance = PadstackInstance()
|
|
22
|
+
self.drill = Drill()
|
|
23
|
+
# self.via = Via()
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def cutouts(self):
|
|
27
|
+
return self._cutouts
|
|
28
|
+
|
|
29
|
+
@cutouts.setter
|
|
30
|
+
def cutouts(self, value): # pragma no cover
|
|
31
|
+
if isinstance(value, list):
|
|
32
|
+
if len([poly for poly in value if isinstance(poly, Polygon)]) == len(value):
|
|
33
|
+
self._cutouts = value
|
|
34
|
+
|
|
35
|
+
def add_cutout(self, cutout=None): # pragma no cover
|
|
36
|
+
if isinstance(cutout, Polygon):
|
|
37
|
+
self._cutouts.append(cutout)
|
|
38
|
+
|
|
39
|
+
def write_xml(self, layer_feature): # pragma no cover
|
|
40
|
+
net = ET.SubElement(layer_feature, "Set")
|
|
41
|
+
net.set("net", self.net)
|
|
42
|
+
if self.feature_type == FeatureType.Polygon:
|
|
43
|
+
self.polygon.write_xml(net)
|
|
44
|
+
elif self.feature_type == FeatureType.Path:
|
|
45
|
+
self.path.write_xml(net)
|
|
46
|
+
elif self.feature_type == FeatureType.PadstackInstance:
|
|
47
|
+
net.set("net", self.padstack_instance.net)
|
|
48
|
+
self.padstack_instance.write_xml(net)
|
|
49
|
+
elif self.feature_type == FeatureType.Drill:
|
|
50
|
+
self.drill.write_xml(net)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class FeatureType:
|
|
54
|
+
(Polygon, Path, PadstackInstance, Drill) = range(0, 4)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pyedb.generic.general_methods import ET
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Layer(object):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.name = ""
|
|
7
|
+
self._layer_function = ""
|
|
8
|
+
self._layer_side = ""
|
|
9
|
+
self._layer_polarity = ""
|
|
10
|
+
self.sequence = 0
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def layer_function(self):
|
|
14
|
+
return self._layer_function
|
|
15
|
+
|
|
16
|
+
@layer_function.setter
|
|
17
|
+
def layer_function(self, value): # pragma no cover
|
|
18
|
+
self._layer_function = value
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def layer_side(self):
|
|
22
|
+
return self._layer_side
|
|
23
|
+
|
|
24
|
+
@layer_side.setter
|
|
25
|
+
def layer_side(self, value): # pragma no cover
|
|
26
|
+
self._layer_side = value
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def layer_polarity(self):
|
|
30
|
+
return self._layer_polarity
|
|
31
|
+
|
|
32
|
+
@layer_polarity.setter
|
|
33
|
+
def layer_polarity(self, value): # pragma no cover
|
|
34
|
+
self._layer_polarity = value
|
|
35
|
+
|
|
36
|
+
def write_xml(self, cad_data): # pragma no cover
|
|
37
|
+
layer = ET.SubElement(cad_data, "Layer")
|
|
38
|
+
layer.set("name", self.name)
|
|
39
|
+
layer.set("layerFunction", self.layer_function)
|
|
40
|
+
layer.set("side", self.layer_side)
|
|
41
|
+
layer.set("polarity", self.layer_polarity)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
from pyedb.generic.general_methods import ET, pyedb_function_handler
|
|
4
|
+
from pyedb.ipc2581.ecad.cad_data.feature import Feature, FeatureType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LayerFeature(object):
|
|
8
|
+
"""Class describing IPC2581 layer feature."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, ipc):
|
|
11
|
+
self._ipc = ipc
|
|
12
|
+
self.layer_name = ""
|
|
13
|
+
self.color = ""
|
|
14
|
+
self._features = []
|
|
15
|
+
self.is_drill_feature = False
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def features(self):
|
|
19
|
+
return self._features
|
|
20
|
+
|
|
21
|
+
@features.setter
|
|
22
|
+
def features(self, value): # pragma no cover
|
|
23
|
+
if isinstance(value, list):
|
|
24
|
+
if len([feat for feat in value if isinstance(feat, Feature)]) == len(value):
|
|
25
|
+
self._features = value
|
|
26
|
+
|
|
27
|
+
@pyedb_function_handler()
|
|
28
|
+
def add_feature(self, obj_instance=None): # pragma no cover
|
|
29
|
+
if obj_instance:
|
|
30
|
+
feature = Feature(self._ipc)
|
|
31
|
+
feature.net = obj_instance.net_name
|
|
32
|
+
if obj_instance.type == "Polygon":
|
|
33
|
+
feature.feature_type = FeatureType.Polygon
|
|
34
|
+
feature.polygon.add_poly_step(obj_instance)
|
|
35
|
+
elif obj_instance.type == "Path":
|
|
36
|
+
feature.feature_type = FeatureType.Path
|
|
37
|
+
feature.path.add_path_step(obj_instance)
|
|
38
|
+
self.features.append(feature)
|
|
39
|
+
else:
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
@pyedb_function_handler()
|
|
43
|
+
def add_via_instance_feature(self, padstack_inst=None, padstackdef=None, layer_name=None): # pragma no cover
|
|
44
|
+
if padstack_inst and padstackdef:
|
|
45
|
+
feature = Feature(self._ipc)
|
|
46
|
+
def_name = padstackdef.name
|
|
47
|
+
position = padstack_inst.position if padstack_inst.position else padstack_inst.position
|
|
48
|
+
feature.padstack_instance.net = padstack_inst.net_name
|
|
49
|
+
feature.padstack_instance.isvia = True
|
|
50
|
+
feature.padstack_instance.padstack_def = def_name
|
|
51
|
+
feature.feature_type = FeatureType.PadstackInstance
|
|
52
|
+
feature.padstack_instance.x = self._ipc.from_meter_to_units(position[0], self._ipc.units)
|
|
53
|
+
feature.padstack_instance.y = self._ipc.from_meter_to_units(position[1], self._ipc.units)
|
|
54
|
+
if padstackdef._hole_params is None:
|
|
55
|
+
hole_props = [i.ToDouble() for i in padstackdef.hole_params[2]]
|
|
56
|
+
else:
|
|
57
|
+
hole_props = [i.ToDouble() for i in padstackdef._hole_params[2]]
|
|
58
|
+
feature.padstack_instance.diameter = float(hole_props[0]) if hole_props else 0
|
|
59
|
+
feature.padstack_instance.hole_name = def_name
|
|
60
|
+
feature.padstack_instance.name = padstack_inst.name
|
|
61
|
+
try:
|
|
62
|
+
if padstackdef.pad_by_layer[layer_name].parameters_values is None:
|
|
63
|
+
feature.padstack_instance.standard_primimtive_ref = "CIRCLE_{}".format(
|
|
64
|
+
self._ipc.from_meter_to_units(
|
|
65
|
+
padstackdef.pad_by_layer[layer_name].parameters_values[0], self._ipc.units
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
else:
|
|
69
|
+
feature.padstack_instance.standard_primimtive_ref = "CIRCLE_{}".format(
|
|
70
|
+
self._ipc.from_meter_to_units(
|
|
71
|
+
padstackdef.pad_by_layer[layer_name].parameters_values[0], self._ipc.units
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
self.features.append(feature)
|
|
75
|
+
except:
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
@pyedb_function_handler()
|
|
79
|
+
def add_drill_feature(self, via, diameter=0.0): # pragma no cover
|
|
80
|
+
feature = Feature(self._ipc)
|
|
81
|
+
feature.feature_type = FeatureType.Drill
|
|
82
|
+
feature.drill.net = via.net_name
|
|
83
|
+
position = via._position if via._position else via.position
|
|
84
|
+
feature.drill.x = self._ipc.from_meter_to_units(position[0], self._ipc.units)
|
|
85
|
+
feature.drill.y = self._ipc.from_meter_to_units(via.position[1], self._ipc.units)
|
|
86
|
+
feature.drill.diameter = self._ipc.from_meter_to_units(diameter, self._ipc.units)
|
|
87
|
+
self.features.append(feature)
|
|
88
|
+
|
|
89
|
+
@pyedb_function_handler()
|
|
90
|
+
def add_component_padstack_instance_feature(
|
|
91
|
+
self, component=None, pin=None, top_bottom_layers=[], padstack_def=None
|
|
92
|
+
): # pragma no cover
|
|
93
|
+
if component:
|
|
94
|
+
if pin:
|
|
95
|
+
is_via = False
|
|
96
|
+
if not pin.start_layer == pin.stop_layer:
|
|
97
|
+
is_via = True
|
|
98
|
+
pin_net = pin.GetNet().GetName()
|
|
99
|
+
pos_rot = pin._edb_padstackinstance.GetPositionAndRotationValue()
|
|
100
|
+
pin_rotation = pos_rot[2].ToDouble()
|
|
101
|
+
if pin._edb_padstackinstance.IsLayoutPin():
|
|
102
|
+
out2 = pin._edb_padstackinstance.GetComponent().GetTransform().TransformPoint(pos_rot[1])
|
|
103
|
+
pin_position = [out2.X.ToDouble(), out2.Y.ToDouble()]
|
|
104
|
+
else:
|
|
105
|
+
pin_position = [pos_rot[1].X.ToDouble(), pos_rot[1].Y.ToDouble()]
|
|
106
|
+
pin_x = self._ipc.from_meter_to_units(pin_position[0], self._ipc.units)
|
|
107
|
+
pin_y = self._ipc.from_meter_to_units(pin_position[1], self._ipc.units)
|
|
108
|
+
cmp_rot_deg = component.rotation * 180 / math.pi
|
|
109
|
+
mirror = False
|
|
110
|
+
rotation = cmp_rot_deg + pin_rotation * 180 / math.pi
|
|
111
|
+
if rotation < 0:
|
|
112
|
+
rotation += 360
|
|
113
|
+
comp_placement_layer = component.placement_layer
|
|
114
|
+
if comp_placement_layer == top_bottom_layers[-1]:
|
|
115
|
+
mirror = True
|
|
116
|
+
feature = Feature(self._ipc)
|
|
117
|
+
feature.feature_type = FeatureType.PadstackInstance
|
|
118
|
+
feature.net = pin_net
|
|
119
|
+
feature.padstack_instance.net = pin_net
|
|
120
|
+
feature.padstack_instance.pin = pin.pin.GetName()
|
|
121
|
+
feature.padstack_instance.x = pin_x
|
|
122
|
+
feature.padstack_instance.y = pin_y
|
|
123
|
+
feature.padstack_instance.rotation = rotation
|
|
124
|
+
feature.padstack_instance.mirror = mirror
|
|
125
|
+
feature.padstack_instance.isvia = is_via
|
|
126
|
+
feature.padstack_instance.refdes = component.refdes
|
|
127
|
+
feature.padstack_instance.padstack_def = padstack_def.name
|
|
128
|
+
primitive_ref = self._get_primitive_ref(padstack_def.name, comp_placement_layer)
|
|
129
|
+
if primitive_ref == "default_value":
|
|
130
|
+
other_layer = [lay for lay in top_bottom_layers if lay != comp_placement_layer][0]
|
|
131
|
+
primitive_ref = self._get_primitive_ref(padstack_def.name, other_layer)
|
|
132
|
+
feature.padstack_instance.standard_primimtive_ref = primitive_ref
|
|
133
|
+
self.features.append(feature)
|
|
134
|
+
|
|
135
|
+
@pyedb_function_handler()
|
|
136
|
+
def _get_primitive_ref(self, padstack_def=None, layer=None):
|
|
137
|
+
if padstack_def and layer:
|
|
138
|
+
for pad_def in self._ipc.ecad.cad_data.cad_data_step.padstack_defs[padstack_def].padstack_pad_def:
|
|
139
|
+
if pad_def.layer_ref == layer:
|
|
140
|
+
return pad_def.primitive_ref
|
|
141
|
+
return "default_value"
|
|
142
|
+
|
|
143
|
+
@pyedb_function_handler()
|
|
144
|
+
def write_xml(self, step): # pragma no cover
|
|
145
|
+
layer_feature = ET.SubElement(step, "LayerFeature")
|
|
146
|
+
layer_feature.set("layerRef", self.layer_name)
|
|
147
|
+
color_set = ET.SubElement(layer_feature, "Set")
|
|
148
|
+
color_ref = ET.SubElement(color_set, "ColorRef")
|
|
149
|
+
color_ref.set("id", self.layer_name)
|
|
150
|
+
for feature in self.features:
|
|
151
|
+
feature.write_xml(layer_feature)
|