New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

gerber-plotter

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gerber-plotter - npm Package Compare versions

Comparing version 0.1.4 to 1.0.0

lib/index.js

46

API.md

@@ -9,3 +9,3 @@ # gerber plotter api

var gerberPlotter = require('gerber-plotter')
var plotter = gerberParser(OPTIONS)
var plotter = gerberPlotter(OPTIONS)
```

@@ -15,3 +15,3 @@

Use the gerber plotter like you would any other [Node stream](https://github.com/substack/stream-handbook).
The plotter is a [Node Transform Stream](https://nodejs.org/api/stream.html#stream_class_stream_transform) in object mode. For more information about working with Node streams, read [@substack's stream handbook](https://github.com/substack/stream-handbook).

@@ -29,9 +29,37 @@ ### options

key | value | description
--------------|--------------|---------------------------------------------
`units` | `mm` or `in` | PCB units
`backupUnits` | `mm` or `in` | Backup units in case units are missing
`nota` | `A` or `I` | Absolute or incremental coordinate notation
`backupNota` | `A` or `I` | Backup notation in case notation is missing
key | value | default | description
----------------|--------------|---------|---------------------------------------------------------
`units` | `mm` or `in` | N/A | PCB units
`backupUnits` | `mm` or `in` | `in` | Backup units in case units are missing
`nota` | `A` or `I` | N/A | Absolute or incremental coordinate notation
`backupNota` | `A` or `I` | `A` | Backup notation in case notation is missing
`optimizePaths` | Boolean | `false` | Optimize order of paths in strokes and regions
`plotAsOutline` | Boolean | `false` | Treat layer as an outline by combining all tools for paths
#### units and backup units options
Setting `units` will set the plot units of the file regardless of any units that are specified in the file itself. Setting `backupUnits` specifies a fallback that will only be used if there are no units specified in the file.
#### notation and backup notation options
Coordinates in a Gerber / drill file will either be absolute (common and recommended) or incremental (uncommon and deprecated by the Gerber spec). Setting `nota` will override any settings in the Gerber file, while `backupNota` will be used as a fallback if that setting is missing.
#### optimize paths option
This option is off by default. When `optimizePaths` is true, the plotter will reorganize segments in any given stroke or region for file-size efficiency at the expense of plotting speed. It does this by gathering all points and segments and then re-playing them in adjacency order. This results in smaller stroke and fill objects by removing unnecessary plotter moves.
For example, with `optimizePaths` on, if the Gerber file says `MOVE TO (1, 1); LINE TO (2, 1); MOVE TO (2, 2); LINE TO (2, 1)`, the plotter will convert that to `LINE FROM (1, 1) TO (2, 1); LINE FROM (2, 1) TO (2, 2)`
Setting this option to `false` will speed up plotting at the expense of ensuring paths are as efficient as possible.
#### plot as outline option
This option is off by default. When `plotAsOutline` is true, the plotter will take several actions:
* The `optimizePaths` option will be forced to true
* All stroke tools will be merged into one tool (the first tool in the file used for a stroke)
* The bounding box of the file will be calculated as if all strokes are done in region mode
This option exists to take an image representing an outline layer and optimize it to get at the board information the layer represents. Often, outline layers will (accidentally) use different tools for the same line. Additionally, the size of the board is determined by the center of the edge line, rather than the outside of the line, hence switching the size calculation of the path to region mode.
## public properties

@@ -160,3 +188,3 @@

Regardless of the order they appear in the gerber file itself, this library will try to ensure that any segments from a given tool until the region mode is changed will be places adjacently in `path`. For example, if the Gerber file says `MOVE TO (1, 1); LINE TO (2, 1); MOVE TO (2, 2); LINE TO (2, 1)`, the library will convert that to `LINE FROM (1, 1) TO (2, 1); LINE FROM (2, 1) TO (2, 2)`
The `path` array of these objects will be smaller if the `optimizePaths` option is set to true.

@@ -163,0 +191,0 @@ ``` javascript

@@ -147,5 +147,41 @@ // operate the plotter

var drawArc = function(start, end, offset, tool, mode, arc, region, epsilon, pathGraph, plotter) {
var roundToZero = function(number, epsilon) {
return (number >= epsilon) ? number : 0
}
// find the center of an arc given its endpoints and its radius
// assume the arc is <= 180 degress
// thank you this guy: http://math.stackexchange.com/a/87912
var arcCenterFromRadius = function(start, end, mode, epsilon, radius) {
var sign = (mode === 'ccw') ? 1 : -1
var xAve = (start[0] + end[0]) / 2
var yAve = (start[1] + end[1]) / 2
var deltaX = end[0] - start[1]
var deltaY = end[1] - start[1]
var distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2))
var halfDistance = distance / 2
var squareDifference = Math.sqrt(Math.pow(radius, 2) - Math.pow(halfDistance, 2))
var xOffset = -sign * deltaY * squareDifference / distance
var yOffset = sign * deltaX * squareDifference / distance
return [[
roundToZero(xAve + xOffset, epsilon),
roundToZero(yAve + yOffset, epsilon)
]]
}
var drawArc = function(
start,
end,
offset,
tool,
mode,
arc,
region,
epsilon,
pathGraph,
plotter) {
// get the radius of the arc from the offsets
var r = Math.sqrt(Math.pow(offset[0], 2) + Math.pow(offset[1], 2))
var r = offset[2] || Math.sqrt(Math.pow(offset[0], 2) + Math.pow(offset[1], 2))

@@ -179,8 +215,18 @@ // potential candidates for the arc center

// find valid centers by comparing the distance to start and end for equality with the radius
var validCenters = (arc === 'm') ? candidates : filter(candidates, function(c) {
var startDist = Math.sqrt(Math.pow(c[0] - start[0], 2) + Math.pow(c[1] - start[1], 2))
var endDist = Math.sqrt(Math.pow(c[0] - end[0], 2) + Math.pow(c[1] - end[1], 2))
var validCenters
if (offset[2]) {
arc = 'm'
validCenters = arcCenterFromRadius(start, end, mode, epsilon, offset[2])
}
else if (arc === 's') {
validCenters = filter(candidates, function(c) {
var startDist = Math.sqrt(Math.pow(c[0] - start[0], 2) + Math.pow(c[1] - start[1], 2))
var endDist = Math.sqrt(Math.pow(c[0] - end[0], 2) + Math.pow(c[1] - end[1], 2))
return ((Math.abs(startDist - r) <= epsilon) && (Math.abs(endDist - r) <= epsilon))
})
return ((Math.abs(startDist - r) <= epsilon) && (Math.abs(endDist - r) <= epsilon))
})
}
else {
validCenters = candidates
}

@@ -312,3 +358,3 @@ var cenAndAngles = findCenterAndAngles(start, end, mode, arc, validCenters)

if ((region === false) && (tool.trace.length === 0)) {
if (!region && (tool.trace.length === 0)) {
plotter._warn('tool ' + tool.code + ' is not strokable; ignoring interpolate')

@@ -320,3 +366,3 @@ return boundingBox.new()

// add a line to the path normally if region mode is on or the tool is a circle
if ((region === true) || (tool.trace.length === 1)) {
if (region || (tool.trace.length === 1)) {
return drawLine(start, end, tool, region, pathGraph)

@@ -330,3 +376,3 @@ }

// else, make sure we're allowed to be drawing an arc, then draw an arc
if ((tool.trace.length !== 1) && (region === false)) {
if ((tool.trace.length !== 1) && !region) {
plotter._warn('cannot draw an arc with a non-circular tool')

@@ -351,3 +397,4 @@ return boundingBox.new()

((coord.i != null) ? coord.i : 0),
((coord.j != null) ? coord.j : 0)
((coord.j != null) ? coord.j : 0),
coord.a
]

@@ -354,0 +401,0 @@

2

lib/_pad-shape.js

@@ -320,3 +320,3 @@ // returns a pad shape array given a tool definition

var toolShape = tool.shape
var params = tool.val
var params = tool.params
var holeShape

@@ -323,0 +323,0 @@ var shapeAndBox

@@ -7,2 +7,3 @@ // utilities to create a graph of path segments and traverse that graph

var find = require('lodash.find')
var map = require('lodash.map')

@@ -26,5 +27,6 @@ var pointsEqual = function(point, target) {

var PathGraph = function() {
var PathGraph = function(optimize) {
this._points = []
this._edges = []
this._optimize = optimize

@@ -35,10 +37,15 @@ this.length = 0

PathGraph.prototype.add = function(newSeg) {
var start = find(this._points, function(point) {
return pointsEqual(point.position, newSeg.start)
})
var start
var end
var end = find(this._points, function(point) {
return pointsEqual(point.position, newSeg.end)
})
if (this._optimize) {
start = find(this._points, function(point) {
return pointsEqual(point.position, newSeg.start)
})
end = find(this._points, function(point) {
return pointsEqual(point.position, newSeg.end)
})
}
if (!start) {

@@ -64,2 +71,6 @@ start = {position: newSeg.start, edges: []}

PathGraph.prototype.traverse = function() {
if (!this._optimize) {
return map(this._edges, 'segment')
}
var walked = fill(Array(this._edges.length), false)

@@ -66,0 +77,0 @@ var discovered = []

{
"name": "gerber-plotter",
"version": "0.1.4",
"version": "1.0.0",
"description": "Transform stream that takes objects from gerber-parser and emits PCB image objects",
"main": "lib/gerber-plotter.js",
"main": "lib/index.js",
"scripts": {
"lint": "eslint lib/*.js test/*.js",
"test": "istanbul cover --include-all-sources _mocha",
"test": "istanbul cover --include-all-sources _mocha -- -t 500",
"posttest": "npm run lint",
"test-watch": "mocha --reporter dot --watch",
"browser": "zuul --local -- ./test/*_test.js",
"browser-phantom": "zuul --phantom -- ./test/*_test.js",
"browser-sauce": "zuul -- ./test/*_test.js",
"ci": "npm test && if [ \"${TEST_BROWSERS}\" = \"true\" ]; then npm run ci-browser; fi",
"ci-browser": "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then npm run browser-sauce; fi",
"test:watch": "mocha -t 500 --reporter dot --watch",
"test:browser": "zuul --local -- ./test/*_test.js",
"test:sauce": "zuul -- ./test/*_test.js",
"ci": "npm test && if [ \"${TEST_BROWSERS}\" = \"true\" ]; then npm run ci:browser; fi",
"ci:browser": "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then npm run test:sauce; fi",
"postci": "coveralls < ./coverage/lcov.info"
},
"pre-commit": [
"lint"
],
"repository": {

@@ -44,30 +40,28 @@ "type": "git",

"chai": "^3.2.0",
"coveralls": "^2.11.4",
"eslint": "^1.3.1",
"istanbul": "^0.4.0",
"coveralls": "^2.11.9",
"eslint": "^2.9.0",
"istanbul": "^0.4.3",
"mocha": "^2.3.1",
"phantomjs": "^1.9.18",
"pre-commit": "^1.1.1",
"zuul": "^3.4.0"
"zuul": "^3.10.1"
},
"peerDependencies": {
"gerber-parser": "^0.1.2"
"gerber-parser": "^1.0.0"
},
"dependencies": {
"lodash.assign": "^3.2.0",
"lodash.clone": "^3.0.3",
"lodash.fill": "^3.2.2",
"lodash.filter": "^3.1.1",
"lodash.find": "^3.2.1",
"lodash.foreach": "^3.0.3",
"lodash.foreachright": "^3.0.2",
"lodash.has": "^3.2.1",
"lodash.isfinite": "^3.2.0",
"inherits": "^2.0.1",
"lodash.clone": "^4.3.2",
"lodash.fill": "^3.3.4",
"lodash.filter": "^4.3.0",
"lodash.find": "^4.3.0",
"lodash.foreach": "^4.2.0",
"lodash.foreachright": "^4.1.0",
"lodash.has": "^4.3.1",
"lodash.isfinite": "^3.3.1",
"lodash.isfunction": "^3.0.6",
"lodash.mapvalues": "^3.0.1",
"lodash.pick": "^3.1.0",
"lodash.reduce": "^3.1.2",
"lodash.transform": "^3.0.4",
"readable-stream": "^2.0.2"
"lodash.map": "^4.3.0",
"lodash.mapvalues": "^4.3.0",
"lodash.reduce": "^4.3.0",
"lodash.transform": "^4.3.0",
"readable-stream": "^2.1.2"
}
}
# gerber plotter
[![npm](https://img.shields.io/npm/v/gerber-plotter.svg?style=flat-square)](https://www.npmjs.com/package/gerber-plotter)

@@ -25,5 +26,9 @@ [![Travis](https://img.shields.io/travis/mcous/gerber-plotter.svg?style=flat-square)](https://travis-ci.org/mcous/gerber-plotter)

plotter.on('warning', function(w) {
console.warn(`plotter warning at line ${w.line}: ${w.message}`)
console.warn('plotter warning at line ' + w.line + ': ' + w.message)
})
plotter.once('error', function(e) {
console.error('plotter error: ' + e.message)
})
fs.createReadStream('/path/to/gerber/file.gbr', {encoding: 'utf8'})

@@ -33,3 +38,3 @@ .pipe(parser)

.on('data', function(obj) {
console.log(obj)
console.log(JSON.stringify(obj))
})

@@ -46,3 +51,3 @@ ```

Tests are written in [Mocha](http://mochajs.org/) and run in Node, [PhantomJS](http://phantomjs.org/), and a variety of browsers with [Zuul](https://github.com/defunctzombie/zuul) and [Open Sauce](https://saucelabs.com/opensauce/). All PRs should be accompanied by unit tests, with ideally one feature / bugfix per PR. Code linting happens with [ESLint](http://eslint.org/) automatically post-test and pre-commit.
Tests are written in [Mocha](http://mochajs.org/) and run in Node and a variety of browsers with [Zuul](https://github.com/defunctzombie/zuul) and [Open Sauce](https://saucelabs.com/opensauce/). All PRs should be accompanied by unit tests, with ideally one feature / bugfix per PR. Code linting happens with [ESLint](http://eslint.org/) automatically post-test.

@@ -55,9 +60,10 @@ Code is deployed on tags via [TravisCI](https://travis-ci.org/) and code coverage is tracked with [Coveralls](https://coveralls.io/).

* `$ npm run test` - runs Node unit tests
* `$ npm run test-watch` - runs unit tests and re-runs on changes
* `$ npm run browser-test` - runs tests in a local browser
* `$ npm run browser-test-phantom` - runs tests in PhantomJS
* `$ npm run browser-test-sauce` - runs tests in Sauce Labs on multiple browsers
* `$ npm run test:watch` - runs unit tests and re-runs on changes
* `$ npm run test:browser` - runs tests in a local browser
* `$ npm run test:sauce` - runs tests in Sauce Labs on multiple browsers
* Sauce Labs account required
* Local [.zuulrc](https://github.com/defunctzombie/zuul/wiki/Zuulrc) required
* `$ npm run ci` - Script for CI server to run
* Runs `npm test` and sends coverage report to Coveralls
* If you want to run this locally, you'll need to set some environment variables
* If not a PR, runs browser tests in Sauce
* Not designed to (and won't) run locally

@@ -10,3 +10,3 @@ 'use strict'

beforeEach(function() {
p = new PathGraph()
p = new PathGraph(true)
})

@@ -130,2 +130,26 @@

})
it('should not optimize the path if passed a false during construction', function() {
p = new PathGraph(false)
p.add({type: 'line', start: [0, 0], end: [1, 0]})
p.add({type: 'line', start: [0, 0], end: [-1, 0]})
p.add({type: 'line', start: [0, 1], end: [1, 1]})
p.add({type: 'line', start: [-1, -1], end: [0, -1]})
p.add({type: 'line', start: [0, 0], end: [0, 1]})
p.add({type: 'line', start: [0, 0], end: [0, -1]})
p.add({type: 'line', start: [1, 0], end: [1, 1]})
p.add({type: 'line', start: [-1, 0], end: [-1, -1]})
expect(p.traverse()).to.eql([
{type: 'line', start: [0, 0], end: [1, 0]},
{type: 'line', start: [0, 0], end: [-1, 0]},
{type: 'line', start: [0, 1], end: [1, 1]},
{type: 'line', start: [-1, -1], end: [0, -1]},
{type: 'line', start: [0, 0], end: [0, 1]},
{type: 'line', start: [0, 0], end: [0, -1]},
{type: 'line', start: [1, 0], end: [1, 1]},
{type: 'line', start: [-1, 0], end: [-1, -1]}
])
})
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc