Compare commits
48 Commits
v6.10.0
...
v6.11.0-BETA
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b37bd172e | |||
| fbbd468989 | |||
| 86b54509bf | |||
| 6e3f72dfb6 | |||
| 4aab04f751 | |||
| 9d2624b59e | |||
| be87c08e7e | |||
| 2f888a0090 | |||
| 34490b50b2 | |||
| 2439510f35 | |||
| 3049d4910c | |||
| d166c58161 | |||
| 144c19b44b | |||
| aef300d902 | |||
| 7ae773ab77 | |||
| 698fba5630 | |||
| 34d475b18a | |||
| 66d2eb9a0e | |||
| 1fe823270e | |||
| 0d7e60b5a4 | |||
| 13b31e6dd5 | |||
| 5ef6952ef4 | |||
| 19c78e5fa9 | |||
| 7f8c790936 | |||
| 27b32b0b3c | |||
| eeca9f112d | |||
| 122a91a6f0 | |||
| 246763419c | |||
| 9721307586 | |||
| 9765f04e3c | |||
| df873df04a | |||
| 16f54fa479 | |||
| b76d315f44 | |||
| 90e10f4597 | |||
| 3506c97403 | |||
| 324cb20634 | |||
| 39c7743c30 | |||
| 0c26a71174 | |||
| 2e6354883f | |||
| a6329c45bd | |||
| f73574641c | |||
| 9f6124f719 | |||
| 47d67d6311 | |||
| 025fcab11b | |||
| b2f99c7022 | |||
| bff9e05843 | |||
| b245396845 | |||
| eea7d45cc9 |
@@ -27,7 +27,9 @@ env:
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
runs-on: ubuntu-latest
|
||||
# amake/innosetup's wine cannot start its wineserver on Ubuntu 26.04 ("socket: Function not
|
||||
# implemented"); pinned until the image supports it
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 375 KiB After Width: | Height: | Size: 377 KiB |
|
Before Width: | Height: | Size: 293 KiB After Width: | Height: | Size: 312 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 433 KiB After Width: | Height: | Size: 432 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 210 KiB |
|
Before Width: | Height: | Size: 601 KiB After Width: | Height: | Size: 600 KiB |
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 463 KiB After Width: | Height: | Size: 463 KiB |
|
Before Width: | Height: | Size: 775 KiB After Width: | Height: | Size: 775 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 359 KiB |
|
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 805 KiB After Width: | Height: | Size: 966 KiB |
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 721 KiB After Width: | Height: | Size: 722 KiB |
|
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 3.7 MiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 730 KiB After Width: | Height: | Size: 732 KiB |
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 593 KiB After Width: | Height: | Size: 594 KiB |
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 250 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 13 MiB After Width: | Height: | Size: 13 MiB |
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 358 KiB |
|
Before Width: | Height: | Size: 398 KiB After Width: | Height: | Size: 398 KiB |
|
Before Width: | Height: | Size: 862 KiB After Width: | Height: | Size: 862 KiB |
|
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
|
Before Width: | Height: | Size: 351 KiB After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 220 KiB |
|
Before Width: | Height: | Size: 582 KiB After Width: | Height: | Size: 616 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 261 KiB |
|
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 235 KiB |
|
Before Width: | Height: | Size: 275 KiB After Width: | Height: | Size: 297 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 318 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 155 KiB |
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: regression-test
|
||||
description: Run the DIYLC end-to-end regression suite, which renders ~700 sample .diy projects and compares PNG exports and netlists against reference outputs. Use after any change to rendering, component drawing, serialization, netlist or analyzer logic, or when asked to check for regressions or regenerate reference files.
|
||||
description: Run the DIYLC end-to-end regression suite, which renders just under 100 sample .diy projects and compares PNG exports and netlists against reference outputs. Use after any change to rendering, component drawing, serialization, netlist or analyzer logic, or when asked to check for regressions or regenerate reference files.
|
||||
---
|
||||
|
||||
# Running the DIYLC regression suite
|
||||
@@ -29,16 +29,18 @@ already has the arguments and JVM flags. Offer that first.
|
||||
|
||||
The runner needs the `--add-opens` / `--add-exports` flags and a classpath spanning all three
|
||||
modules; `mvn exec:java` will not work because it runs in Maven's own classloader and fails to find
|
||||
Reflections. Build a classpath and fork a JVM:
|
||||
Reflections. Build a classpath and fork a JVM.
|
||||
|
||||
The classpath has to be built in the same reactor run as the compile. Running
|
||||
`dependency:build-classpath` on a single module fails with a `DependencyResolutionException`,
|
||||
because `diylc-processor` is not installed in the local repository and the plugin can only resolve
|
||||
it from the reactor. The relative `outputFile` gives each module its own `target/cp.txt`:
|
||||
|
||||
```bash
|
||||
cd diylc
|
||||
SP=/tmp # or the session scratchpad
|
||||
|
||||
mvn -q -pl diylc-swing -am test-compile
|
||||
mvn -q -pl diylc-swing dependency:build-classpath -Dmdep.outputFile=$SP/cp-swing.txt -Dmdep.includeScope=test
|
||||
mvn -q -pl diylc-core dependency:build-classpath -Dmdep.outputFile=$SP/cp-core.txt -Dmdep.includeScope=test
|
||||
mvn -q -pl diylc-library dependency:build-classpath -Dmdep.outputFile=$SP/cp-lib.txt -Dmdep.includeScope=test
|
||||
mvn -q -pl diylc-swing -am test-compile dependency:build-classpath \
|
||||
-Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=test
|
||||
|
||||
java \
|
||||
--add-exports java.desktop/com.apple.eawt.event=ALL-UNNAMED \
|
||||
@@ -49,19 +51,20 @@ java \
|
||||
--add-opens java.desktop/java.awt=ALL-UNNAMED \
|
||||
--add-opens java.desktop/java.awt.font=ALL-UNNAMED \
|
||||
--add-opens java.desktop/java.awt.geom=ALL-UNNAMED \
|
||||
-cp "diylc-swing/target/test-classes:diylc-swing/target/classes:diylc-core/target/classes:diylc-library/target/classes:$(cat $SP/cp-swing.txt):$(cat $SP/cp-core.txt):$(cat $SP/cp-lib.txt)" \
|
||||
-cp "diylc-swing/target/test-classes:diylc-swing/target/classes:diylc-core/target/classes:diylc-library/target/classes:$(cat diylc-swing/target/cp.txt):$(cat diylc-core/target/cp.txt):$(cat diylc-library/target/cp.txt)" \
|
||||
org.diylc.RegressionTestRunner \
|
||||
"$(cd .. && pwd)/diylc-regression-data" TEST [filter]
|
||||
```
|
||||
|
||||
Sanity-check the log line `Presenter - Current DIYLC version: 6.4.0` near the end. If it reports
|
||||
`5.0.0`, the `--add-opens` flags are missing and the run is invalid.
|
||||
Sanity-check the log line `Presenter - Current DIYLC version: ...`. It should report the newest
|
||||
version in `diylc-core/src/main/resources/update.xml`; if it reports `5.0.0`, the `--add-opens`
|
||||
flags are missing and the run is invalid.
|
||||
|
||||
### Arguments
|
||||
|
||||
1. Path to `diylc-regression-data`
|
||||
2. `TEST` or `PREPARE`
|
||||
3. Optional filter — a substring matched against file paths. **Use it.** The full suite is ~700
|
||||
3. Optional filter — a substring matched against file paths. The full suite is just under 100
|
||||
projects; while narrowing down an issue, run one file or one directory at a time
|
||||
(e.g. `splitter2`, or `guitar`).
|
||||
|
||||
|
||||
@@ -210,6 +210,14 @@ logic, netlist and analyzer behaviour, datasheet parsing, core utilities. Compon
|
||||
user interaction are covered by the regression suite instead, not by unit tests. Test classes are
|
||||
named `*Test` or `*Tests` and carry the license header like any other file.
|
||||
|
||||
## Changelog
|
||||
|
||||
User-facing changes are listed in `diylc-core/src/main/resources/update.xml`, one `Version` block
|
||||
per release. Within a block, all `NEW_FEATURE` entries come first, then `IMPROVEMENT`, then
|
||||
`BUG_FIX`; keep the existing order inside each group and add a new entry at the end of its own
|
||||
group, not at the end of the block. After a merge that brings entries in from both sides, sort the
|
||||
unreleased block again. Released blocks stay exactly as they shipped.
|
||||
|
||||
## Git
|
||||
|
||||
**Do not commit or push.** Make the change in the working tree and stop; the maintainer reviews and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version" : "6.10.0",
|
||||
"version" : "6.11.0",
|
||||
"components" : [ {
|
||||
"name" : "Blank Board",
|
||||
"className" : "boards.BlankBoard",
|
||||
@@ -7,7 +7,7 @@
|
||||
"namePrefix" : "Board",
|
||||
"description" : "Blank circuit board",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Use 'Explicit' value for 'Dimension Mode' when placing a new board. The single control point places the top-left corner and 'Explicit Length' and 'Explicit Width' properties determine the dimensions", "Set 'Underside Display' only if explicitly asked to. The values other than 'NONE' render the mirror image of the board in the provided direction with the offset controlled by 'Underside Offset'", "Use this board as a base of PCB, eyelet and turret boards unless asked otherwise" ],
|
||||
"notes" : [ "Use 'Explicit' value for 'Dimension Mode' when placing a new board. The single control point places the top-left corner and 'Explicit Length' and 'Explicit Width' properties determine the dimensions", "Set 'Underside Display' only if explicitly asked to. The values other than 'NONE' render the mirror image of the board in the provided direction with the offset controlled by 'Underside Offset'", "Use this board as a base of PCB, eyelet and turret boards unless asked otherwise", "When the board needs mounting holes, because the request asks for them or the board goes into an enclosure, also select Drill Hole and use one Drill Hole per hole" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -99,6 +99,7 @@
|
||||
"namePrefix" : "BB",
|
||||
"description" : "David Haillant's eurorack format stripboard for prototyping and building simple modules",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Set 'Underside Display' only if explicitly asked to. The values other than 'NONE' render the mirror image of the board in the provided direction with the offset controlled by 'Underside Offset'" ],
|
||||
"properties" : [ {
|
||||
"name" : "Board Color",
|
||||
"type" : "Color",
|
||||
@@ -127,6 +128,21 @@
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFC593"
|
||||
}, {
|
||||
"name" : "Underside Display",
|
||||
"type" : "BoardUndersideDisplay",
|
||||
"possibleValues" : [ "NONE", "ABOVE", "BELOW", "LEFT", "RIGHT" ],
|
||||
"defaultValue" : "NONE"
|
||||
}, {
|
||||
"name" : "Underside Offset",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Underside Transparency",
|
||||
"type" : "Boolean",
|
||||
"defaultValue" : "true"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Eyelet Board",
|
||||
@@ -322,7 +338,7 @@
|
||||
"namePrefix" : "BB",
|
||||
"description" : "A prototyping board for modular synths, central bus with V+ GND and V-",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The control point is the top-left corner of the 2in x 4in body and 'Orientation' rotates the board around it", "With 'Orientation' DEFAULT, pad row n (1-33) is (0.4 + n x 0.1)in below the control point. Each row is split into separately connected groups, labeled by column: 1-2, 3-5, 6-8, 9-11, 12-14 and 15-16, at 0.1-0.2, 0.4-0.6, 0.7-0.9, 1.2-1.4, 1.5-1.7 and 1.8-1.9in to the right of it" ],
|
||||
"notes" : [ "Set 'Underside Display' only if explicitly asked to. The values other than 'NONE' render the mirror image of the board in the provided direction with the offset controlled by 'Underside Offset'", "The control point is the top-left corner of the 2in x 4in body and 'Orientation' rotates the board around it", "With 'Orientation' DEFAULT, pad row n (1-33) is (0.4 + n x 0.1)in below the control point. Each row is split into separately connected groups, labeled by column: 1-2, 3-5, 6-8, 9-11, 12-14 and 15-16, at 0.1-0.2, 0.4-0.6, 0.7-0.9, 1.2-1.4, 1.5-1.7 and 1.8-1.9in to the right of it" ],
|
||||
"properties" : [ {
|
||||
"name" : "Board Color",
|
||||
"type" : "Color",
|
||||
@@ -351,6 +367,17 @@
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFC593"
|
||||
}, {
|
||||
"name" : "Underside Display",
|
||||
"type" : "BoardUndersideDisplay",
|
||||
"possibleValues" : [ "NONE", "ABOVE", "BELOW", "LEFT", "RIGHT" ],
|
||||
"defaultValue" : "NONE"
|
||||
}, {
|
||||
"name" : "Underside Offset",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Underside Pad Color",
|
||||
"type" : "Color",
|
||||
@@ -361,6 +388,10 @@
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#D7B2FF"
|
||||
}, {
|
||||
"name" : "Underside Transparency",
|
||||
"type" : "Boolean",
|
||||
"defaultValue" : "true"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Perf Board w/ Pads",
|
||||
@@ -465,6 +496,7 @@
|
||||
"namePrefix" : "BB",
|
||||
"description" : "Prototyping board similar to Radio Shack 276-168B or MPJA 33304",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Set 'Underside Display' only if explicitly asked to. The values other than 'NONE' render the mirror image of the board in the provided direction with the offset controlled by 'Underside Offset'" ],
|
||||
"properties" : [ {
|
||||
"name" : "Board Color",
|
||||
"type" : "Color",
|
||||
@@ -498,6 +530,21 @@
|
||||
"type" : "ProtoBoard780Type",
|
||||
"possibleValues" : [ "RS", "MPJA" ],
|
||||
"defaultValue" : "MPJA"
|
||||
}, {
|
||||
"name" : "Underside Display",
|
||||
"type" : "BoardUndersideDisplay",
|
||||
"possibleValues" : [ "NONE", "ABOVE", "BELOW", "LEFT", "RIGHT" ],
|
||||
"defaultValue" : "NONE"
|
||||
}, {
|
||||
"name" : "Underside Offset",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Underside Transparency",
|
||||
"type" : "Boolean",
|
||||
"defaultValue" : "true"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Tag Strip",
|
||||
@@ -1035,7 +1082,7 @@
|
||||
}, {
|
||||
"name" : "Layer",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_1"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
@@ -1077,7 +1124,7 @@
|
||||
}, {
|
||||
"name" : "Layer",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_1"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
@@ -1196,6 +1243,11 @@
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "A junction marker for schematics and wiring diagrams; it is drawing only and connects nothing, since ends that meet at the same point are already connected. For a pad on a board use Solder Pad" ],
|
||||
"properties" : [ {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
@@ -1277,7 +1329,7 @@
|
||||
}, {
|
||||
"name" : "Layer",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_1"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
@@ -1459,6 +1511,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -1681,7 +1738,7 @@
|
||||
"namePrefix" : "Pad",
|
||||
"description" : "Copper solder pad, round or square",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Use on Blank Board and PCB layouts; Perf Board, Vero Board, TriPad Board and the proto boards already have their own pads" ],
|
||||
"notes" : [ "Use on Blank Board and PCB layouts; Perf Board, Vero Board, TriPad Board and the proto boards already have their own pads; a pad with Hole Type 'Plated Through Hole' is on both copper layers and joins them, so its Layer is ignored" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -1702,11 +1759,11 @@
|
||||
"name" : "Hole Type",
|
||||
"type" : "HoleType",
|
||||
"possibleValues" : [ "NONE", "PTH", "NTPH" ],
|
||||
"defaultValue" : "NTPH"
|
||||
"defaultValue" : "PTH"
|
||||
}, {
|
||||
"name" : "Layer",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_1"
|
||||
}, {
|
||||
"name" : "Node Name",
|
||||
@@ -1921,6 +1978,44 @@
|
||||
} ]
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Via",
|
||||
"className" : "connectivity.Via",
|
||||
"category" : "Connectivity",
|
||||
"namePrefix" : "Via",
|
||||
"description" : "Plated hole joining the copper on the top and bottom of a PCB",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Use on Blank Board and PCB layouts to take a trace from one copper layer to the other", "Place the control point where a Top trace and a Bottom trace meet; the via joins the copper of both layers there. It is not a component pad: leads go into a Solder Pad" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Hole",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.4mm"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Size",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.8mm"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "sequential"
|
||||
}
|
||||
}, {
|
||||
"name" : "Arduino Mega 2560",
|
||||
"className" : "micro.ArduinoMega",
|
||||
@@ -7155,6 +7250,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Font Size Override",
|
||||
"type" : "Integer"
|
||||
@@ -7228,6 +7328,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Font Size Override",
|
||||
"type" : "Integer"
|
||||
@@ -7306,6 +7411,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Font Size Override",
|
||||
"type" : "Integer"
|
||||
@@ -7746,6 +7856,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Display",
|
||||
"type" : "Display",
|
||||
@@ -7851,6 +7966,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -8509,6 +8629,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
@@ -8577,6 +8702,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Font Size Override",
|
||||
"type" : "Integer"
|
||||
@@ -8645,6 +8775,11 @@
|
||||
}, {
|
||||
"name" : "Angle Offset",
|
||||
"type" : "Angle"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -9035,6 +9170,11 @@
|
||||
}, {
|
||||
"name" : "Angle",
|
||||
"type" : "Angle"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -9372,6 +9512,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -9496,6 +9641,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -11466,6 +11616,7 @@
|
||||
"namePrefix" : "Hole",
|
||||
"description" : "Drill hole marker for PCB, chassis or faceplate",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Use for round holes: the mounting holes of a Blank Board, and the holes for jacks, pots, switches and LEDs in an Enclosure; for other openings in an Enclosure use the Rectangular, Elliptical or Polygonal Cutout", "The single control point is the centre of the hole and 'Diameter' is the drilled size, e.g. 3.2mm for an M3 mounting screw. Place mounting holes inside the board, typically one near each corner and clear of the components and traces", "A hole is not conductive and has no terminals, so nothing connects to it; on a PCB it is exported as a non-plated drill" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -11526,7 +11677,7 @@
|
||||
"namePrefix" : "ENC",
|
||||
"description" : "Top panel of an enclosure or chassis, optionally with its sides unfolded",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The two control points are opposite corners of the enclosure's top panel. With 'Height' above zero the sides are unfolded around it as an exploded view, each as tall as 'Height' and set 'Spacing' apart from it: the front against the top panel's upper edge, the back against its lower edge and, when 'Sides' is All, the left and right sides against its left and right edges. The bottom is never drawn. With 'Sides' set to None, or 'Height' at zero, it is a single flat panel of any size, such as one side of a chassis drawn on its own", "The enclosure is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly", "A datasheet model is a Hammond enclosure part number such as 1590BB, 1550B or 1444-32, or a generic size such as 125B, and is stored as 'Value'; it sets the top panel to the enclosure's length and width, upright for pedal-sized die-cast boxes up to 125 mm long and horizontal for bigger boxes and amplifier chassis and 'Height' to its wall height. 125B is a generic size sold by several makers; its Hammond equivalent is 1590N1" ],
|
||||
"notes" : [ "One Enclosure draws a whole box, so use one per box rather than one per side. Also select Drill Hole for the round holes of its jacks, pots, switches and LEDs, and the Rectangular, Elliptical or Polygonal Cutout for any other openings", "Draw each hole and cutout on the panel it goes through, inside that panel's outline", "The two control points are opposite corners of the enclosure's top panel. With 'Height' above zero the sides are unfolded around it as an exploded view, each as tall as 'Height' and set 'Spacing' apart from it: the front against the top panel's upper edge, the back against its lower edge and, when 'Sides' is All, the left and right sides against its left and right edges. The bottom is never drawn. With 'Sides' set to None, or 'Height' at zero, it is a single flat panel of any size, such as one side of a chassis drawn on its own", "The enclosure is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly", "A datasheet model is a Hammond enclosure part number such as 1590BB, 1550B or 1444-32, or a generic size such as 125B, and is stored as 'Value'; it sets the top panel to the enclosure's length and width, upright for pedal-sized die-cast boxes up to 125 mm long and horizontal for bigger boxes and amplifier chassis and 'Height' to its wall height. 125B is a generic size sold by several makers; its Hammond equivalent is 1590N1" ],
|
||||
"datasheetModels" : [ "1444-10", "1444-1172", "1444-12", "1444-1372", "1444-14", "1444-15", "1444-16", "1444-17132", "1444-18", "1444-22", "1444-26", "1444-29", "1444-30", "1444-45351", "1444-542", "1444-6", "1444-6415", "1444-772", "1444-8", "1444-84515", "1444-862", "1444-9", "1444-9552", "1444-972", "1444-1053", "1444-10825", "1444-12103", "1444-12123", "1444-1273", "1444-12825", "1444-14103", "1444-1463", "1444-1573", "1444-1593", "1444-17123", "1444-17133", "1444-17143", "1444-17173", "1444-1763", "1444-1773", "1444-1783", "1444-20", "1444-24", "1444-28", "1444-32", "1444-643", "1444-753", "1444-95525", "1444-9553", "1444-17105", "1444-17134", "1444-17135", "1444-17154", "1444-17156", "1444-17174", "1444-33", "1441-10", "1441-12", "1441-14", "1441-15", "1441-16", "1441-18", "1441-20", "1441-22", "1441-24", "1441-26", "1441-28", "1441-29", "1441-30", "1441-32", "1441-33", "1441-34", "1441-36", "1441-38", "1441-40", "1441-42", "1441-6", "1441-8", "1441-9", "1550A", "1550B", "1550C", "1550D", "1550E", "1550F", "1550G", "1550H", "1550J", "1550K", "1550L", "1550M", "1550N", "1550P", "1550Q", "1590A", "1590B", "1590B2", "1590B3", "1590BB", "1590BB2", "1590BBS", "1590BS", "1590BX", "1590BX2", "1590C", "1590CE", "1590D", "1590DD", "1590DE", "1590E", "1590EE", "1590F", "1590G", "1590G2", "1590H", "1590J", "1590K", "1590KK", "1590LB", "1590LLB", "1590N1", "1590P1", "1590Q", "1590R1", "1590S", "1590T", "1590U", "1590V", "1590X", "1590XX", "1590Y", "125B" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
@@ -11841,6 +11992,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -11969,7 +12125,7 @@
|
||||
}, {
|
||||
"name" : "Layer",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_1"
|
||||
}, {
|
||||
"name" : "Orientation",
|
||||
@@ -12081,6 +12237,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12169,6 +12330,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12251,6 +12417,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12366,6 +12537,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12491,6 +12667,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12588,6 +12769,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12692,6 +12878,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12803,6 +12994,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12912,6 +13108,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -12993,6 +13194,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -13082,6 +13288,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Coil",
|
||||
"type" : "Color",
|
||||
@@ -13221,6 +13432,11 @@
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#333333"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -13300,6 +13516,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -13458,6 +13679,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -13526,6 +13752,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -13620,6 +13851,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -13727,6 +13963,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -13785,6 +14026,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -13843,6 +14089,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -16500,6 +16751,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -16573,6 +16829,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -16836,6 +17097,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -16929,6 +17195,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
@@ -17016,6 +17287,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -17101,6 +17377,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -17262,6 +17543,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -17343,6 +17629,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -17778,6 +18069,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -18209,6 +18505,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -19071,6 +19372,11 @@
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
@@ -20010,6 +20316,11 @@
|
||||
"type" : "Base",
|
||||
"possibleValues" : [ "B9A", "OCTAL", "B7G", "B12C", "UX4" ],
|
||||
"defaultValue" : "B9A"
|
||||
}, {
|
||||
"name" : "Board Side",
|
||||
"type" : "PCBLayer",
|
||||
"possibleValues" : [ "_1", "_2" ],
|
||||
"defaultValue" : "_2"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"version" : "6.10.0",
|
||||
"version" : "6.11.0",
|
||||
"categories" : {
|
||||
"Boards" : [ {
|
||||
"name" : "Blank Board",
|
||||
"className" : "boards.BlankBoard",
|
||||
"notes" : [ "Use this board as a base of PCB, eyelet and turret boards unless asked otherwise" ]
|
||||
"notes" : [ "Use this board as a base of PCB, eyelet and turret boards unless asked otherwise", "When the board needs mounting holes, because the request asks for them or the board goes into an enclosure, also select Drill Hole and use one Drill Hole per hole" ]
|
||||
}, {
|
||||
"name" : "Breadboard",
|
||||
"className" : "boards.Breadboard"
|
||||
@@ -85,7 +85,7 @@
|
||||
}, {
|
||||
"name" : "Solder Pad",
|
||||
"className" : "connectivity.SolderPad",
|
||||
"notes" : [ "Use on Blank Board and PCB layouts; Perf Board, Vero Board, TriPad Board and the proto boards already have their own pads" ]
|
||||
"notes" : [ "Use on Blank Board and PCB layouts; Perf Board, Vero Board, TriPad Board and the proto boards already have their own pads; a pad with Hole Type 'Plated Through Hole' is on both copper layers and joins them, so its Layer is ignored" ]
|
||||
}, {
|
||||
"name" : "Trace Cut",
|
||||
"className" : "connectivity.TraceCut"
|
||||
@@ -96,6 +96,10 @@
|
||||
"name" : "Twisted Leads",
|
||||
"className" : "connectivity.TwistedWire",
|
||||
"notes" : [ "Electrically a single conductor between its two ends, exactly like Hookup Wire, even though two twisted leads are drawn; use it only for the look of a twisted pair, and where the circuit must be electrically correct and analyzable, draw each conductor as its own Hookup Wire or Right Angle Wire instead" ]
|
||||
}, {
|
||||
"name" : "Via",
|
||||
"className" : "connectivity.Via",
|
||||
"notes" : [ "Use on Blank Board and PCB layouts to take a trace from one copper layer to the other" ]
|
||||
} ],
|
||||
"Controllers" : [ {
|
||||
"name" : "Arduino Mega 2560",
|
||||
@@ -283,13 +287,15 @@
|
||||
"className" : "chassis.DialScale"
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole"
|
||||
"className" : "electromechanical.DrillHole",
|
||||
"notes" : [ "Use for round holes: the mounting holes of a Blank Board, and the holes for jacks, pots, switches and LEDs in an Enclosure; for other openings in an Enclosure use the Rectangular, Elliptical or Polygonal Cutout" ]
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout"
|
||||
}, {
|
||||
"name" : "Enclosure",
|
||||
"className" : "chassis.ChassisPanel"
|
||||
"className" : "chassis.ChassisPanel",
|
||||
"notes" : [ "One Enclosure draws a whole box, so use one per box rather than one per side. Also select Drill Hole for the round holes of its jacks, pots, switches and LEDs, and the Rectangular, Elliptical or Polygonal Cutout for any other openings" ]
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout"
|
||||
|
||||
@@ -97,10 +97,10 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.diylc.local</groupId>
|
||||
<artifactId>gerber-writer-api-1.1.0</artifactId>
|
||||
<artifactId>gerber-writer-api-1.2.0</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.1.0.jar</systemPath>
|
||||
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.2.0.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.diylc.local</groupId>
|
||||
|
||||
@@ -72,5 +72,9 @@ public enum DrawOption {
|
||||
/**
|
||||
* When applied, all colors will be converted to blackest black or whitest white
|
||||
*/
|
||||
MONOCHROMATIC;
|
||||
MONOCHROMATIC,
|
||||
/**
|
||||
* Paint on the bottom side of a board is drawn at reduced opacity, as if seen through the board.
|
||||
*/
|
||||
FADE_FAR_SIDE;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String FONT_SCALE_FACTOR_KEY = "fontScaleFactor";
|
||||
public static final String SHOW_RESIZE_DIMENSIONS_TOOLTIP_KEY = "showResizeDimensionsTooltip";
|
||||
public static final String AUTO_UNIT_CONVERSION_KEY = "autoUnitConversion";
|
||||
public static final String VALUE_NOTATION_KEY = "valueNotation";
|
||||
|
||||
|
||||
public static final String RULER_IN_SUBDIVISION_2 = "base of 2";
|
||||
@@ -101,10 +102,16 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String SNAP_TO_COMPONENTS = "Components";
|
||||
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
|
||||
|
||||
public static final String VALUE_NOTATION_DECIMAL = "Decimal (4.7K, 0.22uF, 6.3V)";
|
||||
public static final String VALUE_NOTATION_RKM = "RKM (4K7, 0u22, 6V3)";
|
||||
public static final String VALUE_NOTATION_DEFAULT = VALUE_NOTATION_DECIMAL;
|
||||
|
||||
public static final String SHOW_NODE_NAME_TOOLTIPS_KEY = "showNodeNameTooltips";
|
||||
|
||||
public static final String LOCKED_ALPHA = "lockedAlpha";
|
||||
|
||||
public static final String FADE_FAR_SIDE_KEY = "fadeFarSide";
|
||||
|
||||
public static final String LANGUAGE = "language";
|
||||
public static final String LANGUAGE_DEFAULT = "English";
|
||||
|
||||
@@ -357,22 +364,24 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
void setNewComponentTypeSlot(ComponentType componentType, Template template, String[] model, boolean forceInstatiate);
|
||||
|
||||
/**
|
||||
* Locks or unlocks the specified layer. All components within +- 0.5 range will be affected by
|
||||
* the change as well.
|
||||
* Locks or unlocks the specified layer: the components whose z-order rounds to it, or the
|
||||
* components on one side of the board for a trace layer.
|
||||
*
|
||||
* @param layerZOrder
|
||||
* @param layerId a z-order such as {@link org.diylc.core.IDIYComponent#BOARD}, or one of the
|
||||
* trace layers in {@link org.diylc.core.LayerIds}
|
||||
* @param locked
|
||||
*/
|
||||
void setLayerLocked(int layerZOrder, boolean locked);
|
||||
void setLayerLocked(int layerId, boolean locked);
|
||||
|
||||
/**
|
||||
* Shows or hides the specified layer. All components within +- 0.5 range will be affected by the
|
||||
* change as well.
|
||||
* Shows or hides the specified layer: the components whose z-order rounds to it, or the
|
||||
* components on one side of the board for a trace layer.
|
||||
*
|
||||
* @param layerZOrder
|
||||
* @param layerId a z-order such as {@link org.diylc.core.IDIYComponent#BOARD}, or one of the
|
||||
* trace layers in {@link org.diylc.core.LayerIds}
|
||||
* @param visible
|
||||
*/
|
||||
void setLayerVisibility(int layerZOrder, boolean visible);
|
||||
void setLayerVisibility(int layerId, boolean visible);
|
||||
|
||||
/**
|
||||
* @return selection size expressed in both inches or centimeters, respectively
|
||||
|
||||
@@ -77,7 +77,8 @@ public interface ISelectionProcessor extends IGroupProcessor {
|
||||
/**
|
||||
* Selects all components in the project.
|
||||
*
|
||||
* @param int layer if > 0, designates which layer to select. If <= 0 we should select all
|
||||
* @param int layer if > 0, the id of the layer to select, as for
|
||||
* {@link IPlugInPort#setLayerVisibility(int, boolean)}. If <= 0 we should select all
|
||||
* regardless of layer
|
||||
*/
|
||||
void selectAll(int layer);
|
||||
|
||||
@@ -25,7 +25,11 @@ import org.diylc.core.gerber.GerberLayer;
|
||||
|
||||
public enum PCBLayer {
|
||||
|
||||
_1("Bottom"), _2("Top"), _3("Inner 1"), _4("Inner 2"), _5("Inner 3"), _6("Inner 4"), _7("Inner 5"), _8("Inner 6");
|
||||
_1("Bottom"), _2("Top"),
|
||||
// DIYLC models two-sided boards only. The inner layers are kept, in order, so that files using
|
||||
// them still load with the same layer ids; the editor hides them and Gerber export rejects them.
|
||||
@Deprecated _3("Inner 1"), @Deprecated _4("Inner 2"), @Deprecated _5("Inner 3"),
|
||||
@Deprecated _6("Inner 4"), @Deprecated _7("Inner 5"), @Deprecated _8("Inner 6");
|
||||
|
||||
private String label;
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
public interface IBoard {
|
||||
|
||||
Size DEFAULT_UNDERSIDE_OFFSET = new Size(0.1, SizeUnit.in);
|
||||
|
||||
Rectangle2D getBoardRectangle();
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.core;
|
||||
|
||||
import org.diylc.common.PCBLayer;
|
||||
|
||||
/**
|
||||
* Interface for components on one side of a board, such as a resistor, an IC or a trace. The side
|
||||
* says where the part sits physically; it is separate from {@link ILayeredComponent}, which drives
|
||||
* continuity, because the leads of a through-hole part connect to copper on both sides whichever
|
||||
* side the part is mounted on. Copper implements it through {@link IPCBLayerComponent}, whose layer
|
||||
* is its side and also drives its continuity.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IBoardSideComponent {
|
||||
|
||||
/**
|
||||
* @return {@link PCBLayer#_2} for the top of the board or {@link PCBLayer#_1} for the bottom,
|
||||
* never an inner layer or null
|
||||
*/
|
||||
PCBLayer getBoardSide();
|
||||
|
||||
/**
|
||||
* Sets the side of the board the component is mounted on. The component is not mirrored.
|
||||
*
|
||||
* @param boardSide {@link PCBLayer#_2} for the top or {@link PCBLayer#_1} for the bottom
|
||||
*/
|
||||
void setBoardSide(PCBLayer boardSide);
|
||||
|
||||
/**
|
||||
* @return {@link PCBLayer#_1} for a component mounted on the bottom of the board, and
|
||||
* {@link PCBLayer#_2} for any other, including components that have no side
|
||||
*/
|
||||
static PCBLayer sideOf(IDIYComponent<?> component) {
|
||||
return component instanceof IBoardSideComponent sided && sided.getBoardSide() == PCBLayer._1
|
||||
? PCBLayer._1 : PCBLayer._2;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
*/
|
||||
package org.diylc.core;
|
||||
|
||||
import org.diylc.common.PCBLayer;
|
||||
|
||||
/**
|
||||
* Interface for tracking component drawing process. Components may use it to stop or restart
|
||||
* tracking. Anything drawn while tracking is stopped will not be added to the mouse hot-spot area.
|
||||
@@ -65,4 +67,26 @@ public interface IDrawingObserver {
|
||||
* @param marker
|
||||
*/
|
||||
void setContinuityMarker(String marker);
|
||||
|
||||
/**
|
||||
* Notifies the observer that what follows is painted on the given side of the board, until
|
||||
* {@link #stopDrawingSide()}. Paint that is not bracketed is on the top (component) side. The
|
||||
* observer may draw paint on the side facing away from the viewer at reduced opacity, as if seen
|
||||
* through the board. Inner layers count as the bottom side.
|
||||
*
|
||||
* @param side the layer the paint lies on
|
||||
*/
|
||||
default void startDrawingSide(PCBLayer side) {}
|
||||
|
||||
/**
|
||||
* Notifies the observer that what follows is visible from both sides of the board, such as a
|
||||
* drilled hole or a cut through the copper, and is never drawn faded, until
|
||||
* {@link #stopDrawingSide()}.
|
||||
*/
|
||||
default void startDrawingBothSides() {}
|
||||
|
||||
/**
|
||||
* Notifies the observer that paint is back on the top (component) side.
|
||||
*/
|
||||
default void stopDrawingSide() {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.core;
|
||||
|
||||
import org.diylc.common.PCBLayer;
|
||||
|
||||
/**
|
||||
* Interface for copper drawn on a layer of a PCB, such as a trace, pad, ground fill or PCB text.
|
||||
* The layer is the copper's board side, but unlike the side of a mounted part it also decides
|
||||
* which other copper the copper connects to. It keeps the name 'Layer' in the editor, which is
|
||||
* what PCB tools call it for copper.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IPCBLayerComponent extends IBoardSideComponent {
|
||||
|
||||
PCBLayer getLayer();
|
||||
|
||||
void setLayer(PCBLayer layer);
|
||||
|
||||
/**
|
||||
* @return the layer, with the deprecated inner layers counted as the bottom
|
||||
*/
|
||||
@Override
|
||||
default PCBLayer getBoardSide() {
|
||||
return getLayer() == PCBLayer._2 ? PCBLayer._2 : PCBLayer._1;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setBoardSide(PCBLayer boardSide) {
|
||||
setLayer(boardSide);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.core;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Ids of the layers that can be hidden or locked in a project. A layer is a rounded z-order, such
|
||||
* as {@link IDIYComponent#BOARD}, except that the traces are split into a bottom and a top layer.
|
||||
* <p>
|
||||
* The traces used to be one layer, {@link IDIYComponent#TRACE}, and older DIYLC versions still
|
||||
* know only that one. Project files therefore keep {@link #LEGACY_TRACES} in a hidden or locked
|
||||
* set exactly when both trace layers are in it, so that an older version hides or locks all
|
||||
* traces when the new one has both sides hidden or locked.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public final class LayerIds {
|
||||
|
||||
public static final int LEGACY_TRACES = IDIYComponent.TRACE;
|
||||
public static final int BOTTOM_TRACES = IDIYComponent.TRACE * 10 + 1;
|
||||
public static final int TOP_TRACES = IDIYComponent.TRACE * 10 + 2;
|
||||
|
||||
private LayerIds() {}
|
||||
|
||||
/**
|
||||
* Brings a hidden or locked layer set read from a file up to date. The legacy trace layer, from
|
||||
* an old file or written by an older version, stands for both trace layers. Both trace layers
|
||||
* without it can only mean that an older version showed or unlocked its single trace layer, so
|
||||
* neither side is hidden or locked any more.
|
||||
*/
|
||||
public static void migrateLoaded(Set<Integer> layers) {
|
||||
if (layers.contains(LEGACY_TRACES)) {
|
||||
layers.add(BOTTOM_TRACES);
|
||||
layers.add(TOP_TRACES);
|
||||
} else if (layers.contains(BOTTOM_TRACES) && layers.contains(TOP_TRACES)) {
|
||||
layers.remove(BOTTOM_TRACES);
|
||||
layers.remove(TOP_TRACES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps the legacy trace layer in a hidden or locked set after it has been changed: present
|
||||
* exactly when both trace layers are.
|
||||
*/
|
||||
public static void syncLegacy(Set<Integer> layers) {
|
||||
if (layers.contains(BOTTOM_TRACES) && layers.contains(TOP_TRACES)) {
|
||||
layers.add(LEGACY_TRACES);
|
||||
} else {
|
||||
layers.remove(LEGACY_TRACES);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,17 @@ public class Project implements Serializable, Cloneable {
|
||||
return hiddenLayers;
|
||||
}
|
||||
|
||||
// called by XStream after loading, whichever way the project is opened; the trace layer was split
|
||||
// in two, and files from older versions name only the single legacy one
|
||||
private Object readResolve() {
|
||||
if (lockedLayers == null) {
|
||||
lockedLayers = new HashSet<Integer>();
|
||||
}
|
||||
LayerIds.migrateLoaded(lockedLayers);
|
||||
LayerIds.migrateLoaded(getHiddenLayers());
|
||||
return this;
|
||||
}
|
||||
|
||||
public VersionNumber getFileVersion() {
|
||||
return fileVersion;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import org.diylc.core.ValidationException;
|
||||
|
||||
/**
|
||||
* Same as {@link PositiveNonZeroMeasureValidator}, but also rejects an empty value. Use it for
|
||||
* measures the component cannot be drawn without.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class RequiredPositiveNonZeroMeasureValidator extends PositiveNonZeroMeasureValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object owner, Object value) throws ValidationException {
|
||||
if (value == null) {
|
||||
throw new ValidationException("must not be empty.");
|
||||
}
|
||||
super.validate(owner, value);
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,12 @@ import java.util.stream.Collectors;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.bancika.gerberwriter.DataLayer;
|
||||
import com.bancika.gerberwriter.DrillFormat;
|
||||
|
||||
import org.diylc.common.PCBLayer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IBoard;
|
||||
import org.diylc.core.IBoardSideComponent;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.core.Project;
|
||||
@@ -30,6 +33,9 @@ public class GerberExporter {
|
||||
public static final double OUTLINE_THICKNESS = new Size(0.3d, SizeUnit.mm).convertToPixels();
|
||||
private static final Logger LOG = Logger.getLogger(GerberExporter.class);
|
||||
|
||||
// Excellon is the drill format every fab accepts; Gerber drill files are not read by all of them
|
||||
private static final DrillFormat DRILL_FORMAT = DrillFormat.EXCELLON;
|
||||
|
||||
public static void exportGerber(String fileNameBase, Project currentProject, IView view,
|
||||
Graphics2D graphics2d, String diylcVersion) {
|
||||
|
||||
@@ -135,6 +141,23 @@ public class GerberExporter {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
g2d.getDrillLayerMap().forEach((layer, drillLayer) -> {
|
||||
try {
|
||||
String fileName = layer.formatFileName(fileNameBase, boardComponent.getName(),
|
||||
DRILL_FORMAT == DrillFormat.EXCELLON ? "drl" : "gbr");
|
||||
LOG.info("Exporting layer: " + layer + " for board " + boardComponent.getName()
|
||||
+ " to file: " + fileName);
|
||||
drillLayer.dumpToFile(fileName, DRILL_FORMAT);
|
||||
generatedFiles.add(fileName);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing drill file: " + e.getMessage());
|
||||
view.showMessage(
|
||||
LangUtil.translate(
|
||||
"Failed to export the project to gerber. Please check the log for details"),
|
||||
LangUtil.translate("Gerber Export"), IView.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
});
|
||||
view.showMessage(
|
||||
String.format(
|
||||
@@ -145,8 +168,12 @@ public class GerberExporter {
|
||||
LOG.info("Completed export to gerber");
|
||||
}
|
||||
|
||||
private static void drawComponent(Project currentProject, GerberG2DWrapper g2d,
|
||||
IDIYComponent<?> c, boolean outlineMode) {
|
||||
/**
|
||||
* Draws the specified component into the Gerber layers it belongs to. This is the only place that
|
||||
* decides which layer a component's output goes to.
|
||||
*/
|
||||
static void drawComponent(Project currentProject, GerberG2DWrapper g2d,
|
||||
IDIYComponent<?> c, boolean outlineMode) {
|
||||
IGerberComponent gerberComponent = (IGerberComponent) c;
|
||||
g2d.startedDrawingComponent();
|
||||
if (gerberComponent instanceof IGerberComponentCustom) {
|
||||
@@ -156,7 +183,10 @@ public class GerberExporter {
|
||||
IGerberComponentSimple gerberComponentSimple = (IGerberComponentSimple) gerberComponent;
|
||||
g2d.startGerberOutput(gerberComponentSimple.getGerberLayer(),
|
||||
gerberComponentSimple.getGerberFunction(), gerberComponentSimple.isGerberNegative());
|
||||
// text on the bottom silkscreen is read from below, so it is written mirrored
|
||||
g2d.setMirrorText(IBoardSideComponent.sideOf(c) == PCBLayer._1);
|
||||
c.draw(g2d, ComponentState.NORMAL, outlineMode, currentProject, g2d);
|
||||
g2d.setMirrorText(false);
|
||||
g2d.stopGerberOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
@@ -32,6 +33,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.bancika.gerberwriter.DataLayer;
|
||||
import com.bancika.gerberwriter.DrillLayer;
|
||||
import com.bancika.gerberwriter.Point;
|
||||
import com.bancika.gerberwriter.padmasters.Circle;
|
||||
|
||||
@@ -45,6 +47,7 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
private static final double CURVE_APPROXIMATION_TOLERANCE = 1d;
|
||||
|
||||
private Map<GerberLayer, DataLayer> layerMap;
|
||||
private Map<GerberLayer, DrillLayer> drillLayerMap;
|
||||
private boolean trackingGerber = false;
|
||||
private Map<GerberLayer, GerberProperties> currentLayers =
|
||||
new HashMap<GerberLayer, GerberProperties>();
|
||||
@@ -58,12 +61,14 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
private double tolerance;
|
||||
|
||||
private Rectangle2D boardRect;
|
||||
private boolean mirrorText = false;
|
||||
|
||||
public GerberG2DWrapper(Graphics2D graphics2d, String diylcVersion, Rectangle2D boardRect) {
|
||||
super();
|
||||
this.graphics2d = graphics2d;
|
||||
this.boardRect = boardRect;
|
||||
this.layerMap = new HashMap<GerberLayer, DataLayer>();
|
||||
this.drillLayerMap = new HashMap<GerberLayer, DrillLayer>();
|
||||
this.diylcVersion = diylcVersion;
|
||||
}
|
||||
|
||||
@@ -114,7 +119,11 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
|
||||
@Override
|
||||
public void startGerberOutput(GerberLayer layer, String function, boolean negative) {
|
||||
layerMap.computeIfAbsent(layer, k -> layer.buildLayer(diylcVersion));
|
||||
if (layer.isDrill()) {
|
||||
drillLayerMap.computeIfAbsent(layer, k -> layer.buildDrillLayer(diylcVersion));
|
||||
} else {
|
||||
layerMap.computeIfAbsent(layer, k -> layer.buildLayer(diylcVersion));
|
||||
}
|
||||
currentLayers.put(layer, new GerberProperties(function, negative));
|
||||
trackingGerber = true;
|
||||
}
|
||||
@@ -154,10 +163,28 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
return layerMap;
|
||||
}
|
||||
|
||||
public Map<GerberLayer, DrillLayer> getDrillLayerMap() {
|
||||
return drillLayerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether text is written mirrored, each string about its own centre. The output is in top
|
||||
* view, so text on the bottom side has to be mirrored to read correctly once the board is turned
|
||||
* over.
|
||||
*/
|
||||
public void setMirrorText(boolean mirrorText) {
|
||||
this.mirrorText = mirrorText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Shape s) {
|
||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||
currentLayers.entrySet().forEach(entry -> {
|
||||
// only round fills are holes; outlines, such as a drill hole marker's border and
|
||||
// crosshair, are not drilled
|
||||
if (entry.getKey().isDrill()) {
|
||||
return;
|
||||
}
|
||||
double width = 1;
|
||||
if (stroke != null && stroke instanceof BasicStroke) {
|
||||
width = ((BasicStroke) stroke).getLineWidth();
|
||||
@@ -181,6 +208,10 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
GlyphVector gv = font.createGlyphVector(graphics2d.getFontRenderContext(), str);
|
||||
|
||||
AffineTransform translateInstance = AffineTransform.getTranslateInstance(x, y);
|
||||
if (mirrorText) {
|
||||
translateInstance.translate(gv.getLogicalBounds().getWidth(), 0);
|
||||
translateInstance.scale(-1, 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < gv.getNumGlyphs(); i++) {
|
||||
Shape glyphShape = gv.getGlyphOutline(i);
|
||||
@@ -208,6 +239,10 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
public void fillShape(Shape s) {
|
||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||
currentLayers.entrySet().forEach(entry -> {
|
||||
// only round fills are holes
|
||||
if (entry.getKey().isDrill()) {
|
||||
return;
|
||||
}
|
||||
DataLayer dataLayer = layerMap.get(entry.getKey());
|
||||
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
||||
GerberPathRenderer.outputPathArea(s.getPathIterator(finalTx), dataLayer,
|
||||
@@ -220,6 +255,10 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
private void fillFlash(Ellipse2D c) {
|
||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||
currentLayers.entrySet().forEach(entry -> {
|
||||
if (entry.getKey().isDrill()) {
|
||||
addHole(c, entry.getKey(), entry.getValue().function);
|
||||
return;
|
||||
}
|
||||
DataLayer dataLayer = layerMap.get(entry.getKey());
|
||||
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
||||
if (Math.abs(c.getWidth() - c.getHeight()) < 0.1 && finalTx.getShearX() == 0
|
||||
@@ -241,6 +280,17 @@ public class GerberG2DWrapper extends Graphics2D
|
||||
}
|
||||
}
|
||||
|
||||
private void addHole(Ellipse2D c, GerberLayer layer, String function) {
|
||||
AffineTransform finalTx = getFinalTx(layer.isMirrored());
|
||||
Point2D center = finalTx.transform(new Point2D.Double(c.getCenterX(), c.getCenterY()), null);
|
||||
double factor = SizeUnit.px.getFactor();
|
||||
// the drawing transform scales evenly, so the circle stays a circle, scaled by the square root
|
||||
// of the determinant whether or not it is also rotated
|
||||
double diameter = c.getWidth() * Math.sqrt(Math.abs(finalTx.getDeterminant())) * factor;
|
||||
drillLayerMap.get(layer).addHole(new Point(center.getX() * factor, center.getY() * factor),
|
||||
diameter, function);
|
||||
}
|
||||
|
||||
private AffineTransform getFinalTx(boolean isMirrored) {
|
||||
AffineTransform finalTx = new AffineTransform();
|
||||
if (isMirrored) {
|
||||
|
||||