mirror of
https://github.com/scottbez1/smartknob.git
synced 2025-09-26 23:09:27 +08:00
Fab automation (#2)
- Use KiKit for fab automation - Add splitflap scripts for exporting pcb pdfs, and switch to splitflap script for 3d rendering (for consistency with fab automation) - Added support in 3d rendering scripts for soldermask & silkscreen colors, option to skip virtual components - Added silkscreen to base and screen pcbs for commit and date info
This commit is contained in:
parent
8957d8b28e
commit
56feeb484c
57
.github/workflows/electronics.yml
vendored
57
.github/workflows/electronics.yml
vendored
@ -14,13 +14,62 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Set up outputs directory
|
- name: Set up outputs directory
|
||||||
run: mkdir -p electronics/build
|
run: mkdir -p electronics/build/outputs
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: ./electronics/scripts/dependencies.sh
|
||||||
|
|
||||||
|
- name: Export JLCPCB fabrication files [view_base]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/export_jlcpcb.py electronics/view_base/view_base.kicad_pcb
|
||||||
|
cp -r electronics/build/view_base-jlc electronics/build/outputs
|
||||||
|
|
||||||
|
- name: Export PCB overview PDF [view_base]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/generate_pdf.py electronics/view_base/view_base.kicad_pcb
|
||||||
|
cp electronics/build/view_base-pcb-packet.pdf electronics/build/outputs
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
|
- name: Render PCB 3D [view_base]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/export_3d.py electronics/view_base/view_base.kicad_pcb --suffix front --width 1280 --height 1280 --skip-virtual --color-soldermask 0.95 0.95 0.95 --color-silk 0.1 0.1 0.1 transform z+ z+
|
||||||
|
cp electronics/build/view_base-front-3d.png electronics/build/outputs
|
||||||
|
./scripts/annotate_image.sh electronics/build/outputs/view_base-front-3d.png
|
||||||
|
./electronics/scripts/export_3d.py electronics/view_base/view_base.kicad_pcb --suffix back --width 1280 --height 1280 --skip-virtual --color-soldermask 0.95 0.95 0.95 --color-silk 0.1 0.1 0.1 transform z+ z+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+
|
||||||
|
cp electronics/build/view_base-back-3d.png electronics/build/outputs
|
||||||
|
./scripts/annotate_image.sh electronics/build/outputs/view_base-back-3d.png
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
|
- name: Export JLCPCB fabrication files [view_screen]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/export_jlcpcb.py electronics/view_screen/view_screen.kicad_pcb
|
||||||
|
cp -r electronics/build/view_screen-jlc electronics/build/outputs
|
||||||
|
|
||||||
|
- name: Export PCB overview PDF [view_screen]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/generate_pdf.py electronics/view_screen/view_screen.kicad_pcb
|
||||||
|
cp electronics/build/view_screen-pcb-packet.pdf electronics/build/outputs
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
|
- name: Render PCB 3D [view_screen]
|
||||||
|
run: |
|
||||||
|
./electronics/scripts/export_3d.py electronics/view_screen/view_screen.kicad_pcb --suffix front --width 1280 --height 1280 --skip-virtual --color-soldermask 0.95 0.95 0.95 --color-silk 0.1 0.1 0.1 transform z+ z+
|
||||||
|
cp electronics/build/view_screen-front-3d.png electronics/build/outputs
|
||||||
|
./scripts/annotate_image.sh electronics/build/outputs/view_screen-front-3d.png
|
||||||
|
./electronics/scripts/export_3d.py electronics/view_screen/view_screen.kicad_pcb --suffix back --width 1280 --height 1280 --skip-virtual --color-soldermask 0.95 0.95 0.95 --color-silk 0.1 0.1 0.1 transform z+ z+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+ ry+
|
||||||
|
cp electronics/build/view_screen-back-3d.png electronics/build/outputs
|
||||||
|
./scripts/annotate_image.sh electronics/build/outputs/view_screen-back-3d.png
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
- name: Export artifacts (KiBot) [view_base]
|
- name: Export artifacts (KiBot) [view_base]
|
||||||
uses: INTI-CMNB/KiBot@fb6d637c17fbba2daf005a9a7972e4c02c1c997c
|
uses: INTI-CMNB/KiBot@fb6d637c17fbba2daf005a9a7972e4c02c1c997c
|
||||||
with:
|
with:
|
||||||
config: electronics/view_base/view_base.kibot.yml
|
config: electronics/view_base/view_base.kibot.yml
|
||||||
dir: electronics/build
|
dir: electronics/build/outputs
|
||||||
schema: 'electronics/view_base/view_base.sch'
|
schema: 'electronics/view_base/view_base.sch'
|
||||||
board: 'electronics/view_base/view_base.kicad_pcb'
|
board: 'electronics/view_base/view_base.kicad_pcb'
|
||||||
|
|
||||||
@ -28,7 +77,7 @@ jobs:
|
|||||||
uses: INTI-CMNB/KiBot@fb6d637c17fbba2daf005a9a7972e4c02c1c997c
|
uses: INTI-CMNB/KiBot@fb6d637c17fbba2daf005a9a7972e4c02c1c997c
|
||||||
with:
|
with:
|
||||||
config: electronics/view_screen/view_screen.kibot.yml
|
config: electronics/view_screen/view_screen.kibot.yml
|
||||||
dir: electronics/build
|
dir: electronics/build/outputs
|
||||||
schema: 'electronics/view_screen/view_screen.sch'
|
schema: 'electronics/view_screen/view_screen.sch'
|
||||||
board: 'electronics/view_screen/view_screen.kicad_pcb'
|
board: 'electronics/view_screen/view_screen.kicad_pcb'
|
||||||
|
|
||||||
@ -51,5 +100,5 @@ jobs:
|
|||||||
- name: Sync artifacts to S3
|
- name: Sync artifacts to S3
|
||||||
if: github.event_name == 'push' && github.repository_owner == 'scottbez1'
|
if: github.event_name == 'push' && github.repository_owner == 'scottbez1'
|
||||||
run: |
|
run: |
|
||||||
aws s3 sync electronics/build s3://smartknob-artifacts/${GITHUB_REF#refs/heads/}/electronics --delete --cache-control max-age=0,no-cache
|
aws s3 sync electronics/build/outputs s3://smartknob-artifacts/${GITHUB_REF#refs/heads/}/electronics --delete --cache-control max-age=0,no-cache
|
||||||
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -27,3 +27,5 @@ build/
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
!.vscode/*.code-snippets
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
__pycache__
|
||||||
|
|
||||||
|
23
README.md
23
README.md
@ -13,11 +13,11 @@ Premium SmartKnob experience. Under active development. Untested & unproven.
|
|||||||
|
|
||||||
#### Base PCB
|
#### Base PCB
|
||||||
|
|
||||||
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-3D_top.png">
|
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-front-3d.png">
|
||||||
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-3D_top.png" width="300" />
|
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-front-3d.png" width="300" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-3D_bottom.png">
|
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-back-3d.png">
|
||||||
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-3D_bottom.png" width="300" />
|
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-back-3d.png" width="300" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
@ -25,13 +25,17 @@ Premium SmartKnob experience. Under active development. Untested & unproven.
|
|||||||
|
|
||||||
[Interactive BOM](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-ibom.html)
|
[Interactive BOM](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-ibom.html)
|
||||||
|
|
||||||
|
[PCB Packet](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-pcb-packet.pdf)
|
||||||
|
|
||||||
|
[Gerbers](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_base-jlc/gerbers.zip)
|
||||||
|
|
||||||
#### Screen PCB
|
#### Screen PCB
|
||||||
|
|
||||||
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-3D_top.png">
|
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-front-3d.png">
|
||||||
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-3D_top.png" width="300" />
|
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-front-3d.png" width="300" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-3D_bottom.png">
|
<a href="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-back-3d.png">
|
||||||
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-3D_bottom.png" width="300" />
|
<img src="https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-back-3d.png" width="300" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +43,9 @@ Premium SmartKnob experience. Under active development. Untested & unproven.
|
|||||||
|
|
||||||
[Interactive BOM](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-ibom.html)
|
[Interactive BOM](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-ibom.html)
|
||||||
|
|
||||||
|
[PCB Packet](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-pcb-packet.pdf)
|
||||||
|
|
||||||
|
[Gerbers](https://smartknob-artifacts.s3.us-west-1.amazonaws.com/master/electronics/view_screen-jlc/gerbers.zip)
|
||||||
|
|
||||||
### SmartKnob Handheld
|
### SmartKnob Handheld
|
||||||
An exploration of a small handheld form-factor. Under active development.
|
An exploration of a small handheld form-factor. Under active development.
|
||||||
|
0
__init__.py
Normal file
0
__init__.py
Normal file
0
electronics/scripts/__init__.py
Normal file
0
electronics/scripts/__init__.py
Normal file
87
electronics/scripts/config/eeschema
Normal file
87
electronics/scripts/config/eeschema
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
SchematicFramePos_x=89
|
||||||
|
SchematicFramePos_y=38
|
||||||
|
SchematicFrameSize_x=1125
|
||||||
|
SchematicFrameSize_y=739
|
||||||
|
SchematicFrameMaximized=0
|
||||||
|
SchematicFrameAutoSaveInterval=600
|
||||||
|
SchematicFramePerspective=layout2|name=MainToolbar;caption=;state=139644;dir=1;layer=6;row=0;pos=0;prop=100000;bestw=1016;besth=36;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=OptToolbar;caption=;state=139596;dir=4;layer=3;row=0;pos=0;prop=100000;bestw=36;besth=212;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=ToolsToolbar;caption=;state=139596;dir=2;layer=1;row=0;pos=0;prop=100000;bestw=36;besth=688;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrame;caption=;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=387;besth=181;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131452;dir=3;layer=6;row=0;pos=0;prop=100000;bestw=400;besth=34;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,6,0)=36|dock_size(4,3,0)=36|dock_size(2,1,0)=36|dock_size(5,0,0)=337|dock_size(3,6,0)=34|
|
||||||
|
SchematicFrameMostRecentlyUsedPath=
|
||||||
|
SchematicFrameUnits=1
|
||||||
|
SchematicFrameShowGrid=1
|
||||||
|
SchematicFrame_LastGridSize=5
|
||||||
|
SchematicFrameFirstRunShown=0
|
||||||
|
SchematicFrameDevelMaxUndoItems=0
|
||||||
|
SchematicFrameGalDisplayOptionsGridStyle=0
|
||||||
|
SchematicFrameGalDisplayOptionsGridLineWidth=1
|
||||||
|
SchematicFrameGalDisplayOptionsGridMaxDensity=10
|
||||||
|
SchematicFrameGalDisplayOptionsGridAxesEnabled=0
|
||||||
|
SchematicFrameGalDisplayOptionsCursorFullscreen=0
|
||||||
|
SchematicFrameGalDisplayOptionsForceDisplayCursor=1
|
||||||
|
ShowPageLimits=1
|
||||||
|
Units=1
|
||||||
|
PrintMonochrome=1
|
||||||
|
PrintSheetReferenceAndTitleBlock=1
|
||||||
|
RepeatStepX=0
|
||||||
|
RepeatStepY=100
|
||||||
|
RepeatLabelIncrement=1
|
||||||
|
ShowIllegalSymbolLibDialog=1
|
||||||
|
ShowSheetFileNameCaseSensitivityDlg=1
|
||||||
|
DefaultBusWidth=12
|
||||||
|
DefaultWireWidth=6
|
||||||
|
DefaultJunctionSize=40
|
||||||
|
ShowHiddenPins=0
|
||||||
|
HorizVertLinesOnly=1
|
||||||
|
AutoplaceFields=1
|
||||||
|
AutoplaceJustify=1
|
||||||
|
AutoplaceAlign=0
|
||||||
|
FootprintPreview=0
|
||||||
|
SimCmdLine=
|
||||||
|
LastFindReplaceFlags=1
|
||||||
|
LastFindString=
|
||||||
|
LastReplaceString=
|
||||||
|
FieldNames=(templatefields)
|
||||||
|
canvas_type=2
|
||||||
|
Color4DWireEx=rgb(0, 132, 0)
|
||||||
|
Color4DBusEx=rgb(0, 0, 132)
|
||||||
|
Color4DConnEx=rgb(0, 132, 0)
|
||||||
|
Color4DLLabelEx=rgb(0, 0, 0)
|
||||||
|
Color4DHLabelEx=rgb(132, 132, 0)
|
||||||
|
Color4DGLabelEx=rgb(132, 0, 0)
|
||||||
|
Color4DPinNumEx=rgb(132, 0, 0)
|
||||||
|
Color4DPinNameEx=rgb(0, 132, 132)
|
||||||
|
Color4DFieldEx=rgb(132, 0, 132)
|
||||||
|
Color4DReferenceEx=rgb(0, 132, 132)
|
||||||
|
Color4DValueEx=rgb(0, 132, 132)
|
||||||
|
Color4DNoteEx=rgb(0, 0, 194)
|
||||||
|
Color4DBodyEx=rgb(132, 0, 0)
|
||||||
|
Color4DBodyBgEx=rgb(255, 255, 194)
|
||||||
|
Color4DNetNameEx=rgb(132, 132, 132)
|
||||||
|
Color4DPinEx=rgb(132, 0, 0)
|
||||||
|
Color4DSheetEx=rgb(132, 0, 132)
|
||||||
|
Color4DSheetFileNameEx=rgb(132, 132, 0)
|
||||||
|
Color4DSheetNameEx=rgb(0, 132, 132)
|
||||||
|
Color4DSheetLabelEx=rgb(132, 132, 0)
|
||||||
|
Color4DNoConnectEx=rgb(0, 0, 132)
|
||||||
|
Color4DErcWEx=rgba(0, 132, 0, 0.800)
|
||||||
|
Color4DErcEEx=rgba(132, 0, 0, 0.800)
|
||||||
|
Color4DGridEx=rgb(132, 132, 132)
|
||||||
|
Color4DBgCanvasEx=rgb(255, 255, 255)
|
||||||
|
Color4DCursorEx=rgb(0, 0, 0)
|
||||||
|
Color4DBrightenedEx=rgb(255, 0, 255)
|
||||||
|
Color4DHiddenEx=rgb(194, 194, 194)
|
||||||
|
Color4DWorksheetEx=rgb(132, 0, 0)
|
||||||
|
file1=
|
||||||
|
file2=
|
||||||
|
file3=
|
||||||
|
file4=
|
||||||
|
file5=
|
||||||
|
file6=
|
||||||
|
file7=
|
||||||
|
file8=
|
||||||
|
file9=
|
||||||
|
PlotModeColor=1
|
||||||
|
PlotFrameRef=1
|
||||||
|
PlotFormat=3
|
||||||
|
PlotHPGLOrg=0
|
||||||
|
PlotHPGLPaperSize=0
|
||||||
|
PlotHPGLPenSize=0.4826
|
556
electronics/scripts/config/pcbnew
Normal file
556
electronics/scripts/config/pcbnew
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
Color4DPCBLayer_F.Cu=rgb(132, 0, 0)
|
||||||
|
Color4DPCBLayer_In1.Cu=rgb(194, 194, 0)
|
||||||
|
Color4DPCBLayer_In2.Cu=rgb(194, 0, 194)
|
||||||
|
Color4DPCBLayer_In3.Cu=rgb(194, 0, 0)
|
||||||
|
Color4DPCBLayer_In4.Cu=rgb(0, 132, 132)
|
||||||
|
Color4DPCBLayer_In5.Cu=rgb(0, 132, 0)
|
||||||
|
Color4DPCBLayer_In6.Cu=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_In7.Cu=rgb(132, 132, 132)
|
||||||
|
Color4DPCBLayer_In8.Cu=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_In9.Cu=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_In10.Cu=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_In11.Cu=rgb(132, 0, 0)
|
||||||
|
Color4DPCBLayer_In12.Cu=rgb(132, 132, 0)
|
||||||
|
Color4DPCBLayer_In13.Cu=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_In14.Cu=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_In15.Cu=rgb(0, 132, 0)
|
||||||
|
Color4DPCBLayer_In16.Cu=rgb(132, 0, 0)
|
||||||
|
Color4DPCBLayer_In17.Cu=rgb(194, 194, 0)
|
||||||
|
Color4DPCBLayer_In18.Cu=rgb(194, 0, 194)
|
||||||
|
Color4DPCBLayer_In19.Cu=rgb(194, 0, 0)
|
||||||
|
Color4DPCBLayer_In20.Cu=rgb(0, 132, 132)
|
||||||
|
Color4DPCBLayer_In21.Cu=rgb(0, 132, 0)
|
||||||
|
Color4DPCBLayer_In22.Cu=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_In23.Cu=rgb(132, 132, 132)
|
||||||
|
Color4DPCBLayer_In24.Cu=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_In25.Cu=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_In26.Cu=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_In27.Cu=rgb(132, 0, 0)
|
||||||
|
Color4DPCBLayer_In28.Cu=rgb(132, 132, 0)
|
||||||
|
Color4DPCBLayer_In29.Cu=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_In30.Cu=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_B.Cu=rgba(0, 132, 0, 0.439)
|
||||||
|
Color4DPCBLayer_B.Adhes=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_F.Adhes=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_B.Paste=rgb(0, 194, 194)
|
||||||
|
Color4DPCBLayer_F.Paste=rgb(132, 0, 0)
|
||||||
|
Color4DPCBLayer_B.SilkS=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_F.SilkS=rgb(0, 132, 132)
|
||||||
|
Color4DPCBLayer_B.Mask=rgb(132, 132, 0)
|
||||||
|
Color4DPCBLayer_F.Mask=rgb(132, 0, 132)
|
||||||
|
Color4DPCBLayer_Dwgs.User=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_Cmts.User=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_Eco1.User=rgb(0, 132, 0)
|
||||||
|
Color4DPCBLayer_Eco2.User=rgb(194, 194, 0)
|
||||||
|
Color4DPCBLayer_Edge.Cuts=rgb(194, 194, 0)
|
||||||
|
Color4DPCBLayer_Margin=rgb(194, 0, 194)
|
||||||
|
Color4DPCBLayer_B.CrtYd=rgb(132, 132, 132)
|
||||||
|
Color4DPCBLayer_F.CrtYd=rgb(194, 194, 194)
|
||||||
|
Color4DPCBLayer_B.Fab=rgb(0, 0, 132)
|
||||||
|
Color4DPCBLayer_F.Fab=rgb(132, 132, 132)
|
||||||
|
Color4DTxtFrontEx=rgb(194, 194, 194)
|
||||||
|
Color4DTxtBackEx=rgb(0, 0, 132)
|
||||||
|
Color4DTxtInvisEx=rgb(132, 132, 132)
|
||||||
|
Color4DPadBackEx=rgb(0, 132, 0)
|
||||||
|
Color4DAnchorEx=rgb(0, 0, 132)
|
||||||
|
Color4DPadFrontEx=rgb(132, 0, 0)
|
||||||
|
Color4DPadThruHoleEx=rgb(194, 194, 0)
|
||||||
|
Color4DNonPlatedEx=rgb(194, 194, 0)
|
||||||
|
Color4DPCBBackground=rgb(0, 0, 0)
|
||||||
|
Color4DPCBCursor=rgb(255, 255, 255)
|
||||||
|
Color4DAuxItems=rgb(255, 255, 255)
|
||||||
|
Color4DWorksheet=rgb(72, 0, 0)
|
||||||
|
Color4DGrid=rgb(132, 132, 132)
|
||||||
|
Color4DViaThruEx=rgb(194, 194, 194)
|
||||||
|
Color4DViaBBlindEx=rgb(132, 132, 0)
|
||||||
|
Color4DViaMicroEx=rgb(0, 132, 132)
|
||||||
|
Color4DRatsEx=rgb(255, 255, 255)
|
||||||
|
Color4DNoNetPadMarker=rgb(0, 0, 132)
|
||||||
|
LegacyAutoDeleteOldTrack=1
|
||||||
|
LegacyUse45DegreeTracks=1
|
||||||
|
LegacyUseTwoSegmentTracks=1
|
||||||
|
Use45DegreeGraphicSegments=0
|
||||||
|
MagneticPads=2
|
||||||
|
MagneticTracks=1
|
||||||
|
EditActionChangesTrackWidth=0
|
||||||
|
DragSelects=1
|
||||||
|
PcbFramePos_x=72
|
||||||
|
PcbFramePos_y=27
|
||||||
|
PcbFrameSize_x=2488
|
||||||
|
PcbFrameSize_y=1413
|
||||||
|
PcbFrameMaximized=1
|
||||||
|
PcbFrameAutoSaveInterval=600
|
||||||
|
PcbFramePerspective=layout2|name=MainToolbar;caption=;state=139644;dir=1;layer=6;row=0;pos=0;prop=100000;bestw=956;besth=38;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=AuxToolbar;caption=;state=139644;dir=1;layer=4;row=0;pos=0;prop=100000;bestw=995;besth=38;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131452;dir=3;layer=6;row=0;pos=0;prop=100000;bestw=400;besth=34;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=OptToolbar;caption=;state=139596;dir=4;layer=3;row=0;pos=0;prop=100000;bestw=36;besth=597;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MicrowaveToolbar;caption=;state=139598;dir=2;layer=1;row=0;pos=0;prop=100000;bestw=36;besth=187;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=ToolsToolbar;caption=;state=139596;dir=2;layer=2;row=0;pos=0;prop=100000;bestw=36;besth=708;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=LayersManager;caption=Layers Manager;state=1532;dir=2;layer=3;row=0;pos=0;prop=100000;bestw=198;besth=32;minw=198;minh=32;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=198;floath=32|name=DrawFrame;caption=;state=1022;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=387;besth=181;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrameGal;caption=;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=1112;besth=731;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,6,0)=38|dock_size(1,4,0)=38|dock_size(3,6,0)=34|dock_size(4,3,0)=36|dock_size(2,2,0)=36|dock_size(2,3,0)=198|dock_size(5,0,0)=389|
|
||||||
|
PcbFrameMostRecentlyUsedPath=
|
||||||
|
PcbFrameShowGrid=1
|
||||||
|
PcbFrameGridColor=rgb(132, 132, 132)
|
||||||
|
PcbFrame_LastGridSize=2
|
||||||
|
PcbFrameFirstRunShown=1
|
||||||
|
PcbFrameDevelMaxUndoItems=0
|
||||||
|
PcbFrameGalDisplayOptionsOpenGLAntialiasingMode=0
|
||||||
|
PcbFrameGalDisplayOptionsGridStyle=0
|
||||||
|
PcbFrameGalDisplayOptionsGridLineWidth=1
|
||||||
|
PcbFrameGalDisplayOptionsGridMaxDensity=10
|
||||||
|
PcbFrameGalDisplayOptionsGridAxesEnabled=0
|
||||||
|
PcbFrameGalDisplayOptionsCursorFullscreen=0
|
||||||
|
PcbFrameGalDisplayOptionsForceDisplayCursor=0
|
||||||
|
PcbFramePcbUserGrid_X=0.254
|
||||||
|
PcbFramePcbUserGrid_Y=0.254
|
||||||
|
PcbFramePcbUserGrid_Unit=1
|
||||||
|
PcbFrameDiPadFi=1
|
||||||
|
PcbFrameDiViaFi=1
|
||||||
|
PcbFrameDiPadNu=1
|
||||||
|
PcbFrameDiModEd=1
|
||||||
|
PcbFrameDiModTx=1
|
||||||
|
PcbFrameFastGrid1=0
|
||||||
|
PcbFrameFastGrid2=0
|
||||||
|
Units=1
|
||||||
|
DisplayPolarCoords=0
|
||||||
|
ShowNetNamesMode=3
|
||||||
|
DisplayTrackFilled=1
|
||||||
|
TrackDisplayClearance=2
|
||||||
|
PadFill=1
|
||||||
|
ViaFill=1
|
||||||
|
PadAffG=1
|
||||||
|
PadSNum=1
|
||||||
|
ModAffC=1
|
||||||
|
ModAffT=1
|
||||||
|
PcbAffT=1
|
||||||
|
PcbShowZonesMode=0
|
||||||
|
RotationAngle=900
|
||||||
|
MaxLnkS=3
|
||||||
|
PlotLineWidth_mm=0.1
|
||||||
|
ShowMicrowaveTools=0
|
||||||
|
ShowLayerManagerTools=1
|
||||||
|
ShowPageLimits=0
|
||||||
|
canvas_type=1
|
||||||
|
pcbnew.InteractiveRouter.Mode=1
|
||||||
|
pcbnew.InteractiveRouter.OptimizerEffort=1
|
||||||
|
pcbnew.InteractiveRouter.RemoveLoops=1
|
||||||
|
pcbnew.InteractiveRouter.SmartPads=1
|
||||||
|
pcbnew.InteractiveRouter.ShoveVias=1
|
||||||
|
pcbnew.InteractiveRouter.StartDiagonal=0
|
||||||
|
pcbnew.InteractiveRouter.ShoveTimeLimit=1000
|
||||||
|
pcbnew.InteractiveRouter.ShoveIterationLimit=250
|
||||||
|
pcbnew.InteractiveRouter.WalkaroundIterationLimit=50
|
||||||
|
pcbnew.InteractiveRouter.JumpOverObstacles=0
|
||||||
|
pcbnew.InteractiveRouter.SmoothDraggedSegments=1
|
||||||
|
pcbnew.InteractiveRouter.CanViolateDRC=0
|
||||||
|
pcbnew.InteractiveRouter.SuggestFinish=0
|
||||||
|
pcbnew.InteractiveRouter.FreeAngleMode=0
|
||||||
|
pcbnew.InteractiveRouter.InlineDragEnabled=0
|
||||||
|
MousewheelPAN=0
|
||||||
|
ZoomNoCenter=0
|
||||||
|
AutoPAN=1
|
||||||
|
file1=
|
||||||
|
file2=
|
||||||
|
file3=
|
||||||
|
file4=
|
||||||
|
file5=
|
||||||
|
file6=
|
||||||
|
file7=
|
||||||
|
file8=
|
||||||
|
file9=
|
||||||
|
PcbFrameCursorShape=0
|
||||||
|
PcbFrameMaxUndoItems=0
|
||||||
|
ViaHoleDisplayMode=1
|
||||||
|
ColorPCBLayer_F.Cu=Red 2
|
||||||
|
ColorPCBLayer_In1.Cu=Yellow 3
|
||||||
|
ColorPCBLayer_In2.Cu=Magenta 3
|
||||||
|
ColorPCBLayer_In3.Cu=Red 3
|
||||||
|
ColorPCBLayer_In4.Cu=Cyan 2
|
||||||
|
ColorPCBLayer_In5.Cu=Green 2
|
||||||
|
ColorPCBLayer_In6.Cu=Blue 2
|
||||||
|
ColorPCBLayer_In7.Cu=Gray 2
|
||||||
|
ColorPCBLayer_In8.Cu=Magenta 2
|
||||||
|
ColorPCBLayer_In9.Cu=Gray 3
|
||||||
|
ColorPCBLayer_In10.Cu=Magenta 2
|
||||||
|
ColorPCBLayer_In11.Cu=Red 2
|
||||||
|
ColorPCBLayer_In12.Cu=Brown 2
|
||||||
|
ColorPCBLayer_In13.Cu=Gray 3
|
||||||
|
ColorPCBLayer_In14.Cu=Blue 2
|
||||||
|
ColorPCBLayer_In15.Cu=Green 2
|
||||||
|
ColorPCBLayer_In16.Cu=Red 2
|
||||||
|
ColorPCBLayer_In17.Cu=Yellow 3
|
||||||
|
ColorPCBLayer_In18.Cu=Magenta 3
|
||||||
|
ColorPCBLayer_In19.Cu=Red 3
|
||||||
|
ColorPCBLayer_In20.Cu=Cyan 2
|
||||||
|
ColorPCBLayer_In21.Cu=Green 2
|
||||||
|
ColorPCBLayer_In22.Cu=Blue 2
|
||||||
|
ColorPCBLayer_In23.Cu=Gray 2
|
||||||
|
ColorPCBLayer_In24.Cu=Magenta 2
|
||||||
|
ColorPCBLayer_In25.Cu=Gray 3
|
||||||
|
ColorPCBLayer_In26.Cu=Magenta 2
|
||||||
|
ColorPCBLayer_In27.Cu=Red 2
|
||||||
|
ColorPCBLayer_In28.Cu=Brown 2
|
||||||
|
ColorPCBLayer_In29.Cu=Gray 3
|
||||||
|
ColorPCBLayer_In30.Cu=Blue 2
|
||||||
|
ColorPCBLayer_B.Cu=Green 2
|
||||||
|
ColorPCBLayer_B.Adhes=Blue 2
|
||||||
|
ColorPCBLayer_F.Adhes=Magenta 2
|
||||||
|
ColorPCBLayer_B.Paste=Cyan 3
|
||||||
|
ColorPCBLayer_F.Paste=Red 2
|
||||||
|
ColorPCBLayer_B.SilkS=Magenta 2
|
||||||
|
ColorPCBLayer_F.SilkS=Cyan 2
|
||||||
|
ColorPCBLayer_B.Mask=Brown 2
|
||||||
|
ColorPCBLayer_F.Mask=Magenta 2
|
||||||
|
ColorPCBLayer_Dwgs.User=Gray 3
|
||||||
|
ColorPCBLayer_Cmts.User=Blue 2
|
||||||
|
ColorPCBLayer_Eco1.User=Green 2
|
||||||
|
ColorPCBLayer_Eco2.User=Yellow 3
|
||||||
|
ColorPCBLayer_Edge.Cuts=Yellow 3
|
||||||
|
ColorPCBLayer_Margin=Magenta 3
|
||||||
|
ColorPCBLayer_B.CrtYd=Yellow 3
|
||||||
|
ColorPCBLayer_F.CrtYd=Gray 2
|
||||||
|
ColorPCBLayer_B.Fab=Red 2
|
||||||
|
ColorPCBLayer_F.Fab=Yellow 3
|
||||||
|
ColorTxtFrontEx=Gray 3
|
||||||
|
ColorTxtBackEx=Blue 2
|
||||||
|
ColorTxtInvisEx=Gray 2
|
||||||
|
ColorAnchorEx=Blue 2
|
||||||
|
ColorPadBackEx=Green 2
|
||||||
|
ColorPadFrontEx=Red 2
|
||||||
|
ColorViaThruEx=Gray 3
|
||||||
|
ColorViaBBlindEx=Brown 2
|
||||||
|
ColorViaMicroEx=Cyan 2
|
||||||
|
ColorNonPlatedEx=Yellow 3
|
||||||
|
ColorRatsEx=White
|
||||||
|
ShowMRa=1
|
||||||
|
TwoSegT=1
|
||||||
|
SegmPcb45Only=1
|
||||||
|
PcbMagPadOpt=1
|
||||||
|
PcbMagTrackOpt=1
|
||||||
|
MiddleButtonPAN=1
|
||||||
|
MiddleBtnPANLimited=0
|
||||||
|
FootprintWizardPos_x=384
|
||||||
|
FootprintWizardPos_y=514
|
||||||
|
FootprintWizardSize_x=2272
|
||||||
|
FootprintWizardSize_y=1000
|
||||||
|
FootprintWizardMaximized=0
|
||||||
|
FootprintWizardPerspective=layout2|name=m_mainToolBar;caption=;state=139632;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=393;besth=36;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=m_parametersPanel;caption=;state=508;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=360;minh=180;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=m_buildMessageBox;caption=;state=508;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=104;besth=73;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrame;caption=;state=256;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=382;besth=63;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131388;dir=3;layer=1;row=0;pos=0;prop=100000;bestw=400;besth=68;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=36|dock_size(4,0,0)=513|dock_size(5,0,0)=300|dock_size(3,1,0)=68|
|
||||||
|
FootprintWizardMostRecentlyUsedPath=
|
||||||
|
FootprintWizardShowGrid=1
|
||||||
|
FootprintWizardGridColor=rgb(132, 132, 132)
|
||||||
|
FootprintWizard_LastGridSize=0
|
||||||
|
FootprintWizardFirstRunShown=0
|
||||||
|
FootprintWizardDevelMaxUndoItems=0
|
||||||
|
FootprintWizardGalDisplayOptionsOpenGLAntialiasingMode=0
|
||||||
|
FootprintWizardGalDisplayOptionsGridStyle=0
|
||||||
|
FootprintWizardGalDisplayOptionsGridLineWidth=0.5
|
||||||
|
FootprintWizardGalDisplayOptionsGridMaxDensity=10
|
||||||
|
FootprintWizardGalDisplayOptionsGridAxesEnabled=0
|
||||||
|
FootprintWizardGalDisplayOptionsCursorFullscreen=0
|
||||||
|
FootprintWizardGalDisplayOptionsForceDisplayCursor=0
|
||||||
|
Fpwizard_auiPerspective=layout2|name=m_mainToolBar;caption=;state=139632;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=393;besth=36;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=m_parametersPanel;caption=;state=508;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=360;minh=180;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=m_buildMessageBox;caption=;state=508;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=104;besth=73;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrame;caption=;state=256;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=382;besth=63;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131388;dir=3;layer=1;row=0;pos=0;prop=100000;bestw=400;besth=68;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=36|dock_size(4,0,0)=513|dock_size(5,0,0)=300|dock_size(3,1,0)=68|
|
||||||
|
ModEditColor4DPCBLayer_F.Cu=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In1.Cu=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DPCBLayer_In2.Cu=rgb(194, 0, 194)
|
||||||
|
ModEditColor4DPCBLayer_In3.Cu=rgb(194, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In4.Cu=rgb(0, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_In5.Cu=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_In6.Cu=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In7.Cu=rgb(132, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_In8.Cu=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In9.Cu=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_In10.Cu=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In11.Cu=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In12.Cu=rgb(132, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_In13.Cu=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_In14.Cu=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In15.Cu=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_In16.Cu=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In17.Cu=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DPCBLayer_In18.Cu=rgb(194, 0, 194)
|
||||||
|
ModEditColor4DPCBLayer_In19.Cu=rgb(194, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In20.Cu=rgb(0, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_In21.Cu=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_In22.Cu=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In23.Cu=rgb(132, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_In24.Cu=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In25.Cu=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_In26.Cu=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_In27.Cu=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_In28.Cu=rgb(132, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_In29.Cu=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_In30.Cu=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_B.Cu=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_B.Adhes=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_F.Adhes=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_B.Paste=rgb(0, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_F.Paste=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPCBLayer_B.SilkS=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_F.SilkS=rgb(0, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_B.Mask=rgb(132, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_F.Mask=rgb(132, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_Dwgs.User=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_Cmts.User=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_Eco1.User=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DPCBLayer_Eco2.User=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DPCBLayer_Edge.Cuts=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DPCBLayer_Margin=rgb(194, 0, 194)
|
||||||
|
ModEditColor4DPCBLayer_B.CrtYd=rgb(132, 132, 132)
|
||||||
|
ModEditColor4DPCBLayer_F.CrtYd=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DPCBLayer_B.Fab=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPCBLayer_F.Fab=rgb(132, 132, 132)
|
||||||
|
ModEditColor4DTxtFrontEx=rgb(194, 194, 194)
|
||||||
|
ModEditColor4DTxtBackEx=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DTxtInvisEx=rgb(132, 132, 132)
|
||||||
|
ModEditColor4DPadBackEx=rgb(0, 132, 0)
|
||||||
|
ModEditColor4DAnchorEx=rgb(0, 0, 132)
|
||||||
|
ModEditColor4DPadFrontEx=rgb(132, 0, 0)
|
||||||
|
ModEditColor4DPadThruHoleEx=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DNonPlatedEx=rgb(194, 194, 0)
|
||||||
|
ModEditColor4DPCBBackground=rgb(0, 0, 0)
|
||||||
|
ModEditColor4DPCBCursor=rgb(255, 255, 255)
|
||||||
|
ModEditColor4DAuxItems=rgb(255, 255, 255)
|
||||||
|
ModEditColor4DWorksheet=rgb(72, 0, 0)
|
||||||
|
ModEditColor4DGrid=rgb(132, 132, 132)
|
||||||
|
ModEditFramePos_x=72
|
||||||
|
ModEditFramePos_y=27
|
||||||
|
ModEditFrameSize_x=1848
|
||||||
|
ModEditFrameSize_y=1053
|
||||||
|
ModEditFrameMaximized=1
|
||||||
|
ModEditFramePerspective=layout2|name=MainToolbar;caption=;state=139644;dir=1;layer=6;row=0;pos=0;prop=100000;bestw=982;besth=38;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131452;dir=3;layer=6;row=0;pos=0;prop=100000;bestw=400;besth=34;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=OptToolbar;caption=;state=139596;dir=4;layer=3;row=0;pos=0;prop=100000;bestw=36;besth=366;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Footprints;caption=Libraries;state=2044;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=552;besth=-1;minw=250;minh=400;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=ToolsToolbar;caption=;state=139596;dir=2;layer=1;row=0;pos=0;prop=100000;bestw=36;besth=418;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=LayersManager;caption=Layers Manager;state=1532;dir=2;layer=3;row=0;pos=0;prop=100000;bestw=188;besth=32;minw=188;minh=32;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=188;floath=32|name=DrawFrame;caption=;state=1022;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=387;besth=144;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrameGal;caption=;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=1112;besth=731;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,6,0)=38|dock_size(3,6,0)=34|dock_size(4,3,0)=36|dock_size(4,1,0)=554|dock_size(2,1,0)=36|dock_size(2,3,0)=188|dock_size(5,0,0)=554|
|
||||||
|
ModEditFrameMostRecentlyUsedPath=
|
||||||
|
ModEditFrameShowGrid=1
|
||||||
|
ModEditFrameGridColor=rgb(132, 132, 132)
|
||||||
|
ModEditFrame_LastGridSize=16
|
||||||
|
ModEditFrameFirstRunShown=0
|
||||||
|
ModEditFrameDevelMaxUndoItems=0
|
||||||
|
ModEditFrameGalDisplayOptionsOpenGLAntialiasingMode=0
|
||||||
|
ModEditFrameGalDisplayOptionsGridStyle=0
|
||||||
|
ModEditFrameGalDisplayOptionsGridLineWidth=0.5
|
||||||
|
ModEditFrameGalDisplayOptionsGridMaxDensity=10
|
||||||
|
ModEditFrameGalDisplayOptionsGridAxesEnabled=1
|
||||||
|
ModEditFrameGalDisplayOptionsCursorFullscreen=0
|
||||||
|
ModEditFrameGalDisplayOptionsForceDisplayCursor=0
|
||||||
|
ModEditFramePcbUserGrid_X=0.254
|
||||||
|
ModEditFramePcbUserGrid_Y=0.254
|
||||||
|
ModEditFramePcbUserGrid_Unit=1
|
||||||
|
ModEditFrameDiPadFi=1
|
||||||
|
ModEditFrameDiViaFi=1
|
||||||
|
ModEditFrameDiPadNu=1
|
||||||
|
ModEditFrameDiModEd=1
|
||||||
|
ModEditFrameDiModTx=1
|
||||||
|
ModEditFrameFastGrid1=0
|
||||||
|
ModEditFrameFastGrid2=0
|
||||||
|
FpEditorUnits=1
|
||||||
|
FpEditorDisplayPolarCoords=0
|
||||||
|
FpEditorPadDisplayMode=1
|
||||||
|
FpEditorGraphicLinesDisplayMode=1
|
||||||
|
FpEditorTextsDisplayMode=1
|
||||||
|
FpEditorTextsRefDefaultText=REF**
|
||||||
|
FpEditorGrlineWidth=0.15
|
||||||
|
FpEditorTextsDefaultSizeH=1
|
||||||
|
FpEditorTextsDefaultSizeV=1
|
||||||
|
FpEditorTextsDefaultThickness=0.15
|
||||||
|
FpEditorRefDefaultText=REF**
|
||||||
|
FpEditorRefDefaultVisibility=1
|
||||||
|
FpEditorRefDefaultLayer=37
|
||||||
|
FpEditorValueDefaultText=
|
||||||
|
FpEditorValueDefaultVisibility=1
|
||||||
|
FpEditorValueDefaultLayer=49
|
||||||
|
ModViewFramePos_x=72
|
||||||
|
ModViewFramePos_y=27
|
||||||
|
ModViewFrameSize_x=2488
|
||||||
|
ModViewFrameSize_y=1413
|
||||||
|
ModViewFrameMaximized=1
|
||||||
|
ModViewFramePerspective=layout2|name=MainToolbar;caption=;state=139644;dir=1;layer=6;row=0;pos=0;prop=100000;bestw=779;besth=38;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=MsgPanel;caption=;state=131452;dir=3;layer=6;row=0;pos=0;prop=100000;bestw=400;besth=34;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Libraries;caption=;state=1020;dir=4;layer=2;row=0;pos=0;prop=100000;bestw=200;besth=-1;minw=100;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Footprints;caption=;state=1020;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=300;besth=-1;minw=100;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrame;caption=;state=1022;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=387;besth=144;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrameGal;caption=;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=1835;besth=1040;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,6,0)=38|dock_size(3,6,0)=34|dock_size(4,2,0)=202|dock_size(4,1,0)=302|dock_size(5,0,0)=389|
|
||||||
|
ModViewFrameMostRecentlyUsedPath=
|
||||||
|
ModViewFrameShowGrid=1
|
||||||
|
ModViewFrameGridColor=rgb(132, 132, 132)
|
||||||
|
ModViewFrame_LastGridSize=1
|
||||||
|
ModViewFrameFirstRunShown=0
|
||||||
|
ModViewFrameDevelMaxUndoItems=0
|
||||||
|
ModViewFrameGalDisplayOptionsOpenGLAntialiasingMode=0
|
||||||
|
ModViewFrameGalDisplayOptionsGridStyle=0
|
||||||
|
ModViewFrameGalDisplayOptionsGridLineWidth=0.5
|
||||||
|
ModViewFrameGalDisplayOptionsGridMaxDensity=10
|
||||||
|
ModViewFrameGalDisplayOptionsGridAxesEnabled=1
|
||||||
|
ModViewFrameGalDisplayOptionsCursorFullscreen=0
|
||||||
|
ModViewFrameGalDisplayOptionsForceDisplayCursor=0
|
||||||
|
import_last_path=
|
||||||
|
FpWizardListWidth=588
|
||||||
|
FpWizardListHeight=482
|
||||||
|
Viewer3DFrameNamePos_x=72
|
||||||
|
Viewer3DFrameNamePos_y=27
|
||||||
|
Viewer3DFrameNameSize_x=2488
|
||||||
|
Viewer3DFrameNameSize_y=1413
|
||||||
|
Viewer3DFrameNameMaximized=1
|
||||||
|
Viewer3DFrameNamePerspective=layout2|name=MainToolbar;caption=;state=139644;dir=1;layer=6;row=0;pos=0;prop=100000;bestw=735;besth=36;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=DrawFrame;caption=;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,6,0)=36|dock_size(5,0,0)=22|
|
||||||
|
Viewer3DFrameNameMostRecentlyUsedPath=
|
||||||
|
BgColor_Red=0.4
|
||||||
|
BgColor_Green=0.4
|
||||||
|
BgColor_Blue=0.5
|
||||||
|
BgColor_Red_Top=0.8
|
||||||
|
BgColor_Green_Top=0.8
|
||||||
|
BgColor_Blue_Top=0.9
|
||||||
|
SMaskColor_Red=0.0784314
|
||||||
|
SMaskColor_Green=0.2
|
||||||
|
SMaskColor_Blue=0.141176
|
||||||
|
SPasteColor_Red=0.501961
|
||||||
|
SPasteColor_Green=0.501961
|
||||||
|
SPasteColor_Blue=0.501961
|
||||||
|
SilkColor_Red=0.9
|
||||||
|
SilkColor_Green=0.9
|
||||||
|
SilkColor_Blue=0.9
|
||||||
|
CopperColor_Red=0.7
|
||||||
|
CopperColor_Green=0.612157
|
||||||
|
CopperColor_Blue=0
|
||||||
|
BoardBodyColor_Red=0.2
|
||||||
|
BoardBodyColor_Green=0.168627
|
||||||
|
BoardBodyColor_Blue=0.0862745
|
||||||
|
ShowRealisticMode=1
|
||||||
|
MousewheelPAN3D=0
|
||||||
|
RenderEngine=0
|
||||||
|
Render_Material=0
|
||||||
|
Render_OGL_ShowCopperThickness=1
|
||||||
|
Render_OGL_ShowModelBoudingBoxes=0
|
||||||
|
Render_RAY_Shadows=1
|
||||||
|
Render_RAY_Backfloor=1
|
||||||
|
Render_RAY_Refractions=1
|
||||||
|
Render_RAY_Reflections=1
|
||||||
|
Render_RAY_PostProcess=1
|
||||||
|
Render_RAY_AntiAliasing=1
|
||||||
|
Render_RAY_ProceduralTextures=1
|
||||||
|
ShowAxis=1
|
||||||
|
ShowGrid3D=0
|
||||||
|
ShowFootprints_Normal=1
|
||||||
|
ShowFootprints_Insert=1
|
||||||
|
ShowFootprints_Virtual=1
|
||||||
|
ShowZones=1
|
||||||
|
ShowAdhesiveLayers=1
|
||||||
|
ShowSilkScreenLayers=1
|
||||||
|
ShowSolderMasLayers=1
|
||||||
|
ShowSolderPasteLayers=1
|
||||||
|
ShowCommentsLayers=1
|
||||||
|
ShowEcoLayers=1
|
||||||
|
ShowBoardBody=1
|
||||||
|
SilentMode=0
|
||||||
|
NetlistDeleteSinglePadNets=1
|
||||||
|
NetlistReportFilterMsg=15
|
||||||
|
TestMissingCourtyard=0
|
||||||
|
TestFootprintCourtyard=0
|
||||||
|
RefillZonesBeforeDrc=0
|
||||||
|
Zone_Ouline_Hatch_Opt=2
|
||||||
|
Zone_Filter_Opt=Net-*
|
||||||
|
Zone_Clearance=20
|
||||||
|
Zone_Thickness=10
|
||||||
|
Zone_TH_Gap=20
|
||||||
|
Zone_TH_Copper_Width=39.37007874015748
|
||||||
|
PcbIconScale=-1
|
||||||
|
PrintModuleScale=3
|
||||||
|
PrintMonochrome=1
|
||||||
|
ModEditColor4DPCBLayer_Rescue=rgb(132, 0, 0)
|
||||||
|
ActionPluginButtons=
|
||||||
|
ModEditFrameUnits=1
|
||||||
|
FpEditorSilkLineWidth=0.15
|
||||||
|
FpEditorSilkTextSizeH=1
|
||||||
|
FpEditorSilkTextSizeV=1
|
||||||
|
FpEditorSilkTextThickness=0.15
|
||||||
|
FpEditorSilkTextItalic=0
|
||||||
|
FpEditorCopperLineWidth=0.12
|
||||||
|
FpEditorCopperTextSizeV=1.5
|
||||||
|
FpEditorCopperTextSizeH=1.5
|
||||||
|
FpEditorCopperTextThickness=0.3
|
||||||
|
FpEditorCopperTextItalic=0
|
||||||
|
FpEditorEdgeCutLineWidth=0.12
|
||||||
|
FpEditorCourtyardLineWidth=0.12
|
||||||
|
FpEditorOthersLineWidth=0.12
|
||||||
|
FpEditorOthersTextSizeV=1
|
||||||
|
FpEditorOthersTextSizeH=1
|
||||||
|
FpEditorOthersTextSizeThickness=0.15
|
||||||
|
FpEditorOthersTextItalic=0
|
||||||
|
ModeditLibWidth=552
|
||||||
|
NetlistUpdateFootprints=1
|
||||||
|
NetlistDeleteShortingTracks=0
|
||||||
|
NetlistDeleteExtraFootprints=1
|
||||||
|
FootprintTextShownColumns=0 1 2 3 4 5 6
|
||||||
|
DrcTrackToZoneTest=0
|
||||||
|
ModViewFrameUnits=1
|
||||||
|
ModViewFrameModalPcbUserGrid_X=0.254
|
||||||
|
ModViewFrameModalPcbUserGrid_Y=0.254
|
||||||
|
ModViewFrameModalPcbUserGrid_Unit=1
|
||||||
|
ModViewFrameModalDiPadFi=1
|
||||||
|
ModViewFrameModalDiViaFi=1
|
||||||
|
ModViewFrameModalDiPadNu=1
|
||||||
|
ModViewFrameModalDiModEd=1
|
||||||
|
ModViewFrameModalDiModTx=1
|
||||||
|
ModViewFrameModalFastGrid1=0
|
||||||
|
ModViewFrameModalFastGrid2=0
|
||||||
|
ModViewFrameAutoZoom=1
|
||||||
|
ModViewFrameZoom=17.1134
|
||||||
|
Color4DPCBLayer_Rescue=rgb(132, 0, 0)
|
||||||
|
MagneticGraphics=1
|
||||||
|
PcbFrameUnits=1
|
||||||
|
PrintScale=1
|
||||||
|
PrintPageFrame=1
|
||||||
|
PlotLayer_0=1
|
||||||
|
PlotLayer_1=0
|
||||||
|
PlotLayer_2=0
|
||||||
|
PlotLayer_3=0
|
||||||
|
PlotLayer_4=0
|
||||||
|
PlotLayer_5=0
|
||||||
|
PlotLayer_6=0
|
||||||
|
PlotLayer_7=0
|
||||||
|
PlotLayer_8=0
|
||||||
|
PlotLayer_9=0
|
||||||
|
PlotLayer_10=0
|
||||||
|
PlotLayer_11=0
|
||||||
|
PlotLayer_12=0
|
||||||
|
PlotLayer_13=0
|
||||||
|
PlotLayer_14=0
|
||||||
|
PlotLayer_15=0
|
||||||
|
PlotLayer_16=0
|
||||||
|
PlotLayer_17=0
|
||||||
|
PlotLayer_18=0
|
||||||
|
PlotLayer_19=0
|
||||||
|
PlotLayer_20=0
|
||||||
|
PlotLayer_21=0
|
||||||
|
PlotLayer_22=0
|
||||||
|
PlotLayer_23=0
|
||||||
|
PlotLayer_24=0
|
||||||
|
PlotLayer_25=0
|
||||||
|
PlotLayer_26=0
|
||||||
|
PlotLayer_27=0
|
||||||
|
PlotLayer_28=0
|
||||||
|
PlotLayer_29=0
|
||||||
|
PlotLayer_30=0
|
||||||
|
PlotLayer_31=1
|
||||||
|
PlotLayer_32=0
|
||||||
|
PlotLayer_33=0
|
||||||
|
PlotLayer_34=1
|
||||||
|
PlotLayer_35=1
|
||||||
|
PlotLayer_36=1
|
||||||
|
PlotLayer_37=1
|
||||||
|
PlotLayer_38=1
|
||||||
|
PlotLayer_39=1
|
||||||
|
PlotLayer_40=0
|
||||||
|
PlotLayer_41=0
|
||||||
|
PlotLayer_42=0
|
||||||
|
PlotLayer_43=0
|
||||||
|
PlotLayer_44=1
|
||||||
|
PlotLayer_45=0
|
||||||
|
PlotLayer_46=0
|
||||||
|
PlotLayer_47=0
|
||||||
|
PlotLayer_48=0
|
||||||
|
PlotLayer_49=0
|
||||||
|
PlotLayer_50=0
|
||||||
|
PrintPadsDrillOpt=2
|
||||||
|
PrintSinglePage=0
|
||||||
|
PlotXFineScaleAdj=1
|
||||||
|
PlotYFineScaleAdj=1
|
||||||
|
CheckZonesBeforePlotting=1
|
||||||
|
PSPlotFineWidthAdj=0
|
||||||
|
DrillZerosFormat=0
|
||||||
|
DrillMirrorYOpt=0
|
||||||
|
DrillMergePTHNPTH=0
|
||||||
|
DrillMinHeader=0
|
||||||
|
DrillUnit=1
|
||||||
|
DrillMapFileType=1
|
||||||
|
DrillFileType=0
|
||||||
|
OvalHolesRouteMode=1
|
||||||
|
PlaceFileUnits=1
|
||||||
|
PlaceFileOpts=0
|
||||||
|
PlaceFileFormat=1
|
||||||
|
LibFootprintTextShownColumns=0 1 2 3 4 5 6
|
96
electronics/scripts/config/policy.xml
Normal file
96
electronics/scripts/config/policy.xml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE policymap [
|
||||||
|
<!ELEMENT policymap (policy)+>
|
||||||
|
<!ATTLIST policymap xmlns CDATA #FIXED ''>
|
||||||
|
<!ELEMENT policy EMPTY>
|
||||||
|
<!ATTLIST policy xmlns CDATA #FIXED '' domain NMTOKEN #REQUIRED
|
||||||
|
name NMTOKEN #IMPLIED pattern CDATA #IMPLIED rights NMTOKEN #IMPLIED
|
||||||
|
stealth NMTOKEN #IMPLIED value CDATA #IMPLIED>
|
||||||
|
]>
|
||||||
|
<!--
|
||||||
|
Configure ImageMagick policies.
|
||||||
|
|
||||||
|
Domains include system, delegate, coder, filter, path, or resource.
|
||||||
|
|
||||||
|
Rights include none, read, write, execute and all. Use | to combine them,
|
||||||
|
for example: "read | write" to permit read from, or write to, a path.
|
||||||
|
|
||||||
|
Use a glob expression as a pattern.
|
||||||
|
|
||||||
|
Suppose we do not want users to process MPEG video images:
|
||||||
|
|
||||||
|
<policy domain="delegate" rights="none" pattern="mpeg:decode" />
|
||||||
|
|
||||||
|
Here we do not want users reading images from HTTP:
|
||||||
|
|
||||||
|
<policy domain="coder" rights="none" pattern="HTTP" />
|
||||||
|
|
||||||
|
The /repository file system is restricted to read only. We use a glob
|
||||||
|
expression to match all paths that start with /repository:
|
||||||
|
|
||||||
|
<policy domain="path" rights="read" pattern="/repository/*" />
|
||||||
|
|
||||||
|
Lets prevent users from executing any image filters:
|
||||||
|
|
||||||
|
<policy domain="filter" rights="none" pattern="*" />
|
||||||
|
|
||||||
|
Any large image is cached to disk rather than memory:
|
||||||
|
|
||||||
|
<policy domain="resource" name="area" value="1GP"/>
|
||||||
|
|
||||||
|
Define arguments for the memory, map, area, width, height and disk resources
|
||||||
|
with SI prefixes (.e.g 100MB). In addition, resource policies are maximums
|
||||||
|
for each instance of ImageMagick (e.g. policy memory limit 1GB, -limit 2GB
|
||||||
|
exceeds policy maximum so memory limit is 1GB).
|
||||||
|
|
||||||
|
Rules are processed in order. Here we want to restrict ImageMagick to only
|
||||||
|
read or write a small subset of proven web-safe image types:
|
||||||
|
|
||||||
|
<policy domain="delegate" rights="none" pattern="*" />
|
||||||
|
<policy domain="filter" rights="none" pattern="*" />
|
||||||
|
<policy domain="coder" rights="none" pattern="*" />
|
||||||
|
<policy domain="coder" rights="read|write" pattern="{GIF,JPEG,PNG,WEBP}" />
|
||||||
|
-->
|
||||||
|
<policymap>
|
||||||
|
<!-- <policy domain="system" name="shred" value="2"/> -->
|
||||||
|
<!-- <policy domain="system" name="precision" value="6"/> -->
|
||||||
|
<!-- <policy domain="system" name="memory-map" value="anonymous"/> -->
|
||||||
|
<!-- <policy domain="system" name="max-memory-request" value="256MiB"/> -->
|
||||||
|
<!-- <policy domain="resource" name="temporary-path" value="/tmp"/> -->
|
||||||
|
<policy domain="resource" name="memory" value="256MiB"/>
|
||||||
|
<policy domain="resource" name="map" value="512MiB"/>
|
||||||
|
<policy domain="resource" name="width" value="16KP"/>
|
||||||
|
<policy domain="resource" name="height" value="16KP"/>
|
||||||
|
<!-- <policy domain="resource" name="list-length" value="128"/> -->
|
||||||
|
<policy domain="resource" name="area" value="128MB"/>
|
||||||
|
<policy domain="resource" name="disk" value="1GiB"/>
|
||||||
|
<!-- <policy domain="resource" name="file" value="768"/> -->
|
||||||
|
<!-- <policy domain="resource" name="thread" value="4"/> -->
|
||||||
|
<!-- <policy domain="resource" name="throttle" value="0"/> -->
|
||||||
|
<!-- <policy domain="resource" name="time" value="3600"/> -->
|
||||||
|
<!-- <policy domain="coder" rights="none" pattern="MVG" /> -->
|
||||||
|
<!-- <policy domain="module" rights="none" pattern="{PS,PDF,XPS}" /> -->
|
||||||
|
<!-- <policy domain="delegate" rights="none" pattern="HTTPS" /> -->
|
||||||
|
<!-- <policy domain="path" rights="none" pattern="@*" /> -->
|
||||||
|
<!-- <policy domain="cache" name="memory-map" value="anonymous"/> -->
|
||||||
|
<!-- <policy domain="cache" name="synchronize" value="True"/> -->
|
||||||
|
<!-- <policy domain="cache" name="shared-secret" value="passphrase" stealth="true"/> -->
|
||||||
|
<!-- <policy domain="system" name="pixel-cache-memory" value="anonymous"/> -->
|
||||||
|
<!-- <policy domain="system" name="shred" value="2"/> -->
|
||||||
|
<!-- <policy domain="system" name="precision" value="6"/> -->
|
||||||
|
<!-- not needed due to the need to use explicitly by mvg: -->
|
||||||
|
<!-- <policy domain="delegate" rights="none" pattern="MVG" /> -->
|
||||||
|
<!-- use curl -->
|
||||||
|
<policy domain="delegate" rights="none" pattern="URL" />
|
||||||
|
<policy domain="delegate" rights="none" pattern="HTTPS" />
|
||||||
|
<policy domain="delegate" rights="none" pattern="HTTP" />
|
||||||
|
<!-- in order to avoid to get image with password text -->
|
||||||
|
<policy domain="path" rights="none" pattern="@*"/>
|
||||||
|
<!-- disable ghostscript format types -->
|
||||||
|
<policy domain="coder" rights="none" pattern="PS" />
|
||||||
|
<policy domain="coder" rights="none" pattern="PS2" />
|
||||||
|
<policy domain="coder" rights="none" pattern="PS3" />
|
||||||
|
<policy domain="coder" rights="none" pattern="EPS" />
|
||||||
|
<policy domain="coder" rights="read|write" pattern="PDF" />
|
||||||
|
<policy domain="coder" rights="none" pattern="XPS" />
|
||||||
|
</policymap>
|
28
electronics/scripts/dependencies.sh
Executable file
28
electronics/scripts/dependencies.sh
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ -z "${GITHUB_WORKFLOW}" ]]; then
|
||||||
|
>&2 echo "Aborting! This script is meant to be run in CI (Github Actions) only. It may modify/damage your system configuration if run outside of CI."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -v
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
sudo add-apt-repository --yes ppa:kicad/kicad-5.1-releases
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y kicad inkscape poppler-utils xdotool recordmydesktop python3-dev python3-pip
|
||||||
|
|
||||||
|
# KiKit is installed via pinned git revision to get "new" CLI with support for V-Cuts layer specification. TODO: switch to release version once landed.
|
||||||
|
sudo python3 -m pip install psutil kikit==1.0.2 xvfbwrapper
|
||||||
|
|
||||||
|
mkdir -p ~/.config/kicad
|
||||||
|
cp /usr/share/kicad/template/fp-lib-table ~/.config/kicad/
|
||||||
|
cp /usr/share/kicad/template/sym-lib-table ~/.config/kicad/
|
||||||
|
|
||||||
|
cp "$DIR/config/eeschema" ~/.config/kicad/
|
||||||
|
cp "$DIR/config/pcbnew" ~/.config/kicad/
|
||||||
|
|
||||||
|
# Install ImageMagick policy that allows PDF conversion (safe in CI because we control all inputs/outputs)
|
||||||
|
sudo cp "$DIR/config/policy.xml" /etc/ImageMagick-6/policy.xml
|
192
electronics/scripts/export_3d.py
Executable file
192
electronics/scripts/export_3d.py
Executable file
@ -0,0 +1,192 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright 2015-2021 Scott Bezek and the splitflap contributors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import psutil
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
electronics_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
repo_root = os.path.dirname(electronics_root)
|
||||||
|
sys.path.append(repo_root)
|
||||||
|
|
||||||
|
from util import file_util
|
||||||
|
from export_util import (
|
||||||
|
patch_config,
|
||||||
|
PopenContext,
|
||||||
|
versioned_file,
|
||||||
|
xdotool,
|
||||||
|
wait_for_window,
|
||||||
|
recorded_xvfb,
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
RENDER_TIMEOUT = 10 * 60
|
||||||
|
|
||||||
|
|
||||||
|
def _wait_for_pcbnew_idle():
|
||||||
|
start = time.time()
|
||||||
|
while time.time() < start + RENDER_TIMEOUT:
|
||||||
|
for proc in psutil.process_iter():
|
||||||
|
if proc.name() == 'pcbnew':
|
||||||
|
cpu = proc.cpu_percent(interval=1)
|
||||||
|
print(f'CPU={cpu}', flush=True)
|
||||||
|
if cpu < 5:
|
||||||
|
print('Render took %d seconds' % (time.time() - start))
|
||||||
|
return
|
||||||
|
time.sleep(1)
|
||||||
|
raise RuntimeError('Timeout waiting for pcbnew to go idle')
|
||||||
|
|
||||||
|
|
||||||
|
def _zoom_in():
|
||||||
|
xdotool([
|
||||||
|
'click',
|
||||||
|
'4',
|
||||||
|
])
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
|
||||||
|
def _invoke_view_option(index):
|
||||||
|
command = ['key', 'alt+v'] + ['Down']*index + ['Return']
|
||||||
|
xdotool(command)
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
|
_transforms = {
|
||||||
|
'z+': ('Zoom in', _zoom_in),
|
||||||
|
'rx+': ('Rotate X Clockwise', lambda: _invoke_view_option(4)),
|
||||||
|
'rx-': ('Rotate X Counterclockwise', lambda: _invoke_view_option(5)),
|
||||||
|
'ry+': ('Rotate Y Clockwise', lambda: _invoke_view_option(6)),
|
||||||
|
'ry-': ('Rotate Y Counterclockwise', lambda: _invoke_view_option(7)),
|
||||||
|
'rz+': ('Rotate Z Clockwise', lambda: _invoke_view_option(8)),
|
||||||
|
'rz-': ('Rotate Z Counterclockwise', lambda: _invoke_view_option(9)),
|
||||||
|
'ml': ('Move left', lambda: _invoke_view_option(10)),
|
||||||
|
'mr': ('Move right', lambda: _invoke_view_option(11)),
|
||||||
|
'mu': ('Move up', lambda: _invoke_view_option(12)),
|
||||||
|
'md': ('Move down', lambda: _invoke_view_option(13)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _pcbnew_export_3d(output_file, width, height, transforms):
|
||||||
|
if os.path.exists(output_file):
|
||||||
|
os.remove(output_file)
|
||||||
|
|
||||||
|
wait_for_window('pcbnew', 'Pcbnew ', additional_commands=['windowfocus'])
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
logger.info('Open 3d viewer')
|
||||||
|
xdotool(['key', 'alt+3'])
|
||||||
|
|
||||||
|
wait_for_window('3D Viewer', '3D Viewer', additional_commands=['windowfocus'])
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
# Maximize window
|
||||||
|
xdotool(['search', '--name', '3D Viewer', 'windowmove', '0', '0'])
|
||||||
|
xdotool(['search', '--name', '3D Viewer', 'windowsize', str(width), str(height)])
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
for transform in transforms:
|
||||||
|
description, func = _transforms[transform]
|
||||||
|
logger.info(description)
|
||||||
|
func()
|
||||||
|
|
||||||
|
logger.info('Wait for rendering...')
|
||||||
|
|
||||||
|
_wait_for_pcbnew_idle()
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
logger.info('Export current view')
|
||||||
|
xdotool([
|
||||||
|
'key',
|
||||||
|
'alt+f',
|
||||||
|
'Return',
|
||||||
|
])
|
||||||
|
|
||||||
|
logger.info('Enter build output filename')
|
||||||
|
xdotool([
|
||||||
|
'key',
|
||||||
|
'ctrl+a',
|
||||||
|
])
|
||||||
|
xdotool(['type', output_file])
|
||||||
|
|
||||||
|
logger.info('Save')
|
||||||
|
xdotool(['key', 'Return'])
|
||||||
|
|
||||||
|
logger.info('Wait before shutdown')
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
|
def export_3d(filename, suffix, width, height, transforms, raytrace, virtual, color_soldermask, color_silk):
|
||||||
|
pcb_file = os.path.abspath(filename)
|
||||||
|
output_dir = os.path.join(electronics_root, 'build')
|
||||||
|
file_util.mkdir_p(output_dir)
|
||||||
|
|
||||||
|
screencast_output_file = os.path.join(output_dir, 'export_3d_screencast.ogv')
|
||||||
|
|
||||||
|
name, _ = os.path.splitext(os.path.basename(pcb_file))
|
||||||
|
if suffix:
|
||||||
|
name = name + '-' + suffix
|
||||||
|
output_file = os.path.join(output_dir, f'{name}-3d.png')
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
'canvas_type': '1',
|
||||||
|
'SMaskColor_Red': str(color_soldermask[0]),
|
||||||
|
'SMaskColor_Green': str(color_soldermask[1]),
|
||||||
|
'SMaskColor_Blue': str(color_soldermask[2]),
|
||||||
|
'SilkColor_Red': str(color_silk[0]),
|
||||||
|
'SilkColor_Green': str(color_silk[1]),
|
||||||
|
'SilkColor_Blue': str(color_silk[2]),
|
||||||
|
'RenderEngine': '1' if raytrace else '0',
|
||||||
|
'ShowFootprints_Virtual': '1' if virtual else '0',
|
||||||
|
'Render_RAY_ProceduralTextures': '0',
|
||||||
|
}
|
||||||
|
with patch_config(os.path.expanduser('~/.config/kicad/pcbnew'), settings):
|
||||||
|
with versioned_file(pcb_file):
|
||||||
|
with recorded_xvfb(screencast_output_file, width=width, height=height, colordepth=24):
|
||||||
|
with PopenContext(['pcbnew', pcb_file], close_fds=True) as pcbnew_proc:
|
||||||
|
_pcbnew_export_3d(output_file, width, height, transforms)
|
||||||
|
pcbnew_proc.terminate()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('pcb')
|
||||||
|
parser.add_argument('--suffix', default='')
|
||||||
|
parser.add_argument('--width', type=int, default=2560)
|
||||||
|
parser.add_argument('--height', type=int, default=1440)
|
||||||
|
parser.add_argument('--skip-raytrace', action='store_true')
|
||||||
|
parser.add_argument('--skip-virtual', action='store_true', help='Don\'t render virtual footprints')
|
||||||
|
parser.add_argument('--color-soldermask', type=float, nargs=3, help='Soldermask color as 3 floats from 0-1', default=[0.1, 0.1, 0.1])
|
||||||
|
parser.add_argument('--color-silk', type=float, nargs=3, help='Silkscreen color as 3 floats from 0-1', default=[0.9, 0.9, 0.9])
|
||||||
|
|
||||||
|
# Use subparsers to for an optional nargs="*" choices argument (workaround for https://bugs.python.org/issue9625)
|
||||||
|
subparsers = parser.add_subparsers(dest='which')
|
||||||
|
transform_parser = subparsers.add_parser('transform', help='Apply one or more transforms before capturing image')
|
||||||
|
transform_parser.add_argument('transform', nargs='+', choices=list(_transforms.keys()))
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
transforms = args.transform if args.which == 'transform' else []
|
||||||
|
|
||||||
|
export_3d(args.pcb, args.suffix, args.width, args.height, transforms, not args.skip_raytrace, not args.skip_virtual, args.color_soldermask, args.color_silk)
|
70
electronics/scripts/export_jlcpcb.py
Executable file
70
electronics/scripts/export_jlcpcb.py
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright 2021 Scott Bezek and the splitflap contributors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
electronics_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
repo_root = os.path.dirname(electronics_root)
|
||||||
|
sys.path.append(repo_root)
|
||||||
|
|
||||||
|
from util import file_util
|
||||||
|
from export_util import (
|
||||||
|
versioned_file,
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def export_jlcpcb(pcb, schematic, alt_fields):
|
||||||
|
pcb_file = os.path.abspath(pcb)
|
||||||
|
|
||||||
|
output_dir = os.path.join(electronics_root, 'build', os.path.splitext(os.path.basename(pcb_file))[0] + '-jlc')
|
||||||
|
file_util.mkdir_p(output_dir)
|
||||||
|
|
||||||
|
with versioned_file(pcb_file):
|
||||||
|
command = [
|
||||||
|
'kikit',
|
||||||
|
'fab',
|
||||||
|
'jlcpcb',
|
||||||
|
]
|
||||||
|
if schematic is not None:
|
||||||
|
schematic_file = os.path.abspath(schematic)
|
||||||
|
command += [
|
||||||
|
'--assembly',
|
||||||
|
'--schematic',
|
||||||
|
schematic_file,
|
||||||
|
'--field',
|
||||||
|
]
|
||||||
|
command.append(','.join(alt_fields + ['LCSC']))
|
||||||
|
command += [
|
||||||
|
pcb_file,
|
||||||
|
output_dir,
|
||||||
|
]
|
||||||
|
subprocess.check_call(command)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('pcb')
|
||||||
|
parser.add_argument('--assembly-schematic')
|
||||||
|
parser.add_argument('--alt-fields', nargs='+')
|
||||||
|
args = parser.parse_args()
|
||||||
|
export_jlcpcb(args.pcb, args.assembly_schematic, args.alt_fields)
|
138
electronics/scripts/export_util.py
Normal file
138
electronics/scripts/export_util.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2015-2016 Scott Bezek and the splitflap contributors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
electronics_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
repo_root = os.path.dirname(electronics_root)
|
||||||
|
sys.path.append(repo_root)
|
||||||
|
|
||||||
|
from xvfbwrapper import Xvfb
|
||||||
|
from util import file_util, rev_info
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class PopenContext(subprocess.Popen):
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
if self.stdout:
|
||||||
|
self.stdout.close()
|
||||||
|
if self.stderr:
|
||||||
|
self.stderr.close()
|
||||||
|
if self.stdin:
|
||||||
|
self.stdin.close()
|
||||||
|
if type:
|
||||||
|
self.terminate()
|
||||||
|
# Wait for the process to terminate, to avoid zombies.
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
def xdotool(command):
|
||||||
|
return subprocess.check_output(['xdotool'] + command)
|
||||||
|
|
||||||
|
def wait_for_window(name, window_regex, additional_commands=None, timeout=10):
|
||||||
|
if additional_commands is not None:
|
||||||
|
commands = additional_commands
|
||||||
|
else:
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
DELAY = 0.5
|
||||||
|
logger.info('Waiting for %s window...', name)
|
||||||
|
for i in range(int(timeout/DELAY)):
|
||||||
|
try:
|
||||||
|
xdotool(['search', '--name', window_regex] + commands)
|
||||||
|
logger.info('Found %s window', name)
|
||||||
|
return
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
pass
|
||||||
|
time.sleep(DELAY)
|
||||||
|
raise RuntimeError('Timed out waiting for %s window' % name)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def recorded_xvfb(video_filename, **xvfb_args):
|
||||||
|
with Xvfb(**xvfb_args):
|
||||||
|
with PopenContext([
|
||||||
|
'recordmydesktop',
|
||||||
|
'--no-sound',
|
||||||
|
'--no-frame',
|
||||||
|
'--on-the-fly-encoding',
|
||||||
|
'-o', video_filename], close_fds=True) as screencast_proc:
|
||||||
|
yield
|
||||||
|
screencast_proc.terminate()
|
||||||
|
|
||||||
|
|
||||||
|
def get_versioned_contents(filename):
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
original_contents = f.read()
|
||||||
|
date = rev_info.git_date()
|
||||||
|
date_long = rev_info.git_date(short=False)
|
||||||
|
rev = rev_info.git_short_rev()
|
||||||
|
logger.info('Replacing placeholders with %s and %s' % (date, rev))
|
||||||
|
return original_contents, original_contents \
|
||||||
|
.replace('Date ""', 'Date "%s"' % date_long) \
|
||||||
|
.replace('DATE: YYYY-MM-DD TIME TZ', 'DATE: %s' % date_long) \
|
||||||
|
.replace('DATE: YYYY-MM-DD', 'DATE: %s' % date) \
|
||||||
|
.replace('Rev ""', 'Rev "%s"' % rev) \
|
||||||
|
.replace('COMMIT: deadbeef', 'COMMIT: %s' % rev)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def versioned_file(filename):
|
||||||
|
original_contents, versioned_contents = get_versioned_contents(filename)
|
||||||
|
with open(filename, 'w') as temp_schematic:
|
||||||
|
logger.debug('Writing to %s', filename)
|
||||||
|
temp_schematic.write(versioned_contents)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
with open(filename, 'w') as temp_schematic:
|
||||||
|
logger.debug('Restoring %s', filename)
|
||||||
|
temp_schematic.write(original_contents)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def patch_config(filename, replacements):
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
yield
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
original_contents = f.read()
|
||||||
|
|
||||||
|
new_contents = original_contents
|
||||||
|
for (key, value) in replacements.items():
|
||||||
|
pattern = '^' + re.escape(key) + '=(.*)$'
|
||||||
|
new_contents = re.sub(pattern, key + '=' + value, new_contents, flags=re.MULTILINE)
|
||||||
|
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
logger.debug('Writing to %s', filename)
|
||||||
|
f.write(new_contents)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
logger.debug('Restoring %s', filename)
|
||||||
|
f.write(original_contents)
|
||||||
|
|
80
electronics/scripts/generate_pdf.py
Executable file
80
electronics/scripts/generate_pdf.py
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2015-2021 Scott Bezek and the splitflap contributors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import pcbnew
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
import pcb_util
|
||||||
|
|
||||||
|
electronics_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def run(pcb_file):
|
||||||
|
output_directory = os.path.join(electronics_root, 'build')
|
||||||
|
temp_dir = os.path.join(output_directory, 'temp_pdfs')
|
||||||
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||||
|
try:
|
||||||
|
os.makedirs(temp_dir)
|
||||||
|
plot_to_directory(pcb_file, output_directory, temp_dir)
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
|
def plot_to_directory(pcb_file, output_directory, temp_dir):
|
||||||
|
board_name = os.path.splitext(os.path.basename(pcb_file))[0]
|
||||||
|
|
||||||
|
with pcb_util.get_plotter(pcb_file, temp_dir) as plotter:
|
||||||
|
plotter.plot_options.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)
|
||||||
|
plotter.plot_options.SetExcludeEdgeLayer(False)
|
||||||
|
|
||||||
|
LayerDef = namedtuple('LayerDef', ['layer', 'mirror'])
|
||||||
|
layers = [
|
||||||
|
LayerDef(pcbnew.F_Cu, False),
|
||||||
|
LayerDef(pcbnew.B_Cu, True),
|
||||||
|
LayerDef(pcbnew.F_SilkS, False),
|
||||||
|
LayerDef(pcbnew.B_SilkS, True),
|
||||||
|
LayerDef(pcbnew.F_Mask, False),
|
||||||
|
LayerDef(pcbnew.B_Mask, True),
|
||||||
|
LayerDef(pcbnew.F_Paste, False),
|
||||||
|
]
|
||||||
|
|
||||||
|
pdfs = []
|
||||||
|
for layer in layers:
|
||||||
|
plotter.plot_options.SetMirror(layer.mirror)
|
||||||
|
output_filename = plotter.plot(layer.layer, pcbnew.PLOT_FORMAT_PDF)
|
||||||
|
pdfs.append(output_filename)
|
||||||
|
|
||||||
|
_, map_file = plotter.plot_drill()
|
||||||
|
pdfs.append(map_file)
|
||||||
|
|
||||||
|
output_pdf_filename = os.path.join(output_directory, '%s-pcb-packet.pdf' % (board_name,))
|
||||||
|
|
||||||
|
command = ['pdfunite'] + pdfs + [output_pdf_filename]
|
||||||
|
subprocess.check_call(command)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser('Generate a pdf of the PCB')
|
||||||
|
parser.add_argument('pcb_file')
|
||||||
|
args = parser.parse_args()
|
||||||
|
run(args.pcb_file)
|
||||||
|
|
112
electronics/scripts/pcb_util.py
Normal file
112
electronics/scripts/pcb_util.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2015-2021 Scott Bezek and the splitflap contributors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import pcbnew
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
from export_util import (
|
||||||
|
get_versioned_contents
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def versioned_board(filename):
|
||||||
|
_, versioned_contents = get_versioned_contents(filename)
|
||||||
|
with tempfile.NamedTemporaryFile(suffix='.kicad_pcb', mode='w') as temp_pcb:
|
||||||
|
logger.debug('Writing to %s', temp_pcb.name)
|
||||||
|
temp_pcb.write(versioned_contents)
|
||||||
|
temp_pcb.flush()
|
||||||
|
|
||||||
|
logger.debug('Load board')
|
||||||
|
board = pcbnew.LoadBoard(temp_pcb.name)
|
||||||
|
yield board
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def get_plotter(pcb_filename, build_directory):
|
||||||
|
with versioned_board(pcb_filename) as board:
|
||||||
|
yield Plotter(board, build_directory)
|
||||||
|
|
||||||
|
|
||||||
|
class Plotter(object):
|
||||||
|
def __init__(self, board, build_directory):
|
||||||
|
self.board = board
|
||||||
|
self.build_directory = build_directory
|
||||||
|
self.plot_controller = pcbnew.PLOT_CONTROLLER(board)
|
||||||
|
self.plot_options = self.plot_controller.GetPlotOptions()
|
||||||
|
self.plot_options.SetOutputDirectory(build_directory)
|
||||||
|
|
||||||
|
self.plot_options.SetPlotFrameRef(False)
|
||||||
|
self.plot_options.SetLineWidth(pcbnew.FromMM(0.35))
|
||||||
|
self.plot_options.SetScale(1)
|
||||||
|
self.plot_options.SetUseAuxOrigin(True)
|
||||||
|
self.plot_options.SetMirror(False)
|
||||||
|
self.plot_options.SetExcludeEdgeLayer(True)
|
||||||
|
|
||||||
|
def plot(self, layer, plot_format):
|
||||||
|
layer_name = self.board.GetLayerName(layer)
|
||||||
|
logger.info('Plotting layer %s (kicad layer=%r)', layer_name, layer)
|
||||||
|
self.plot_controller.SetLayer(layer)
|
||||||
|
self.plot_controller.OpenPlotfile(layer_name, plot_format , 'Plot')
|
||||||
|
output_filename = self.plot_controller.GetPlotFileName()
|
||||||
|
self.plot_controller.PlotLayer()
|
||||||
|
self.plot_controller.ClosePlot()
|
||||||
|
return output_filename
|
||||||
|
|
||||||
|
def plot_drill(self):
|
||||||
|
board_name = os.path.splitext(os.path.basename(self.board.GetFileName()))[0]
|
||||||
|
logger.info('Plotting drill file')
|
||||||
|
drill_writer = pcbnew.EXCELLON_WRITER(self.board)
|
||||||
|
drill_writer.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)
|
||||||
|
|
||||||
|
mirror = False
|
||||||
|
minimalHeader = False
|
||||||
|
offset = pcbnew.wxPoint(0, 0)
|
||||||
|
merge_npth = True
|
||||||
|
drill_writer.SetOptions(mirror, minimalHeader, offset, merge_npth)
|
||||||
|
|
||||||
|
metric_format = True
|
||||||
|
drill_writer.SetFormat(metric_format)
|
||||||
|
|
||||||
|
generate_drill = True
|
||||||
|
generate_map = True
|
||||||
|
drill_writer.CreateDrillandMapFilesSet(self.build_directory, generate_drill, generate_map)
|
||||||
|
|
||||||
|
drill_file_name = os.path.join(
|
||||||
|
self.build_directory,
|
||||||
|
'%s.drl' % (board_name,)
|
||||||
|
)
|
||||||
|
|
||||||
|
map_file_name = os.path.join(
|
||||||
|
self.build_directory,
|
||||||
|
'%s-drl_map.pdf' % (board_name,)
|
||||||
|
)
|
||||||
|
return drill_file_name, map_file_name
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='Test pcb util')
|
||||||
|
parser.add_argument('input_file', help='Input .kicad_pcb file')
|
||||||
|
args = parser.parse_args()
|
||||||
|
with versioned_board(args.input_file) as board:
|
||||||
|
logger.info('Loaded %s', board.GetFileName())
|
||||||
|
for module in board.GetModules():
|
||||||
|
logger.info('Module %s: %s', module.GetReference(), module.GetValue())
|
@ -8,6 +8,32 @@ preflight:
|
|||||||
update_xml: true
|
update_xml: true
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
|
# - name: pdf
|
||||||
|
# type: pdf_pcb_print
|
||||||
|
# dir: pdf
|
||||||
|
# options:
|
||||||
|
# separated: true
|
||||||
|
# layers:
|
||||||
|
# - 'F.Cu'
|
||||||
|
# - 'B.Cu'
|
||||||
|
# - 'F.Paste'
|
||||||
|
# - 'B.Paste'
|
||||||
|
# - 'F.SilkS'
|
||||||
|
# - 'B.SilkS'
|
||||||
|
# - 'Edge.Cuts'
|
||||||
|
|
||||||
|
# - name: gerber
|
||||||
|
# type: gerber
|
||||||
|
# dir: gerber
|
||||||
|
# layers:
|
||||||
|
# - 'F.Cu'
|
||||||
|
# - 'B.Cu'
|
||||||
|
# - 'F.Paste'
|
||||||
|
# - 'B.Paste'
|
||||||
|
# - 'F.SilkS'
|
||||||
|
# - 'B.SilkS'
|
||||||
|
# - 'Edge.Cuts'
|
||||||
|
|
||||||
- name: ibom
|
- name: ibom
|
||||||
comment: 'Interactive BOM'
|
comment: 'Interactive BOM'
|
||||||
type: ibom
|
type: ibom
|
||||||
@ -19,24 +45,24 @@ outputs:
|
|||||||
- name: schematic
|
- name: schematic
|
||||||
type: pdf_sch_print
|
type: pdf_sch_print
|
||||||
|
|
||||||
- name: 3d
|
# - name: 3d
|
||||||
type: render_3d
|
# type: render_3d
|
||||||
options:
|
# options:
|
||||||
no_virtual: true
|
# no_virtual: true
|
||||||
view: 'top'
|
# view: 'top'
|
||||||
silk: '#111111'
|
# silk: '#111111'
|
||||||
solder_mask: '#ffffff'
|
# solder_mask: '#ffffff'
|
||||||
board: '#C3BA9B'
|
# board: '#C3BA9B'
|
||||||
copper: '#99967F'
|
# copper: '#99967F'
|
||||||
zoom: 4
|
# zoom: 4
|
||||||
orthographic: true
|
# orthographic: true
|
||||||
ray_tracing: true
|
# ray_tracing: true
|
||||||
height: 1920
|
# height: 1920
|
||||||
width: 1920
|
# width: 1920
|
||||||
|
|
||||||
- name: 3d_back
|
# - name: 3d_back
|
||||||
type: render_3d
|
# type: render_3d
|
||||||
extends: 3d
|
# extends: 3d
|
||||||
options:
|
# options:
|
||||||
view: 'bottom'
|
# view: 'bottom'
|
||||||
zoom: 3
|
# zoom: 3
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,24 +19,24 @@ outputs:
|
|||||||
- name: schematic
|
- name: schematic
|
||||||
type: pdf_sch_print
|
type: pdf_sch_print
|
||||||
|
|
||||||
- name: 3d
|
# - name: 3d
|
||||||
type: render_3d
|
# type: render_3d
|
||||||
options:
|
# options:
|
||||||
no_virtual: true
|
# no_virtual: true
|
||||||
view: 'top'
|
# view: 'top'
|
||||||
silk: '#111111'
|
# silk: '#111111'
|
||||||
solder_mask: '#ffffff'
|
# solder_mask: '#ffffff'
|
||||||
board: '#C3BA9B'
|
# board: '#C3BA9B'
|
||||||
copper: '#99967F'
|
# copper: '#99967F'
|
||||||
orthographic: true
|
# orthographic: true
|
||||||
ray_tracing: true
|
# ray_tracing: true
|
||||||
height: 1920
|
# height: 1920
|
||||||
width: 1920
|
# width: 1920
|
||||||
zoom: 3
|
# zoom: 4
|
||||||
|
|
||||||
- name: 3d_back
|
# - name: 3d_back
|
||||||
type: render_3d
|
# type: render_3d
|
||||||
extends: 3d
|
# extends: 3d
|
||||||
options:
|
# options:
|
||||||
view: 'bottom'
|
# view: 'bottom'
|
||||||
zoom: 3
|
# zoom: 3
|
||||||
|
File diff suppressed because it is too large
Load Diff
BIN
scripts/RobotoMono-Bold.ttf
Normal file
BIN
scripts/RobotoMono-Bold.ttf
Normal file
Binary file not shown.
16
scripts/annotate_image.sh
Executable file
16
scripts/annotate_image.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
FONT="$DIR/RobotoMono-Bold.ttf"
|
||||||
|
|
||||||
|
# Make sure font exists
|
||||||
|
ls "$FONT"
|
||||||
|
|
||||||
|
set -v
|
||||||
|
|
||||||
|
LABEL="`date --rfc-3339=seconds`\n`git rev-parse --short HEAD`"
|
||||||
|
convert -background black -fill white -pointsize 12 -font "$FONT" -size 300x36 label:"$LABEL" -bordercolor black -border 3 $1 +swap -append $1
|
||||||
|
|
0
util/__init__.py
Normal file
0
util/__init__.py
Normal file
14
util/file_util.py
Normal file
14
util/file_util.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import errno
|
||||||
|
import os
|
||||||
|
|
||||||
|
def mkdir_p(path):
|
||||||
|
try:
|
||||||
|
os.makedirs(path)
|
||||||
|
except OSError as exc: # Python >2.5
|
||||||
|
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
32
util/rev_info.py
Normal file
32
util/rev_info.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import datetime
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def git_short_rev():
|
||||||
|
try:
|
||||||
|
return subprocess.check_output([
|
||||||
|
'git',
|
||||||
|
'rev-parse',
|
||||||
|
'--short',
|
||||||
|
'HEAD',
|
||||||
|
]).decode('utf-8').strip()
|
||||||
|
except Exception:
|
||||||
|
raise RuntimeError("Could not read git revision. Make sure you have git installed and you're working with a git clone of the repository.")
|
||||||
|
|
||||||
|
def current_date():
|
||||||
|
return datetime.date.today().strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
def git_date(short=True):
|
||||||
|
try:
|
||||||
|
iso = subprocess.check_output([
|
||||||
|
'git',
|
||||||
|
'log',
|
||||||
|
'-1',
|
||||||
|
'--format=%ci',
|
||||||
|
'HEAD',
|
||||||
|
]).decode('utf-8').strip()
|
||||||
|
if short:
|
||||||
|
return iso.split(' ')[0]
|
||||||
|
else:
|
||||||
|
return iso
|
||||||
|
except Exception:
|
||||||
|
raise RuntimeError("Could not read git commit date. Make sure you have git installed and you're working with a git clone of the repository.")
|
Loading…
Reference in New Issue
Block a user