pcb-tools-extension
===
pcb-tools-extension is a Python library to panelize gerber files.
This library is designed based on [pcb-tools](https://github.com/curtacircuitos/pcb-tools) which provides cool functionality to handle PCB such as generationg PCB image from gerber files.
pcb-tools-extension adds following function to pcb-tools.
- Rotate PCB data
- Write back loaded PCB data (original pcb-tools does not work in some condition)
- Merge multiple PCB data
- Translate DXF file to PCB data
Only RS-274x format and Excellon drill format data can be handled by current version of this library.
## Installation
You can install a stable version by following step.
```shell
$ pip install pcb-tools-extension
```
If you have a intention to try latest developing version, please install as follows.
```shell
$ pip install git+https://github.com/opiopan/pcb-tools-extension.git
```
## How to panelize
Following code is a example to panelize two top metal layer files.
``` python
import gerberex
ctx = gerberex.GerberComposition()
metal1 = gerberex.read('board1.gtl')
ctx.merge(metal1)
metal2 = gerberex.read('board2.gtl')
metal2.to_metric()
metal2.rotate(-20)
metal2.offset(30, 0)
ctx.merge(metal2)
ctx.dump('panelized-board.gtl')
```
```rotate()``` method can be used to rotate PCB data counterclockwise. you have to specify angle in degree.
```offset()``` method can be used to move PCB data. Specified offset values are interpreted according to unit setting of PCB data. In case of the above code, ```board2.gtl``` move to 30mm left since ```to_metric()``` is called.
In case of Excellon drill data, you have to use ```DrillCompositon``` instead of ```GerberComposition```.
```python
import gerberex
ctx = gerberex.DrillComposition()
drill1 = gerberex.read('board1.txt')
ctx.merge(drill1)
drill2 = gerberex.read('board2.txt')
drill2.to_metric()
drill2.rotate(-20)
drill2.offset(30, 0)
ctx.merge(drill2)
ctx.dump('panelized-board.txt')
```
## DXF file translation
pcb-tools-extension hsa a function to load a DXF file and handle that as same as RX-274x gerber file or Excellon NC file.
In this version, Only line, circle, arc, and polyline objects are recognized and are translated to gerber file or NC file.
### Two way to tranlate DXF file
Both composition objects, ```GerberComposition``` for RX-274x and ```DrillionComposition``` for Excellon, can accept an object created as result of DXF file loaded. When composition object dump text stream, DXF data tranclate to appropriate format data.
The object which represent DXF file, can also output translated data directly by ```save``` method. In this case output format is specified by ```filetype``` argument. If ```filetype``` argument is ommited, DXF data is translated to RX-274x gerber data.
```python
import gerberex
dxf = gerberex.read('sample.dxf')
# translate to RX-274x using composition object
ctx = gerberex.GerberComposition()
ctx.merge(dxf)
ctx.dump('sample.gml')
# translate to Excellon using composition object
ctx = gerberex.DrillComposition()
ctx.merge(dxf)
ctx.dump('sample.txt')
# translate to RX-274x directly
dxf.save('sample2.gml')
# translate to Excellon directly
dxf.save('sample2.txt', filetype=dxf.FT_EXCELLON)
```
### Generating Rectangle
If you want to arrange simple rectangle for PCB outline, ```gerberex.rectangle()``` is better solution. This generate a object representing a rectangle compatible with DXF file object.
```python
import gerberex
outline = gerberex.rectangle(width=100, height=100, units='metric')
outline.write('outline.gml')
```
### Drawing Mode
PCB tools extension provide three type of translation method that affects geometric finish. These method are specified a value for ```draw_mode``` attribute, as ```DM_LINE```, ```DM_MOUSE_BITES```, or ```DM_FILL```.
```DM_LINE``` and ```DM_MOUSE_BITES``` are used to translate to both of RX-274x and Excellon, however ```DM_FILL``` is used to translate to only RX-274x.
![Drawing Mode](https://raw.githubusercontent.com/wiki/opiopan/pcb-tools-extension/images/draw_mode.jpg)
- **draw_mode = DM_LINE**
All edge expressed as DXF line object, circle object, arc object and plyline objects are translated to line and arc applied a circular aperture in case of RX-274x. That circular aperture radius is specified by ```width``` attribute. Default value of width is 0.
In case of Excellon, DXF objects are translated to routing path command sequence.
This function is useful to generate outline data of pnanelized PCB boad.
```python
import gerberex
dxf = gerberex.read('outline.dxf')
dxf.to_inch()
dxf.width = 0.004
dxf.write('outline.gml')
```
- **draw_mode = DM_MOUSE_BITES**
If DM_MOUSE_BITES is specified for draw_mode, filled circles are arranged at equal intervals along a paths consisted of DXF line, arc, circle, and plyline objects.
DXF file object in this state can be merged to excellon file also. That means you can arrange mouse bites easily.
```python
import gerberex
ctx = gerberex.DrillComposition()
drill = gerberex.read('drill.txt')
ctx.merge(drill)
dxf = gerberex.read('mousebites.dxf')
dxf.draw_mode = dxf.DM_MOUSE_BITES
dxf.to_metric()
dxf.width = 0.5
dxf.pitch = 1
ctx.merge(dxf)
ctx.dump('merged_drill.txt')
```
- **draw_mode = DM_FILL**
You can translate DXF closed shapes such as circle to RX-274x polygon fill sequence.
In order to fill closed shapes, ```DM_FILL``` has to be set to ```draw_mode``` property. In this mode, All object except closed shapes listed below are ignored.
- circle
- closed polyline
- closed path which consists of lines and arcs
If a closed shape is completly included in other closed shape, The inner shape will be draw with reversed polality of container shape as above example image.
I assume there are two typical use cases for this mode.
One is to arrange logo design on silk layer. This is superior to other method generating raster image data since image data express as vector data.
The other one is generating gerber data represented cropped area of panelized PCB.
By merging rectangle and PCB outline data, generate a file represented cropped area as below, and this kind of data is useful to make PCB image look good a little bit.
[This script](https://github.com/opiopan/pcb-tools-extension/blob/master/examples/genimage.py) which generate example image shown below, also uses this technic.
```python
import gerberex
ctx = gerberex.GerberComposition()
rectangle = gerberex.rectangle(width=100, height=100, left=0, bottom=0, units='metric')
rectangle.draw_mode = rectangle.DM_FILL
ctx.merge(rectangle)
outline = gerberex.read('outline.dxf')
outline.draw_mode = outline.DM_FILL
outline.negate_polarity()
ctx.merge(outline)
ctx.dump('cropped_area.gml')
```
NOTE: ```DM_FILL``` can be used only to generate RX-274x data, it cannot be used to generate Excellon data.
## Panelizing Example
This example board image is generated by following scripts from [these source data](https://github.com/opiopan/pcb-tools-extension/tree/master/examples/inputs).
- [panelizing script](https://github.com/opiopan/pcb-tools-extension/blob/master/examples/panelize.py)
- [imaging script](https://github.com/opiopan/pcb-tools-extension/blob/master/examples/genimage.py)
## Notes ### Equivalence of output pcb-tools-extension generate data block stream to focus equivalence of final image, but not focus equivalence of data block sequence. There are some difference between input data and output data as below. - **Aperture definition [RS-274x]**