You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This may be out of scope for this project, but I think pygerber has enough infrastructure to add support for IPC2581. That standard is supported by an increasing number of board houses and CAD packages, and parsing the files is fairly straightforward.
A CAD packages produces a .cvg file, which is an XML file following the IPC2581 standard. Unfortunately, the standard is not freely available (unless you become a member, which is free). Even still, being a plain text XML file it's easy to understand the structure:
IPC-2581 (root)
Content - Layer names, color dictionary, standard shapes with units
LogisticHeader - Owner and enterprise information, if applicable
Bom - Collection of BomItems, each having attributes relating to a component in the BOM
Ecad - Layer stackup and materials, layer geometry
Most interesting is the Ecad node. It is divided into CadHeader and CadData. The CadHeader has layers in Spec nodes which have optional MATERIAL properties, e.g. Solder Resist. The CadData node contains layer information (each layer has a name, function, side, and polarity), stackup information under a Stackup node, and actual geometry (both traces and component geometry) under a Step node.
This is not comprehensive, it's built up based on a random example file I had.
Examples
Parsing Layers and Nets
defget_layer_list(root: ET.Element):
""" Return a list of layers in dictionary format for this document Parameters ---------- root : ET.Element Returns ------- List of layer dictionaries with elements: name Layer name layerFunction Layer function as a string, one of {'DRILL', 'DOCUMENT', 'PASTEMASK', 'LEGEND', 'SOLDERMASK', 'SIGNAL', 'DIELCORE'} side PCB side, one of {'TOP', 'BOTTOM', 'INTERNAL'} polarity Layer drawing polarity, one of {'POSITIVE','NEGATIVE'} thickness Layer thickness as float sequence Layer sequence position as int z Layer z position as float (bottom is z=0) """rpf='{http://webstds.ipc.org/2581}'# Root prefix# Get layer names and functionslayers=root.findall(f'{rpf}Ecad/{rpf}CadData/{rpf}Layer')
layers= [l.attribforlinlayers]
# Get layer thicknessesforlayerinlayers:
name=layer['name']
stackuplayer=root.find(
f'{rpf}Ecad/{rpf}CadData/{rpf}Stackup/{rpf}StackupGroup/{rpf}StackupLayer[@layerOrGroupRef="{name}"]')
layer['thickness'] =float(stackuplayer.attrib['thickness'])
layer['sequence'] =int(stackuplayer.attrib['sequence'])
thicknesses= [layer['thickness'] forlayerinlayers]
zpos=np.cumsum(-np.array(thicknesses)) +np.sum(thicknesses)
fori, layerinenumerate(layers):
layer['z'] =np.around(zpos[i], decimals=6)
returnlayersdefget_layer_net_list(root: ET.Element, layername: str):
""" Return list of layer nets (as strings) given root and layer name Parameters ---------- root : ET.Element layername : str Returns ------- None. """rpf='{http://webstds.ipc.org/2581}'# Root prefixLayerFeatureRoot=root.find(f'{rpf}Ecad/{rpf}CadData/{rpf}Step/{rpf}LayerFeature[@layerRef="{layername}"]')
LayerSets=LayerFeatureRoot.findall(f'{rpf}Set')
netnames= []
forlsetinLayerSets:
if'net'inlset.attrib.keys():
#if lset.attrib['net'] != 'No Net':netnames.append(lset.attrib['net'])
returnnetnames
Parsing Line and Arc Elements
defparse_Line_element(line_elem: ET.Element, z: float=0.):
""" Given the XML element for a Line, parse into an OCCT Geom_TrimmedCurve :param line_elem: :param z: z-coordinate for layer """prec=10# number of decimal places to keep, in case of precision issuesstartX=np.around(float(line_elem.attrib['startX']), prec)
startY=np.around(float(line_elem.attrib['startY']), prec)
endX=np.around(float(line_elem.attrib['endX']), prec)
endY=np.around(float(line_elem.attrib['endY']), prec)
start_pt= (startX, startY, z)
end_pt= (endX, endY, z)
LineDesc_elem=line_elem.find(f'{rpf}LineDesc')
tracewidth=np.around(float(LineDesc_elem.attrib['lineWidth']), 3)
endstyle=LineDesc_elem.attrib['lineEnd']
defparse_Arc_element(arc_elem: ET.Element, z: float=0.):
""" Given the XML element for an Arc, parse into an OCCT Geom_TrimmedCurve :param arc_elem: :param z: """prec=10startX=np.around(float(arc_elem.attrib['startX']), prec)
startY=np.around(float(arc_elem.attrib['startY']), prec)
endX=np.around(float(arc_elem.attrib['endX']), prec)
endY=np.around(float(arc_elem.attrib['endY']), prec)
centerX=np.around(float(arc_elem.attrib['centerX']), prec)
centerY=np.around(float(arc_elem.attrib['centerY']), prec)
is_cw=bool(arc_elem.attrib['clockwise'] =='true')
start_pt= (startX, startY, z)
end_pt= (endX, endY, z)
center_pt= (centerX, centerY, z)
radius=distance(center_pt,start_pt)
LineDesc_elem=arc_elem.find(f'{rpf}LineDesc')
tracewidth=np.around(float(LineDesc_elem.attrib['lineWidth']), 3)
endstyle=LineDesc_elem.attrib['lineEnd']
IPC2581 has information on geometry, stackup, BOM, components, vias, and pads. This means generating 3D geometry is possible without any additional information, and everything is in a single file which is convenient. I wrote myself a simple proof-of-concept program that uses Open CASCADE Technology (OCCT) as the geometry kernel, so you can generate .IGES and .STEP files. The only tools available for generating CAD data from Gerbers or IPC2581 .cvg files seem to be paid tools (e.g. Zofsz, NETEX-G) so including basic export functionality for STEP or IGES could be a good addition. But that's just one reason why IPC2581 support would be beneficial.
The text was updated successfully, but these errors were encountered:
In general PyGerber was designed with support for other PCB-realted file formats in mind and hence addiotion of IPC-2851 related modules is welcome. I have reached out to IPC-2581 consortium via contact form, we will see how they respond. I am not so keen on reverse enginieering the format as I am not interested in facing legal action for violation of intelectual property. Additionally I would like the implementation to be high quality rather than limited by what we could have guessed on our own.
Assuming positive response on their side, we could look into implementation of IPC-2851. I must admit that currently I don't have enough processing capacity to tackle it myself, so help would be welcome.
Since implementation will likely require additional dependencies I would prefer to have this feature as dedicated extras set to avoid limiting poratability of PyGerber and keep minimal set of dependencies required to use core functionalities of PyGerber (similarily to how language server and SVG rendering is done). Implementation details are yet to be discussed, but I would like to mention tools like CadQuery and lxml/BeautifulSoup4 which could be helpful in implementing IPC-2851.
I hope that Ucamco wont feel ofended by addition IPC-2851 but if they happen to be, we will probably resort to creating separate library for that.
This may be out of scope for this project, but I think
pygerber
has enough infrastructure to add support for IPC2581. That standard is supported by an increasing number of board houses and CAD packages, and parsing the files is fairly straightforward.A CAD packages produces a
.cvg
file, which is an XML file following the IPC2581 standard. Unfortunately, the standard is not freely available (unless you become a member, which is free). Even still, being a plain text XML file it's easy to understand the structure:IPC-2581
(root)Content
- Layer names, color dictionary, standard shapes with unitsLogisticHeader
- Owner and enterprise information, if applicableBom
- Collection ofBomItem
s, each having attributes relating to a component in the BOMEcad
- Layer stackup and materials, layer geometryMost interesting is the
Ecad
node. It is divided intoCadHeader
andCadData
. TheCadHeader
has layers inSpec
nodes which have optionalMATERIAL
properties, e.g.Solder Resist
. TheCadData
node contains layer information (each layer has a name, function, side, and polarity), stackup information under aStackup
node, and actual geometry (both traces and component geometry) under aStep
node.Here's a sort of tree view of the nodes:
This is not comprehensive, it's built up based on a random example file I had.
Examples
Parsing Layers and Nets
Parsing Line and Arc Elements
IPC2581 has information on geometry, stackup, BOM, components, vias, and pads. This means generating 3D geometry is possible without any additional information, and everything is in a single file which is convenient. I wrote myself a simple proof-of-concept program that uses Open CASCADE Technology (OCCT) as the geometry kernel, so you can generate .IGES and .STEP files. The only tools available for generating CAD data from Gerbers or IPC2581
.cvg
files seem to be paid tools (e.g. Zofsz, NETEX-G) so including basic export functionality for STEP or IGES could be a good addition. But that's just one reason why IPC2581 support would be beneficial.The text was updated successfully, but these errors were encountered: