tracespace
tracespace copied to clipboard
Collect board stats when processing gerber collection
(@mcous has taken over this post to elevate comment below):
New package proposal: @tracespace/stats
. It think it could have the same signature as pcb-stackup or be included in pcb-stackup by default.
As a user rendering boards, I often to collect other information about the board for manufacturing / quoting purposes. The following pieces of information should be "easy" to collect:
- Number of layers of a given type
- Minimum trace width
- Number of drill hits
- Drill sizes
- Board size
- Number of pads
- At the moment, hard to distinguish between TH and SM pads
Both @kasbah and myself have received emails about this sort of functionality. Also see #139
This could be a good thing to pair with a what's that gerber update. I've been thinking about a more sane API for wtg, and a return object (rather than a string) of something like:
{
type: 'copper',
side: 'top'
}
// and
{
type: 'drill',
side: 'all'
}
Would both be way easier to use and make something like this more straightforward
Once #77 is merged, this can be accomplished with:
const pcbStackup = require('pcb-stackup')
const wtg = require('wtg')
const layers = getLayersSomehow()
pcbStackup(layers, (error, stackup) => {
if (error) return console.error(error)
console.log(`Number of copper layers: ${
stackup.layers.filter(ly => ly.type === wtg.TYPE_COPPER).length
}`)
})
I guess pre-77, you could still do:
const pcbStackup = require('pcb-stackup')
const layers = getLayersSomehow()
pcbStackup(layers, (error, stackup) => {
if (error) return console.error(error)
console.log(`Number of copper layers: ${
stackup.layers.filter(ly => ly.type.slice(1) === 'cu').length
}`)
})
@kasbah do you think that's satisfactory to close this issue?
Thinking this might be worth a package: @tracespace/stats
or something. It think it could have the same signature as pcb-stackup
. I've gotten a few emails about various bits of information people are trying to glean, and I think there's at least a naive path forward on most of them.
- Number of layers of type
- Minimum trace width
- Minimum trace spacing
- Not sure how to do this one; it's getting into DFM checker territory
- Number of drill hits
- Drill sizes
- Board size
Yes, I agree. I was going to open an issue about minimum trace width actually as I may be able to get a paid gig to work on that.
Prior art: https://github.com/bellmann/pcb.js/blob/master/index.js
Is there any updates to this? I'm yet another person who would like to glean them juicy statistics (trace width, trace spacing, pad size being the main ones I'm looking for). Even just an idea of how to approach getting this information would be incredibly appreciated.
@mcous You mentioned having a "naive path forward" -- is there any documentation on this? I've been trying to think of an approach and the best I can do is "parse out and interpret values from the SVG markup produced by gerber-to-svg" but my unfortunate lack of PCB manufacturing and vector imaging knowledge really holds me back (that, and budget heh). And I also feel like that approach may be entirely wrong!
Thanks, and kudos on this fantastic set of utilities! Been a pleasure working with all these tools.
@dontpanic there's been some progress in the sense that the next major version of the tracespace project will be much more geared towards producing inspectable trees at various steps rather than streaming directly into an SVG string:
- Abstract syntax tree of each Gerber file
- Plot trees for each file <- this is what you'd inspect for stuff
- SVG syntax tree
You can try out (1): npm i @tracespace/parser@next
. The rest are still in progress. It would, however, be a pretty tall order to glean any information from the syntax tree itself (though it's certainly possible! At that point, you're effectively starting work on a plot tree generator...).
For now, you could try to using the existing gerber-to-svg
pipeline and hook into the plotter:
const converter = gerberToSvg(copperFileContents)
const plotter = converter.plotter
plotter.on('data', () => {
// grab tool shapes, pad flashes, and trace strokes here
// see https://github.com/tracespace/tracespace/blob/main/packages/gerber-plotter/API.md
})
From there, you could "naively" grab:
- Trace width, by looking at the tool diameter used for
stroke
plotter objects- If your Gerber file uses strokes for copper fills, like Eagle often does, this could be misleading
- Pad size, by looking at the tool shape + size params for
pad
plotter objects- Sometimes, CAD programs (still looking at Eagle) will use strokes for pads, so again, this is naive
Unfortunately, copper spacing is a much harder problem because it involves building up an actual geometric understanding of the shapes plotted rather than simply recording them
Is a there a way I can solve the strokes for pads
issue because I'm having trouble counting the pads.
In a single file I get different kinds of output.
{
type: 'shape',
tool: '10',
shape: [
{ type: 'rect', cx: 0, cy: 0, r: 0, width: 0.35, height: 0.35 },
],
},
{ type: 'pad', tool: '10', x: 43.5164, y: 30.8491 },
{ type: 'pad', tool: '10', x: 44.5164, y: 30.8491 },
{ type: 'pad', tool: '10', x: 47.9505, y: 32.7134 },
{ type: 'pad', tool: '10', x: 46.9505, y: 32.7134 },
{
type: 'stroke',
width: 0.145,
path: [
{type: 'line',start: [53.8203, 31.0353],end: [55.0653, 31.0353]},
{type: 'line',start: [55.0653, 31.0353],end: [55.0653, 30.6003]},
{type: 'line',start: [55.0653, 30.6003],end: [53.8203, 30.6003]},
{type: 'line',start: [53.8203, 30.6003],end: [53.8203, 31.0353]},
{type: 'line',start: [53.8203, 30.738],end: [55.0653, 30.738]},
{type: 'line',start: [55.0653, 30.8757],end: [53.8203, 30.8757]},
{type: 'line',start: [53.8203, 31.0134],end: [55.0653, 31.0134]},
{type: 'line',start: [55.0653, 31.9853],end: [53.8203, 31.9853]},
{type: 'line',start: [53.8203, 31.9853],end: [53.8203, 31.5503]},
{type: 'line',start: [53.8203, 31.5503],end: [55.0653, 31.5503]},
{type: 'line',start: [55.0653, 31.5503],end: [55.0653, 31.9853]},
{type: 'line',start: [53.8203, 31.688],end: [55.0653, 31.688]},
{type: 'line',start: [55.0653, 31.8257],end: [53.8203, 31.8257]},
{type: 'line',start: [53.8203, 31.9634],end: [55.0653, 31.9634]},
{type: 'line',start: [55.0653, 32.9353],end: [53.8203, 32.9353]},
{type: 'line',start: [53.8203, 32.9353],end: [53.8203, 32.5003]},
{type: 'line',start: [53.8203, 32.5003],end: [55.0653, 32.5003]},
{type: 'line',start: [55.0653, 32.5003],end: [55.0653, 32.9353]},
{type: 'line',start: [53.8203, 32.638],end: [55.0653, 32.638]},
{type: 'line',start: [55.0653, 32.7757],end: [53.8203, 32.7757]},
{type: 'line',start: [53.8203, 32.9134],end: [55.0653, 32.9134]},
{type: 'line',start: [52.7353, 32.9353],end: [51.4903, 32.9353]},
{type: 'line',start: [51.4903, 32.9353],end: [51.4903, 32.5003]},
{type: 'line',start: [51.4903, 32.5003],end: [52.7353, 32.5003]},
{type: 'line',start: [52.7353, 32.5003],end: [52.7353, 32.9353]},
{type: 'line',start: [51.4903, 32.638],end: [52.7353, 32.638]},
{type: 'line',start: [52.7353, 32.7757],end: [51.4903, 32.7757]},
{type: 'line',start: [51.4903, 32.9134],end: [52.7353, 32.9134]},
{type: 'line',start: [52.7353, 31.0353],end: [51.4903, 31.0353]},
{type: 'line',start: [51.4903, 31.0353],end: [51.4903, 30.6003]},
{type: 'line',start: [51.4903, 30.6003],end: [52.7353, 30.6003]},
{type: 'line',start: [52.7353, 30.6003],end: [52.7353, 31.0353]},
{type: 'line',start: [51.4903, 30.738],end: [52.7353, 30.738]},
{type: 'line',start: [52.7353, 30.8757],end: [51.4903, 30.8757]},
{type: 'line',start: [51.4903, 31.0134],end: [52.7353, 31.0134]},
],
}
The pads that have strokes instead of tool size have been marked
This is the file I used to extract the pads. gerber_paste_layer_example.zip
Please help.
The parameters most often required for quoting PCB manufacturing are:
- Dimensions and UOM (already available)
- Thickness
- Layer count (already available)
- Laminations - to cover blind and buried vias (any drill hole that doesn't pass through all layers requires a lamination. This significantly impacts the cost of manufacturing)
- Copper weight
- Material type (e.g. FR4)
- Finish (e.g. ENIG)
- SilkScreen color - if specified in the file
- Solder Mask (top, bottom, both)
- Solder Mask Color (e.g. green) if specified in the file
- IPC Class
- Drill sizes
- Finish
Other fields are helpful, but these are used by many PCB fab houses in determining the cost.
A lot of those are not available in the RS274-X format though. I believe more are available in Gerber X2 but Tracespace doesn't support that yet.
I've added a $500 bounty to #372 which is a start on some of this functionality: https://www.bountysource.com/issues/102825979-extract-drill-information
Feel free to add to that bounty if you have an interest in this functionality.
@kasbah aren't they available already?
I am happy to back further development of this package (especially when it comes to statistics!) but would prefer somewhat of a scope first, if feasible at all.
Not sure what you mean @ju5t, #372 has a more reduced scope. Do you mean it's already been implemented?
@kasbah sorry, you're right that there isn't a great API for this yet.