mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 20:34:55 +10:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b3b0ef746f | |||
| 8abaf2884b | |||
| a678b52f4d | |||
| 47f9056588 | |||
| c5a462a385 | |||
| b15a6e3f64 | |||
| 79d230ff07 | |||
| 23ecf9e8d7 | |||
| fce069895f | |||
| 4688879d0e | |||
| 15277452f4 | |||
| 5d92812d3e |
@@ -2,7 +2,7 @@ Switch setup: [ ALL ]
|
||||
|
||||
2K2.+ <-> D1.K <-> D4.K <-> Q1.2
|
||||
2K2.+ <-> D2.A <-> D3.A <-> Q2.2
|
||||
2K2.- <-> 2K2.- <-> C6.- <-> C7.- <-> J1.Tip <-> J2.Tip <-> J3.Tip <-> LM324.10 <-> LM324.3 <-> LM324.5 <-> Q1.1 <-> Q2.1 <-> R5.2 <-> VR1.3 <-> VR2.3
|
||||
2K2.- <-> 2K2.- <-> C6.- <-> C7.- <-> J1.Tip <-> J2.Tip <-> J3.Tip <-> LM324.12 <-> LM324.3 <-> LM324.5 <-> Q1.1 <-> Q2.1 <-> R5.2 <-> VR1.3 <-> VR2.3
|
||||
C1.+ <-> J1.Sleeve
|
||||
C1.- <-> R1.1
|
||||
C2.+ <-> J2.Sleeve
|
||||
@@ -11,15 +11,15 @@ Switch setup: [ ALL ]
|
||||
C3.- <-> VR2.1
|
||||
C4.+ <-> LM324.1 <-> R1.2
|
||||
C4.- <-> VR1.1
|
||||
C5.+ <-> LM324.8 <-> R3.2
|
||||
C5.+ <-> LM324.14 <-> R3.2
|
||||
C5.- <-> J3.Sleeve <-> R5.1
|
||||
C6.+ <-> LM324.11 <-> Q2.3
|
||||
C7.+ <-> LM324.4 <-> Q1.3
|
||||
D1.A <-> D2.K
|
||||
D3.K <-> D4.A
|
||||
LM324.13 <-> R3.1 <-> R3.1 <-> R4.1
|
||||
LM324.2 <-> R1.1 <-> R1.2
|
||||
LM324.6 <-> R1.1 <-> R2.2
|
||||
LM324.9 <-> R3.1 <-> R3.1 <-> R4.1
|
||||
R3.2 <-> VR2.2
|
||||
R4.2 <-> VR1.2
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Switch setup: [ ALL ]
|
||||
|
||||
2K2.+ <-> D1.K <-> D4.K <-> Q1.2
|
||||
2K2.+ <-> D2.A <-> D3.A <-> Q2.2
|
||||
2K2.- <-> 2K2.- <-> C6.- <-> C7.- <-> J1.Tip <-> J2.Tip <-> J3.Tip <-> LM324.10 <-> LM324.3 <-> LM324.5 <-> Q1.1 <-> Q2.1 <-> R5.2 <-> VR1.3 <-> VR2.3
|
||||
2K2.- <-> 2K2.- <-> C6.- <-> C7.- <-> J1.Tip <-> J2.Tip <-> J3.Tip <-> LM324.12 <-> LM324.3 <-> LM324.5 <-> Q1.1 <-> Q2.1 <-> R5.2 <-> VR1.3 <-> VR2.3
|
||||
C1.+ <-> J1.Sleeve
|
||||
C1.- <-> R1.1
|
||||
C2.+ <-> J2.Sleeve
|
||||
@@ -11,15 +11,15 @@ Switch setup: [ ALL ]
|
||||
C3.- <-> VR2.1
|
||||
C4.+ <-> LM324.1 <-> R1.2
|
||||
C4.- <-> VR1.1
|
||||
C5.+ <-> LM324.8 <-> R3.2
|
||||
C5.+ <-> LM324.14 <-> R3.2
|
||||
C5.- <-> J3.Sleeve <-> R5.1
|
||||
C6.+ <-> LM324.11 <-> Q2.3
|
||||
C7.+ <-> LM324.4 <-> Q1.3
|
||||
D1.A <-> D2.K
|
||||
D3.K <-> D4.A
|
||||
LM324.13 <-> R3.1 <-> R3.1 <-> R4.1
|
||||
LM324.2 <-> R1.1 <-> R1.2
|
||||
LM324.6 <-> R1.1 <-> R2.2
|
||||
LM324.9 <-> R3.1 <-> R3.1 <-> R4.1
|
||||
R3.2 <-> VR2.2
|
||||
R4.2 <-> VR1.2
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
+12V.+ <-> +12V.- <-> Arduino Nano.10 <-> Arduino Nano.11 <-> Arduino Nano.12 <-> Arduino Nano.13 <-> Arduino Nano.14 <-> Arduino Nano.15 <-> Arduino Nano.25 <-> Arduino Nano.26 <-> Arduino Nano.27 <-> Arduino Nano.28 <-> Arduino Nano.29 <-> Arduino Nano.30 <-> Arduino Nano.4 <-> Arduino Nano.5 <-> Arduino Nano.6 <-> Arduino Nano.7 <-> Arduino Nano.8 <-> Arduino Nano.9 <-> C1.1 <-> C1.2 <-> C2.1 <-> C2.2 <-> D1.A <-> D1.K <-> D2.A <-> D2.K <-> LM2902.1 <-> LM2902.1 <-> LM2902.10 <-> LM2902.10 <-> LM2902.11 <-> LM2902.11 <-> LM2902.12 <-> LM2902.12 <-> LM2902.13 <-> LM2902.13 <-> LM2902.14 <-> LM2902.14 <-> LM2902.2 <-> LM2902.2 <-> LM2902.3 <-> LM2902.3 <-> LM2902.4 <-> LM2902.4 <-> LM2902.5 <-> LM2902.5 <-> LM2902.6 <-> LM2902.6 <-> LM2902.7 <-> LM2902.7 <-> LM2902.8 <-> LM2902.8 <-> LM2902.9 <-> LM2902.9 <-> MPSA05.1 <-> MPSA05.1 <-> MPSA05.2 <-> MPSA05.2 <-> MPSA05.3 <-> MPSA05.3 <-> PH1.1 <-> PH1.2 <-> PH1.3 <-> PH2.1 <-> PH2.2 <-> PH2.3 <-> PH3.1 <-> PH3.2 <-> PH4.1 <-> PH4.2 <-> PH4.3 <-> PH5.1 <-> PH5.2 <-> PH5.3 <-> PH6.1 <-> Q3.1 <-> Q3.2 <-> Q3.3 <-> R1.1 <-> R1.1 <-> R1.2 <-> R1.2 <-> R10.1 <-> R10.1 <-> R10.2 <-> R10.2 <-> R11.1 <-> R11.1 <-> R11.2 <-> R11.2 <-> R12.1 <-> R12.1 <-> R12.2 <-> R12.2 <-> R3.1 <-> R3.1 <-> R3.2 <-> R3.2 <-> R4.1 <-> R4.1 <-> R4.2 <-> R4.2 <-> R5.1 <-> R5.1 <-> R5.2 <-> R5.2 <-> R6.1 <-> R6.1 <-> R6.2 <-> R6.2 <-> R8.1 <-> R8.1 <-> R8.2 <-> R8.2 <-> R9.1 <-> R9.1 <-> R9.2 <-> R9.2 <-> VR1.1 <-> VR1.2 <-> VR1.3 <-> VR2.1 <-> VR2.2 <-> VR2.3 <-> VR3.1 <-> VR3.2 <-> VR3.3 <-> VR4.1 <-> VR4.2 <-> VR4.3
|
||||
+12V.+ <-> +12V.- <-> Arduino Nano.10 <-> Arduino Nano.11 <-> Arduino Nano.12 <-> Arduino Nano.13 <-> Arduino Nano.14 <-> Arduino Nano.15 <-> Arduino Nano.16 <-> Arduino Nano.17 <-> Arduino Nano.18 <-> Arduino Nano.19 <-> Arduino Nano.20 <-> Arduino Nano.21 <-> Arduino Nano.4 <-> Arduino Nano.5 <-> Arduino Nano.6 <-> Arduino Nano.7 <-> Arduino Nano.8 <-> Arduino Nano.9 <-> C1.1 <-> C1.2 <-> C2.1 <-> C2.2 <-> D1.A <-> D1.K <-> D2.A <-> D2.K <-> LM2902.1 <-> LM2902.1 <-> LM2902.10 <-> LM2902.10 <-> LM2902.11 <-> LM2902.11 <-> LM2902.12 <-> LM2902.12 <-> LM2902.13 <-> LM2902.13 <-> LM2902.14 <-> LM2902.14 <-> LM2902.2 <-> LM2902.2 <-> LM2902.3 <-> LM2902.3 <-> LM2902.4 <-> LM2902.4 <-> LM2902.5 <-> LM2902.5 <-> LM2902.6 <-> LM2902.6 <-> LM2902.7 <-> LM2902.7 <-> LM2902.8 <-> LM2902.8 <-> LM2902.9 <-> LM2902.9 <-> MPSA05.1 <-> MPSA05.1 <-> MPSA05.2 <-> MPSA05.2 <-> MPSA05.3 <-> MPSA05.3 <-> PH1.1 <-> PH1.2 <-> PH1.3 <-> PH2.1 <-> PH2.2 <-> PH2.3 <-> PH3.1 <-> PH3.2 <-> PH4.1 <-> PH4.2 <-> PH4.3 <-> PH5.1 <-> PH5.2 <-> PH5.3 <-> PH6.1 <-> Q3.1 <-> Q3.2 <-> Q3.3 <-> R1.1 <-> R1.1 <-> R1.2 <-> R1.2 <-> R10.1 <-> R10.1 <-> R10.2 <-> R10.2 <-> R11.1 <-> R11.1 <-> R11.2 <-> R11.2 <-> R12.1 <-> R12.1 <-> R12.2 <-> R12.2 <-> R3.1 <-> R3.1 <-> R3.2 <-> R3.2 <-> R4.1 <-> R4.1 <-> R4.2 <-> R4.2 <-> R5.1 <-> R5.1 <-> R5.2 <-> R5.2 <-> R6.1 <-> R6.1 <-> R6.2 <-> R6.2 <-> R8.1 <-> R8.1 <-> R8.2 <-> R8.2 <-> R9.1 <-> R9.1 <-> R9.2 <-> R9.2 <-> VR1.1 <-> VR1.2 <-> VR1.3 <-> VR2.1 <-> VR2.2 <-> VR2.3 <-> VR3.1 <-> VR3.2 <-> VR3.3 <-> VR4.1 <-> VR4.2 <-> VR4.3
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
+12V.+ <-> +12V.- <-> Arduino Nano.10 <-> Arduino Nano.11 <-> Arduino Nano.12 <-> Arduino Nano.13 <-> Arduino Nano.14 <-> Arduino Nano.15 <-> Arduino Nano.25 <-> Arduino Nano.26 <-> Arduino Nano.27 <-> Arduino Nano.28 <-> Arduino Nano.29 <-> Arduino Nano.30 <-> Arduino Nano.4 <-> Arduino Nano.5 <-> Arduino Nano.6 <-> Arduino Nano.7 <-> Arduino Nano.8 <-> Arduino Nano.9 <-> C1.1 <-> C1.2 <-> C2.1 <-> C2.2 <-> D1.A <-> D1.K <-> D2.A <-> D2.K <-> LM2902.1 <-> LM2902.1 <-> LM2902.10 <-> LM2902.10 <-> LM2902.11 <-> LM2902.11 <-> LM2902.12 <-> LM2902.12 <-> LM2902.13 <-> LM2902.13 <-> LM2902.14 <-> LM2902.14 <-> LM2902.2 <-> LM2902.2 <-> LM2902.3 <-> LM2902.3 <-> LM2902.4 <-> LM2902.4 <-> LM2902.5 <-> LM2902.5 <-> LM2902.6 <-> LM2902.6 <-> LM2902.7 <-> LM2902.7 <-> LM2902.8 <-> LM2902.8 <-> LM2902.9 <-> LM2902.9 <-> MPSA05.1 <-> MPSA05.1 <-> MPSA05.2 <-> MPSA05.2 <-> MPSA05.3 <-> MPSA05.3 <-> PH1.1 <-> PH1.2 <-> PH1.3 <-> PH2.1 <-> PH2.2 <-> PH2.3 <-> PH3.1 <-> PH3.2 <-> PH4.1 <-> PH4.2 <-> PH4.3 <-> PH5.1 <-> PH5.2 <-> PH5.3 <-> PH6.1 <-> Q3.1 <-> Q3.2 <-> Q3.3 <-> R1.1 <-> R1.1 <-> R1.2 <-> R1.2 <-> R10.1 <-> R10.1 <-> R10.2 <-> R10.2 <-> R11.1 <-> R11.1 <-> R11.2 <-> R11.2 <-> R12.1 <-> R12.1 <-> R12.2 <-> R12.2 <-> R3.1 <-> R3.1 <-> R3.2 <-> R3.2 <-> R4.1 <-> R4.1 <-> R4.2 <-> R4.2 <-> R5.1 <-> R5.1 <-> R5.2 <-> R5.2 <-> R6.1 <-> R6.1 <-> R6.2 <-> R6.2 <-> R8.1 <-> R8.1 <-> R8.2 <-> R8.2 <-> R9.1 <-> R9.1 <-> R9.2 <-> R9.2 <-> VR1.1 <-> VR1.2 <-> VR1.3 <-> VR2.1 <-> VR2.2 <-> VR2.3 <-> VR3.1 <-> VR3.2 <-> VR3.3 <-> VR4.1 <-> VR4.2 <-> VR4.3
|
||||
+12V.+ <-> +12V.- <-> Arduino Nano.10 <-> Arduino Nano.11 <-> Arduino Nano.12 <-> Arduino Nano.13 <-> Arduino Nano.14 <-> Arduino Nano.15 <-> Arduino Nano.16 <-> Arduino Nano.17 <-> Arduino Nano.18 <-> Arduino Nano.19 <-> Arduino Nano.20 <-> Arduino Nano.21 <-> Arduino Nano.4 <-> Arduino Nano.5 <-> Arduino Nano.6 <-> Arduino Nano.7 <-> Arduino Nano.8 <-> Arduino Nano.9 <-> C1.1 <-> C1.2 <-> C2.1 <-> C2.2 <-> D1.A <-> D1.K <-> D2.A <-> D2.K <-> LM2902.1 <-> LM2902.1 <-> LM2902.10 <-> LM2902.10 <-> LM2902.11 <-> LM2902.11 <-> LM2902.12 <-> LM2902.12 <-> LM2902.13 <-> LM2902.13 <-> LM2902.14 <-> LM2902.14 <-> LM2902.2 <-> LM2902.2 <-> LM2902.3 <-> LM2902.3 <-> LM2902.4 <-> LM2902.4 <-> LM2902.5 <-> LM2902.5 <-> LM2902.6 <-> LM2902.6 <-> LM2902.7 <-> LM2902.7 <-> LM2902.8 <-> LM2902.8 <-> LM2902.9 <-> LM2902.9 <-> MPSA05.1 <-> MPSA05.1 <-> MPSA05.2 <-> MPSA05.2 <-> MPSA05.3 <-> MPSA05.3 <-> PH1.1 <-> PH1.2 <-> PH1.3 <-> PH2.1 <-> PH2.2 <-> PH2.3 <-> PH3.1 <-> PH3.2 <-> PH4.1 <-> PH4.2 <-> PH4.3 <-> PH5.1 <-> PH5.2 <-> PH5.3 <-> PH6.1 <-> Q3.1 <-> Q3.2 <-> Q3.3 <-> R1.1 <-> R1.1 <-> R1.2 <-> R1.2 <-> R10.1 <-> R10.1 <-> R10.2 <-> R10.2 <-> R11.1 <-> R11.1 <-> R11.2 <-> R11.2 <-> R12.1 <-> R12.1 <-> R12.2 <-> R12.2 <-> R3.1 <-> R3.1 <-> R3.2 <-> R3.2 <-> R4.1 <-> R4.1 <-> R4.2 <-> R4.2 <-> R5.1 <-> R5.1 <-> R5.2 <-> R5.2 <-> R6.1 <-> R6.1 <-> R6.2 <-> R6.2 <-> R8.1 <-> R8.1 <-> R8.2 <-> R8.2 <-> R9.1 <-> R9.1 <-> R9.2 <-> R9.2 <-> VR1.1 <-> VR1.2 <-> VR1.3 <-> VR2.1 <-> VR2.2 <-> VR2.3 <-> VR3.1 <-> VR3.2 <-> VR3.3 <-> VR4.1 <-> VR4.2 <-> VR4.3
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.+ <-> R10.2 <-> R2.1 <-> R9.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.11 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.13 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.14 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.12 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C10.1 <-> R22.1 <-> R30.2
|
||||
C10.2 <-> R16.1 <-> V3.7
|
||||
C11.1 <-> IC3.9
|
||||
C11.1 <-> IC3.16
|
||||
C11.2 <-> C14.1 <-> C8.2 <-> R18.1 <-> R25.2
|
||||
C12.1 <-> R11.1 <-> V2.3
|
||||
C12.2 <-> R21.2
|
||||
C13.2 <-> R17.2 <-> V3.6
|
||||
C14.2 <-> C23.1 <-> IC2.9 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C14.2 <-> C23.1 <-> IC2.16 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C15.1 <-> C9.1 <-> R19.1
|
||||
C15.2 <-> C22.1 <-> IC2.13 <-> R19.2 <-> R29.1
|
||||
C15.2 <-> C22.1 <-> IC2.12 <-> R19.2 <-> R29.1
|
||||
C16.1 <-> C21.1 <-> R27.1 <-> V2.1
|
||||
C16.2 <-> R32.2 <-> V2.2 <-> VR1.2
|
||||
C17.1 <-> R13.2 <-> V3.3
|
||||
C17.2 <-> R34.1
|
||||
C18.+ <-> IC1.4 <-> Q2.1
|
||||
C18.- <-> C29.- <-> IC1.3 <-> Q2.2 <-> SW1.2
|
||||
C18.+ <-> IC1.3 <-> Q2.1
|
||||
C18.- <-> C29.- <-> IC1.4 <-> Q2.2 <-> SW1.2
|
||||
C19.2 <-> R21.1 <-> R28.2 <-> V2.7
|
||||
C2.+ <-> C6.2 <-> R11.2 <-> R12.2 <-> R2.2 <-> R3.1
|
||||
C20.1 <-> C27.1 <-> R26.2 <-> V1.1
|
||||
@@ -40,11 +40,11 @@ Switch setup: [ ALL ]
|
||||
C8.1 <-> R10.1 <-> V1.8
|
||||
D2.A <-> D3.K
|
||||
D4.A <-> D5.K
|
||||
D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC2.16 <-> IC3.16 <-> IC4.16 <-> SW1.1
|
||||
D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC2.9 <-> IC3.9 <-> IC4.9 <-> SW1.1
|
||||
D9.A <-> R37.2
|
||||
IC3.13 <-> R36.2
|
||||
IC4.11 <-> VR6.2 <-> VR6.3
|
||||
IC4.9 <-> VR7.2 <-> VR7.3
|
||||
IC3.12 <-> R36.2
|
||||
IC4.14 <-> VR6.2 <-> VR6.3
|
||||
IC4.16 <-> VR7.2 <-> VR7.3
|
||||
Q1.3 <-> R1.1 <-> R4.1
|
||||
R16.2 <-> R17.1 <-> R31.2
|
||||
R22.2 <-> R34.2 <-> VR6.1 <-> VR7.1
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
Switch setup: [ SW1.ON1 ]
|
||||
|
||||
C1.+ <-> R10.2 <-> R2.1 <-> R9.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.11 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.13 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.14 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.12 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C10.1 <-> R22.1 <-> R30.2
|
||||
C10.2 <-> R16.1 <-> V3.7
|
||||
C11.1 <-> IC3.9
|
||||
C11.1 <-> IC3.16
|
||||
C11.2 <-> C14.1 <-> C8.2 <-> R18.1 <-> R25.2
|
||||
C12.1 <-> R11.1 <-> V2.3
|
||||
C12.2 <-> R21.2
|
||||
C13.2 <-> R17.2 <-> V3.6
|
||||
C14.2 <-> C23.1 <-> IC2.9 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C14.2 <-> C23.1 <-> IC2.16 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C15.1 <-> C9.1 <-> R19.1
|
||||
C15.2 <-> C22.1 <-> IC2.13 <-> R19.2 <-> R29.1
|
||||
C15.2 <-> C22.1 <-> IC2.12 <-> R19.2 <-> R29.1
|
||||
C16.1 <-> C21.1 <-> R27.1 <-> V2.1
|
||||
C16.2 <-> R32.2 <-> V2.2 <-> VR1.2
|
||||
C17.1 <-> R13.2 <-> V3.3
|
||||
C17.2 <-> R34.1
|
||||
C18.+ <-> IC1.4 <-> Q2.1
|
||||
C18.- <-> C29.- <-> D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC1.3 <-> IC2.16 <-> IC3.16 <-> IC4.16 <-> Q2.2
|
||||
C18.+ <-> IC1.3 <-> Q2.1
|
||||
C18.- <-> C29.- <-> D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC1.4 <-> IC2.9 <-> IC3.9 <-> IC4.9 <-> Q2.2
|
||||
C19.2 <-> R21.1 <-> R28.2 <-> V2.7
|
||||
C2.+ <-> C6.2 <-> R11.2 <-> R12.2 <-> R2.2 <-> R3.1
|
||||
C20.1 <-> C27.1 <-> R26.2 <-> V1.1
|
||||
@@ -41,9 +41,9 @@ Switch setup: [ SW1.ON1 ]
|
||||
D2.A <-> D3.K
|
||||
D4.A <-> D5.K
|
||||
D9.A <-> R37.2
|
||||
IC3.13 <-> R36.2
|
||||
IC4.11 <-> VR6.2 <-> VR6.3
|
||||
IC4.9 <-> VR7.2 <-> VR7.3
|
||||
IC3.12 <-> R36.2
|
||||
IC4.14 <-> VR6.2 <-> VR6.3
|
||||
IC4.16 <-> VR7.2 <-> VR7.3
|
||||
Q1.3 <-> R1.1 <-> R4.1
|
||||
R16.2 <-> R17.1 <-> R31.2
|
||||
R22.2 <-> R34.2 <-> VR6.1 <-> VR7.1
|
||||
@@ -53,23 +53,23 @@ Switch setup: [ SW1.ON1 ]
|
||||
Switch setup: [ SW1.ON2 ]
|
||||
|
||||
C1.+ <-> R10.2 <-> R2.1 <-> R9.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.11 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.13 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C1.- <-> C19.1 <-> C2.- <-> C20.2 <-> C21.2 <-> C22.2 <-> C23.2 <-> C28.2 <-> C3.- <-> C4.- <-> C5.- <-> D3.A <-> D5.A <-> IC2.1 <-> IC2.2 <-> IC2.3 <-> IC2.4 <-> IC2.5 <-> IC3.1 <-> IC3.14 <-> IC3.2 <-> IC3.3 <-> IC3.4 <-> IC3.5 <-> IC4.1 <-> IC4.12 <-> IC4.2 <-> IC4.3 <-> IC4.4 <-> IC4.5 <-> R23.2 <-> R24.2 <-> R25.1 <-> R26.1 <-> R27.2 <-> R28.1 <-> R29.2 <-> R30.1 <-> R31.1 <-> R32.1 <-> R33.2 <-> R35.2 <-> R4.2 <-> R5.2 <-> R6.2 <-> R7.2 <-> VR1.3 <-> VR2.3 <-> VR4.1 <-> VR4.2
|
||||
C10.1 <-> R22.1 <-> R30.2
|
||||
C10.2 <-> R16.1 <-> V3.7
|
||||
C11.1 <-> IC3.9
|
||||
C11.1 <-> IC3.16
|
||||
C11.2 <-> C14.1 <-> C8.2 <-> R18.1 <-> R25.2
|
||||
C12.1 <-> R11.1 <-> V2.3
|
||||
C12.2 <-> R21.2
|
||||
C13.2 <-> R17.2 <-> V3.6
|
||||
C14.2 <-> C23.1 <-> IC2.9 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C14.2 <-> C23.1 <-> IC2.16 <-> R18.2 <-> R33.1 <-> V3.2
|
||||
C15.1 <-> C9.1 <-> R19.1
|
||||
C15.2 <-> C22.1 <-> IC2.13 <-> R19.2 <-> R29.1
|
||||
C15.2 <-> C22.1 <-> IC2.12 <-> R19.2 <-> R29.1
|
||||
C16.1 <-> C21.1 <-> R27.1 <-> V2.1
|
||||
C16.2 <-> R32.2 <-> V2.2 <-> VR1.2
|
||||
C17.1 <-> R13.2 <-> V3.3
|
||||
C17.2 <-> R34.1
|
||||
C18.+ <-> IC1.4 <-> Q2.1
|
||||
C18.- <-> C29.- <-> IC1.3 <-> Q2.2
|
||||
C18.+ <-> IC1.3 <-> Q2.1
|
||||
C18.- <-> C29.- <-> IC1.4 <-> Q2.2
|
||||
C19.2 <-> R21.1 <-> R28.2 <-> V2.7
|
||||
C2.+ <-> C6.2 <-> R11.2 <-> R12.2 <-> R2.2 <-> R3.1
|
||||
C20.1 <-> C27.1 <-> R26.2 <-> V1.1
|
||||
@@ -92,11 +92,11 @@ Switch setup: [ SW1.ON2 ]
|
||||
C8.1 <-> R10.1 <-> V1.8
|
||||
D2.A <-> D3.K
|
||||
D4.A <-> D5.K
|
||||
D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC2.16 <-> IC3.16 <-> IC4.16
|
||||
D6.A <-> D7.A <-> D8.A <-> D9.K <-> IC2.9 <-> IC3.9 <-> IC4.9
|
||||
D9.A <-> R37.2
|
||||
IC3.13 <-> R36.2
|
||||
IC4.11 <-> VR6.2 <-> VR6.3
|
||||
IC4.9 <-> VR7.2 <-> VR7.3
|
||||
IC3.12 <-> R36.2
|
||||
IC4.14 <-> VR6.2 <-> VR6.3
|
||||
IC4.16 <-> VR7.2 <-> VR7.3
|
||||
Q1.3 <-> R1.1 <-> R4.1
|
||||
R16.2 <-> R17.1 <-> R31.2
|
||||
R22.2 <-> R34.2 <-> VR6.1 <-> VR7.1
|
||||
|
||||
@@ -2,15 +2,15 @@ Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> Q1.2 <-> R2.1
|
||||
C1.2 <-> VR2.3
|
||||
C2.+ <-> IC1.8 <-> R3.1
|
||||
C2.+ <-> IC1.5 <-> R3.1
|
||||
C2.- <-> R4.2 <-> SW1.2
|
||||
C3.1 <-> IC1.6
|
||||
C3.1 <-> IC1.7
|
||||
C3.2 <-> C4.- <-> C5.2 <-> IC1.3 <-> IC1.4 <-> J1.Sleeve <-> J2.Sleeve <-> J3.Center <-> R1.1 <-> R2.2 <-> VR2.1
|
||||
C4.+ <-> IC1.7 <-> J3.Sleeve <-> Q1.1
|
||||
C4.+ <-> IC1.6 <-> J3.Sleeve <-> Q1.1
|
||||
C5.1 <-> R3.2
|
||||
IC1.1 <-> VR1.3
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR1.2
|
||||
IC1.8 <-> VR1.2
|
||||
J1.Tip <-> R4.1 <-> R5.1 <-> SW1.1
|
||||
J2.Tip <-> Q1.3 <-> R1.2
|
||||
R5.2 <-> SW1.3
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
Switch setup: [ SW1.OFF ]
|
||||
|
||||
C1.1 <-> Q1.2 <-> R2.1
|
||||
C1.2 <-> VR2.3
|
||||
C2.+ <-> IC1.8 <-> R3.1
|
||||
C2.- <-> R4.2
|
||||
C3.1 <-> IC1.6
|
||||
C3.2 <-> C4.- <-> C5.2 <-> IC1.3 <-> IC1.4 <-> J1.Sleeve <-> J2.Sleeve <-> J3.Center <-> R1.1 <-> R2.2 <-> VR2.1
|
||||
C4.+ <-> IC1.7 <-> J3.Sleeve <-> Q1.1
|
||||
C5.1 <-> R3.2
|
||||
IC1.1 <-> VR1.3
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR1.2
|
||||
J1.Tip <-> R4.1 <-> R5.1
|
||||
J2.Tip <-> Q1.3 <-> R1.2
|
||||
|
||||
Switch setup: [ SW1.ON1 ]
|
||||
|
||||
C1.1 <-> Q1.2 <-> R2.1
|
||||
C1.2 <-> VR2.3
|
||||
C2.+ <-> IC1.8 <-> R3.1
|
||||
C2.+ <-> IC1.5 <-> R3.1
|
||||
C2.- <-> J1.Tip <-> R4.1 <-> R4.2 <-> R5.1
|
||||
C3.1 <-> IC1.6
|
||||
C3.1 <-> IC1.7
|
||||
C3.2 <-> C4.- <-> C5.2 <-> IC1.3 <-> IC1.4 <-> J1.Sleeve <-> J2.Sleeve <-> J3.Center <-> R1.1 <-> R2.2 <-> VR2.1
|
||||
C4.+ <-> IC1.7 <-> J3.Sleeve <-> Q1.1
|
||||
C4.+ <-> IC1.6 <-> J3.Sleeve <-> Q1.1
|
||||
C5.1 <-> R3.2
|
||||
IC1.1 <-> VR1.3
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR1.2
|
||||
IC1.8 <-> VR1.2
|
||||
J2.Tip <-> Q1.3 <-> R1.2
|
||||
|
||||
Switch setup: [ SW1.OFF ]
|
||||
|
||||
C1.1 <-> Q1.2 <-> R2.1
|
||||
C1.2 <-> VR2.3
|
||||
C2.+ <-> IC1.5 <-> R3.1
|
||||
C2.- <-> R4.2
|
||||
C3.1 <-> IC1.7
|
||||
C3.2 <-> C4.- <-> C5.2 <-> IC1.3 <-> IC1.4 <-> J1.Sleeve <-> J2.Sleeve <-> J3.Center <-> R1.1 <-> R2.2 <-> VR2.1
|
||||
C4.+ <-> IC1.6 <-> J3.Sleeve <-> Q1.1
|
||||
C5.1 <-> R3.2
|
||||
IC1.1 <-> VR1.3
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.8 <-> VR1.2
|
||||
J1.Tip <-> R4.1 <-> R5.1
|
||||
J2.Tip <-> Q1.3 <-> R1.2
|
||||
|
||||
Switch setup: [ SW1.ON2 ]
|
||||
|
||||
C1.1 <-> Q1.2 <-> R2.1
|
||||
C1.2 <-> VR2.3
|
||||
C2.+ <-> IC1.8 <-> R3.1
|
||||
C2.+ <-> IC1.5 <-> R3.1
|
||||
C2.- <-> R4.2 <-> R5.2
|
||||
C3.1 <-> IC1.6
|
||||
C3.1 <-> IC1.7
|
||||
C3.2 <-> C4.- <-> C5.2 <-> IC1.3 <-> IC1.4 <-> J1.Sleeve <-> J2.Sleeve <-> J3.Center <-> R1.1 <-> R2.2 <-> VR2.1
|
||||
C4.+ <-> IC1.7 <-> J3.Sleeve <-> Q1.1
|
||||
C4.+ <-> IC1.6 <-> J3.Sleeve <-> Q1.1
|
||||
C5.1 <-> R3.2
|
||||
IC1.1 <-> VR1.3
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR1.2
|
||||
IC1.8 <-> VR1.2
|
||||
J1.Tip <-> R4.1 <-> R5.1
|
||||
J2.Tip <-> Q1.3 <-> R1.2
|
||||
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> IC1.8 <-> IC2.16 <-> IC3.2 <-> R3.2 <-> VR1.3
|
||||
C1.2 <-> D14.A <-> D7.K <-> IC1.1 <-> IC2.9 <-> IC3.1 <-> R1.2 <-> VR1.1 <-> VR4.2 <-> VR4.3
|
||||
C2.1 <-> IC3.6 <-> R2.2
|
||||
C1.1 <-> IC1.8 <-> IC2.9 <-> IC3.2 <-> R3.2 <-> VR1.3
|
||||
C1.2 <-> D14.A <-> D7.K <-> IC1.1 <-> IC2.16 <-> IC3.1 <-> R1.2 <-> VR1.1 <-> VR4.2 <-> VR4.3
|
||||
C2.1 <-> IC3.7 <-> R2.2
|
||||
C2.2 <-> VR2.3
|
||||
C3.1 <-> R3.1 <-> VR3.2
|
||||
C3.2 <-> C6.2 <-> C8.+ <-> R4.1 <-> R5.2 <-> R7.2 <-> R9.1
|
||||
C4.1 <-> C7.- <-> C8.- <-> D16.A <-> IC3.4 <-> R7.1 <-> R8.1 <-> VR2.1
|
||||
C4.2 <-> IC3.8 <-> R6.1
|
||||
C4.2 <-> IC3.5 <-> R6.1
|
||||
C5.1 <-> IC3.3 <-> R4.2
|
||||
C5.2 <-> R8.2
|
||||
C6.1 <-> VR3.3
|
||||
C7.+ <-> D16.K <-> IC3.5 <-> R9.2
|
||||
D1.A <-> IC1.15 <-> IC1.16
|
||||
C7.+ <-> D16.K <-> IC3.8 <-> R9.2
|
||||
D1.A <-> IC1.10 <-> IC1.9
|
||||
D1.K <-> D2.A <-> IC1.6 <-> IC1.7
|
||||
D10.A <-> D11.K <-> IC2.12 <-> IC2.13
|
||||
D10.K <-> D9.A <-> IC2.5 <-> IC2.6
|
||||
D11.A <-> D12.K <-> IC2.3 <-> IC2.4
|
||||
D12.A <-> D13.K <-> IC2.10 <-> IC2.11
|
||||
D12.A <-> D13.K <-> IC2.14 <-> IC2.15
|
||||
D13.A <-> D14.K <-> IC2.1 <-> IC2.2
|
||||
D15.K <-> Q1.1
|
||||
D2.K <-> D3.A <-> IC1.13 <-> IC1.14
|
||||
D2.K <-> D3.A <-> IC1.11 <-> IC1.12
|
||||
D3.K <-> D4.A <-> IC1.4 <-> IC1.5
|
||||
D4.K <-> D5.A <-> IC1.11 <-> IC1.12
|
||||
D4.K <-> D5.A <-> IC1.13 <-> IC1.14
|
||||
D5.K <-> D6.A <-> IC1.2 <-> IC1.3
|
||||
D6.K <-> D7.A <-> IC1.10 <-> IC1.9
|
||||
D8.A <-> D9.K <-> IC2.14 <-> IC2.15
|
||||
D6.K <-> D7.A <-> IC1.15 <-> IC1.16
|
||||
D8.A <-> D9.K <-> IC2.10 <-> IC2.11
|
||||
D8.K <-> IC2.7 <-> IC2.8
|
||||
IC3.7 <-> R2.1 <-> R5.1
|
||||
IC3.6 <-> R2.1 <-> R5.1
|
||||
Q1.2 <-> Q1.3
|
||||
R1.1 <-> VR1.2
|
||||
R6.2 <-> VR4.1
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> IC1.8 <-> IC2.16 <-> IC3.2 <-> R3.2 <-> VR1.3
|
||||
C1.2 <-> D14.A <-> D7.K <-> IC1.1 <-> IC2.9 <-> IC3.1 <-> R1.2 <-> VR1.1 <-> VR4.2 <-> VR4.3
|
||||
C2.1 <-> IC3.6 <-> R2.2
|
||||
C1.1 <-> IC1.8 <-> IC2.9 <-> IC3.2 <-> R3.2 <-> VR1.3
|
||||
C1.2 <-> D14.A <-> D7.K <-> IC1.1 <-> IC2.16 <-> IC3.1 <-> R1.2 <-> VR1.1 <-> VR4.2 <-> VR4.3
|
||||
C2.1 <-> IC3.7 <-> R2.2
|
||||
C2.2 <-> VR2.3
|
||||
C3.1 <-> R3.1 <-> VR3.2
|
||||
C3.2 <-> C6.2 <-> C8.+ <-> R4.1 <-> R5.2 <-> R7.2 <-> R9.1
|
||||
C4.1 <-> C7.- <-> C8.- <-> D16.A <-> IC3.4 <-> R7.1 <-> R8.1 <-> VR2.1
|
||||
C4.2 <-> IC3.8 <-> R6.1
|
||||
C4.2 <-> IC3.5 <-> R6.1
|
||||
C5.1 <-> IC3.3 <-> R4.2
|
||||
C5.2 <-> R8.2
|
||||
C6.1 <-> VR3.3
|
||||
C7.+ <-> D16.K <-> IC3.5 <-> R9.2
|
||||
D1.A <-> IC1.15 <-> IC1.16
|
||||
C7.+ <-> D16.K <-> IC3.8 <-> R9.2
|
||||
D1.A <-> IC1.10 <-> IC1.9
|
||||
D1.K <-> D2.A <-> IC1.6 <-> IC1.7
|
||||
D10.A <-> D11.K <-> IC2.12 <-> IC2.13
|
||||
D10.K <-> D9.A <-> IC2.5 <-> IC2.6
|
||||
D11.A <-> D12.K <-> IC2.3 <-> IC2.4
|
||||
D12.A <-> D13.K <-> IC2.10 <-> IC2.11
|
||||
D12.A <-> D13.K <-> IC2.14 <-> IC2.15
|
||||
D13.A <-> D14.K <-> IC2.1 <-> IC2.2
|
||||
D15.K <-> Q1.1
|
||||
D2.K <-> D3.A <-> IC1.13 <-> IC1.14
|
||||
D2.K <-> D3.A <-> IC1.11 <-> IC1.12
|
||||
D3.K <-> D4.A <-> IC1.4 <-> IC1.5
|
||||
D4.K <-> D5.A <-> IC1.11 <-> IC1.12
|
||||
D4.K <-> D5.A <-> IC1.13 <-> IC1.14
|
||||
D5.K <-> D6.A <-> IC1.2 <-> IC1.3
|
||||
D6.K <-> D7.A <-> IC1.10 <-> IC1.9
|
||||
D8.A <-> D9.K <-> IC2.14 <-> IC2.15
|
||||
D6.K <-> D7.A <-> IC1.15 <-> IC1.16
|
||||
D8.A <-> D9.K <-> IC2.10 <-> IC2.11
|
||||
D8.K <-> IC2.7 <-> IC2.8
|
||||
IC3.7 <-> R2.1 <-> R5.1
|
||||
IC3.6 <-> R2.1 <-> R5.1
|
||||
Q1.2 <-> Q1.3
|
||||
R1.1 <-> VR1.2
|
||||
R6.2 <-> VR4.1
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> IC1.10 <-> IC1.11 <-> IC1.20 <-> IC1.21 <-> IC1.22 <-> IC1.28 <-> IC1.29 <-> IC1.3 <-> IC1.30 <-> IC1.31 <-> IC1.33 <-> IC1.4 <-> IC2.10 <-> IC2.11 <-> IC2.20 <-> IC2.21 <-> IC2.22 <-> IC2.28 <-> IC2.29 <-> IC2.3 <-> IC2.30 <-> IC2.31 <-> IC2.33 <-> IC2.4 <-> IC3.4 <-> IC3.8 <-> IC4.8
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> IC1.32 <-> IC1.42 <-> IC1.5 <-> IC1.6 <-> IC1.8 <-> IC2.32 <-> IC2.42 <-> IC2.5 <-> IC2.6 <-> IC2.8 <-> IC3.9 <-> IC4.6 <-> IC4.9
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> IC1.10 <-> IC1.11 <-> IC1.20 <-> IC1.21 <-> IC1.22 <-> IC1.3 <-> IC1.4 <-> IC1.40 <-> IC1.42 <-> IC1.43 <-> IC1.44 <-> IC1.45 <-> IC2.10 <-> IC2.11 <-> IC2.20 <-> IC2.21 <-> IC2.22 <-> IC2.3 <-> IC2.4 <-> IC2.40 <-> IC2.42 <-> IC2.43 <-> IC2.44 <-> IC2.45 <-> IC3.4 <-> IC3.8 <-> IC4.8
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> IC1.31 <-> IC1.41 <-> IC1.5 <-> IC1.6 <-> IC1.8 <-> IC2.31 <-> IC2.41 <-> IC2.5 <-> IC2.6 <-> IC2.8 <-> IC3.16 <-> IC4.16 <-> IC4.6
|
||||
IC1.1 <-> IC2.1
|
||||
IC1.12 <-> IC2.12
|
||||
IC1.13 <-> IC2.13
|
||||
@@ -12,9 +12,9 @@ Switch setup: [ ALL ]
|
||||
IC1.18 <-> IC2.18
|
||||
IC1.19 <-> IC2.19
|
||||
IC1.2 <-> IC2.2
|
||||
IC1.25 <-> IC2.25
|
||||
IC1.26 <-> IC2.26
|
||||
IC1.27 <-> IC2.27 <-> IC3.5 <-> IC4.5
|
||||
IC1.46 <-> IC2.46 <-> IC3.5 <-> IC4.5
|
||||
IC1.47 <-> IC2.47
|
||||
IC1.48 <-> IC2.48
|
||||
IC3.1 <-> IC4.1
|
||||
IC3.2 <-> IC4.2
|
||||
IC3.3 <-> IC4.3
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> IC1.10 <-> IC1.11 <-> IC1.20 <-> IC1.21 <-> IC1.22 <-> IC1.28 <-> IC1.29 <-> IC1.3 <-> IC1.30 <-> IC1.31 <-> IC1.33 <-> IC1.4 <-> IC2.10 <-> IC2.11 <-> IC2.20 <-> IC2.21 <-> IC2.22 <-> IC2.28 <-> IC2.29 <-> IC2.3 <-> IC2.30 <-> IC2.31 <-> IC2.33 <-> IC2.4 <-> IC3.4 <-> IC3.8 <-> IC4.8
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> IC1.32 <-> IC1.42 <-> IC1.5 <-> IC1.6 <-> IC1.8 <-> IC2.32 <-> IC2.42 <-> IC2.5 <-> IC2.6 <-> IC2.8 <-> IC3.9 <-> IC4.6 <-> IC4.9
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> IC1.10 <-> IC1.11 <-> IC1.20 <-> IC1.21 <-> IC1.22 <-> IC1.3 <-> IC1.4 <-> IC1.40 <-> IC1.42 <-> IC1.43 <-> IC1.44 <-> IC1.45 <-> IC2.10 <-> IC2.11 <-> IC2.20 <-> IC2.21 <-> IC2.22 <-> IC2.3 <-> IC2.4 <-> IC2.40 <-> IC2.42 <-> IC2.43 <-> IC2.44 <-> IC2.45 <-> IC3.4 <-> IC3.8 <-> IC4.8
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> IC1.31 <-> IC1.41 <-> IC1.5 <-> IC1.6 <-> IC1.8 <-> IC2.31 <-> IC2.41 <-> IC2.5 <-> IC2.6 <-> IC2.8 <-> IC3.16 <-> IC4.16 <-> IC4.6
|
||||
IC1.1 <-> IC2.1
|
||||
IC1.12 <-> IC2.12
|
||||
IC1.13 <-> IC2.13
|
||||
@@ -12,9 +12,9 @@ Switch setup: [ ALL ]
|
||||
IC1.18 <-> IC2.18
|
||||
IC1.19 <-> IC2.19
|
||||
IC1.2 <-> IC2.2
|
||||
IC1.25 <-> IC2.25
|
||||
IC1.26 <-> IC2.26
|
||||
IC1.27 <-> IC2.27 <-> IC3.5 <-> IC4.5
|
||||
IC1.46 <-> IC2.46 <-> IC3.5 <-> IC4.5
|
||||
IC1.47 <-> IC2.47
|
||||
IC1.48 <-> IC2.48
|
||||
IC3.1 <-> IC4.1
|
||||
IC3.2 <-> IC4.2
|
||||
IC3.3 <-> IC4.3
|
||||
|
||||
+6
-6
@@ -3,21 +3,21 @@ Switch setup: [ ALL ]
|
||||
C1.1 <-> IC1.2 <-> R1.1
|
||||
C1.2 <-> C3.- <-> C7.- <-> C8.+ <-> D3.K <-> IC1.4 <-> R3.2
|
||||
C10.+ <-> D5.K <-> D6.A
|
||||
C10.- <-> C9.+ <-> IC2.8
|
||||
C10.- <-> C9.+ <-> IC2.5
|
||||
C12.+ <-> D6.K
|
||||
C12.- <-> C14.- <-> C2.2 <-> IC2.4 <-> R4.2
|
||||
C14.+ <-> D5.A <-> IC2.7
|
||||
C14.+ <-> D5.A <-> IC2.6
|
||||
C2.1 <-> IC2.2 <-> R5.1
|
||||
C3.+ <-> D1.A <-> IC1.7
|
||||
C4.+ <-> C5.- <-> C6.+ <-> IC1.8
|
||||
C3.+ <-> D1.A <-> IC1.6
|
||||
C4.+ <-> C5.- <-> C6.+ <-> IC1.5
|
||||
C4.- <-> R1.2 <-> R2.2
|
||||
C5.+ <-> D1.K <-> D2.A
|
||||
C6.- <-> D3.A <-> D4.K
|
||||
C7.+ <-> D2.K
|
||||
C8.- <-> D4.A
|
||||
C9.- <-> R5.2 <-> R6.2
|
||||
IC1.1 <-> IC1.5
|
||||
IC1.1 <-> IC1.8
|
||||
IC1.3 <-> R2.1 <-> R3.1
|
||||
IC2.1 <-> IC2.5
|
||||
IC2.1 <-> IC2.8
|
||||
IC2.3 <-> R4.1 <-> R6.1
|
||||
|
||||
|
||||
+6
-6
@@ -3,21 +3,21 @@ Switch setup: [ ALL ]
|
||||
C1.1 <-> IC1.2 <-> R1.1
|
||||
C1.2 <-> C3.- <-> C7.- <-> C8.+ <-> D3.K <-> IC1.4 <-> R3.2
|
||||
C10.+ <-> D5.K <-> D6.A
|
||||
C10.- <-> C9.+ <-> IC2.8
|
||||
C10.- <-> C9.+ <-> IC2.5
|
||||
C12.+ <-> D6.K
|
||||
C12.- <-> C14.- <-> C2.2 <-> IC2.4 <-> R4.2
|
||||
C14.+ <-> D5.A <-> IC2.7
|
||||
C14.+ <-> D5.A <-> IC2.6
|
||||
C2.1 <-> IC2.2 <-> R5.1
|
||||
C3.+ <-> D1.A <-> IC1.7
|
||||
C4.+ <-> C5.- <-> C6.+ <-> IC1.8
|
||||
C3.+ <-> D1.A <-> IC1.6
|
||||
C4.+ <-> C5.- <-> C6.+ <-> IC1.5
|
||||
C4.- <-> R1.2 <-> R2.2
|
||||
C5.+ <-> D1.K <-> D2.A
|
||||
C6.- <-> D3.A <-> D4.K
|
||||
C7.+ <-> D2.K
|
||||
C8.- <-> D4.A
|
||||
C9.- <-> R5.2 <-> R6.2
|
||||
IC1.1 <-> IC1.5
|
||||
IC1.1 <-> IC1.8
|
||||
IC1.3 <-> R2.1 <-> R3.1
|
||||
IC2.1 <-> IC2.5
|
||||
IC2.1 <-> IC2.8
|
||||
IC2.3 <-> R4.1 <-> R6.1
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> IC1.10 <-> IC2.10 <-> IC5.10
|
||||
C1.2 <-> C10.2 <-> C2.2 <-> C3.2 <-> C4.1 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.2 <-> IC1.11 <-> IC10.11 <-> IC10.12 <-> IC11.11 <-> IC2.11 <-> IC3.11 <-> IC4.17 <-> IC5.11 <-> IC6.12 <-> IC6.6 <-> IC6.9 <-> IC7.11 <-> IC9.11
|
||||
C10.1 <-> C4.2 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> C9.1 <-> IC10.1 <-> IC10.10 <-> IC11.1 <-> IC11.10 <-> IC3.1 <-> IC3.10 <-> IC4.16 <-> IC4.27 <-> IC6.8 <-> IC7.1 <-> IC7.10 <-> IC9.1 <-> IC9.10
|
||||
C1.2 <-> C10.2 <-> C2.2 <-> C3.2 <-> C4.1 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.2 <-> IC1.20 <-> IC10.19 <-> IC10.20 <-> IC11.20 <-> IC2.20 <-> IC3.20 <-> IC4.32 <-> IC5.20 <-> IC6.13 <-> IC6.16 <-> IC6.6 <-> IC7.20 <-> IC9.20
|
||||
C10.1 <-> C4.2 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> C9.1 <-> IC10.1 <-> IC10.10 <-> IC11.1 <-> IC11.10 <-> IC3.1 <-> IC3.10 <-> IC4.16 <-> IC4.22 <-> IC6.8 <-> IC7.1 <-> IC7.10 <-> IC9.1 <-> IC9.10
|
||||
IC1.1 <-> IC2.1 <-> IC5.1
|
||||
IC1.2 <-> IC10.13 <-> IC11.13 <-> IC2.2 <-> IC3.20 <-> IC4.13 <-> IC4.22 <-> IC5.2 <-> IC7.19 <-> IC9.13
|
||||
IC1.3 <-> IC10.14 <-> IC11.14 <-> IC2.3 <-> IC3.19 <-> IC4.14 <-> IC4.23 <-> IC5.3 <-> IC7.18 <-> IC9.14
|
||||
IC1.4 <-> IC10.15 <-> IC11.15 <-> IC2.4 <-> IC3.18 <-> IC4.15 <-> IC4.26 <-> IC5.4 <-> IC7.17 <-> IC9.15
|
||||
IC1.5 <-> IC10.16 <-> IC11.16 <-> IC2.5 <-> IC3.17 <-> IC4.32 <-> IC5.5 <-> IC7.16 <-> IC9.16
|
||||
IC1.6 <-> IC10.17 <-> IC11.17 <-> IC2.6 <-> IC3.16 <-> IC4.31 <-> IC5.6 <-> IC7.15 <-> IC9.17
|
||||
IC1.7 <-> IC10.18 <-> IC11.18 <-> IC2.7 <-> IC3.15 <-> IC4.30 <-> IC5.7 <-> IC7.14 <-> IC9.18
|
||||
IC1.8 <-> IC10.19 <-> IC11.19 <-> IC2.8 <-> IC3.14 <-> IC4.29 <-> IC5.8 <-> IC7.13 <-> IC9.19
|
||||
IC1.9 <-> IC10.20 <-> IC11.20 <-> IC2.9 <-> IC3.13 <-> IC4.28 <-> IC5.9 <-> IC7.20 <-> IC9.20
|
||||
IC11.12 <-> IC6.11
|
||||
IC3.12 <-> IC6.14
|
||||
IC4.25 <-> IC6.4 <-> IC6.5
|
||||
IC6.13 <-> IC9.12
|
||||
IC6.15 <-> IC7.12
|
||||
IC1.2 <-> IC10.18 <-> IC11.18 <-> IC2.2 <-> IC3.11 <-> IC4.13 <-> IC4.27 <-> IC5.2 <-> IC7.12 <-> IC9.18
|
||||
IC1.3 <-> IC10.17 <-> IC11.17 <-> IC2.3 <-> IC3.12 <-> IC4.14 <-> IC4.26 <-> IC5.3 <-> IC7.13 <-> IC9.17
|
||||
IC1.4 <-> IC10.16 <-> IC11.16 <-> IC2.4 <-> IC3.13 <-> IC4.15 <-> IC4.23 <-> IC5.4 <-> IC7.14 <-> IC9.16
|
||||
IC1.5 <-> IC10.15 <-> IC11.15 <-> IC2.5 <-> IC3.14 <-> IC4.17 <-> IC5.5 <-> IC7.15 <-> IC9.15
|
||||
IC1.6 <-> IC10.14 <-> IC11.14 <-> IC2.6 <-> IC3.15 <-> IC4.18 <-> IC5.6 <-> IC7.16 <-> IC9.14
|
||||
IC1.7 <-> IC10.13 <-> IC11.13 <-> IC2.7 <-> IC3.16 <-> IC4.19 <-> IC5.7 <-> IC7.17 <-> IC9.13
|
||||
IC1.8 <-> IC10.12 <-> IC11.12 <-> IC2.8 <-> IC3.17 <-> IC4.20 <-> IC5.8 <-> IC7.18 <-> IC9.12
|
||||
IC1.9 <-> IC10.11 <-> IC11.11 <-> IC2.9 <-> IC3.18 <-> IC4.21 <-> IC5.9 <-> IC7.11 <-> IC9.11
|
||||
IC11.19 <-> IC6.14
|
||||
IC3.19 <-> IC6.11
|
||||
IC4.24 <-> IC6.4 <-> IC6.5
|
||||
IC6.10 <-> IC7.19
|
||||
IC6.12 <-> IC9.19
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> IC1.10 <-> IC2.10 <-> IC5.10
|
||||
C1.2 <-> C10.2 <-> C2.2 <-> C3.2 <-> C4.1 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.2 <-> IC1.11 <-> IC10.11 <-> IC10.12 <-> IC11.11 <-> IC2.11 <-> IC3.11 <-> IC4.17 <-> IC5.11 <-> IC6.12 <-> IC6.6 <-> IC6.9 <-> IC7.11 <-> IC9.11
|
||||
C10.1 <-> C4.2 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> C9.1 <-> IC10.1 <-> IC10.10 <-> IC11.1 <-> IC11.10 <-> IC3.1 <-> IC3.10 <-> IC4.16 <-> IC4.27 <-> IC6.8 <-> IC7.1 <-> IC7.10 <-> IC9.1 <-> IC9.10
|
||||
C1.2 <-> C10.2 <-> C2.2 <-> C3.2 <-> C4.1 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.2 <-> IC1.20 <-> IC10.19 <-> IC10.20 <-> IC11.20 <-> IC2.20 <-> IC3.20 <-> IC4.32 <-> IC5.20 <-> IC6.13 <-> IC6.16 <-> IC6.6 <-> IC7.20 <-> IC9.20
|
||||
C10.1 <-> C4.2 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> C9.1 <-> IC10.1 <-> IC10.10 <-> IC11.1 <-> IC11.10 <-> IC3.1 <-> IC3.10 <-> IC4.16 <-> IC4.22 <-> IC6.8 <-> IC7.1 <-> IC7.10 <-> IC9.1 <-> IC9.10
|
||||
IC1.1 <-> IC2.1 <-> IC5.1
|
||||
IC1.2 <-> IC10.13 <-> IC11.13 <-> IC2.2 <-> IC3.20 <-> IC4.13 <-> IC4.22 <-> IC5.2 <-> IC7.19 <-> IC9.13
|
||||
IC1.3 <-> IC10.14 <-> IC11.14 <-> IC2.3 <-> IC3.19 <-> IC4.14 <-> IC4.23 <-> IC5.3 <-> IC7.18 <-> IC9.14
|
||||
IC1.4 <-> IC10.15 <-> IC11.15 <-> IC2.4 <-> IC3.18 <-> IC4.15 <-> IC4.26 <-> IC5.4 <-> IC7.17 <-> IC9.15
|
||||
IC1.5 <-> IC10.16 <-> IC11.16 <-> IC2.5 <-> IC3.17 <-> IC4.32 <-> IC5.5 <-> IC7.16 <-> IC9.16
|
||||
IC1.6 <-> IC10.17 <-> IC11.17 <-> IC2.6 <-> IC3.16 <-> IC4.31 <-> IC5.6 <-> IC7.15 <-> IC9.17
|
||||
IC1.7 <-> IC10.18 <-> IC11.18 <-> IC2.7 <-> IC3.15 <-> IC4.30 <-> IC5.7 <-> IC7.14 <-> IC9.18
|
||||
IC1.8 <-> IC10.19 <-> IC11.19 <-> IC2.8 <-> IC3.14 <-> IC4.29 <-> IC5.8 <-> IC7.13 <-> IC9.19
|
||||
IC1.9 <-> IC10.20 <-> IC11.20 <-> IC2.9 <-> IC3.13 <-> IC4.28 <-> IC5.9 <-> IC7.20 <-> IC9.20
|
||||
IC11.12 <-> IC6.11
|
||||
IC3.12 <-> IC6.14
|
||||
IC4.25 <-> IC6.4 <-> IC6.5
|
||||
IC6.13 <-> IC9.12
|
||||
IC6.15 <-> IC7.12
|
||||
IC1.2 <-> IC10.18 <-> IC11.18 <-> IC2.2 <-> IC3.11 <-> IC4.13 <-> IC4.27 <-> IC5.2 <-> IC7.12 <-> IC9.18
|
||||
IC1.3 <-> IC10.17 <-> IC11.17 <-> IC2.3 <-> IC3.12 <-> IC4.14 <-> IC4.26 <-> IC5.3 <-> IC7.13 <-> IC9.17
|
||||
IC1.4 <-> IC10.16 <-> IC11.16 <-> IC2.4 <-> IC3.13 <-> IC4.15 <-> IC4.23 <-> IC5.4 <-> IC7.14 <-> IC9.16
|
||||
IC1.5 <-> IC10.15 <-> IC11.15 <-> IC2.5 <-> IC3.14 <-> IC4.17 <-> IC5.5 <-> IC7.15 <-> IC9.15
|
||||
IC1.6 <-> IC10.14 <-> IC11.14 <-> IC2.6 <-> IC3.15 <-> IC4.18 <-> IC5.6 <-> IC7.16 <-> IC9.14
|
||||
IC1.7 <-> IC10.13 <-> IC11.13 <-> IC2.7 <-> IC3.16 <-> IC4.19 <-> IC5.7 <-> IC7.17 <-> IC9.13
|
||||
IC1.8 <-> IC10.12 <-> IC11.12 <-> IC2.8 <-> IC3.17 <-> IC4.20 <-> IC5.8 <-> IC7.18 <-> IC9.12
|
||||
IC1.9 <-> IC10.11 <-> IC11.11 <-> IC2.9 <-> IC3.18 <-> IC4.21 <-> IC5.9 <-> IC7.11 <-> IC9.11
|
||||
IC11.19 <-> IC6.14
|
||||
IC3.19 <-> IC6.11
|
||||
IC4.24 <-> IC6.4 <-> IC6.5
|
||||
IC6.10 <-> IC7.19
|
||||
IC6.12 <-> IC9.19
|
||||
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C10.2 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.1 <-> C6.2 <-> C9.2 <-> IC1.1 <-> IC1.10 <-> IC10.12 <-> IC11.12 <-> IC2.1 <-> IC2.10 <-> IC3.1 <-> IC3.10 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.8 <-> IC8.1 <-> IC8.10 <-> IC9.10 <-> IC9.12
|
||||
C1.2 <-> C10.1 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.2 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.1 <-> IC1.11 <-> IC10.11 <-> IC11.11 <-> IC2.11 <-> IC3.11 <-> IC4.9 <-> IC5.11 <-> IC6.9 <-> IC8.11 <-> IC9.11
|
||||
C1.1 <-> C10.2 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.1 <-> C6.2 <-> C9.2 <-> IC1.1 <-> IC1.10 <-> IC10.19 <-> IC11.19 <-> IC2.1 <-> IC2.10 <-> IC3.1 <-> IC3.10 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.8 <-> IC8.1 <-> IC8.10 <-> IC9.10 <-> IC9.19
|
||||
C1.2 <-> C10.1 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.2 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.1 <-> IC1.20 <-> IC10.20 <-> IC11.20 <-> IC2.20 <-> IC3.20 <-> IC4.16 <-> IC5.20 <-> IC6.16 <-> IC8.20 <-> IC9.20
|
||||
C7.2 <-> C8.2 <-> IC10.10 <-> IC11.10
|
||||
IC1.2 <-> IC2.2 <-> IC3.2 <-> IC5.2 <-> IC6.3 <-> IC8.2
|
||||
IC1.3 <-> IC2.3 <-> IC3.3 <-> IC5.3 <-> IC6.2 <-> IC8.3
|
||||
@@ -11,16 +11,16 @@ Switch setup: [ ALL ]
|
||||
IC1.7 <-> IC2.7 <-> IC3.7 <-> IC4.2 <-> IC5.7 <-> IC8.7
|
||||
IC1.8 <-> IC2.8 <-> IC3.8 <-> IC4.6 <-> IC5.8 <-> IC8.8
|
||||
IC1.9 <-> IC2.9 <-> IC3.9 <-> IC4.7 <-> IC5.9 <-> IC8.9
|
||||
IC10.13 <-> IC11.13 <-> IC6.10 <-> IC9.13
|
||||
IC10.14 <-> IC11.14 <-> IC6.1 <-> IC9.14
|
||||
IC10.15 <-> IC11.15 <-> IC6.15 <-> IC9.15
|
||||
IC10.16 <-> IC11.16 <-> IC6.16 <-> IC9.16
|
||||
IC10.17 <-> IC11.17 <-> IC4.10 <-> IC9.17
|
||||
IC10.18 <-> IC11.18 <-> IC4.1 <-> IC9.18
|
||||
IC10.19 <-> IC11.19 <-> IC4.15 <-> IC9.19
|
||||
IC10.20 <-> IC11.20 <-> IC4.16 <-> IC9.20
|
||||
IC10.11 <-> IC11.11 <-> IC4.9 <-> IC9.11
|
||||
IC10.12 <-> IC11.12 <-> IC4.10 <-> IC9.12
|
||||
IC10.13 <-> IC11.13 <-> IC4.1 <-> IC9.13
|
||||
IC10.14 <-> IC11.14 <-> IC4.15 <-> IC9.14
|
||||
IC10.15 <-> IC11.15 <-> IC6.9 <-> IC9.15
|
||||
IC10.16 <-> IC11.16 <-> IC6.10 <-> IC9.16
|
||||
IC10.17 <-> IC11.17 <-> IC6.1 <-> IC9.17
|
||||
IC10.18 <-> IC11.18 <-> IC6.15 <-> IC9.18
|
||||
IC4.11 <-> IC6.11
|
||||
IC4.14 <-> IC6.14
|
||||
IC4.4 <-> IC6.12
|
||||
IC4.5 <-> IC6.13
|
||||
IC4.4 <-> IC6.13
|
||||
IC4.5 <-> IC6.12
|
||||
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C10.2 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.1 <-> C6.2 <-> C9.2 <-> IC1.1 <-> IC1.10 <-> IC10.12 <-> IC11.12 <-> IC2.1 <-> IC2.10 <-> IC3.1 <-> IC3.10 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.8 <-> IC8.1 <-> IC8.10 <-> IC9.10 <-> IC9.12
|
||||
C1.2 <-> C10.1 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.2 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.1 <-> IC1.11 <-> IC10.11 <-> IC11.11 <-> IC2.11 <-> IC3.11 <-> IC4.9 <-> IC5.11 <-> IC6.9 <-> IC8.11 <-> IC9.11
|
||||
C1.1 <-> C10.2 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.1 <-> C6.2 <-> C9.2 <-> IC1.1 <-> IC1.10 <-> IC10.19 <-> IC11.19 <-> IC2.1 <-> IC2.10 <-> IC3.1 <-> IC3.10 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.8 <-> IC8.1 <-> IC8.10 <-> IC9.10 <-> IC9.19
|
||||
C1.2 <-> C10.1 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.2 <-> C6.1 <-> C7.1 <-> C8.1 <-> C9.1 <-> IC1.20 <-> IC10.20 <-> IC11.20 <-> IC2.20 <-> IC3.20 <-> IC4.16 <-> IC5.20 <-> IC6.16 <-> IC8.20 <-> IC9.20
|
||||
C7.2 <-> C8.2 <-> IC10.10 <-> IC11.10
|
||||
IC1.2 <-> IC2.2 <-> IC3.2 <-> IC5.2 <-> IC6.3 <-> IC8.2
|
||||
IC1.3 <-> IC2.3 <-> IC3.3 <-> IC5.3 <-> IC6.2 <-> IC8.3
|
||||
@@ -11,16 +11,16 @@ Switch setup: [ ALL ]
|
||||
IC1.7 <-> IC2.7 <-> IC3.7 <-> IC4.2 <-> IC5.7 <-> IC8.7
|
||||
IC1.8 <-> IC2.8 <-> IC3.8 <-> IC4.6 <-> IC5.8 <-> IC8.8
|
||||
IC1.9 <-> IC2.9 <-> IC3.9 <-> IC4.7 <-> IC5.9 <-> IC8.9
|
||||
IC10.13 <-> IC11.13 <-> IC6.10 <-> IC9.13
|
||||
IC10.14 <-> IC11.14 <-> IC6.1 <-> IC9.14
|
||||
IC10.15 <-> IC11.15 <-> IC6.15 <-> IC9.15
|
||||
IC10.16 <-> IC11.16 <-> IC6.16 <-> IC9.16
|
||||
IC10.17 <-> IC11.17 <-> IC4.10 <-> IC9.17
|
||||
IC10.18 <-> IC11.18 <-> IC4.1 <-> IC9.18
|
||||
IC10.19 <-> IC11.19 <-> IC4.15 <-> IC9.19
|
||||
IC10.20 <-> IC11.20 <-> IC4.16 <-> IC9.20
|
||||
IC10.11 <-> IC11.11 <-> IC4.9 <-> IC9.11
|
||||
IC10.12 <-> IC11.12 <-> IC4.10 <-> IC9.12
|
||||
IC10.13 <-> IC11.13 <-> IC4.1 <-> IC9.13
|
||||
IC10.14 <-> IC11.14 <-> IC4.15 <-> IC9.14
|
||||
IC10.15 <-> IC11.15 <-> IC6.9 <-> IC9.15
|
||||
IC10.16 <-> IC11.16 <-> IC6.10 <-> IC9.16
|
||||
IC10.17 <-> IC11.17 <-> IC6.1 <-> IC9.17
|
||||
IC10.18 <-> IC11.18 <-> IC6.15 <-> IC9.18
|
||||
IC4.11 <-> IC6.11
|
||||
IC4.14 <-> IC6.14
|
||||
IC4.4 <-> IC6.12
|
||||
IC4.5 <-> IC6.13
|
||||
IC4.4 <-> IC6.13
|
||||
IC4.5 <-> IC6.12
|
||||
|
||||
|
||||
+8
-8
@@ -1,20 +1,20 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> IC1.10 <-> IC1.14 <-> IC1.15 <-> IC1.16 <-> IC1.9 <-> IC2.1 <-> IC2.10 <-> IC2.14 <-> IC2.15 <-> IC2.16 <-> IC2.9 <-> IC3.10 <-> IC3.14 <-> IC3.15 <-> IC3.16 <-> IC3.9 <-> IC4.10 <-> IC4.14 <-> IC4.15 <-> IC4.16 <-> IC4.9 <-> IC5.11 <-> IC6.11 <-> IC7.11 <-> IC8.11
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> IC1.10 <-> IC1.11 <-> IC1.15 <-> IC1.16 <-> IC1.9 <-> IC2.1 <-> IC2.10 <-> IC2.11 <-> IC2.15 <-> IC2.16 <-> IC2.9 <-> IC3.10 <-> IC3.11 <-> IC3.15 <-> IC3.16 <-> IC3.9 <-> IC4.10 <-> IC4.11 <-> IC4.15 <-> IC4.16 <-> IC4.9 <-> IC5.20 <-> IC6.20 <-> IC7.20 <-> IC8.20
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> IC1.1 <-> IC1.8 <-> IC2.8 <-> IC3.1 <-> IC3.8 <-> IC4.1 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.1 <-> IC6.10 <-> IC7.1 <-> IC7.10 <-> IC8.1 <-> IC8.10
|
||||
IC1.11 <-> IC2.11 <-> IC3.11 <-> IC4.11
|
||||
IC1.12 <-> IC3.4
|
||||
IC1.13 <-> IC3.5
|
||||
IC1.12 <-> IC3.5
|
||||
IC1.13 <-> IC3.4
|
||||
IC1.14 <-> IC2.14 <-> IC3.14 <-> IC4.14
|
||||
IC1.2 <-> IC5.3 <-> IC8.3
|
||||
IC1.3 <-> IC5.2 <-> IC8.2
|
||||
IC1.4 <-> IC2.12
|
||||
IC1.5 <-> IC2.13
|
||||
IC1.4 <-> IC2.13
|
||||
IC1.5 <-> IC2.12
|
||||
IC1.6 <-> IC5.4 <-> IC8.4
|
||||
IC1.7 <-> IC5.5 <-> IC8.5
|
||||
IC2.2 <-> IC6.7 <-> IC7.7
|
||||
IC2.3 <-> IC6.6 <-> IC7.6
|
||||
IC2.4 <-> IC4.12
|
||||
IC2.5 <-> IC4.13
|
||||
IC2.4 <-> IC4.13
|
||||
IC2.5 <-> IC4.12
|
||||
IC2.6 <-> IC6.8 <-> IC7.8
|
||||
IC2.7 <-> IC6.9 <-> IC7.9
|
||||
IC3.2 <-> IC5.7 <-> IC8.7
|
||||
|
||||
+8
-8
@@ -1,20 +1,20 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> IC1.10 <-> IC1.14 <-> IC1.15 <-> IC1.16 <-> IC1.9 <-> IC2.1 <-> IC2.10 <-> IC2.14 <-> IC2.15 <-> IC2.16 <-> IC2.9 <-> IC3.10 <-> IC3.14 <-> IC3.15 <-> IC3.16 <-> IC3.9 <-> IC4.10 <-> IC4.14 <-> IC4.15 <-> IC4.16 <-> IC4.9 <-> IC5.11 <-> IC6.11 <-> IC7.11 <-> IC8.11
|
||||
C1.1 <-> C2.1 <-> C3.1 <-> C4.1 <-> C5.2 <-> C6.2 <-> C7.2 <-> C8.2 <-> IC1.10 <-> IC1.11 <-> IC1.15 <-> IC1.16 <-> IC1.9 <-> IC2.1 <-> IC2.10 <-> IC2.11 <-> IC2.15 <-> IC2.16 <-> IC2.9 <-> IC3.10 <-> IC3.11 <-> IC3.15 <-> IC3.16 <-> IC3.9 <-> IC4.10 <-> IC4.11 <-> IC4.15 <-> IC4.16 <-> IC4.9 <-> IC5.20 <-> IC6.20 <-> IC7.20 <-> IC8.20
|
||||
C1.2 <-> C2.2 <-> C3.2 <-> C4.2 <-> C5.1 <-> C6.1 <-> C7.1 <-> C8.1 <-> IC1.1 <-> IC1.8 <-> IC2.8 <-> IC3.1 <-> IC3.8 <-> IC4.1 <-> IC4.8 <-> IC5.1 <-> IC5.10 <-> IC6.1 <-> IC6.10 <-> IC7.1 <-> IC7.10 <-> IC8.1 <-> IC8.10
|
||||
IC1.11 <-> IC2.11 <-> IC3.11 <-> IC4.11
|
||||
IC1.12 <-> IC3.4
|
||||
IC1.13 <-> IC3.5
|
||||
IC1.12 <-> IC3.5
|
||||
IC1.13 <-> IC3.4
|
||||
IC1.14 <-> IC2.14 <-> IC3.14 <-> IC4.14
|
||||
IC1.2 <-> IC5.3 <-> IC8.3
|
||||
IC1.3 <-> IC5.2 <-> IC8.2
|
||||
IC1.4 <-> IC2.12
|
||||
IC1.5 <-> IC2.13
|
||||
IC1.4 <-> IC2.13
|
||||
IC1.5 <-> IC2.12
|
||||
IC1.6 <-> IC5.4 <-> IC8.4
|
||||
IC1.7 <-> IC5.5 <-> IC8.5
|
||||
IC2.2 <-> IC6.7 <-> IC7.7
|
||||
IC2.3 <-> IC6.6 <-> IC7.6
|
||||
IC2.4 <-> IC4.12
|
||||
IC2.5 <-> IC4.13
|
||||
IC2.4 <-> IC4.13
|
||||
IC2.5 <-> IC4.12
|
||||
IC2.6 <-> IC6.8 <-> IC7.8
|
||||
IC2.7 <-> IC6.9 <-> IC7.9
|
||||
IC3.2 <-> IC5.7 <-> IC8.7
|
||||
|
||||
+30
-30
@@ -1,31 +1,31 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
BC548.1 <-> C1.1 <-> D1.K <-> IC1.9 <-> IC2.10
|
||||
BC548.1 <-> C2.2 <-> D2.K <-> IC1.11 <-> IC5.10
|
||||
BC548.1 <-> C3.1 <-> D4.K <-> IC1.1 <-> IC4.10
|
||||
BC548.1 <-> C4.1 <-> D3.K <-> IC1.3 <-> IC6.12
|
||||
BC548.1 <-> C1.1 <-> D1.K <-> IC1.13 <-> IC2.12
|
||||
BC548.1 <-> C2.2 <-> D2.K <-> IC1.11 <-> IC5.12
|
||||
BC548.1 <-> C3.1 <-> D4.K <-> IC1.1 <-> IC4.12
|
||||
BC548.1 <-> C4.1 <-> D3.K <-> IC1.3 <-> IC6.10
|
||||
BC548.2 <-> BC558.3 <-> R13.1
|
||||
BC548.2 <-> BC558.3 <-> R17.1
|
||||
BC548.2 <-> BC558.3 <-> R2.1
|
||||
BC548.2 <-> BC558.3 <-> R36.1
|
||||
BC548.3 <-> BC548.3 <-> BC548.3 <-> BC548.3 <-> C1.2 <-> C2.1 <-> C3.2 <-> C4.2 <-> IC1.13 <-> IC1.5 <-> IC1.7 <-> IC2.5 <-> IC5.5 <-> R11.2 <-> R14.2 <-> R18.1 <-> R22.2 <-> R23.2 <-> R24.2 <-> R26.2 <-> R27.2 <-> R28.2 <-> R3.2 <-> R30.2 <-> R37.2 <-> R39.2 <-> R40.2 <-> R5.1 <-> R8.2 <-> R9.2 <-> VR13.2 <-> VR2.2 <-> VR7.2 <-> VR8.2
|
||||
BC548.3 <-> BC548.3 <-> BC548.3 <-> BC548.3 <-> C1.2 <-> C2.1 <-> C3.2 <-> C4.2 <-> IC1.5 <-> IC1.7 <-> IC1.9 <-> IC2.5 <-> IC5.5 <-> R11.2 <-> R14.2 <-> R18.1 <-> R22.2 <-> R23.2 <-> R24.2 <-> R26.2 <-> R27.2 <-> R28.2 <-> R3.2 <-> R30.2 <-> R37.2 <-> R39.2 <-> R40.2 <-> R5.1 <-> R8.2 <-> R9.2 <-> VR13.2 <-> VR2.2 <-> VR7.2 <-> VR8.2
|
||||
BC558.1 <-> BC558.1 <-> IC2.11 <-> IC3.11 <-> IC4.11 <-> IC5.11 <-> IC6.11 <-> IC7.11 <-> R21.2 <-> R7.2
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R1.1
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R12.1
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R16.1
|
||||
BC558.2 <-> R31.2 <-> R32.2 <-> R33.2 <-> R34.2 <-> R35.1
|
||||
C10.1 <-> IC6.10 <-> IC6.3 <-> R37.1
|
||||
C10.2 <-> IC6.13 <-> IC6.14
|
||||
C5.1 <-> IC2.8 <-> IC2.9
|
||||
C5.2 <-> IC2.12 <-> IC2.3 <-> R3.1
|
||||
C10.1 <-> IC6.12 <-> IC6.3 <-> R37.1
|
||||
C10.2 <-> IC6.8 <-> IC6.9
|
||||
C5.1 <-> IC2.13 <-> IC2.14
|
||||
C5.2 <-> IC2.10 <-> IC2.3 <-> R3.1
|
||||
C6.1 <-> D5.K <-> D6.K <-> R7.1
|
||||
C6.2 <-> R8.1 <-> Square/Triangle 1.3
|
||||
C7.1 <-> IC5.8 <-> IC5.9
|
||||
C7.2 <-> IC5.12 <-> IC5.3 <-> R24.1
|
||||
C7.1 <-> IC5.13 <-> IC5.14
|
||||
C7.2 <-> IC5.10 <-> IC5.3 <-> R24.1
|
||||
C8.1 <-> D12.K <-> D7.K <-> R21.1
|
||||
C8.2 <-> R22.1 <-> Square/Triangle 2.3
|
||||
C9.1 <-> IC4.12 <-> IC4.5 <-> R14.1
|
||||
C9.2 <-> IC4.8 <-> IC4.9
|
||||
C9.1 <-> IC4.10 <-> IC4.5 <-> R14.1
|
||||
C9.2 <-> IC4.13 <-> IC4.14
|
||||
Coarse 1.2 <-> NTC.1
|
||||
Coarse 2.2 <-> NTC.1
|
||||
Coarse 3.2 <-> NTC.1
|
||||
@@ -34,13 +34,13 @@ Switch setup: [ ALL ]
|
||||
CV In 2.Tip <-> NTC.1
|
||||
CV In 3.Tip <-> NTC.1
|
||||
CV In 4.Tip <-> R33.1
|
||||
D1.A <-> IC1.10
|
||||
D12.A <-> IC5.14 <-> R19.2 <-> R20.1
|
||||
D2.A <-> IC1.12
|
||||
D1.A <-> IC1.12
|
||||
D12.A <-> IC5.8 <-> R19.2 <-> R20.1
|
||||
D2.A <-> IC1.10
|
||||
D3.A <-> IC1.4
|
||||
D4.A <-> IC1.2
|
||||
D5.A <-> IC2.7 <-> Slope Shift 1.3
|
||||
D6.A <-> IC2.14 <-> R4.2 <-> R6.1
|
||||
D6.A <-> IC2.8 <-> R4.2 <-> R6.1
|
||||
D7.A <-> IC5.7 <-> Slope Shift 2.3
|
||||
Fine 1.2 <-> NTC.1
|
||||
Fine 2.2 <-> NTC.1
|
||||
@@ -50,38 +50,38 @@ Switch setup: [ ALL ]
|
||||
FM In 2.Tip <-> VR4.2
|
||||
FM In 3.Tip <-> VR6.2
|
||||
FM In 4.Tip <-> VR10.2
|
||||
IC1.8 <-> IC2.4 <-> IC3.4 <-> IC4.4 <-> IC5.4 <-> IC6.4 <-> IC7.4 <-> R13.2 <-> R17.2 <-> R2.2 <-> R36.2 <-> R42.2
|
||||
IC1.14 <-> IC2.4 <-> IC3.4 <-> IC4.4 <-> IC5.4 <-> IC6.4 <-> IC7.4 <-> R13.2 <-> R17.2 <-> R2.2 <-> R36.2 <-> R42.2
|
||||
IC2.1 <-> R10.1
|
||||
IC2.13 <-> R4.1 <-> R5.2
|
||||
IC2.2 <-> Pulsewidth 1.2 <-> R9.1 <-> VR3.1
|
||||
IC2.6 <-> R6.2 <-> Slope Shift 1.2
|
||||
IC2.9 <-> R4.1 <-> R5.2
|
||||
IC3.1 <-> IC3.2 <-> Square/Triangle 2.1
|
||||
IC3.10 <-> Square/Triangle 1.2
|
||||
IC3.12 <-> R10.2 <-> R11.1
|
||||
IC3.13 <-> IC3.14 <-> Square/Triangle 1.1
|
||||
IC3.10 <-> R10.2 <-> R11.1
|
||||
IC3.12 <-> Square/Triangle 1.2
|
||||
IC3.13 <-> IC3.14 <-> Output 1.Tip
|
||||
IC3.3 <-> R25.2 <-> R26.1
|
||||
IC3.5 <-> Square/Triangle 2.2
|
||||
IC3.6 <-> IC3.7 <-> Output 2.Tip
|
||||
IC3.8 <-> IC3.9 <-> Output 1.Tip
|
||||
IC3.8 <-> IC3.9 <-> Square/Triangle 1.1
|
||||
IC4.1 <-> IC4.2 <-> Square/Sawtooth 3.1
|
||||
IC4.13 <-> R15.1 <-> R27.1
|
||||
IC4.14 <-> R15.2 <-> Square/Sawtooth 3.3
|
||||
IC4.3 <-> R29.2 <-> R30.1
|
||||
IC4.6 <-> Pulsewidth 3.2 <-> R28.1 <-> VR9.1
|
||||
IC4.7 <-> R29.1
|
||||
IC4.8 <-> R15.2 <-> Square/Sawtooth 3.3
|
||||
IC4.9 <-> R15.1 <-> R27.1
|
||||
IC5.1 <-> R25.1
|
||||
IC5.13 <-> R18.2 <-> R19.1
|
||||
IC5.2 <-> Pulsewidth 2.2 <-> R23.1 <-> VR5.1
|
||||
IC5.6 <-> R20.2 <-> Slope Shift 2.2
|
||||
IC5.9 <-> R18.2 <-> R19.1
|
||||
IC6.1 <-> R41.1
|
||||
IC6.13 <-> R38.1 <-> R39.1
|
||||
IC6.14 <-> R38.2 <-> Square/Sawtooth 4.3
|
||||
IC6.2 <-> Pulsewidth 4.2 <-> R40.1 <-> VR16.3
|
||||
IC6.5 <-> IC7.12 <-> R41.2 <-> R42.1 <-> Square/Sawtooth 4.2
|
||||
IC6.5 <-> IC7.10 <-> R41.2 <-> R42.1 <-> Square/Sawtooth 4.2
|
||||
IC6.6 <-> IC6.7 <-> Square/Sawtooth 4.1
|
||||
IC6.8 <-> R38.2 <-> Square/Sawtooth 4.3
|
||||
IC6.9 <-> R38.1 <-> R39.1
|
||||
IC7.13 <-> IC7.14 <-> Output 4.Tip
|
||||
IC7.5 <-> Square/Sawtooth 3.2
|
||||
IC7.6 <-> IC7.7 <-> Output 3.Tip
|
||||
IC7.8 <-> IC7.9 <-> Output 4.Tip
|
||||
NTC.1 <-> VR1.1
|
||||
NTC.1 <-> VR4.1
|
||||
PWM In 1.Tip <-> VR3.2
|
||||
|
||||
+30
-30
@@ -1,31 +1,31 @@
|
||||
Switch setup: [ ALL ]
|
||||
|
||||
BC548.1 <-> C1.1 <-> D1.K <-> IC1.9 <-> IC2.10
|
||||
BC548.1 <-> C2.2 <-> D2.K <-> IC1.11 <-> IC5.10
|
||||
BC548.1 <-> C3.1 <-> D4.K <-> IC1.1 <-> IC4.10
|
||||
BC548.1 <-> C4.1 <-> D3.K <-> IC1.3 <-> IC6.12
|
||||
BC548.1 <-> C1.1 <-> D1.K <-> IC1.13 <-> IC2.12
|
||||
BC548.1 <-> C2.2 <-> D2.K <-> IC1.11 <-> IC5.12
|
||||
BC548.1 <-> C3.1 <-> D4.K <-> IC1.1 <-> IC4.12
|
||||
BC548.1 <-> C4.1 <-> D3.K <-> IC1.3 <-> IC6.10
|
||||
BC548.2 <-> BC558.3 <-> R13.1
|
||||
BC548.2 <-> BC558.3 <-> R17.1
|
||||
BC548.2 <-> BC558.3 <-> R2.1
|
||||
BC548.2 <-> BC558.3 <-> R36.1
|
||||
BC548.3 <-> BC548.3 <-> BC548.3 <-> BC548.3 <-> C1.2 <-> C2.1 <-> C3.2 <-> C4.2 <-> IC1.13 <-> IC1.5 <-> IC1.7 <-> IC2.5 <-> IC5.5 <-> R11.2 <-> R14.2 <-> R18.1 <-> R22.2 <-> R23.2 <-> R24.2 <-> R26.2 <-> R27.2 <-> R28.2 <-> R3.2 <-> R30.2 <-> R37.2 <-> R39.2 <-> R40.2 <-> R5.1 <-> R8.2 <-> R9.2 <-> VR13.2 <-> VR2.2 <-> VR7.2 <-> VR8.2
|
||||
BC548.3 <-> BC548.3 <-> BC548.3 <-> BC548.3 <-> C1.2 <-> C2.1 <-> C3.2 <-> C4.2 <-> IC1.5 <-> IC1.7 <-> IC1.9 <-> IC2.5 <-> IC5.5 <-> R11.2 <-> R14.2 <-> R18.1 <-> R22.2 <-> R23.2 <-> R24.2 <-> R26.2 <-> R27.2 <-> R28.2 <-> R3.2 <-> R30.2 <-> R37.2 <-> R39.2 <-> R40.2 <-> R5.1 <-> R8.2 <-> R9.2 <-> VR13.2 <-> VR2.2 <-> VR7.2 <-> VR8.2
|
||||
BC558.1 <-> BC558.1 <-> IC2.11 <-> IC3.11 <-> IC4.11 <-> IC5.11 <-> IC6.11 <-> IC7.11 <-> R21.2 <-> R7.2
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R1.1
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R12.1
|
||||
BC558.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> NTC.2 <-> R16.1
|
||||
BC558.2 <-> R31.2 <-> R32.2 <-> R33.2 <-> R34.2 <-> R35.1
|
||||
C10.1 <-> IC6.10 <-> IC6.3 <-> R37.1
|
||||
C10.2 <-> IC6.13 <-> IC6.14
|
||||
C5.1 <-> IC2.8 <-> IC2.9
|
||||
C5.2 <-> IC2.12 <-> IC2.3 <-> R3.1
|
||||
C10.1 <-> IC6.12 <-> IC6.3 <-> R37.1
|
||||
C10.2 <-> IC6.8 <-> IC6.9
|
||||
C5.1 <-> IC2.13 <-> IC2.14
|
||||
C5.2 <-> IC2.10 <-> IC2.3 <-> R3.1
|
||||
C6.1 <-> D5.K <-> D6.K <-> R7.1
|
||||
C6.2 <-> R8.1 <-> Square/Triangle 1.3
|
||||
C7.1 <-> IC5.8 <-> IC5.9
|
||||
C7.2 <-> IC5.12 <-> IC5.3 <-> R24.1
|
||||
C7.1 <-> IC5.13 <-> IC5.14
|
||||
C7.2 <-> IC5.10 <-> IC5.3 <-> R24.1
|
||||
C8.1 <-> D12.K <-> D7.K <-> R21.1
|
||||
C8.2 <-> R22.1 <-> Square/Triangle 2.3
|
||||
C9.1 <-> IC4.12 <-> IC4.5 <-> R14.1
|
||||
C9.2 <-> IC4.8 <-> IC4.9
|
||||
C9.1 <-> IC4.10 <-> IC4.5 <-> R14.1
|
||||
C9.2 <-> IC4.13 <-> IC4.14
|
||||
Coarse 1.2 <-> NTC.1
|
||||
Coarse 2.2 <-> NTC.1
|
||||
Coarse 3.2 <-> NTC.1
|
||||
@@ -34,13 +34,13 @@ Switch setup: [ ALL ]
|
||||
CV In 2.Tip <-> NTC.1
|
||||
CV In 3.Tip <-> NTC.1
|
||||
CV In 4.Tip <-> R33.1
|
||||
D1.A <-> IC1.10
|
||||
D12.A <-> IC5.14 <-> R19.2 <-> R20.1
|
||||
D2.A <-> IC1.12
|
||||
D1.A <-> IC1.12
|
||||
D12.A <-> IC5.8 <-> R19.2 <-> R20.1
|
||||
D2.A <-> IC1.10
|
||||
D3.A <-> IC1.4
|
||||
D4.A <-> IC1.2
|
||||
D5.A <-> IC2.7 <-> Slope Shift 1.3
|
||||
D6.A <-> IC2.14 <-> R4.2 <-> R6.1
|
||||
D6.A <-> IC2.8 <-> R4.2 <-> R6.1
|
||||
D7.A <-> IC5.7 <-> Slope Shift 2.3
|
||||
Fine 1.2 <-> NTC.1
|
||||
Fine 2.2 <-> NTC.1
|
||||
@@ -50,38 +50,38 @@ Switch setup: [ ALL ]
|
||||
FM In 2.Tip <-> VR4.2
|
||||
FM In 3.Tip <-> VR6.2
|
||||
FM In 4.Tip <-> VR10.2
|
||||
IC1.8 <-> IC2.4 <-> IC3.4 <-> IC4.4 <-> IC5.4 <-> IC6.4 <-> IC7.4 <-> R13.2 <-> R17.2 <-> R2.2 <-> R36.2 <-> R42.2
|
||||
IC1.14 <-> IC2.4 <-> IC3.4 <-> IC4.4 <-> IC5.4 <-> IC6.4 <-> IC7.4 <-> R13.2 <-> R17.2 <-> R2.2 <-> R36.2 <-> R42.2
|
||||
IC2.1 <-> R10.1
|
||||
IC2.13 <-> R4.1 <-> R5.2
|
||||
IC2.2 <-> Pulsewidth 1.2 <-> R9.1 <-> VR3.1
|
||||
IC2.6 <-> R6.2 <-> Slope Shift 1.2
|
||||
IC2.9 <-> R4.1 <-> R5.2
|
||||
IC3.1 <-> IC3.2 <-> Square/Triangle 2.1
|
||||
IC3.10 <-> Square/Triangle 1.2
|
||||
IC3.12 <-> R10.2 <-> R11.1
|
||||
IC3.13 <-> IC3.14 <-> Square/Triangle 1.1
|
||||
IC3.10 <-> R10.2 <-> R11.1
|
||||
IC3.12 <-> Square/Triangle 1.2
|
||||
IC3.13 <-> IC3.14 <-> Output 1.Tip
|
||||
IC3.3 <-> R25.2 <-> R26.1
|
||||
IC3.5 <-> Square/Triangle 2.2
|
||||
IC3.6 <-> IC3.7 <-> Output 2.Tip
|
||||
IC3.8 <-> IC3.9 <-> Output 1.Tip
|
||||
IC3.8 <-> IC3.9 <-> Square/Triangle 1.1
|
||||
IC4.1 <-> IC4.2 <-> Square/Sawtooth 3.1
|
||||
IC4.13 <-> R15.1 <-> R27.1
|
||||
IC4.14 <-> R15.2 <-> Square/Sawtooth 3.3
|
||||
IC4.3 <-> R29.2 <-> R30.1
|
||||
IC4.6 <-> Pulsewidth 3.2 <-> R28.1 <-> VR9.1
|
||||
IC4.7 <-> R29.1
|
||||
IC4.8 <-> R15.2 <-> Square/Sawtooth 3.3
|
||||
IC4.9 <-> R15.1 <-> R27.1
|
||||
IC5.1 <-> R25.1
|
||||
IC5.13 <-> R18.2 <-> R19.1
|
||||
IC5.2 <-> Pulsewidth 2.2 <-> R23.1 <-> VR5.1
|
||||
IC5.6 <-> R20.2 <-> Slope Shift 2.2
|
||||
IC5.9 <-> R18.2 <-> R19.1
|
||||
IC6.1 <-> R41.1
|
||||
IC6.13 <-> R38.1 <-> R39.1
|
||||
IC6.14 <-> R38.2 <-> Square/Sawtooth 4.3
|
||||
IC6.2 <-> Pulsewidth 4.2 <-> R40.1 <-> VR16.3
|
||||
IC6.5 <-> IC7.12 <-> R41.2 <-> R42.1 <-> Square/Sawtooth 4.2
|
||||
IC6.5 <-> IC7.10 <-> R41.2 <-> R42.1 <-> Square/Sawtooth 4.2
|
||||
IC6.6 <-> IC6.7 <-> Square/Sawtooth 4.1
|
||||
IC6.8 <-> R38.2 <-> Square/Sawtooth 4.3
|
||||
IC6.9 <-> R38.1 <-> R39.1
|
||||
IC7.13 <-> IC7.14 <-> Output 4.Tip
|
||||
IC7.5 <-> Square/Sawtooth 3.2
|
||||
IC7.6 <-> IC7.7 <-> Output 3.Tip
|
||||
IC7.8 <-> IC7.9 <-> Output 4.Tip
|
||||
NTC.1 <-> VR1.1
|
||||
NTC.1 <-> VR4.1
|
||||
PWM In 1.Tip <-> VR3.2
|
||||
|
||||
@@ -4,17 +4,17 @@ Switch setup: [ ALL ]
|
||||
1k.2 <-> 3PDT.5
|
||||
3PDT.1 <-> C1.1
|
||||
3PDT.3 <-> 3PDT.9
|
||||
3PDT.4 <-> IC1.5 <-> IC2.5 <-> R2.1
|
||||
3PDT.4 <-> IC1.8 <-> IC2.8 <-> R2.1
|
||||
3PDT.7 <-> Volume.2
|
||||
Blend.1 <-> C3.+ <-> C6.1
|
||||
Blend.2 <-> C5.2
|
||||
Blend.3 <-> C8.+
|
||||
C1.2 <-> IC1.3 <-> IC2.3 <-> R1.1
|
||||
C2.+ <-> IC2.4 <-> LED.K <-> R3.1 <-> R4.2 <-> Volume.1
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.8 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.5 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C4.+ <-> R4.1
|
||||
C4.- <-> IC2.1 <-> IC2.2
|
||||
C6.2 <-> IC2.8 <-> R6.1
|
||||
C6.2 <-> IC2.5 <-> R6.1
|
||||
C7.+ <-> Volume.3
|
||||
C7.- <-> IC1.6 <-> IC1.7
|
||||
C8.- <-> IC2.6 <-> IC2.7
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
Switch setup: [ 3PDT.ON1 ]
|
||||
|
||||
1k.1 <-> LED.A
|
||||
1k.2 <-> IC1.5 <-> IC2.5 <-> R2.1
|
||||
1k.2 <-> IC1.8 <-> IC2.8 <-> R2.1
|
||||
Blend.1 <-> C3.+ <-> C6.1
|
||||
Blend.2 <-> C5.2
|
||||
Blend.3 <-> C8.+
|
||||
C1.2 <-> IC1.3 <-> IC2.3 <-> R1.1
|
||||
C2.+ <-> IC2.4 <-> LED.K <-> R3.1 <-> R4.2 <-> Volume.1
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.8 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.5 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C4.+ <-> R4.1
|
||||
C4.- <-> IC2.1 <-> IC2.2
|
||||
C6.2 <-> IC2.8 <-> R6.1
|
||||
C6.2 <-> IC2.5 <-> R6.1
|
||||
C7.+ <-> Volume.3
|
||||
C7.- <-> IC1.6 <-> IC1.7
|
||||
C8.- <-> IC2.6 <-> IC2.7
|
||||
@@ -23,12 +23,12 @@ Switch setup: [ 3PDT.ON2 ]
|
||||
Blend.3 <-> C8.+
|
||||
C1.2 <-> IC1.3 <-> IC2.3 <-> R1.1
|
||||
C2.+ <-> IC2.4 <-> LED.K <-> R3.1 <-> R4.2 <-> Volume.1
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.8 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C2.- <-> C3.- <-> C5.1 <-> IC1.1 <-> IC1.2 <-> IC1.5 <-> R1.2 <-> R2.2 <-> R3.2 <-> R5.1 <-> R5.2 <-> R6.2
|
||||
C4.+ <-> R4.1
|
||||
C4.- <-> IC2.1 <-> IC2.2
|
||||
C6.2 <-> IC2.8 <-> R6.1
|
||||
C6.2 <-> IC2.5 <-> R6.1
|
||||
C7.+ <-> Volume.3
|
||||
C7.- <-> IC1.6 <-> IC1.7
|
||||
C8.- <-> IC2.6 <-> IC2.7
|
||||
IC1.5 <-> IC2.5 <-> R2.1
|
||||
IC1.8 <-> IC2.8 <-> R2.1
|
||||
|
||||
|
||||
@@ -7,28 +7,28 @@ Switch setup: [ ALL ]
|
||||
C11.2 <-> C14.- <-> C5.1 <-> C8.- <-> C9.- <-> D2.A <-> D3.K <-> IC1.4 <-> IC2.4 <-> IC3.4 <-> R15.2 <-> R19.2 <-> R2.2 <-> R21.2
|
||||
C12.2 <-> R11.1
|
||||
C13.1 <-> C14.+ <-> C15.- <-> IC1.3 <-> IC3.3 <-> R12.2 <-> R19.1 <-> R20.1 <-> R3.1
|
||||
C13.2 <-> D1.K <-> IC3.8 <-> R12.1
|
||||
C15.+ <-> IC1.6 <-> IC2.6 <-> IC3.5 <-> R13.2 <-> R20.2
|
||||
C13.2 <-> D1.K <-> IC3.5 <-> R12.1
|
||||
C15.+ <-> IC1.7 <-> IC2.7 <-> IC3.8 <-> R13.2 <-> R20.2
|
||||
C16.+ <-> IC3.1 <-> LEVEL.2
|
||||
C16.- <-> R21.1
|
||||
C2.1 <-> IC1.1
|
||||
C2.2 <-> IC1.5
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.7
|
||||
C2.2 <-> IC1.8
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.6
|
||||
C3.- <-> C4.1 <-> R2.1
|
||||
C4.2 <-> R3.2 <-> R4.2
|
||||
C5.2 <-> IC2.3 <-> R4.1
|
||||
C6.1 <-> IC2.2 <-> LDR.1 <-> R5.2 <-> R6.2 <-> spst1.1 <-> spst2.1
|
||||
C6.2 <-> IC2.7 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C6.2 <-> IC2.6 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C7.1 <-> IC2.1
|
||||
C7.2 <-> IC2.5
|
||||
C7.2 <-> IC2.8
|
||||
C8.+ <-> R5.1
|
||||
C9.+ <-> R6.1
|
||||
D4.A <-> R14.1
|
||||
D4.K <-> R13.1
|
||||
GAIN.1 <-> IC1.2 <-> R1.2
|
||||
IC3.2 <-> LEVEL.1 <-> R11.2
|
||||
IC3.6 <-> R17.2
|
||||
IC3.7 <-> R15.1 <-> R18.2
|
||||
IC3.6 <-> R15.1 <-> R18.2
|
||||
IC3.7 <-> R17.2
|
||||
Q1.1 <-> Q1.2 <-> R14.2 <-> R16.2 <-> R17.1 <-> R18.1
|
||||
Q1.3 <-> R16.1
|
||||
R10.1 <-> TONE.2
|
||||
|
||||
@@ -7,28 +7,28 @@ Switch setup: [ spst1.ON1:spst2.ON1 ]
|
||||
C11.2 <-> C14.- <-> C5.1 <-> C8.- <-> C9.- <-> D2.A <-> D3.K <-> IC1.4 <-> IC2.4 <-> IC3.4 <-> R15.2 <-> R19.2 <-> R2.2 <-> R21.2
|
||||
C12.2 <-> R11.1
|
||||
C13.1 <-> C14.+ <-> C15.- <-> IC1.3 <-> IC3.3 <-> R12.2 <-> R19.1 <-> R20.1 <-> R3.1
|
||||
C13.2 <-> D1.K <-> IC3.8 <-> R12.1
|
||||
C15.+ <-> IC1.6 <-> IC2.6 <-> IC3.5 <-> R13.2 <-> R20.2
|
||||
C13.2 <-> D1.K <-> IC3.5 <-> R12.1
|
||||
C15.+ <-> IC1.7 <-> IC2.7 <-> IC3.8 <-> R13.2 <-> R20.2
|
||||
C16.+ <-> IC3.1 <-> LEVEL.2
|
||||
C16.- <-> R21.1
|
||||
C2.1 <-> IC1.1
|
||||
C2.2 <-> IC1.5
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.7
|
||||
C2.2 <-> IC1.8
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.6
|
||||
C3.- <-> C4.1 <-> R2.1
|
||||
C4.2 <-> R3.2 <-> R4.2
|
||||
C5.2 <-> IC2.3 <-> R4.1
|
||||
C6.1 <-> IC2.2 <-> LDR.1 <-> R5.2 <-> R6.2 <-> R7.2 <-> R8.2
|
||||
C6.2 <-> IC2.7 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C6.2 <-> IC2.6 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C7.1 <-> IC2.1
|
||||
C7.2 <-> IC2.5
|
||||
C7.2 <-> IC2.8
|
||||
C8.+ <-> R5.1
|
||||
C9.+ <-> R6.1
|
||||
D4.A <-> R14.1
|
||||
D4.K <-> R13.1
|
||||
GAIN.1 <-> IC1.2 <-> R1.2
|
||||
IC3.2 <-> LEVEL.1 <-> R11.2
|
||||
IC3.6 <-> R17.2
|
||||
IC3.7 <-> R15.1 <-> R18.2
|
||||
IC3.6 <-> R15.1 <-> R18.2
|
||||
IC3.7 <-> R17.2
|
||||
Q1.1 <-> Q1.2 <-> R14.2 <-> R16.2 <-> R17.1 <-> R18.1
|
||||
Q1.3 <-> R16.1
|
||||
R10.1 <-> TONE.2
|
||||
@@ -42,28 +42,28 @@ Switch setup: [ spst1.ON1:spst2.ON2 ]
|
||||
C11.2 <-> C14.- <-> C5.1 <-> C8.- <-> C9.- <-> D2.A <-> D3.K <-> IC1.4 <-> IC2.4 <-> IC3.4 <-> R15.2 <-> R19.2 <-> R2.2 <-> R21.2
|
||||
C12.2 <-> R11.1
|
||||
C13.1 <-> C14.+ <-> C15.- <-> IC1.3 <-> IC3.3 <-> R12.2 <-> R19.1 <-> R20.1 <-> R3.1
|
||||
C13.2 <-> D1.K <-> IC3.8 <-> R12.1
|
||||
C15.+ <-> IC1.6 <-> IC2.6 <-> IC3.5 <-> R13.2 <-> R20.2
|
||||
C13.2 <-> D1.K <-> IC3.5 <-> R12.1
|
||||
C15.+ <-> IC1.7 <-> IC2.7 <-> IC3.8 <-> R13.2 <-> R20.2
|
||||
C16.+ <-> IC3.1 <-> LEVEL.2
|
||||
C16.- <-> R21.1
|
||||
C2.1 <-> IC1.1
|
||||
C2.2 <-> IC1.5
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.7
|
||||
C2.2 <-> IC1.8
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.6
|
||||
C3.- <-> C4.1 <-> R2.1
|
||||
C4.2 <-> R3.2 <-> R4.2
|
||||
C5.2 <-> IC2.3 <-> R4.1
|
||||
C6.1 <-> IC2.2 <-> LDR.1 <-> R5.2 <-> R6.2 <-> R7.2
|
||||
C6.2 <-> IC2.7 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C6.2 <-> IC2.6 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C7.1 <-> IC2.1
|
||||
C7.2 <-> IC2.5
|
||||
C7.2 <-> IC2.8
|
||||
C8.+ <-> R5.1
|
||||
C9.+ <-> R6.1
|
||||
D4.A <-> R14.1
|
||||
D4.K <-> R13.1
|
||||
GAIN.1 <-> IC1.2 <-> R1.2
|
||||
IC3.2 <-> LEVEL.1 <-> R11.2
|
||||
IC3.6 <-> R17.2
|
||||
IC3.7 <-> R15.1 <-> R18.2
|
||||
IC3.6 <-> R15.1 <-> R18.2
|
||||
IC3.7 <-> R17.2
|
||||
Q1.1 <-> Q1.2 <-> R14.2 <-> R16.2 <-> R17.1 <-> R18.1
|
||||
Q1.3 <-> R16.1
|
||||
R10.1 <-> TONE.2
|
||||
@@ -77,28 +77,28 @@ Switch setup: [ spst1.ON2:spst2.ON1 ]
|
||||
C11.2 <-> C14.- <-> C5.1 <-> C8.- <-> C9.- <-> D2.A <-> D3.K <-> IC1.4 <-> IC2.4 <-> IC3.4 <-> R15.2 <-> R19.2 <-> R2.2 <-> R21.2
|
||||
C12.2 <-> R11.1
|
||||
C13.1 <-> C14.+ <-> C15.- <-> IC1.3 <-> IC3.3 <-> R12.2 <-> R19.1 <-> R20.1 <-> R3.1
|
||||
C13.2 <-> D1.K <-> IC3.8 <-> R12.1
|
||||
C15.+ <-> IC1.6 <-> IC2.6 <-> IC3.5 <-> R13.2 <-> R20.2
|
||||
C13.2 <-> D1.K <-> IC3.5 <-> R12.1
|
||||
C15.+ <-> IC1.7 <-> IC2.7 <-> IC3.8 <-> R13.2 <-> R20.2
|
||||
C16.+ <-> IC3.1 <-> LEVEL.2
|
||||
C16.- <-> R21.1
|
||||
C2.1 <-> IC1.1
|
||||
C2.2 <-> IC1.5
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.7
|
||||
C2.2 <-> IC1.8
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.6
|
||||
C3.- <-> C4.1 <-> R2.1
|
||||
C4.2 <-> R3.2 <-> R4.2
|
||||
C5.2 <-> IC2.3 <-> R4.1
|
||||
C6.1 <-> IC2.2 <-> LDR.1 <-> R5.2 <-> R6.2 <-> R8.2
|
||||
C6.2 <-> IC2.7 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C6.2 <-> IC2.6 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C7.1 <-> IC2.1
|
||||
C7.2 <-> IC2.5
|
||||
C7.2 <-> IC2.8
|
||||
C8.+ <-> R5.1
|
||||
C9.+ <-> R6.1
|
||||
D4.A <-> R14.1
|
||||
D4.K <-> R13.1
|
||||
GAIN.1 <-> IC1.2 <-> R1.2
|
||||
IC3.2 <-> LEVEL.1 <-> R11.2
|
||||
IC3.6 <-> R17.2
|
||||
IC3.7 <-> R15.1 <-> R18.2
|
||||
IC3.6 <-> R15.1 <-> R18.2
|
||||
IC3.7 <-> R17.2
|
||||
Q1.1 <-> Q1.2 <-> R14.2 <-> R16.2 <-> R17.1 <-> R18.1
|
||||
Q1.3 <-> R16.1
|
||||
R10.1 <-> TONE.2
|
||||
@@ -112,28 +112,28 @@ Switch setup: [ spst1.ON2:spst2.ON2 ]
|
||||
C11.2 <-> C14.- <-> C5.1 <-> C8.- <-> C9.- <-> D2.A <-> D3.K <-> IC1.4 <-> IC2.4 <-> IC3.4 <-> R15.2 <-> R19.2 <-> R2.2 <-> R21.2
|
||||
C12.2 <-> R11.1
|
||||
C13.1 <-> C14.+ <-> C15.- <-> IC1.3 <-> IC3.3 <-> R12.2 <-> R19.1 <-> R20.1 <-> R3.1
|
||||
C13.2 <-> D1.K <-> IC3.8 <-> R12.1
|
||||
C15.+ <-> IC1.6 <-> IC2.6 <-> IC3.5 <-> R13.2 <-> R20.2
|
||||
C13.2 <-> D1.K <-> IC3.5 <-> R12.1
|
||||
C15.+ <-> IC1.7 <-> IC2.7 <-> IC3.8 <-> R13.2 <-> R20.2
|
||||
C16.+ <-> IC3.1 <-> LEVEL.2
|
||||
C16.- <-> R21.1
|
||||
C2.1 <-> IC1.1
|
||||
C2.2 <-> IC1.5
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.7
|
||||
C2.2 <-> IC1.8
|
||||
C3.+ <-> D1.A <-> GAIN.2 <-> IC1.6
|
||||
C3.- <-> C4.1 <-> R2.1
|
||||
C4.2 <-> R3.2 <-> R4.2
|
||||
C5.2 <-> IC2.3 <-> R4.1
|
||||
C6.1 <-> IC2.2 <-> LDR.1 <-> R5.2 <-> R6.2
|
||||
C6.2 <-> IC2.7 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C6.2 <-> IC2.6 <-> LDR.2 <-> R7.1 <-> R8.1 <-> R9.1
|
||||
C7.1 <-> IC2.1
|
||||
C7.2 <-> IC2.5
|
||||
C7.2 <-> IC2.8
|
||||
C8.+ <-> R5.1
|
||||
C9.+ <-> R6.1
|
||||
D4.A <-> R14.1
|
||||
D4.K <-> R13.1
|
||||
GAIN.1 <-> IC1.2 <-> R1.2
|
||||
IC3.2 <-> LEVEL.1 <-> R11.2
|
||||
IC3.6 <-> R17.2
|
||||
IC3.7 <-> R15.1 <-> R18.2
|
||||
IC3.6 <-> R15.1 <-> R18.2
|
||||
IC3.7 <-> R17.2
|
||||
Q1.1 <-> Q1.2 <-> R14.2 <-> R16.2 <-> R17.1 <-> R18.1
|
||||
Q1.3 <-> R16.1
|
||||
R10.1 <-> TONE.2
|
||||
|
||||
@@ -13,10 +13,10 @@ Switch setup: [ ALL ]
|
||||
C14.2 <-> R21.1
|
||||
C15.2 <-> D3.K <-> Q3.2 <-> Q3.3 <-> R18.2
|
||||
C16.+ <-> Q5.3 <-> R20.1
|
||||
C3.1 <-> IC1.7 <-> Q2.3 <-> R3.2
|
||||
C3.1 <-> IC1.6 <-> Q2.3 <-> R3.2
|
||||
C3.2 <-> C4.+ <-> R2.1 <-> R3.1 <-> R4.1 <-> R5.1
|
||||
C5.+ <-> C6.1 <-> D1.K <-> IC1.6 <-> R10.1 <-> R16.2 <-> R20.2 <-> R4.2
|
||||
IC1.8 <-> R19.1
|
||||
C5.+ <-> C6.1 <-> D1.K <-> IC1.7 <-> R10.1 <-> R16.2 <-> R20.2 <-> R4.2
|
||||
IC1.5 <-> R19.1
|
||||
Q1.3 <-> R5.2 <-> R6.2
|
||||
Q5.1 <-> Q5.2
|
||||
R10.2 <-> VR1.2
|
||||
|
||||
@@ -13,10 +13,10 @@ Switch setup: [ ALL ]
|
||||
C14.2 <-> R21.1
|
||||
C15.2 <-> D3.K <-> Q3.2 <-> Q3.3 <-> R18.2
|
||||
C16.+ <-> Q5.3 <-> R20.1
|
||||
C3.1 <-> IC1.7 <-> Q2.3 <-> R3.2
|
||||
C3.1 <-> IC1.6 <-> Q2.3 <-> R3.2
|
||||
C3.2 <-> C4.+ <-> R2.1 <-> R3.1 <-> R4.1 <-> R5.1
|
||||
C5.+ <-> C6.1 <-> D1.K <-> IC1.6 <-> R10.1 <-> R16.2 <-> R20.2 <-> R4.2
|
||||
IC1.8 <-> R19.1
|
||||
C5.+ <-> C6.1 <-> D1.K <-> IC1.7 <-> R10.1 <-> R16.2 <-> R20.2 <-> R4.2
|
||||
IC1.5 <-> R19.1
|
||||
Q1.3 <-> R5.2 <-> R6.2
|
||||
Q5.1 <-> Q5.2
|
||||
R10.2 <-> VR1.2
|
||||
|
||||
@@ -2,42 +2,42 @@ Switch setup: [ ALL ]
|
||||
|
||||
Bass Switch.1 <-> C8.1 <-> R13.2 <-> R14.1
|
||||
Bass Switch.2 <-> Blend.3
|
||||
Bass Switch.3 <-> C10.2 <-> C11.2 <-> IC1.14 <-> R15.1 <-> R16.2
|
||||
Bass Switch.3 <-> C10.2 <-> C11.2 <-> IC1.8 <-> R15.1 <-> R16.2
|
||||
Blend.1 <-> C5.2 <-> C6.2 <-> Q1.2 <-> Q1.3 <-> R12.1
|
||||
Blend.2 <-> C17.1
|
||||
C1.2 <-> IC1.3 <-> IC1.5 <-> R1.1
|
||||
C10.1 <-> Lo Filter.2 <-> R14.2
|
||||
C11.1 <-> IC1.13 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.12 <-> Lo Filter.1
|
||||
C11.1 <-> IC1.9 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.10 <-> Lo Filter.1
|
||||
C12.2 <-> C13.1 <-> C9.2 <-> D1.K <-> Q1.1 <-> R11.2 <-> R12.2 <-> R17.2
|
||||
C13.2 <-> D1.A <-> R20.1 <-> R21.1
|
||||
C14.1 <-> D3.K <-> IC3.2 <-> IC3.6 <-> R24.1
|
||||
C14.2 <-> C15.1 <-> R23.1
|
||||
C15.2 <-> D2.A <-> IC3.10 <-> IC3.13 <-> R24.2
|
||||
C16.1 <-> IC3.12
|
||||
C15.2 <-> D2.A <-> IC3.12 <-> IC3.9 <-> R24.2
|
||||
C16.1 <-> IC3.10
|
||||
C16.2 <-> C18.+ <-> C19.- <-> C2.2 <-> Hi Filter.1 <-> IC3.11 <-> R1.2 <-> R22.1 <-> R23.2 <-> R26.1 <-> R27.1 <-> R5.2
|
||||
C17.2 <-> R25.1
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.12 <-> IC2.14 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.10 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> IC2.8 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C19.+ <-> C20.- <-> R27.2
|
||||
C2.1 <-> R4.2
|
||||
C3.1 <-> IC1.6 <-> R2.2 <-> R4.1
|
||||
C3.2 <-> C4.1 <-> R5.1
|
||||
C4.2 <-> R6.1 <-> Range.2
|
||||
C5.1 <-> IC1.1 <-> IC1.2 <-> R3.1 <-> R9.2
|
||||
C6.1 <-> IC1.10
|
||||
C6.1 <-> IC1.12
|
||||
C7.1 <-> R10.2 <-> R13.1
|
||||
C7.2 <-> C8.2 <-> C9.1 <-> Hi Filter.2
|
||||
D2.K <-> IC3.14
|
||||
D2.K <-> IC3.8
|
||||
D3.A <-> IC3.7
|
||||
IC1.4 <-> IC2.8 <-> IC3.4
|
||||
IC1.13 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC1.14 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.4 <-> IC2.14 <-> IC3.4
|
||||
IC1.7 <-> R18.1 <-> R19.1 <-> R2.1 <-> R6.2
|
||||
IC1.8 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.9 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC2.10 <-> IC2.13 <-> R20.2
|
||||
IC2.11 <-> IC2.2
|
||||
IC2.12 <-> IC2.9 <-> R20.2
|
||||
IC2.4 <-> IC3.1
|
||||
IC2.6 <-> IC3.8
|
||||
IC3.3 <-> IC3.9 <-> R19.2 <-> R22.2
|
||||
IC2.6 <-> IC3.14
|
||||
IC3.13 <-> IC3.3 <-> R19.2 <-> R22.2
|
||||
IC3.5 <-> R18.2
|
||||
R28.2 <-> Range.1
|
||||
|
||||
|
||||
@@ -5,38 +5,38 @@ Switch setup: [ Bass Switch.ON1:Range.ON1 ]
|
||||
Blend.3 <-> C8.1 <-> R13.2 <-> R14.1
|
||||
C1.2 <-> IC1.3 <-> IC1.5 <-> R1.1
|
||||
C10.1 <-> Lo Filter.2 <-> R14.2
|
||||
C10.2 <-> C11.2 <-> IC1.14 <-> R15.1 <-> R16.2
|
||||
C11.1 <-> IC1.13 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.12 <-> Lo Filter.1
|
||||
C10.2 <-> C11.2 <-> IC1.8 <-> R15.1 <-> R16.2
|
||||
C11.1 <-> IC1.9 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.10 <-> Lo Filter.1
|
||||
C12.2 <-> C13.1 <-> C9.2 <-> D1.K <-> Q1.1 <-> R11.2 <-> R12.2 <-> R17.2
|
||||
C13.2 <-> D1.A <-> R20.1 <-> R21.1
|
||||
C14.1 <-> D3.K <-> IC3.2 <-> IC3.6 <-> R24.1
|
||||
C14.2 <-> C15.1 <-> R23.1
|
||||
C15.2 <-> D2.A <-> IC3.10 <-> IC3.13 <-> R24.2
|
||||
C16.1 <-> IC3.12
|
||||
C15.2 <-> D2.A <-> IC3.12 <-> IC3.9 <-> R24.2
|
||||
C16.1 <-> IC3.10
|
||||
C16.2 <-> C18.+ <-> C19.- <-> C2.2 <-> Hi Filter.1 <-> IC3.11 <-> R1.2 <-> R22.1 <-> R23.2 <-> R26.1 <-> R27.1 <-> R5.2
|
||||
C17.2 <-> R25.1
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.12 <-> IC2.14 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.10 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> IC2.8 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C19.+ <-> C20.- <-> R27.2
|
||||
C2.1 <-> R4.2
|
||||
C3.1 <-> IC1.6 <-> R2.2 <-> R4.1
|
||||
C3.2 <-> C4.1 <-> R5.1
|
||||
C4.2 <-> R28.2 <-> R6.1
|
||||
C5.1 <-> IC1.1 <-> IC1.2 <-> R3.1 <-> R9.2
|
||||
C6.1 <-> IC1.10
|
||||
C6.1 <-> IC1.12
|
||||
C7.1 <-> R10.2 <-> R13.1
|
||||
C7.2 <-> C8.2 <-> C9.1 <-> Hi Filter.2
|
||||
D2.K <-> IC3.14
|
||||
D2.K <-> IC3.8
|
||||
D3.A <-> IC3.7
|
||||
IC1.4 <-> IC2.8 <-> IC3.4
|
||||
IC1.13 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC1.14 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.4 <-> IC2.14 <-> IC3.4
|
||||
IC1.7 <-> R18.1 <-> R19.1 <-> R2.1 <-> R6.2
|
||||
IC1.8 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.9 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC2.10 <-> IC2.13 <-> R20.2
|
||||
IC2.11 <-> IC2.2
|
||||
IC2.12 <-> IC2.9 <-> R20.2
|
||||
IC2.4 <-> IC3.1
|
||||
IC2.6 <-> IC3.8
|
||||
IC3.3 <-> IC3.9 <-> R19.2 <-> R22.2
|
||||
IC2.6 <-> IC3.14
|
||||
IC3.13 <-> IC3.3 <-> R19.2 <-> R22.2
|
||||
IC3.5 <-> R18.2
|
||||
|
||||
Switch setup: [ Bass Switch.ON1:Range.ON2 ]
|
||||
@@ -46,119 +46,119 @@ Switch setup: [ Bass Switch.ON1:Range.ON2 ]
|
||||
Blend.3 <-> C8.1 <-> R13.2 <-> R14.1
|
||||
C1.2 <-> IC1.3 <-> IC1.5 <-> R1.1
|
||||
C10.1 <-> Lo Filter.2 <-> R14.2
|
||||
C10.2 <-> C11.2 <-> IC1.14 <-> R15.1 <-> R16.2
|
||||
C11.1 <-> IC1.13 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.12 <-> Lo Filter.1
|
||||
C10.2 <-> C11.2 <-> IC1.8 <-> R15.1 <-> R16.2
|
||||
C11.1 <-> IC1.9 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.10 <-> Lo Filter.1
|
||||
C12.2 <-> C13.1 <-> C9.2 <-> D1.K <-> Q1.1 <-> R11.2 <-> R12.2 <-> R17.2
|
||||
C13.2 <-> D1.A <-> R20.1 <-> R21.1
|
||||
C14.1 <-> D3.K <-> IC3.2 <-> IC3.6 <-> R24.1
|
||||
C14.2 <-> C15.1 <-> R23.1
|
||||
C15.2 <-> D2.A <-> IC3.10 <-> IC3.13 <-> R24.2
|
||||
C16.1 <-> IC3.12
|
||||
C15.2 <-> D2.A <-> IC3.12 <-> IC3.9 <-> R24.2
|
||||
C16.1 <-> IC3.10
|
||||
C16.2 <-> C18.+ <-> C19.- <-> C2.2 <-> Hi Filter.1 <-> IC3.11 <-> R1.2 <-> R22.1 <-> R23.2 <-> R26.1 <-> R27.1 <-> R5.2
|
||||
C17.2 <-> R25.1
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.12 <-> IC2.14 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.10 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> IC2.8 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C19.+ <-> C20.- <-> R27.2
|
||||
C2.1 <-> R4.2
|
||||
C3.1 <-> IC1.6 <-> R2.2 <-> R4.1
|
||||
C3.2 <-> C4.1 <-> R5.1
|
||||
C4.2 <-> R6.1
|
||||
C5.1 <-> IC1.1 <-> IC1.2 <-> R3.1 <-> R9.2
|
||||
C6.1 <-> IC1.10
|
||||
C6.1 <-> IC1.12
|
||||
C7.1 <-> R10.2 <-> R13.1
|
||||
C7.2 <-> C8.2 <-> C9.1 <-> Hi Filter.2
|
||||
D2.K <-> IC3.14
|
||||
D2.K <-> IC3.8
|
||||
D3.A <-> IC3.7
|
||||
IC1.4 <-> IC2.8 <-> IC3.4
|
||||
IC1.13 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC1.14 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.4 <-> IC2.14 <-> IC3.4
|
||||
IC1.7 <-> R18.1 <-> R19.1 <-> R2.1 <-> R6.2
|
||||
IC1.8 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.9 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC2.10 <-> IC2.13 <-> R20.2
|
||||
IC2.11 <-> IC2.2
|
||||
IC2.12 <-> IC2.9 <-> R20.2
|
||||
IC2.4 <-> IC3.1
|
||||
IC2.6 <-> IC3.8
|
||||
IC3.3 <-> IC3.9 <-> R19.2 <-> R22.2
|
||||
IC2.6 <-> IC3.14
|
||||
IC3.13 <-> IC3.3 <-> R19.2 <-> R22.2
|
||||
IC3.5 <-> R18.2
|
||||
|
||||
Switch setup: [ Bass Switch.ON2:Range.ON1 ]
|
||||
|
||||
Blend.1 <-> C5.2 <-> C6.2 <-> Q1.2 <-> Q1.3 <-> R12.1
|
||||
Blend.2 <-> C17.1
|
||||
Blend.3 <-> C10.2 <-> C11.2 <-> IC1.14 <-> R15.1 <-> R16.2
|
||||
Blend.3 <-> C10.2 <-> C11.2 <-> IC1.8 <-> R15.1 <-> R16.2
|
||||
C1.2 <-> IC1.3 <-> IC1.5 <-> R1.1
|
||||
C10.1 <-> Lo Filter.2 <-> R14.2
|
||||
C11.1 <-> IC1.13 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.12 <-> Lo Filter.1
|
||||
C11.1 <-> IC1.9 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.10 <-> Lo Filter.1
|
||||
C12.2 <-> C13.1 <-> C9.2 <-> D1.K <-> Q1.1 <-> R11.2 <-> R12.2 <-> R17.2
|
||||
C13.2 <-> D1.A <-> R20.1 <-> R21.1
|
||||
C14.1 <-> D3.K <-> IC3.2 <-> IC3.6 <-> R24.1
|
||||
C14.2 <-> C15.1 <-> R23.1
|
||||
C15.2 <-> D2.A <-> IC3.10 <-> IC3.13 <-> R24.2
|
||||
C16.1 <-> IC3.12
|
||||
C15.2 <-> D2.A <-> IC3.12 <-> IC3.9 <-> R24.2
|
||||
C16.1 <-> IC3.10
|
||||
C16.2 <-> C18.+ <-> C19.- <-> C2.2 <-> Hi Filter.1 <-> IC3.11 <-> R1.2 <-> R22.1 <-> R23.2 <-> R26.1 <-> R27.1 <-> R5.2
|
||||
C17.2 <-> R25.1
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.12 <-> IC2.14 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.10 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> IC2.8 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C19.+ <-> C20.- <-> R27.2
|
||||
C2.1 <-> R4.2
|
||||
C3.1 <-> IC1.6 <-> R2.2 <-> R4.1
|
||||
C3.2 <-> C4.1 <-> R5.1
|
||||
C4.2 <-> R28.2 <-> R6.1
|
||||
C5.1 <-> IC1.1 <-> IC1.2 <-> R3.1 <-> R9.2
|
||||
C6.1 <-> IC1.10
|
||||
C6.1 <-> IC1.12
|
||||
C7.1 <-> R10.2 <-> R13.1
|
||||
C7.2 <-> C8.2 <-> C9.1 <-> Hi Filter.2
|
||||
C8.1 <-> R13.2 <-> R14.1
|
||||
D2.K <-> IC3.14
|
||||
D2.K <-> IC3.8
|
||||
D3.A <-> IC3.7
|
||||
IC1.4 <-> IC2.8 <-> IC3.4
|
||||
IC1.13 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC1.14 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.4 <-> IC2.14 <-> IC3.4
|
||||
IC1.7 <-> R18.1 <-> R19.1 <-> R2.1 <-> R6.2
|
||||
IC1.8 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.9 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC2.10 <-> IC2.13 <-> R20.2
|
||||
IC2.11 <-> IC2.2
|
||||
IC2.12 <-> IC2.9 <-> R20.2
|
||||
IC2.4 <-> IC3.1
|
||||
IC2.6 <-> IC3.8
|
||||
IC3.3 <-> IC3.9 <-> R19.2 <-> R22.2
|
||||
IC2.6 <-> IC3.14
|
||||
IC3.13 <-> IC3.3 <-> R19.2 <-> R22.2
|
||||
IC3.5 <-> R18.2
|
||||
|
||||
Switch setup: [ Bass Switch.ON2:Range.ON2 ]
|
||||
|
||||
Blend.1 <-> C5.2 <-> C6.2 <-> Q1.2 <-> Q1.3 <-> R12.1
|
||||
Blend.2 <-> C17.1
|
||||
Blend.3 <-> C10.2 <-> C11.2 <-> IC1.14 <-> R15.1 <-> R16.2
|
||||
Blend.3 <-> C10.2 <-> C11.2 <-> IC1.8 <-> R15.1 <-> R16.2
|
||||
C1.2 <-> IC1.3 <-> IC1.5 <-> R1.1
|
||||
C10.1 <-> Lo Filter.2 <-> R14.2
|
||||
C11.1 <-> IC1.13 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.12 <-> Lo Filter.1
|
||||
C11.1 <-> IC1.9 <-> R16.1 <-> R17.1
|
||||
C12.1 <-> IC1.10 <-> Lo Filter.1
|
||||
C12.2 <-> C13.1 <-> C9.2 <-> D1.K <-> Q1.1 <-> R11.2 <-> R12.2 <-> R17.2
|
||||
C13.2 <-> D1.A <-> R20.1 <-> R21.1
|
||||
C14.1 <-> D3.K <-> IC3.2 <-> IC3.6 <-> R24.1
|
||||
C14.2 <-> C15.1 <-> R23.1
|
||||
C15.2 <-> D2.A <-> IC3.10 <-> IC3.13 <-> R24.2
|
||||
C16.1 <-> IC3.12
|
||||
C15.2 <-> D2.A <-> IC3.12 <-> IC3.9 <-> R24.2
|
||||
C16.1 <-> IC3.10
|
||||
C16.2 <-> C18.+ <-> C19.- <-> C2.2 <-> Hi Filter.1 <-> IC3.11 <-> R1.2 <-> R22.1 <-> R23.2 <-> R26.1 <-> R27.1 <-> R5.2
|
||||
C17.2 <-> R25.1
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.12 <-> IC2.14 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C18.- <-> C20.+ <-> IC1.11 <-> IC2.10 <-> IC2.3 <-> IC2.5 <-> IC2.7 <-> IC2.8 <-> R15.2 <-> R21.2 <-> R25.2 <-> R26.2 <-> R28.1 <-> R3.2 <-> R8.2
|
||||
C19.+ <-> C20.- <-> R27.2
|
||||
C2.1 <-> R4.2
|
||||
C3.1 <-> IC1.6 <-> R2.2 <-> R4.1
|
||||
C3.2 <-> C4.1 <-> R5.1
|
||||
C4.2 <-> R6.1
|
||||
C5.1 <-> IC1.1 <-> IC1.2 <-> R3.1 <-> R9.2
|
||||
C6.1 <-> IC1.10
|
||||
C6.1 <-> IC1.12
|
||||
C7.1 <-> R10.2 <-> R13.1
|
||||
C7.2 <-> C8.2 <-> C9.1 <-> Hi Filter.2
|
||||
C8.1 <-> R13.2 <-> R14.1
|
||||
D2.K <-> IC3.14
|
||||
D2.K <-> IC3.8
|
||||
D3.A <-> IC3.7
|
||||
IC1.4 <-> IC2.8 <-> IC3.4
|
||||
IC1.13 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC1.14 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.4 <-> IC2.14 <-> IC3.4
|
||||
IC1.7 <-> R18.1 <-> R19.1 <-> R2.1 <-> R6.2
|
||||
IC1.8 <-> R10.1 <-> R7.1 <-> R8.1
|
||||
IC1.9 <-> R11.1 <-> R7.2 <-> R9.1
|
||||
IC2.10 <-> IC2.13 <-> R20.2
|
||||
IC2.11 <-> IC2.2
|
||||
IC2.12 <-> IC2.9 <-> R20.2
|
||||
IC2.4 <-> IC3.1
|
||||
IC2.6 <-> IC3.8
|
||||
IC3.3 <-> IC3.9 <-> R19.2 <-> R22.2
|
||||
IC2.6 <-> IC3.14
|
||||
IC3.13 <-> IC3.3 <-> R19.2 <-> R22.2
|
||||
IC3.5 <-> R18.2
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@ Switch setup: [ ALL ]
|
||||
|
||||
C1.+ <-> Q1.3
|
||||
C1.- <-> C4.2 <-> R2.2 <-> R3.2 <-> VR2.1
|
||||
C2.+ <-> IC1.7 <-> VR1.3
|
||||
C2.+ <-> IC1.6 <-> VR1.3
|
||||
C2.- <-> IC1.3 <-> IC1.4
|
||||
C3.1 <-> Q1.1 <-> VR1.1 <-> VR1.2
|
||||
C3.2 <-> VR2.3
|
||||
C4.1 <-> IC1.6
|
||||
C5.+ <-> IC1.8
|
||||
C4.1 <-> IC1.7
|
||||
C5.+ <-> IC1.5
|
||||
IC1.1 <-> VR3.1 <-> VR3.2
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR3.3
|
||||
IC1.8 <-> VR3.3
|
||||
R1.2 <-> R3.1
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@ Switch setup: [ ALL ]
|
||||
|
||||
C1.+ <-> Q1.3
|
||||
C1.- <-> C4.2 <-> R2.2 <-> R3.2 <-> VR2.1
|
||||
C2.+ <-> IC1.7 <-> VR1.3
|
||||
C2.+ <-> IC1.6 <-> VR1.3
|
||||
C2.- <-> IC1.3 <-> IC1.4
|
||||
C3.1 <-> Q1.1 <-> VR1.1 <-> VR1.2
|
||||
C3.2 <-> VR2.3
|
||||
C4.1 <-> IC1.6
|
||||
C5.+ <-> IC1.8
|
||||
C4.1 <-> IC1.7
|
||||
C5.+ <-> IC1.5
|
||||
IC1.1 <-> VR3.1 <-> VR3.2
|
||||
IC1.2 <-> VR2.2
|
||||
IC1.5 <-> VR3.3
|
||||
IC1.8 <-> VR3.3
|
||||
R1.2 <-> R3.1
|
||||
|
||||
|
||||
@@ -4,39 +4,39 @@ Switch setup: [ ALL ]
|
||||
C10.1 <-> C9.1 <-> R22.1
|
||||
C10.2 <-> IC3.3 <-> R23.1
|
||||
C11.1 <-> C12.1 <-> R27.2
|
||||
C11.2 <-> IC3.9 <-> R28.2
|
||||
C12.2 <-> IC3.8 <-> R28.1 <-> R31.1
|
||||
C11.2 <-> IC3.13 <-> R28.2
|
||||
C12.2 <-> IC3.14 <-> R28.1 <-> R31.1
|
||||
C2.1 <-> IC1.7 <-> R5.1
|
||||
C2.2 <-> R6.1
|
||||
C3.1 <-> IC1.13 <-> IC1.14 <-> R8.1
|
||||
C3.1 <-> IC1.8 <-> IC1.9 <-> R8.1
|
||||
C3.2 <-> R12.1
|
||||
C4.1 <-> IC2.1 <-> R14.1
|
||||
C4.2 <-> R15.2
|
||||
C5.1 <-> IC2.7 <-> R18.2
|
||||
C5.2 <-> R19.1
|
||||
C6.1 <-> IC2.13 <-> IC2.14 <-> R21.1
|
||||
C6.1 <-> IC2.8 <-> IC2.9 <-> R21.1
|
||||
C7.1 <-> C8.1 <-> R21.2
|
||||
C9.2 <-> IC2.8 <-> IC2.9
|
||||
D1.A <-> D2.K <-> IC2.12 <-> R19.2
|
||||
C9.2 <-> IC2.13 <-> IC2.14
|
||||
D1.A <-> D2.K <-> IC2.10 <-> R19.2
|
||||
D1.K <-> D2.A <-> IC2.3 <-> IC3.10 <-> IC3.12 <-> IC4.3 <-> R1.2 <-> R10.2 <-> R16.1 <-> R17.2 <-> R2.2 <-> R20.1 <-> R23.2 <-> R25.2 <-> R4.1 <-> R7.2 <-> R9.2 <-> VR1.3
|
||||
IC1.10 <-> R8.2 <-> R9.1
|
||||
IC1.10 <-> R7.1
|
||||
IC1.11 <-> IC2.11 <-> IC3.11 <-> IC4.4
|
||||
IC1.12 <-> R7.1
|
||||
IC1.12 <-> R8.2 <-> R9.1
|
||||
IC1.13 <-> R10.1 <-> R11.2
|
||||
IC1.14 <-> R11.1
|
||||
IC1.2 <-> R2.1 <-> R3.1
|
||||
IC1.3 <-> R1.1
|
||||
IC1.4 <-> IC2.4 <-> IC3.4 <-> IC4.5
|
||||
IC1.4 <-> IC2.4 <-> IC3.4 <-> IC4.8
|
||||
IC1.6 <-> R4.2 <-> R5.2
|
||||
IC1.8 <-> R11.1
|
||||
IC1.9 <-> R10.1 <-> R11.2
|
||||
IC2.10 <-> R20.2
|
||||
IC2.12 <-> R20.2
|
||||
IC2.2 <-> R12.2 <-> R13.1 <-> R14.2
|
||||
IC2.5 <-> R15.1 <-> R16.2
|
||||
IC2.6 <-> R17.1 <-> R18.1
|
||||
IC3.1 <-> R22.2 <-> R24.1
|
||||
IC3.13 <-> R26.2 <-> R29.1
|
||||
IC3.14 <-> R29.2 <-> R30.2
|
||||
IC3.2 <-> IC3.5 <-> R24.2
|
||||
IC3.6 <-> IC3.7 <-> R26.1 <-> R27.1
|
||||
IC3.8 <-> R29.2 <-> R30.2
|
||||
IC3.9 <-> R26.2 <-> R29.1
|
||||
IC4.1 <-> R32.1 <-> VR1.1
|
||||
IC4.2 <-> R30.1 <-> R32.2
|
||||
IC4.6 <-> IC4.7
|
||||
|
||||
@@ -4,39 +4,39 @@ Switch setup: [ ALL ]
|
||||
C10.1 <-> C9.1 <-> R22.1
|
||||
C10.2 <-> IC3.3 <-> R23.1
|
||||
C11.1 <-> C12.1 <-> R27.2
|
||||
C11.2 <-> IC3.9 <-> R28.2
|
||||
C12.2 <-> IC3.8 <-> R28.1 <-> R31.1
|
||||
C11.2 <-> IC3.13 <-> R28.2
|
||||
C12.2 <-> IC3.14 <-> R28.1 <-> R31.1
|
||||
C2.1 <-> IC1.7 <-> R5.1
|
||||
C2.2 <-> R6.1
|
||||
C3.1 <-> IC1.13 <-> IC1.14 <-> R8.1
|
||||
C3.1 <-> IC1.8 <-> IC1.9 <-> R8.1
|
||||
C3.2 <-> R12.1
|
||||
C4.1 <-> IC2.1 <-> R14.1
|
||||
C4.2 <-> R15.2
|
||||
C5.1 <-> IC2.7 <-> R18.2
|
||||
C5.2 <-> R19.1
|
||||
C6.1 <-> IC2.13 <-> IC2.14 <-> R21.1
|
||||
C6.1 <-> IC2.8 <-> IC2.9 <-> R21.1
|
||||
C7.1 <-> C8.1 <-> R21.2
|
||||
C9.2 <-> IC2.8 <-> IC2.9
|
||||
D1.A <-> D2.K <-> IC2.12 <-> R19.2
|
||||
C9.2 <-> IC2.13 <-> IC2.14
|
||||
D1.A <-> D2.K <-> IC2.10 <-> R19.2
|
||||
D1.K <-> D2.A <-> IC2.3 <-> IC3.10 <-> IC3.12 <-> IC4.3 <-> R1.2 <-> R10.2 <-> R16.1 <-> R17.2 <-> R2.2 <-> R20.1 <-> R23.2 <-> R25.2 <-> R4.1 <-> R7.2 <-> R9.2 <-> VR1.3
|
||||
IC1.10 <-> R8.2 <-> R9.1
|
||||
IC1.10 <-> R7.1
|
||||
IC1.11 <-> IC2.11 <-> IC3.11 <-> IC4.4
|
||||
IC1.12 <-> R7.1
|
||||
IC1.12 <-> R8.2 <-> R9.1
|
||||
IC1.13 <-> R10.1 <-> R11.2
|
||||
IC1.14 <-> R11.1
|
||||
IC1.2 <-> R2.1 <-> R3.1
|
||||
IC1.3 <-> R1.1
|
||||
IC1.4 <-> IC2.4 <-> IC3.4 <-> IC4.5
|
||||
IC1.4 <-> IC2.4 <-> IC3.4 <-> IC4.8
|
||||
IC1.6 <-> R4.2 <-> R5.2
|
||||
IC1.8 <-> R11.1
|
||||
IC1.9 <-> R10.1 <-> R11.2
|
||||
IC2.10 <-> R20.2
|
||||
IC2.12 <-> R20.2
|
||||
IC2.2 <-> R12.2 <-> R13.1 <-> R14.2
|
||||
IC2.5 <-> R15.1 <-> R16.2
|
||||
IC2.6 <-> R17.1 <-> R18.1
|
||||
IC3.1 <-> R22.2 <-> R24.1
|
||||
IC3.13 <-> R26.2 <-> R29.1
|
||||
IC3.14 <-> R29.2 <-> R30.2
|
||||
IC3.2 <-> IC3.5 <-> R24.2
|
||||
IC3.6 <-> IC3.7 <-> R26.1 <-> R27.1
|
||||
IC3.8 <-> R29.2 <-> R30.2
|
||||
IC3.9 <-> R26.2 <-> R29.1
|
||||
IC4.1 <-> R32.1 <-> VR1.1
|
||||
IC4.2 <-> R30.1 <-> R32.2
|
||||
IC4.6 <-> IC4.7
|
||||
|
||||
@@ -5,24 +5,24 @@ Switch setup: [ ALL ]
|
||||
C1.1 <-> R2.2
|
||||
C1.2 <-> R1.2 <-> S1.3
|
||||
C10.- <-> C12.1 <-> C3.- <-> C5.- <-> C6.1 <-> C7.- <-> IC1.4 <-> IC2.4 <-> Level.1 <-> R1.1 <-> R10.2 <-> R11.2 <-> R12.1 <-> R15.1 <-> R4.1
|
||||
C11.1 <-> IC2.8 <-> Q2.1 <-> R15.2
|
||||
C11.1 <-> IC2.5 <-> Q2.1 <-> R15.2
|
||||
C11.2 <-> R14.2
|
||||
C12.2 <-> C6.2 <-> C7.+ <-> IC1.5 <-> IC2.5 <-> Q2.2 <-> Q2.3 <-> R3.2 <-> VR1.1 <-> VR1.2
|
||||
C12.2 <-> C6.2 <-> C7.+ <-> IC1.8 <-> IC2.8 <-> Q2.2 <-> Q2.3 <-> R3.2 <-> VR1.1 <-> VR1.2
|
||||
C2.1 <-> Q1.1 <-> R14.1 <-> R2.1
|
||||
C2.2 <-> IC1.3 <-> R3.1 <-> R4.2
|
||||
C3.+ <-> R5.1
|
||||
C4.1 <-> C8.+ <-> IC1.1 <-> R6.2 <-> R7.1 <-> R8.1
|
||||
C4.2 <-> Level.3
|
||||
C5.+ <-> IC1.8 <-> R8.2
|
||||
C5.+ <-> IC1.5 <-> R8.2
|
||||
C8.- <-> D1.A <-> R10.1
|
||||
C9.+ <-> IC1.6 <-> R9.2
|
||||
C9.+ <-> IC1.7 <-> R9.2
|
||||
C9.- <-> D2.A <-> R11.1
|
||||
IC1.2 <-> R5.2 <-> R6.1
|
||||
IC1.7 <-> R7.2 <-> R9.1
|
||||
IC1.6 <-> R7.2 <-> R9.1
|
||||
IC2.1 <-> IC2.2 <-> R13.1
|
||||
IC2.3 <-> Ratio.2
|
||||
IC2.6 <-> Q1.2 <-> Q1.3 <-> R16.2
|
||||
IC2.7 <-> R13.2 <-> R16.1
|
||||
IC2.6 <-> R13.2 <-> R16.1
|
||||
IC2.7 <-> Q1.2 <-> Q1.3 <-> R16.2
|
||||
Level.2 <-> S1.8
|
||||
R12.2 <-> Ratio.1
|
||||
S1.1 <-> S1.9
|
||||
|
||||
@@ -5,24 +5,24 @@ Switch setup: [ ALL ]
|
||||
C1.1 <-> R2.2
|
||||
C1.2 <-> R1.2
|
||||
C10.- <-> C12.1 <-> C3.- <-> C5.- <-> C6.1 <-> C7.- <-> IC1.4 <-> IC2.4 <-> Level.1 <-> R1.1 <-> R10.2 <-> R11.2 <-> R12.1 <-> R15.1 <-> R4.1
|
||||
C11.1 <-> IC2.8 <-> Q2.1 <-> R15.2
|
||||
C11.1 <-> IC2.5 <-> Q2.1 <-> R15.2
|
||||
C11.2 <-> R14.2
|
||||
C12.2 <-> C6.2 <-> C7.+ <-> IC1.5 <-> IC2.5 <-> Q2.2 <-> Q2.3 <-> R3.2 <-> VR1.1 <-> VR1.2
|
||||
C12.2 <-> C6.2 <-> C7.+ <-> IC1.8 <-> IC2.8 <-> Q2.2 <-> Q2.3 <-> R3.2 <-> VR1.1 <-> VR1.2
|
||||
C2.1 <-> Q1.1 <-> R14.1 <-> R2.1
|
||||
C2.2 <-> IC1.3 <-> R3.1 <-> R4.2
|
||||
C3.+ <-> R5.1
|
||||
C4.1 <-> C8.+ <-> IC1.1 <-> R6.2 <-> R7.1 <-> R8.1
|
||||
C4.2 <-> Level.3
|
||||
C5.+ <-> IC1.8 <-> R8.2
|
||||
C5.+ <-> IC1.5 <-> R8.2
|
||||
C8.- <-> D1.A <-> R10.1
|
||||
C9.+ <-> IC1.6 <-> R9.2
|
||||
C9.+ <-> IC1.7 <-> R9.2
|
||||
C9.- <-> D2.A <-> R11.1
|
||||
IC1.2 <-> R5.2 <-> R6.1
|
||||
IC1.7 <-> R7.2 <-> R9.1
|
||||
IC1.6 <-> R7.2 <-> R9.1
|
||||
IC2.1 <-> IC2.2 <-> R13.1
|
||||
IC2.3 <-> Ratio.2
|
||||
IC2.6 <-> Q1.2 <-> Q1.3 <-> R16.2
|
||||
IC2.7 <-> R13.2 <-> R16.1
|
||||
IC2.6 <-> R13.2 <-> R16.1
|
||||
IC2.7 <-> Q1.2 <-> Q1.3 <-> R16.2
|
||||
R12.2 <-> Ratio.1
|
||||
Thres.1 <-> Thres.2
|
||||
Thres.3 <-> VR1.3
|
||||
|
||||
@@ -2,14 +2,14 @@ Switch setup: [ ALL ]
|
||||
|
||||
C1.+ <-> C3.1 <-> P1.1 <-> P2B.1 <-> P2B.2 <-> R1.1 <-> R2.2 <-> R3.2
|
||||
C1.- <-> IC1.4 <-> R2.1
|
||||
C2.1 <-> C3.2 <-> IC1.8 <-> R7.1
|
||||
C2.1 <-> C3.2 <-> IC1.5 <-> R7.1
|
||||
C2.2 <-> P2A.1 <-> P2A.2
|
||||
D1.A <-> D2.K <-> R4.2 <-> R5.1
|
||||
D1.K <-> D2.A <-> IC1.6 <-> P1.3 <-> R5.2 <-> R6.1
|
||||
D1.K <-> D2.A <-> IC1.7 <-> P1.3 <-> R5.2 <-> R6.1
|
||||
IC1.1 <-> IC1.2
|
||||
IC1.3 <-> P1.2
|
||||
IC1.5 <-> R1.2 <-> S1.1
|
||||
IC1.7 <-> R3.1 <-> R4.1
|
||||
IC1.6 <-> R3.1 <-> R4.1
|
||||
IC1.8 <-> R1.2 <-> S1.1
|
||||
P2A.3 <-> R6.2
|
||||
P2B.3 <-> R7.2
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@ Switch setup: [ ALL ]
|
||||
|
||||
C1.+ <-> C3.1 <-> P1.1 <-> P2B.1 <-> P2B.2 <-> R1.1 <-> R2.2 <-> R3.2
|
||||
C1.- <-> IC1.4 <-> R2.1
|
||||
C2.1 <-> C3.2 <-> IC1.8 <-> R7.1
|
||||
C2.1 <-> C3.2 <-> IC1.5 <-> R7.1
|
||||
C2.2 <-> P2A.1 <-> P2A.2
|
||||
D1.A <-> D2.K <-> R4.2 <-> R5.1
|
||||
D1.K <-> D2.A <-> IC1.6 <-> P1.3 <-> R5.2 <-> R6.1
|
||||
D1.K <-> D2.A <-> IC1.7 <-> P1.3 <-> R5.2 <-> R6.1
|
||||
IC1.1 <-> IC1.2
|
||||
IC1.3 <-> P1.2
|
||||
IC1.5 <-> R1.2
|
||||
IC1.7 <-> R3.1 <-> R4.1
|
||||
IC1.6 <-> R3.1 <-> R4.1
|
||||
IC1.8 <-> R1.2
|
||||
P2A.3 <-> R6.2
|
||||
P2B.3 <-> R7.2
|
||||
|
||||
|
||||
+422
-305
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version" : "6.10.0",
|
||||
"version" : "6.9.0",
|
||||
"components" : [ {
|
||||
"name" : "Blank Board",
|
||||
"className" : "boards.BlankBoard",
|
||||
@@ -7142,45 +7142,6 @@
|
||||
"label" : "-"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Chassis Panel",
|
||||
"className" : "chassis.ChassisPanel",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "CP",
|
||||
"description" : "One side of a chassis, with or withouth rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Each instance is one side of the chassis: an exploded view of a whole chassis takes five panels, while the top, front and back alone take three, which is typical for pedals and amplifiers. The top panel goes in the centre with the front panel against its upper edge and the back panel against its lower edge; in the five-panel view the left side panel goes against its left edge and the right side panel against its right edge", "The panel 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" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#EEEEEE"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Cliff 1/4\" Jack",
|
||||
"className" : "electromechanical.CliffJack1_4",
|
||||
@@ -7672,66 +7633,6 @@
|
||||
}
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "Hole",
|
||||
"description" : "Drill hole marker for PCB, chassis or faceplate",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "3mm"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "ELC",
|
||||
"description" : "Elliptical chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Fuse Holder (Panel)",
|
||||
"className" : "electromechanical.FuseHolderPanel",
|
||||
@@ -8632,43 +8533,6 @@
|
||||
"label" : "Center"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "POLYC",
|
||||
"description" : "Polygonal chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Edges",
|
||||
"type" : "PointCount",
|
||||
"possibleValues" : [ "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"defaultValue" : "_4"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "RCA Jack",
|
||||
"className" : "electromechanical.RCAJack",
|
||||
@@ -8700,44 +8564,6 @@
|
||||
"label" : "Sleeve"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "RECTC",
|
||||
"description" : "Rectangular chassis cutout, with or without rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Rotary Selector Switch",
|
||||
"className" : "electromechanical.RotarySelectorSwitch",
|
||||
@@ -11587,6 +11413,242 @@
|
||||
"label" : "South Start"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "DS",
|
||||
"description" : "Control panel dial scale",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1in"
|
||||
}, {
|
||||
"name" : "Font",
|
||||
"type" : "Font"
|
||||
}, {
|
||||
"name" : "Marker Size",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Tick Width",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.5mm"
|
||||
}, {
|
||||
"name" : "Type",
|
||||
"type" : "DialScaleType",
|
||||
"possibleValues" : [ "Ticks_Mixed", "Ticks", "Ticks_0_5_5_11", "Dots", "Dots_Gradual", "Numeric_0_10", "Numeric_1_11", "Numeric_1_10", "Numeric_1_12", "Numeric_Even", "Numeric_Even_Ticks" ],
|
||||
"defaultValue" : "Ticks"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "Hole",
|
||||
"description" : "Drill hole marker for PCB, chassis or faceplate",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "3mm"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "ELC",
|
||||
"description" : "Elliptical chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Enclosure",
|
||||
"className" : "chassis.ChassisPanel",
|
||||
"category" : "Hardware",
|
||||
"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" ],
|
||||
"datasheetModels" : [ "1590LLB", "1590LB", "1590H", "1590Y", "1590A", "1590G", "1590G2", "1590S", "1590B", "1590B2", "1590BS", "1590B3", "1590BB", "1590BB2", "1590BBS", "1590Q", "1590U", "1590V", "1590C", "1590T", "1590CE", "1590N1", "1590KK", "1590K", "1590J", "1590XX", "1590X", "1590P1", "1590D", "1590DD", "1590E", "1590F", "1590R1", "1590DE", "1590EE", "1590BX2", "1590BX", "1550Q", "1550P", "1550A", "1550B", "1550D", "1550C", "1550M", "1550K", "1550L", "1550E", "1550F", "1550G", "1550H", "1550N", "1550J", "125B", "1441-9", "1441-15", "1441-6", "1441-8", "1441-12", "1441-10", "1441-14", "1441-16", "1441-22", "1441-29", "1441-18", "1441-26", "1441-30", "1441-34", "1441-24", "1441-28", "1441-20", "1441-32", "1441-36", "1441-38", "1441-33", "1441-40", "1441-42", "1444-45351", "1444-9", "1444-15", "1444-6415", "1444-84515", "1444-6", "1444-542", "1444-8", "1444-12", "1444-772", "1444-10", "1444-862", "1444-14", "1444-972", "1444-9552", "1444-16", "1444-1172", "1444-22", "1444-29", "1444-1372", "1444-18", "1444-26", "1444-30", "1444-17132", "1444-95525", "1444-10825", "1444-12825", "1444-643", "1444-753", "1444-9553", "1444-1053", "1444-1273", "1444-24", "1444-12103", "1444-12123", "1444-1463", "1444-14103", "1444-1573", "1444-1593", "1444-28", "1444-20", "1444-1763", "1444-1773", "1444-1783", "1444-32", "1444-17123", "1444-17133", "1444-17143", "1444-17173", "1444-33", "1444-17134", "1444-17154", "1444-17174", "1444-17105", "1444-17135", "1444-17156" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#EEEEEE"
|
||||
}, {
|
||||
"name" : "Height",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "36mm"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
}, {
|
||||
"name" : "Sides",
|
||||
"type" : "Sides",
|
||||
"possibleValues" : [ "ALL", "FRONT_AND_BACK", "NONE" ],
|
||||
"defaultValue" : "ALL"
|
||||
}, {
|
||||
"name" : "Spacing",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String",
|
||||
"defaultValue" : "125B"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "POLYC",
|
||||
"description" : "Polygonal chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Edges",
|
||||
"type" : "PointCount",
|
||||
"possibleValues" : [ "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"defaultValue" : "_4"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "RECTC",
|
||||
"description" : "Rectangular chassis cutout, with or without rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Auto-Wrap Label",
|
||||
"className" : "misc.WrapLabel",
|
||||
@@ -11688,52 +11750,6 @@
|
||||
"type" : "String",
|
||||
"defaultValue" : "X"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale",
|
||||
"category" : "Misc",
|
||||
"namePrefix" : "DS",
|
||||
"description" : "Control panel dial scale",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1in"
|
||||
}, {
|
||||
"name" : "Font",
|
||||
"type" : "Font"
|
||||
}, {
|
||||
"name" : "Marker Size",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Tick Width",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.5mm"
|
||||
}, {
|
||||
"name" : "Type",
|
||||
"type" : "DialScaleType",
|
||||
"possibleValues" : [ "Ticks_Mixed", "Ticks", "Ticks_0_5_5_11", "Dots", "Dots_Gradual", "Numeric_0_10", "Numeric_1_11", "Numeric_1_10", "Numeric_1_12", "Numeric_Even", "Numeric_Even_Ticks" ],
|
||||
"defaultValue" : "Ticks"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Image",
|
||||
"className" : "misc.Image",
|
||||
@@ -12229,6 +12245,7 @@
|
||||
"description" : "Axial electrolytic capacitor, similar to Sprague Atom, F&T, etc",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "It has no standing mode: keep the control points at least 'Length' apart, or the body is drawn past the holes" ],
|
||||
"datasheetModels" : [ "F&T Typ A", "Illinois TTA", "JJ ANH", "Sprague TVA Atom" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -12343,6 +12360,7 @@
|
||||
"description" : "Vertically mounted electrolytic capacitor, polarized or bipolar",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads", "'Diameter' is the can as seen from above; 'Height' is drawn only when 'Folded' lays the can on its side" ],
|
||||
"datasheetModels" : [ "Elna Silmic II", "Nichicon FG", "Nichicon FW", "Nichicon KZ", "Panasonic FC", "Panasonic FM", "Panasonic NHG" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -12467,6 +12485,7 @@
|
||||
"description" : "Axial film capacitor, similar to Mallory 150s",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point, or over the second with 'Reverse (standing)'; to keep it lying on a tighter footprint, reduce 'Length'" ],
|
||||
"datasheetModels" : [ "Mallory 150", "Solen Fast" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -12563,6 +12582,7 @@
|
||||
"description" : "Radial film capacitor, similar to Sprague Orange Drop",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads", "'Length' and 'Width' are the body as seen from above: 'Length' runs along the line between the leads and 'Width' across it, i.e. the datasheet width and thickness; body height is not drawn" ],
|
||||
"datasheetModels" : [ "Epcos MKT (5mm)", "Epcos MKT (7.5mm)", "Epcos MKT (10mm)", "Orange Drop 225P", "Orange Drop 715P", "Orange Drop 716P", "WIMA FKP-02 (2.5mm)", "WIMA FKP-2 (5mm)", "WIMA FKS-2 (5mm)", "WIMA MKP-2 (5mm)", "WIMA MKP-4", "WIMA MKS-02 (2.5mm)", "WIMA MKS-2 (5mm)", "WIMA MKS-4" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -12965,6 +12985,7 @@
|
||||
"description" : "Standard radial mica capacitor",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads" ],
|
||||
"datasheetModels" : [ "Cornell Dubilier CD10 (3.6mm)", "Cornell Dubilier CD15 (5.9mm)", "Cornell Dubilier CD19 (8.7mm)", "Cornell Dubilier CDV19 (8.7mm)", "Cornell Dubilier CD30 (11.1mm)", "Cornell Dubilier CDV30 (11.1mm)", "Cornell Dubilier CD42 (27mm)" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -13496,7 +13517,8 @@
|
||||
"namePrefix" : "R",
|
||||
"description" : "Resistor layout symbol",
|
||||
"creationMethod" : "POINT_BY_POINT",
|
||||
"notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'" ],
|
||||
"notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'", "A datasheet model sets the body size, shape and colors of a resistor family at one power rating but never the resistance; set 'Power Rating' together with the model to pick the matching size" ],
|
||||
"datasheetModels" : [ "Carbon Comp", "Carbon Film", "Metal Film", "Metal Oxide", "Ceramic", "Dale CMF55", "Dale CMF60" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -14004,58 +14026,6 @@
|
||||
"label" : "-"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Box (Schematic)",
|
||||
"className" : "schematic.SchematicBox",
|
||||
"category" : "Schematic Symbols",
|
||||
"namePrefix" : "U",
|
||||
"description" : "Generic schematic box with configurable terminals",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Body",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Bottom Nodes",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Display",
|
||||
"type" : "Display",
|
||||
"possibleValues" : [ "NAME", "VALUE", "NONE", "BOTH" ],
|
||||
"defaultValue" : "BOTH"
|
||||
}, {
|
||||
"name" : "Left Nodes",
|
||||
"type" : "String",
|
||||
"defaultValue" : "1,2"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Right Nodes",
|
||||
"type" : "String",
|
||||
"defaultValue" : "3,4"
|
||||
}, {
|
||||
"name" : "Top Nodes",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 4,
|
||||
"labels" : "sequential"
|
||||
}
|
||||
}, {
|
||||
"name" : "Bulb (Schematic)",
|
||||
"className" : "misc.BulbSchematicSymbol",
|
||||
@@ -16594,7 +16564,8 @@
|
||||
"namePrefix" : "IC",
|
||||
"description" : "Dual-in-line package IC",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the first row of pins runs down from it 'Pin Spacing' apart, the second row sits 'Row Spacing' to the right and the notch is at the anchor's end. The other orientations rotate this around the anchor" ],
|
||||
"notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the first row of pins runs down from it 'Pin Spacing' apart, the second row sits 'Row Spacing' to the right and the notch is at the anchor's end. The other orientations rotate this around the anchor", "'Pin Names' is a comma-separated list of pin names in pin-number order, starting with pin 1 next to the notch; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package, e.g. GND_1 and GND_2, while 1IN- and 2IN- are inputs of two separate sections", "A datasheet model is a part number such as TL072 or NE555 and sets 'Pins', 'Row Spacing', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model" ],
|
||||
"datasheetModels" : [ "TL061", "TL071", "TL081", "LM741", "LF356", "OPA134", "NE5534", "LF351", "UA741", "OP07", "LM308", "TL062", "TL072", "TL082", "NE5532", "JRC4558", "RC4580", "OPA2134", "OPA2604", "LM4562", "LM358", "LF353", "MC1458", "RC4558", "LM833", "TL022", "OP275", "LME49720", "OPA2132", "OPA2227", "TL074", "TL084", "OPA4134", "LM324", "TL064", "NE555", "ICM7555", "TLC555", "NE556", "ICM7556", "LM555", "LM13700", "CA3080", "SSM2164", "V2164", "LM13600", "AS3080", "AS2164", "LM386", "LM380", "TDA7052", "TDA2822", "MN3007", "MN3207", "BL3207", "BL3208A", "V3207", "MN3008", "MN3005", "BL3208B", "MN3101", "MN3102", "V3102", "PT2399", "NE570", "NE571", "SA571", "ICL7660", "TC1044", "MAX1044", "LT1054", "CD4049", "CD4069", "CD40106", "CD4011", "CD4013", "CD4017", "CD4066", "CD4051", "CD4053", "CD4016", "74HC14", "74HC4051", "PC817", "4N35", "6N138", "H11L1", "6N139", "ATtiny85", "ATmega328P", "ATtiny13A", "LM393" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -16615,11 +16586,6 @@
|
||||
"type" : "Display",
|
||||
"possibleValues" : [ "NAME", "VALUE", "NONE", "BOTH" ],
|
||||
"defaultValue" : "BOTH"
|
||||
}, {
|
||||
"name" : "Display Pin #s",
|
||||
"type" : "DisplayNumbers",
|
||||
"possibleValues" : [ "NO", "DIP", "CONNECTOR", "DIP_MIRROR", "CONNECTOR_MIRROR" ],
|
||||
"defaultValue" : "NO"
|
||||
}, {
|
||||
"name" : "Font Size Override",
|
||||
"type" : "Integer"
|
||||
@@ -16641,6 +16607,14 @@
|
||||
"type" : "Orientation",
|
||||
"possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ],
|
||||
"defaultValue" : "DEFAULT"
|
||||
}, {
|
||||
"name" : "Pin Labels",
|
||||
"type" : "DisplayNumbers",
|
||||
"possibleValues" : [ "NO", "NAMES", "DIP", "CONNECTOR", "DIP_MIRROR", "CONNECTOR_MIRROR" ],
|
||||
"defaultValue" : "NAMES"
|
||||
}, {
|
||||
"name" : "Pin Names",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Pin Spacing",
|
||||
"type" : "Size",
|
||||
@@ -16663,22 +16637,10 @@
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"drivers" : [ "Display Pin #s", "Pins" ],
|
||||
"drivers" : [ "Pin Labels", "Pins" ],
|
||||
"variants" : [ {
|
||||
"when" : {
|
||||
"Display Pin #s" : "NO"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "sequential",
|
||||
"pinCountSamples" : {
|
||||
"_4" : 4,
|
||||
"_16" : 16,
|
||||
"_28" : 28,
|
||||
"_40" : 40
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Display Pin #s" : "DIP"
|
||||
"Pin Labels" : "NO"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
@@ -16708,7 +16670,67 @@
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Display Pin #s" : "CONNECTOR"
|
||||
"Pin Labels" : "NAMES"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
"pinCountSamples" : {
|
||||
"_4" : 4,
|
||||
"_16" : 16,
|
||||
"_28" : 28,
|
||||
"_40" : 40
|
||||
},
|
||||
"example" : {
|
||||
"when" : {
|
||||
"Pins" : "_4"
|
||||
},
|
||||
"pins" : [ {
|
||||
"i" : 0,
|
||||
"label" : "1"
|
||||
}, {
|
||||
"i" : 1,
|
||||
"label" : "2"
|
||||
}, {
|
||||
"i" : 2,
|
||||
"label" : "4"
|
||||
}, {
|
||||
"i" : 3,
|
||||
"label" : "3"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Pin Labels" : "DIP"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
"pinCountSamples" : {
|
||||
"_4" : 4,
|
||||
"_16" : 16,
|
||||
"_28" : 28,
|
||||
"_40" : 40
|
||||
},
|
||||
"example" : {
|
||||
"when" : {
|
||||
"Pins" : "_4"
|
||||
},
|
||||
"pins" : [ {
|
||||
"i" : 0,
|
||||
"label" : "1"
|
||||
}, {
|
||||
"i" : 1,
|
||||
"label" : "2"
|
||||
}, {
|
||||
"i" : 2,
|
||||
"label" : "4"
|
||||
}, {
|
||||
"i" : 3,
|
||||
"label" : "3"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Pin Labels" : "CONNECTOR"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
@@ -16738,7 +16760,7 @@
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Display Pin #s" : "DIP_MIRROR"
|
||||
"Pin Labels" : "DIP_MIRROR"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
@@ -16768,7 +16790,7 @@
|
||||
}
|
||||
}, {
|
||||
"when" : {
|
||||
"Display Pin #s" : "CONNECTOR_MIRROR"
|
||||
"Pin Labels" : "CONNECTOR_MIRROR"
|
||||
},
|
||||
"pinCountExpression" : "Pins",
|
||||
"labels" : "custom",
|
||||
@@ -17068,6 +17090,8 @@
|
||||
"namePrefix" : "IC",
|
||||
"description" : "Multiwatt package IC typically used for audio amplifiers of high power applications",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The leads are staggered in two rows and numbered alternately along the package: pin 1 is the first control point, pins 1, 3, 5, ... form the row bent forward in front of the body, away from the heatsink tab, and pins 2, 4, ... the row that leaves the body from underneath. 'Type' picks the package: Multiwatt 11 for LM3886 or TDA7265, Multiwatt 15 for TDA7293 or TDA7294", "'Pin Names' is a comma-separated list of pin names in pin-number order; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package", "A datasheet model is a part number such as LM3886 and sets 'Type', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model" ],
|
||||
"datasheetModels" : [ "LM3886", "TDA7265", "TDA7293", "TDA7294" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -17101,6 +17125,14 @@
|
||||
"type" : "Orientation",
|
||||
"possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ],
|
||||
"defaultValue" : "DEFAULT"
|
||||
}, {
|
||||
"name" : "Pin Labels",
|
||||
"type" : "PinLabels",
|
||||
"possibleValues" : [ "NONE", "NAMES", "NUMBERS" ],
|
||||
"defaultValue" : "NAMES"
|
||||
}, {
|
||||
"name" : "Pin Names",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Tab",
|
||||
"type" : "Color",
|
||||
@@ -17126,14 +17158,90 @@
|
||||
"when" : {
|
||||
"Type" : "MULTIWATT_11"
|
||||
},
|
||||
"pinCount" : 11,
|
||||
"labels" : "sequential"
|
||||
"pins" : [ {
|
||||
"i" : 0,
|
||||
"label" : "1"
|
||||
}, {
|
||||
"i" : 1,
|
||||
"label" : "3"
|
||||
}, {
|
||||
"i" : 2,
|
||||
"label" : "5"
|
||||
}, {
|
||||
"i" : 3,
|
||||
"label" : "7"
|
||||
}, {
|
||||
"i" : 4,
|
||||
"label" : "9"
|
||||
}, {
|
||||
"i" : 5,
|
||||
"label" : "11"
|
||||
}, {
|
||||
"i" : 6,
|
||||
"label" : "2"
|
||||
}, {
|
||||
"i" : 7,
|
||||
"label" : "4"
|
||||
}, {
|
||||
"i" : 8,
|
||||
"label" : "6"
|
||||
}, {
|
||||
"i" : 9,
|
||||
"label" : "8"
|
||||
}, {
|
||||
"i" : 10,
|
||||
"label" : "10"
|
||||
} ]
|
||||
}, {
|
||||
"when" : {
|
||||
"Type" : "MULTIWATT_15"
|
||||
},
|
||||
"pinCount" : 15,
|
||||
"labels" : "sequential"
|
||||
"pins" : [ {
|
||||
"i" : 0,
|
||||
"label" : "1"
|
||||
}, {
|
||||
"i" : 1,
|
||||
"label" : "3"
|
||||
}, {
|
||||
"i" : 2,
|
||||
"label" : "5"
|
||||
}, {
|
||||
"i" : 3,
|
||||
"label" : "7"
|
||||
}, {
|
||||
"i" : 4,
|
||||
"label" : "9"
|
||||
}, {
|
||||
"i" : 5,
|
||||
"label" : "11"
|
||||
}, {
|
||||
"i" : 6,
|
||||
"label" : "13"
|
||||
}, {
|
||||
"i" : 7,
|
||||
"label" : "15"
|
||||
}, {
|
||||
"i" : 8,
|
||||
"label" : "2"
|
||||
}, {
|
||||
"i" : 9,
|
||||
"label" : "4"
|
||||
}, {
|
||||
"i" : 10,
|
||||
"label" : "6"
|
||||
}, {
|
||||
"i" : 11,
|
||||
"label" : "8"
|
||||
}, {
|
||||
"i" : 12,
|
||||
"label" : "10"
|
||||
}, {
|
||||
"i" : 13,
|
||||
"label" : "12"
|
||||
}, {
|
||||
"i" : 14,
|
||||
"label" : "14"
|
||||
} ]
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
@@ -17143,7 +17251,8 @@
|
||||
"namePrefix" : "IC",
|
||||
"description" : "Single-in-line package IC",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the pins run straight down from it 'Pin Spacing' apart and the indent is at the anchor's end of the body. The other orientations rotate this around the anchor" ],
|
||||
"notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the pins run straight down from it 'Pin Spacing' apart and the indent is at the anchor's end of the body. The other orientations rotate this around the anchor", "The first control point is pin 1. 'Pin Names' is a comma-separated list of pin names in pin-number order; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package, while 1IN and 2IN are separate channels", "A datasheet model is a part number such as LA4440 and sets 'Pins', 'Pin Spacing', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model" ],
|
||||
"datasheetModels" : [ "LA4440", "LA4485", "LA4425A", "TA7205AP", "TDA1013B", "TDA1010A", "TDA1521A", "TDA7056", "TDA7056A", "BA5406", "BA5417", "BA3121N" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
@@ -17182,6 +17291,14 @@
|
||||
"type" : "Orientation",
|
||||
"possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ],
|
||||
"defaultValue" : "DEFAULT"
|
||||
}, {
|
||||
"name" : "Pin Labels",
|
||||
"type" : "PinLabels",
|
||||
"possibleValues" : [ "NONE", "NAMES", "NUMBERS" ],
|
||||
"defaultValue" : "NAMES"
|
||||
}, {
|
||||
"name" : "Pin Names",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Pin Spacing",
|
||||
"type" : "Size",
|
||||
@@ -18618,7 +18735,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -18719,7 +18836,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -18756,7 +18873,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
|
||||
+20
-22
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version" : "6.10.0",
|
||||
"version" : "6.9.0",
|
||||
"categories" : {
|
||||
"Boards" : [ {
|
||||
"name" : "Blank Board",
|
||||
@@ -174,9 +174,6 @@
|
||||
}, {
|
||||
"name" : "9V Battery Snap",
|
||||
"className" : "electromechanical.BatterySnap9V"
|
||||
}, {
|
||||
"name" : "Chassis Panel",
|
||||
"className" : "chassis.ChassisPanel"
|
||||
}, {
|
||||
"name" : "Cliff 1/4\" Jack",
|
||||
"className" : "electromechanical.CliffJack1_4"
|
||||
@@ -189,12 +186,6 @@
|
||||
}, {
|
||||
"name" : "DIP Switch",
|
||||
"className" : "electromechanical.DIPSwitch"
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole"
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout"
|
||||
}, {
|
||||
"name" : "Fuse Holder (Panel)",
|
||||
"className" : "electromechanical.FuseHolderPanel"
|
||||
@@ -225,15 +216,9 @@
|
||||
}, {
|
||||
"name" : "Plastic DC Jack",
|
||||
"className" : "electromechanical.PlasticDCJack"
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout"
|
||||
}, {
|
||||
"name" : "RCA Jack",
|
||||
"className" : "electromechanical.RCAJack"
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout"
|
||||
}, {
|
||||
"name" : "Rotary Selector Switch",
|
||||
"className" : "electromechanical.RotarySelectorSwitch"
|
||||
@@ -293,6 +278,25 @@
|
||||
"name" : "Stingray Bass Pickup",
|
||||
"className" : "guitar.StingrayBassPickup"
|
||||
} ],
|
||||
"Hardware" : [ {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale"
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole"
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout"
|
||||
}, {
|
||||
"name" : "Enclosure",
|
||||
"className" : "chassis.ChassisPanel"
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout"
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout"
|
||||
} ],
|
||||
"Misc" : [ {
|
||||
"name" : "Auto-Wrap Label",
|
||||
"className" : "misc.WrapLabel"
|
||||
@@ -302,9 +306,6 @@
|
||||
}, {
|
||||
"name" : "Common Node",
|
||||
"className" : "misc.CommonNode"
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale"
|
||||
}, {
|
||||
"name" : "Image",
|
||||
"className" : "misc.Image"
|
||||
@@ -389,9 +390,6 @@
|
||||
}, {
|
||||
"name" : "Battery (Schematic)",
|
||||
"className" : "misc.BatterySymbol"
|
||||
}, {
|
||||
"name" : "Box (Schematic)",
|
||||
"className" : "schematic.SchematicBox"
|
||||
}, {
|
||||
"name" : "Bulb (Schematic)",
|
||||
"className" : "misc.BulbSchematicSymbol"
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.schematic.ISchematicFactory;
|
||||
|
||||
/**
|
||||
* Entity class used to describe a component type.
|
||||
@@ -57,7 +56,6 @@ public class ComponentType implements Serializable {
|
||||
private boolean enableCache;
|
||||
private List<String[]> datasheet;
|
||||
private int datasheetCreationStepCount;
|
||||
private Class<? extends ISchematicFactory> schematicFactoryClass;
|
||||
|
||||
public ComponentType() {
|
||||
}
|
||||
@@ -160,18 +158,6 @@ public class ComponentType implements Serializable {
|
||||
return datasheetCreationStepCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the declared {@link ISchematicFactory} class for this type, or {@code null} when the
|
||||
* type relies on the generic box fallback.
|
||||
*/
|
||||
public Class<? extends ISchematicFactory> getSchematicFactoryClass() {
|
||||
return schematicFactoryClass;
|
||||
}
|
||||
|
||||
public void setSchematicFactoryClass(Class<? extends ISchematicFactory> schematicFactoryClass) {
|
||||
this.schematicFactoryClass = schematicFactoryClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.List;
|
||||
import org.diylc.netlist.INetlistParser;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.NetlistException;
|
||||
import org.diylc.presenter.ContinuityArea;
|
||||
|
||||
/**
|
||||
* Interface for {@link Netlist} related operations.
|
||||
@@ -43,14 +42,7 @@ public interface INetlistProcessor {
|
||||
* @throws NetlistException
|
||||
*/
|
||||
List<Netlist> extractNetlists(boolean includeSwitches) throws NetlistException;
|
||||
|
||||
/**
|
||||
* @return the current continuity areas as computed by the drawing manager. Needed to build a
|
||||
* netlist outside of the presenter, e.g. for schematic generation.
|
||||
*/
|
||||
List<ContinuityArea> getContinuityAreas();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Finds all available {@link INetlistAnalyzer} implementations.
|
||||
*
|
||||
|
||||
@@ -68,7 +68,6 @@ public class Project implements Serializable, Cloneable {
|
||||
private Set<IDIYComponent<?>> lockedComponents;
|
||||
private Set<Integer> hiddenLayers;
|
||||
private Font font = DEFAULT_FONT;
|
||||
private SchematicView schematicView;
|
||||
|
||||
public Project() {
|
||||
components = new ArrayList<IDIYComponent<?>>();
|
||||
@@ -197,30 +196,6 @@ public class Project implements Serializable, Cloneable {
|
||||
return hiddenLayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the schematic representation of this project, or {@code null} if the user has never
|
||||
* opened the schematic view. Use {@link #getOrCreateSchematicView()} when a non-null
|
||||
* instance is required.
|
||||
*/
|
||||
public SchematicView getSchematicView() {
|
||||
return schematicView;
|
||||
}
|
||||
|
||||
public void setSchematicView(SchematicView schematicView) {
|
||||
this.schematicView = schematicView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily initializes and returns the {@link SchematicView}. Calling this method causes the
|
||||
* schematic data to be persisted with the project from now on.
|
||||
*/
|
||||
public SchematicView getOrCreateSchematicView() {
|
||||
if (schematicView == null) {
|
||||
schematicView = new SchematicView();
|
||||
}
|
||||
return schematicView;
|
||||
}
|
||||
|
||||
public VersionNumber getFileVersion() {
|
||||
return fileVersion;
|
||||
}
|
||||
@@ -348,11 +323,6 @@ public class Project implements Serializable, Cloneable {
|
||||
return false;
|
||||
} else if (!hiddenLayers.equals(other.hiddenLayers))
|
||||
return false;
|
||||
if (schematicView == null) {
|
||||
if (other.schematicView != null)
|
||||
return false;
|
||||
} else if (!schematicView.equals(other.schematicView))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -388,10 +358,7 @@ public class Project implements Serializable, Cloneable {
|
||||
project.setWidth(this.getWidth());
|
||||
project.getLockedLayers().addAll(this.getLockedLayers());
|
||||
project.getHiddenLayers().addAll(this.getHiddenLayers());
|
||||
project.setFont(this.getFont());
|
||||
if (this.schematicView != null) {
|
||||
project.setSchematicView(this.schematicView.clone());
|
||||
}
|
||||
project.setFont(this.getFont());
|
||||
|
||||
Map<IDIYComponent<?>, IDIYComponent<?>> cloneMap = new HashMap<IDIYComponent<?>, IDIYComponent<?>>();
|
||||
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
|
||||
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.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
/**
|
||||
* Schematic representation of a physical layout {@link Project}. It is derived from the layout via
|
||||
* the netlist infrastructure and rendered using the regular DIYLC drawing pipeline. It is embedded
|
||||
* in {@link Project} and serialized alongside the rest of the project data, but only after the user
|
||||
* opens the schematic view for the first time (the field stays {@code null} until then, keeping
|
||||
* files unchanged for users who never use the feature).
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class SchematicView implements Serializable, Cloneable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size DEFAULT_WIDTH = new Size(42d, SizeUnit.cm);
|
||||
public static Size DEFAULT_HEIGHT = new Size(30d, SizeUnit.cm);
|
||||
public static Size DEFAULT_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
/** Schematic components: symbols and auto-routed wires, sorted by z-order ascending. */
|
||||
private List<IDIYComponent<?>> components;
|
||||
|
||||
/**
|
||||
* Maps a physical component id ({@link IDIYComponent#getId()}) to the ids of the schematic
|
||||
* symbol(s) that were spawned from it. The relation is 1:N to support multi-section components
|
||||
* such as dual triodes or dual op-amps.
|
||||
*/
|
||||
private Map<UUID, List<UUID>> physicalToSchematicMap;
|
||||
|
||||
private Size width;
|
||||
private Size height;
|
||||
private Size gridSpacing;
|
||||
|
||||
public SchematicView() {
|
||||
this.components = new ArrayList<IDIYComponent<?>>();
|
||||
this.physicalToSchematicMap = new LinkedHashMap<UUID, List<UUID>>();
|
||||
this.width = DEFAULT_WIDTH;
|
||||
this.height = DEFAULT_HEIGHT;
|
||||
this.gridSpacing = DEFAULT_GRID_SPACING;
|
||||
}
|
||||
|
||||
public List<IDIYComponent<?>> getComponents() {
|
||||
if (components == null) {
|
||||
components = new ArrayList<IDIYComponent<?>>();
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(List<IDIYComponent<?>> components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public Map<UUID, List<UUID>> getPhysicalToSchematicMap() {
|
||||
if (physicalToSchematicMap == null) {
|
||||
physicalToSchematicMap = new LinkedHashMap<UUID, List<UUID>>();
|
||||
}
|
||||
return physicalToSchematicMap;
|
||||
}
|
||||
|
||||
public void setPhysicalToSchematicMap(Map<UUID, List<UUID>> physicalToSchematicMap) {
|
||||
this.physicalToSchematicMap = physicalToSchematicMap;
|
||||
}
|
||||
|
||||
public Size getWidth() {
|
||||
return width == null ? DEFAULT_WIDTH : width;
|
||||
}
|
||||
|
||||
public void setWidth(Size width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Size getHeight() {
|
||||
return height == null ? DEFAULT_HEIGHT : height;
|
||||
}
|
||||
|
||||
public void setHeight(Size height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Size getGridSpacing() {
|
||||
return gridSpacing == null ? DEFAULT_GRID_SPACING : gridSpacing;
|
||||
}
|
||||
|
||||
public void setGridSpacing(Size gridSpacing) {
|
||||
this.gridSpacing = gridSpacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the schematic has already been generated at least once.
|
||||
*/
|
||||
public boolean isGenerated() {
|
||||
return components != null && !components.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicView clone() {
|
||||
SchematicView clone = new SchematicView();
|
||||
clone.setWidth(this.getWidth());
|
||||
clone.setHeight(this.getHeight());
|
||||
clone.setGridSpacing(this.getGridSpacing());
|
||||
for (IDIYComponent<?> component : this.getComponents()) {
|
||||
try {
|
||||
clone.getComponents().add(component.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<UUID, List<UUID>> entry : this.getPhysicalToSchematicMap().entrySet()) {
|
||||
clone.getPhysicalToSchematicMap().put(entry.getKey(), new ArrayList<UUID>(entry.getValue()));
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((components == null) ? 0 : components.hashCode());
|
||||
result = prime * result + ((width == null) ? 0 : width.hashCode());
|
||||
result = prime * result + ((height == null) ? 0 : height.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
SchematicView other = (SchematicView) obj;
|
||||
if (components == null) {
|
||||
if (other.components != null)
|
||||
return false;
|
||||
} else if (other.components == null || components.size() != other.components.size()) {
|
||||
return false;
|
||||
} else {
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
if (!components.get(i).equalsTo(other.components.get(i)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (width == null ? other.width != null : !width.equals(other.width))
|
||||
return false;
|
||||
if (height == null ? other.height != null : !height.equals(other.height))
|
||||
return false;
|
||||
if (gridSpacing == null ? other.gridSpacing != null : !gridSpacing.equals(other.gridSpacing))
|
||||
return false;
|
||||
return new HashMap<UUID, List<UUID>>(getPhysicalToSchematicMap())
|
||||
.equals(new HashMap<UUID, List<UUID>>(other.getPhysicalToSchematicMap()));
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.awt.geom.Point2D;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Template {
|
||||
|
||||
@@ -35,6 +36,8 @@ public class Template {
|
||||
@Deprecated
|
||||
private boolean defaultFlag;
|
||||
private LocalDateTime createdOn;
|
||||
// set only on a factory variant that has been withdrawn, which then carries nothing but its name
|
||||
private LocalDateTime deletedOn;
|
||||
|
||||
public Template() {
|
||||
}
|
||||
@@ -82,11 +85,20 @@ public class Template {
|
||||
this.createdOn = createdOn;
|
||||
}
|
||||
|
||||
public LocalDateTime getDeletedOn() {
|
||||
return deletedOn;
|
||||
}
|
||||
|
||||
public void setDeletedOn(LocalDateTime deletedOn) {
|
||||
this.deletedOn = deletedOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((createdOn == null) ? 0 : createdOn.hashCode());
|
||||
result = prime * result + ((deletedOn == null) ? 0 : deletedOn.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((points == null) ? 0 : points.hashCode());
|
||||
result = prime * result + ((values == null) ? 0 : values.hashCode());
|
||||
@@ -107,6 +119,9 @@ public class Template {
|
||||
return false;
|
||||
} else if (!createdOn.equals(other.createdOn))
|
||||
return false;
|
||||
if (!Objects.equals(deletedOn, other.deletedOn)) {
|
||||
return false;
|
||||
}
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.diylc.common.DefaultComponentTransformer;
|
||||
import org.diylc.common.IComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.schematic.ISchematicFactory;
|
||||
|
||||
/**
|
||||
* Annotation that needs to be used for each {@link IDIYComponent} implementation. Describes
|
||||
@@ -131,13 +130,12 @@ public @interface ComponentDescriptor {
|
||||
int datasheetCreationStepCount() default 0;
|
||||
|
||||
/**
|
||||
* Strategy that converts an instance of this component type into one or more schematic symbols
|
||||
* when the schematic view is generated. When left at the default ({@link ISchematicFactory}
|
||||
* itself, used here only as a "none" marker), a generic box symbol is produced instead.
|
||||
* If datasheet is enabled, the column that names the part a row describes. It is what the AI
|
||||
* refers to a model by, while the columns before it only group rows in the toolbox.
|
||||
*
|
||||
* @return the schematic factory class, or {@code ISchematicFactory.class} when none is declared
|
||||
* @return index of the model name column
|
||||
*/
|
||||
Class<? extends ISchematicFactory> schematicFactory() default ISchematicFactory.class;
|
||||
int datasheetModelColumn() default 0;
|
||||
|
||||
/**
|
||||
* @return true if the component type should not be listed in the palette (toolbox and
|
||||
|
||||
+13
@@ -52,6 +52,7 @@ import org.diylc.plugins.chatbot.model.AiCatalogIndexEntry;
|
||||
import org.diylc.plugins.chatbot.model.pinout.AiPinout;
|
||||
import org.diylc.presenter.ComparatorFactory;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.DatasheetService;
|
||||
import org.diylc.presenter.ReleaseHistory;
|
||||
|
||||
/**
|
||||
@@ -175,6 +176,18 @@ public class ComponentCatalogGenerator {
|
||||
comp.put("notes", notes);
|
||||
}
|
||||
|
||||
// a datasheet lists one row per part, so the model names are the distinct values of its model
|
||||
// column
|
||||
List<String[]> datasheet = ct.getDatasheet();
|
||||
if (datasheet != null) {
|
||||
int column = DatasheetService.getInstance().getModelColumn(ct.getInstanceClass());
|
||||
List<String> models = datasheet.stream()
|
||||
.map(row -> row[column].trim())
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
comp.put("datasheetModels", models);
|
||||
}
|
||||
|
||||
// Extract editable properties
|
||||
try {
|
||||
List<PropertyWrapper> properties = processor.extractProperties(ct.getInstanceClass());
|
||||
|
||||
@@ -118,16 +118,10 @@ public class ComparatorFactory {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
ComponentType type1 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o1.getClass());
|
||||
ComponentType type2 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o2.getClass());
|
||||
return Double.valueOf(type1.getZOrder()).compareTo(type2.getZOrder());
|
||||
return Double.compare(ComponentProcessor.getInstance().getZOrder(o1),
|
||||
ComponentProcessor.getInstance().getZOrder(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,11 +133,6 @@ public class ComponentProcessor {
|
||||
new ComponentType(name, description, creationMethod, category, namePrefix, author, icon, clazz, zOrder,
|
||||
flexibleZOrder, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag, cacheDrawing, datasheet,
|
||||
datasheetCreationStepCount);
|
||||
Class<? extends org.diylc.schematic.ISchematicFactory> schematicFactory =
|
||||
clazz.getAnnotation(ComponentDescriptor.class).schematicFactory();
|
||||
if (schematicFactory != null && schematicFactory != org.diylc.schematic.ISchematicFactory.class) {
|
||||
componentType.setSchematicFactoryClass(schematicFactory);
|
||||
}
|
||||
componentTypeMap.put(clazz.getName(), componentType);
|
||||
return componentType;
|
||||
}
|
||||
@@ -414,6 +409,31 @@ public class ComponentProcessor {
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the z-order (layer) of the component. A {@link CompositeComponent} sits on the lowest
|
||||
* layer among its children rather than the one its class declares: it is drawn as a
|
||||
* single unit, so it takes one place in the stack, and that place has to be under
|
||||
* whatever is later put on top of it. A block of chassis panels therefore stays on the
|
||||
* chassis layer, and a block built from a board, pads and silkscreen text on the board
|
||||
* layer.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public double getZOrder(IDIYComponent<?> component) {
|
||||
if (component instanceof CompositeComponent) {
|
||||
double zOrder = Double.MAX_VALUE;
|
||||
for (IDIYComponent<?> child : ((CompositeComponent) component).getChildComponents()) {
|
||||
zOrder = Math.min(zOrder, getZOrder(child));
|
||||
}
|
||||
if (zOrder < Double.MAX_VALUE) {
|
||||
return zOrder;
|
||||
}
|
||||
}
|
||||
ComponentType type =
|
||||
extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
// internal types without a descriptor do not take part in layering
|
||||
return type == null ? Double.MAX_VALUE : type.getZOrder();
|
||||
}
|
||||
|
||||
public static boolean hasStickyPoint(IDIYComponent<?> c) {
|
||||
for (int i = 0; i < c.getControlPointCount(); i++)
|
||||
if (c.isControlPointSticky(0))
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.apache.log4j.Logger;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.measures.AbstractMeasure;
|
||||
import org.diylc.core.measures.Unit;
|
||||
|
||||
@@ -128,6 +129,16 @@ public class DatasheetService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz
|
||||
* @return the datasheet column that names the model a row describes, see
|
||||
* {@link ComponentDescriptor#datasheetModelColumn()}.
|
||||
*/
|
||||
public int getModelColumn(Class<?> clazz) {
|
||||
ComponentDescriptor descriptor = clazz.getAnnotation(ComponentDescriptor.class);
|
||||
return descriptor == null ? 0 : descriptor.datasheetModelColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the rows of a datasheet series by its name, ignoring case. When no series has exactly
|
||||
* that name, every series whose name contains it is returned instead.
|
||||
@@ -141,14 +152,16 @@ public class DatasheetService {
|
||||
if (datasheet == null || series == null || series.isBlank()) {
|
||||
return new ArrayList<String[]>();
|
||||
}
|
||||
int column = getModelColumn(clazz);
|
||||
String name = series.trim();
|
||||
List<String[]> rows = datasheet.stream()
|
||||
.filter(row -> row.length > 0 && row[0].trim().equalsIgnoreCase(name))
|
||||
.filter(row -> row.length > column && row[column].trim().equalsIgnoreCase(name))
|
||||
.collect(Collectors.toList());
|
||||
if (rows.isEmpty()) {
|
||||
String lowerName = name.toLowerCase();
|
||||
rows = datasheet.stream()
|
||||
.filter(row -> row.length > 0 && row[0].trim().toLowerCase().contains(lowerName))
|
||||
.filter(row -> row.length > column
|
||||
&& row[column].trim().toLowerCase().contains(lowerName))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return rows;
|
||||
@@ -170,7 +183,7 @@ public class DatasheetService {
|
||||
return null;
|
||||
}
|
||||
Object value = component.getValue();
|
||||
if (value == null) {
|
||||
if (value == null || (value instanceof String text && text.isBlank())) {
|
||||
// nothing to preserve, but nothing to choose by either
|
||||
return rows.size() == 1 ? rows.get(0) : null;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,8 @@ public class GroupAndLockIndex {
|
||||
if (componentType == null) {
|
||||
return false;
|
||||
}
|
||||
return project.getLockedLayers().contains((int) Math.round(componentType.getZOrder()))
|
||||
return project.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)))
|
||||
|| project.getLockedComponents().contains(component);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,7 +494,8 @@ public class Presenter implements IPlugInPort {
|
||||
// for internal types
|
||||
if (componentType == null)
|
||||
return true;
|
||||
return !currentProject.getHiddenLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return !currentProject.getHiddenLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1076,10 +1077,9 @@ public class Presenter implements IPlugInPort {
|
||||
Iterator<IDIYComponent<?>> i = newSelection.iterator();
|
||||
while (i.hasNext()) {
|
||||
IDIYComponent<?> c = i.next();
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
if ((int) type.getZOrder() != layer)
|
||||
if ((int) ComponentProcessor.getInstance().getZOrder(c) != layer) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSelection(newSelection);
|
||||
@@ -2229,6 +2229,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2236,11 +2237,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index > 0) {
|
||||
IDIYComponent<?> componentBefore = currentProject.getComponents().get(index - 1);
|
||||
if (!selectedComponents.contains(componentBefore)) {
|
||||
ComponentType componentBeforeType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentBefore.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentBeforeType.getZOrder()) < Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentBefore)) < layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2278,6 +2276,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2285,11 +2284,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index < currentProject.getComponents().size() - 1) {
|
||||
IDIYComponent<?> componentAfter = currentProject.getComponents().get(index + 1);
|
||||
if (!selectedComponents.contains(componentAfter)) {
|
||||
ComponentType componentAfterType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentAfter.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentAfterType.getZOrder()) > Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentAfter)) > layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2684,13 +2680,9 @@ public class Presenter implements IPlugInPort {
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addComponent(IDIYComponent<?> component, boolean allowAutoCreate) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > 0
|
||||
&& ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass()).getZOrder() < ComponentProcessor
|
||||
.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) currentProject.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > 0 && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
if (index < currentProject.getComponents().size()) {
|
||||
@@ -2724,12 +2716,9 @@ public class Presenter implements IPlugInPort {
|
||||
int maxIndex = 0;
|
||||
for (IDIYComponent<?> component : components) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > maxIndex && ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass())
|
||||
.getZOrder() < ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) currentProject
|
||||
.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > maxIndex && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
|
||||
@@ -3132,12 +3121,9 @@ public class Presenter implements IPlugInPort {
|
||||
return GroupAndLockIndex.isLocked(currentProject, component);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean isComponentLayerLocked(IDIYComponent<?> component) {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
return currentProject.getLockedLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return currentProject.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3208,15 +3194,10 @@ public class Presenter implements IPlugInPort {
|
||||
@Override
|
||||
public List<Netlist> extractNetlists(boolean includeSwitches) throws NetlistException {
|
||||
List<ContinuityArea> continuityAreas = drawingManager.getContinuityAreas();
|
||||
|
||||
|
||||
return NetlistBuilder.extractNetlists(includeSwitches, currentProject, continuityAreas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinuityArea> getContinuityAreas() {
|
||||
return drawingManager.getContinuityAreas();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<INetlistAnalyzer> getNetlistAnalyzers() {
|
||||
try {
|
||||
|
||||
@@ -65,6 +65,7 @@ public class VariantManager {
|
||||
.readObject(IPlugInPort.DEFAULT_TEMPLATES_IMPORT_DATE_KEY, LocalDateTime.MIN);
|
||||
|
||||
int importCount = 0;
|
||||
int deleteCount = 0;
|
||||
|
||||
try {
|
||||
InputStream inputStream = Presenter.class.getResourceAsStream("/" + VARIANTS_FILE_NAME);
|
||||
@@ -89,7 +90,20 @@ public class VariantManager {
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (Template variant : entry.getValue()) {
|
||||
if ((variant.getCreatedOn() == null || importDate.compareTo(variant.getCreatedOn()) < 0)
|
||||
// a deletion stub keeps nothing but its name, so a missing createdOn only means an old
|
||||
// entry when the variant has not been deleted
|
||||
boolean created = variant.getCreatedOn() == null ? variant.getDeletedOn() == null
|
||||
: importDate.compareTo(variant.getCreatedOn()) < 0;
|
||||
boolean deleted =
|
||||
variant.getDeletedOn() != null && importDate.compareTo(variant.getDeletedOn()) < 0;
|
||||
// a variant created and deleted since the last import never reached the user, and a
|
||||
// deletion older than the last import was applied then, so a variant the user has since
|
||||
// created under the same name stays
|
||||
if (deleted && !created) {
|
||||
if (existingVariants.removeIf(x -> variant.getName().equals(x.getName()))) {
|
||||
deleteCount++;
|
||||
}
|
||||
} else if (created && variant.getDeletedOn() == null
|
||||
&& !existingNames.contains(variant.getName())) {
|
||||
existingVariants.add(variant);
|
||||
importCount++;
|
||||
@@ -104,6 +118,9 @@ public class VariantManager {
|
||||
if (importCount > 0) {
|
||||
LOG.info(String.format("Imported default %d variants", importCount));
|
||||
}
|
||||
if (deleteCount > 0) {
|
||||
LOG.info(String.format("Deleted %d withdrawn default variants", deleteCount));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load default variants", e);
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Strategy that converts a physical layout component into one or more schematic symbols.
|
||||
*
|
||||
* <p>
|
||||
* Implementations are declared per component type through
|
||||
* {@code @ComponentDescriptor(schematicFactory = ...)}. When a type declares no factory, the
|
||||
* schematic generator falls back to a generic box symbol.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Implementations must have a public no-argument constructor. They are instantiated once and reused,
|
||||
* so they must be stateless.
|
||||
* </p>
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface ISchematicFactory {
|
||||
|
||||
/**
|
||||
* Creates fully instantiated and configured schematic symbol instances for the given physical
|
||||
* component. The returned symbols only need to be positioned by the caller.
|
||||
*
|
||||
* @param physicalComponent the physical layout component
|
||||
* @return list of {@link SchematicSymbolMapping} entries, one per schematic symbol (1:1 for simple
|
||||
* components, 1:N for multi-section components). An empty list means the component produces
|
||||
* no symbol and should be treated as excluded.
|
||||
*/
|
||||
List<SchematicSymbolMapping> createSchematicSymbols(IDIYComponent<?> physicalComponent);
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Describes a single schematic symbol that an {@link ISchematicFactory} spawned from a physical
|
||||
* layout component. For multi-section physical components (dual triodes, dual op-amps, etc.) a
|
||||
* factory returns more than one of these.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class SchematicSymbolMapping {
|
||||
|
||||
private IDIYComponent<?> schematicSymbol;
|
||||
private Map<Integer, Integer> pinMapping;
|
||||
private String sectionLabel;
|
||||
|
||||
public SchematicSymbolMapping() {
|
||||
this.pinMapping = new HashMap<Integer, Integer>();
|
||||
}
|
||||
|
||||
public SchematicSymbolMapping(IDIYComponent<?> schematicSymbol) {
|
||||
this();
|
||||
this.schematicSymbol = schematicSymbol;
|
||||
}
|
||||
|
||||
public SchematicSymbolMapping(IDIYComponent<?> schematicSymbol, Map<Integer, Integer> pinMapping,
|
||||
String sectionLabel) {
|
||||
this.schematicSymbol = schematicSymbol;
|
||||
this.pinMapping = pinMapping == null ? new HashMap<Integer, Integer>() : pinMapping;
|
||||
this.sectionLabel = sectionLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fully configured schematic symbol instance. It only needs to be positioned.
|
||||
*/
|
||||
public IDIYComponent<?> getSchematicSymbol() {
|
||||
return schematicSymbol;
|
||||
}
|
||||
|
||||
public void setSchematicSymbol(IDIYComponent<?> schematicSymbol) {
|
||||
this.schematicSymbol = schematicSymbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a physical component control point index to the control point index on
|
||||
* {@link #getSchematicSymbol()}. Physical control points that are not present in this map have no
|
||||
* counterpart on the symbol and any net attached to them is dropped for this symbol.
|
||||
*
|
||||
* @return physical control point index -> schematic control point index
|
||||
*/
|
||||
public Map<Integer, Integer> getPinMapping() {
|
||||
if (pinMapping == null) {
|
||||
pinMapping = new HashMap<Integer, Integer>();
|
||||
}
|
||||
return pinMapping;
|
||||
}
|
||||
|
||||
public void setPinMapping(Map<Integer, Integer> pinMapping) {
|
||||
this.pinMapping = pinMapping;
|
||||
}
|
||||
|
||||
public SchematicSymbolMapping mapPin(int physicalIndex, int schematicIndex) {
|
||||
getPinMapping().put(physicalIndex, schematicIndex);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an optional label identifying the section of a multi-section component, e.g.
|
||||
* "Section A". May be {@code null}.
|
||||
*/
|
||||
public String getSectionLabel() {
|
||||
return sectionLabel;
|
||||
}
|
||||
|
||||
public void setSectionLabel(String sectionLabel) {
|
||||
this.sectionLabel = sectionLabel;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,253 +1,5 @@
|
||||
<java.util.Arrays_-ArrayList>
|
||||
<a class="org.diylc.appframework.update.Version-array">
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>10</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-01-20 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'M' and 'N' potentiometer taper options (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added E-C-B BJT pinout to TO-92 transistor package</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed the performance issue that happens when groups of components are copy-pasted and the project size grows uncontrollably</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>All building blocks of the same type get added to the same group</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Tactile Micro Switch' editor doesn't show up on double click</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>11</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-02-15 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added ability to export chat history from 'AI Assistant' to a HTML file</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Upgraded AI models for AI-powered tools and improved overall quality of the responses</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Windows installer prompts for installation folder instead of forcing one</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Shape components shouldn't appear in the BOM</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved rendering of 'Switch (Latching)' symbol to clearly make visual contact between the terminals</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Consolidate a few keyboard shortcuts for consistency</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Using "Duplicate Selection" results in duplicates of component ids, breaking Project Explorer panel and causing other issues downstream</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Calculated length disappeared from Hookup Wire and similar curved components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resize dimensions do not show for 'Chassis Panel' component when dragging a corner point</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>12</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-03-26 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Auto-Unit Conversion' configuration which automatically converts between metric and imperial units based on the ruler unit preference</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added a new section in the output of 'AI Circuit Analyzer' which provides insights into the operation of the circuit and individual components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Better error handling for AI tools</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Pressing the 'Esc' key closes selection editor dialog</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Right click (or two finger tap on mac) after selecting a component with a regular click opens editor dialog in addition to the context menu</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Clicking on a component type in the left-hand component tree sometimes does not register and does not instantiate the component</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>13</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-04-07 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added new 'Heat Sink Resistor' component with a bunch of factory variants covering the most common types</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added new 'Dial Scale' variations - 'Ticks + Numeric (0/5.5/11)' a'la Friedman and another variation of 'Ticks' with more pronounced 9/12/3 o'clock indices</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Core' property to 'Radial Inductor' component that allows selection between Ferrite and Air core inductor models'</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Envelope' property to tube symbol components which can be used to display one side of the outer envelope dashed indicating section A or section B of a tube</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added more ceramic resistor variants to 'Resistor' component</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Uniformized rendering of components while being dragged</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Ability to blank-out previously populated values for unit-type measures, e.g. resistance, capacitance, dimensions, etc</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved logic when moving component(s) that have other components stuck with them; in case there are non-sticky control points within the included components, they will be moved along retaining component shape (e.g. wires or curved traces)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Decommission 'Loadline Editor' option from the File menu</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>14</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-06-03 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Potentiometer (Miniature)' component with two variations - right-angled and vertically mounted</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Thonk 3.5mm Jack' component with two variations - mono switched and stereo</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Enable all types of potentiometers and jacks for guitar diagram analysis</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Increase maximum number of switch combination for analysis to 1024</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>'Line' component set to px used to render slightly thicker than 1px, appearing thicker than schematic symbols; changed to match the thickenss of schematic symbols</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>15</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-06-13 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Add Freeway Blade switches 3B3-01, 5B5-01, 5B5-02 (thank you Martin Morell)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>IEC variations of fuse and potentiometer symbols</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Detect the style of a treble bleed based on the topology and component values (e.g. Fender, DiMarzio, Kinman, etc)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved quality of AI Assistant responses in some cases</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved precision of rendering, in some cases there was a sub-pixel misalignment between the lines that should meet exactly</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Tone capacitor mistaken for treble bleed when connected to the input lug of the volume pot</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Dragging a component from the component tree to the canvas sometimes does not work as expected without clicking on it first and then dragging it</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Schaller Megaswitch' not rendered correctly when rotated for 90 or 270 degrees</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>6</major>
|
||||
@@ -744,5 +496,65 @@
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>6</major>
|
||||
<minor>10</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-10-30 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Pin Names' property to 'DIP IC', 'SIP IC' and 'Multiwatt IC' to name each pin, e.g. 1OUT, 1IN-, VCC+; the names are drawn on the component and used in node tooltips, netlists and AI analysis</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Pin Labels' property to 'SIP IC' and 'Multiwatt IC' to show pin names or pin numbers next to the pins</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Derive the z-order of a building blocks placed as a single component based on its child components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added datasheets to 'DIP IC', 'SIP IC' and 'Multiwatt IC' - pick a part by its number from the component's submenu to set its pin count, spacing and pin names at once - more than 100 chips in total; the AI Assistant can place these parts by part number too</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>'Chassis Panel' is now 'Enclosure' and can draw an exploded view of the whole box; set 'Height' and choose which 'Sides' to unfold</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added a datasheet to 'Enclosure' with Hammond 1590, 1550, 1441 and 1444 enclosures and the 125B size - more than 130 variations</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Moved 'Enclosure', cutouts, 'Drill Hole' and 'Dial Scale' to the new 'Hardware' category</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'DIP IC' with 'Display Pin #s' set to 'No' numbered its pins in the wrong order in netlists and AI analysis, e.g. pin 8 of an 8-pin IC was reported as pin 5</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Multiwatt IC' numbered its pins row by row instead of alternating between the two rows as on the real package</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Multiwatt IC' in the Multiwatt 11 package had its leads 1.27mm apart instead of 1.7mm; existing Multiwatt 11 parts change shape when the project is opened</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'SIP IC' body was drawn too short when 'Pin Spacing' is not a multiple of 0.1 inch, leaving the last pin outside the body</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
|
||||
@@ -5325,5 +5325,253 @@
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>10</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-01-20 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'M' and 'N' potentiometer taper options (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added E-C-B BJT pinout to TO-92 transistor package</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed the performance issue that happens when groups of components are copy-pasted and the project size grows uncontrollably</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>All building blocks of the same type get added to the same group</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Tactile Micro Switch' editor doesn't show up on double click</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>11</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-02-15 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added ability to export chat history from 'AI Assistant' to a HTML file</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Upgraded AI models for AI-powered tools and improved overall quality of the responses</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Windows installer prompts for installation folder instead of forcing one</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Shape components shouldn't appear in the BOM</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved rendering of 'Switch (Latching)' symbol to clearly make visual contact between the terminals</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Consolidate a few keyboard shortcuts for consistency</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Using "Duplicate Selection" results in duplicates of component ids, breaking Project Explorer panel and causing other issues downstream</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Calculated length disappeared from Hookup Wire and similar curved components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resize dimensions do not show for 'Chassis Panel' component when dragging a corner point</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>12</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-03-26 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Auto-Unit Conversion' configuration which automatically converts between metric and imperial units based on the ruler unit preference</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added a new section in the output of 'AI Circuit Analyzer' which provides insights into the operation of the circuit and individual components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Better error handling for AI tools</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Pressing the 'Esc' key closes selection editor dialog</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Right click (or two finger tap on mac) after selecting a component with a regular click opens editor dialog in addition to the context menu</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Clicking on a component type in the left-hand component tree sometimes does not register and does not instantiate the component</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>13</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-04-07 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added new 'Heat Sink Resistor' component with a bunch of factory variants covering the most common types</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added new 'Dial Scale' variations - 'Ticks + Numeric (0/5.5/11)' a'la Friedman and another variation of 'Ticks' with more pronounced 9/12/3 o'clock indices</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Core' property to 'Radial Inductor' component that allows selection between Ferrite and Air core inductor models'</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Envelope' property to tube symbol components which can be used to display one side of the outer envelope dashed indicating section A or section B of a tube</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added more ceramic resistor variants to 'Resistor' component</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Uniformized rendering of components while being dragged</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Ability to blank-out previously populated values for unit-type measures, e.g. resistance, capacitance, dimensions, etc</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved logic when moving component(s) that have other components stuck with them; in case there are non-sticky control points within the included components, they will be moved along retaining component shape (e.g. wires or curved traces)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Decommission 'Loadline Editor' option from the File menu</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>14</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-06-03 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Potentiometer (Miniature)' component with two variations - right-angled and vertically mounted</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Thonk 3.5mm Jack' component with two variations - mono switched and stereo</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Enable all types of potentiometers and jacks for guitar diagram analysis</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Increase maximum number of switch combination for analysis to 1024</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>'Line' component set to px used to render slightly thicker than 1px, appearing thicker than schematic symbols; changed to match the thickenss of schematic symbols</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>15</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2026-06-13 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Add Freeway Blade switches 3B3-01, 5B5-01, 5B5-02 (thank you Martin Morell)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>IEC variations of fuse and potentiometer symbols</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Detect the style of a treble bleed based on the topology and component values (e.g. Fender, DiMarzio, Kinman, etc)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved quality of AI Assistant responses in some cases</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved precision of rendering, in some cases there was a sub-pixel misalignment between the lines that should meet exactly</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Tone capacitor mistaken for treble bleed when connected to the input lug of the volume pot</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Dragging a component from the component tree to the canvas sometimes does not work as expected without clicking on it first and then dragging it</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'Schaller Megaswitch' not rendered correctly when rotated for 90 or 270 degrees</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
|
||||
+78
@@ -35,7 +35,12 @@ import java.util.UUID;
|
||||
|
||||
import org.diylc.common.Percentage;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.presenter.ComparatorFactory;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.GroupAndLockIndex;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.testcomponents.OnePointTestComponent;
|
||||
import org.diylc.testcomponents.TwoPointTestComponent;
|
||||
@@ -326,4 +331,77 @@ public class CompositeComponentTest {
|
||||
assertNotNull(blank.getChildComponents());
|
||||
assertTrue(blank.getChildComponents().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChassisOnlyCompositeIsTheChassisLayer() {
|
||||
CompositeComponent composite = customBoard(new ChassisTestComponent(),
|
||||
new ChassisTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAMixedCompositeIsItsLowestChildLayer() {
|
||||
CompositeComponent composite = customBoard(new TextTestComponent(), twoPoint("R1"),
|
||||
new BoardTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.BOARD, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfANestedCompositeLooksThroughTheInnerComposite() {
|
||||
CompositeComponent inner = customBoard(new ChassisTestComponent());
|
||||
CompositeComponent outer = customBoard(twoPoint("R1"), inner);
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(outer), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChildlessCompositeIsTheDeclaredOne() {
|
||||
assertEquals(IDIYComponent.COMPONENT,
|
||||
ComponentProcessor.getInstance().getZOrder(new CompositeComponent()), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockingTheChildLayerLocksTheComposite() {
|
||||
Project project = new Project();
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
project.getComponents().add(chassis);
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.COMPONENT);
|
||||
assertFalse(GroupAndLockIndex.isLocked(project, chassis));
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.CHASSIS);
|
||||
assertTrue(GroupAndLockIndex.isLocked(project, chassis));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compositeSortsByItsChildLayer() {
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
BoardTestComponent board = new BoardTestComponent();
|
||||
|
||||
assertTrue(ComparatorFactory.getInstance().getComponentZOrderComparator().compare(chassis,
|
||||
board) < 0);
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Chassis Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "CT", zOrder = IDIYComponent.CHASSIS)
|
||||
public static class ChassisTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Board Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "BT", zOrder = IDIYComponent.BOARD)
|
||||
public static class BoardTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Text Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "TT", zOrder = IDIYComponent.TEXT)
|
||||
public static class TextTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,21 @@
|
||||
*/
|
||||
package org.diylc.components.chassis;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.components.shapes.AbstractShape;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.AiNote;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
@@ -39,60 +43,206 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@AiNote("Each instance is one side of the chassis: an exploded view of a whole chassis takes five panels, while the top, front and back alone take three, which is typical for pedals and amplifiers. The top panel goes in the centre with the front panel against its upper edge and the back panel against its lower edge; in the five-panel view the left side panel goes against its left edge and the right side panel against its right edge")
|
||||
@AiNote("The panel 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")
|
||||
@ComponentDescriptor(name = "Chassis Panel", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
instanceNamePrefix = "CP", description = "One side of a chassis, with or withouth rounded edges",
|
||||
@AiNote("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")
|
||||
@AiNote("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")
|
||||
@AiNote("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")
|
||||
@ComponentDescriptor(name = "Enclosure", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "ENC",
|
||||
description = "Top panel of an enclosure or chassis, optionally with its sides unfolded",
|
||||
zOrder = IDIYComponent.CHASSIS, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
public class ChassisPanel extends AbstractShape {
|
||||
transformer = SimpleComponentTransformer.class, enableDatasheet = true,
|
||||
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
|
||||
public class ChassisPanel extends AbstractTransparentComponent<String>
|
||||
implements IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected Size edgeRadius = new Size(0d, SizeUnit.mm);
|
||||
|
||||
public static Color COLOR = LIGHT_METAL_COLOR;
|
||||
public static Color BORDER_COLOR = LIGHT_METAL_COLOR.darker();
|
||||
// a new enclosure is a 125B, the most common pedal enclosure, upright as in its datasheet row
|
||||
public static String DEFAULT_MODEL = "125B";
|
||||
public static Size DEFAULT_TOP_WIDTH = new Size(66d, SizeUnit.mm);
|
||||
public static Size DEFAULT_TOP_LENGTH = new Size(122d, SizeUnit.mm);
|
||||
public static Size DEFAULT_WALL_HEIGHT = new Size(36d, SizeUnit.mm);
|
||||
public static Size DEFAULT_RADIUS = new Size(0d, SizeUnit.mm);
|
||||
public static Size DEFAULT_SPACING = new Size(0d, SizeUnit.mm);
|
||||
|
||||
// the fields below up to borderThickness carry the names they had when this class extended
|
||||
// AbstractShape, because old files store them under those names
|
||||
private String value = DEFAULT_MODEL;
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(
|
||||
DEFAULT_TOP_WIDTH.convertToPixels(), DEFAULT_TOP_LENGTH.convertToPixels())};
|
||||
private Point2D.Double firstPoint = new Point2D.Double();
|
||||
private Point2D.Double secondPoint = new Point2D.Double();
|
||||
private Color color = COLOR;
|
||||
private Color borderColor = BORDER_COLOR;
|
||||
// no longer used; kept so that old files that store it still load
|
||||
@Deprecated
|
||||
private Size borderThickness;
|
||||
protected Size edgeRadius = DEFAULT_RADIUS;
|
||||
private Size height = DEFAULT_WALL_HEIGHT;
|
||||
private Sides sides = Sides.ALL;
|
||||
private Size spacing = DEFAULT_SPACING;
|
||||
|
||||
public ChassisPanel() {
|
||||
this.color = LIGHT_METAL_COLOR;
|
||||
this.borderColor = LIGHT_METAL_COLOR.darker();
|
||||
updateCorners();
|
||||
}
|
||||
|
||||
public ChassisPanel(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: group, model, top panel size along x and along y, wall height. The wall height leaves
|
||||
// out the lid, which is the bottom left out of the view. Pedal-sized boxes are listed upright,
|
||||
// as pedals use them, and the bigger ones horizontal
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
setValue(model[1]);
|
||||
setHeight(Size.parseSize(model[4]));
|
||||
// the first control point stays put and the top panel keeps the direction it is drawn in
|
||||
Point2D first = controlPoints[0];
|
||||
Point2D second = controlPoints[1];
|
||||
double x = Size.parseSize(model[2]).convertToPixels();
|
||||
double y = Size.parseSize(model[3]).convertToPixels();
|
||||
setControlPoint(new Point2D.Double(first.getX() + (second.getX() < first.getX() ? -x : x),
|
||||
first.getY() + (second.getY() < first.getY() ? -y : y)), 1);
|
||||
}
|
||||
|
||||
private void updateCorners() {
|
||||
firstPoint.setLocation(Math.min(controlPoints[0].getX(), controlPoints[1].getX()),
|
||||
Math.min(controlPoints[0].getY(), controlPoints[1].getY()));
|
||||
secondPoint.setLocation(Math.max(controlPoints[0].getX(), controlPoints[1].getX()),
|
||||
Math.max(controlPoints[0].getY(), controlPoints[1].getY()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the side panels of the exploded view, folded out from the edges of the top panel:
|
||||
* front, back and then, when all sides are shown, left and right. Empty when no sides are
|
||||
* shown or the enclosure has no height.
|
||||
*/
|
||||
Rectangle2D[] getSidePanels() {
|
||||
double h = getHeight() == null ? 0 : getHeight().convertToPixels();
|
||||
if (h <= 0 || getSides() == Sides.NONE) {
|
||||
return new Rectangle2D[0];
|
||||
}
|
||||
double s = getSpacing() == null ? 0 : getSpacing().convertToPixels();
|
||||
double x = firstPoint.getX();
|
||||
double y = firstPoint.getY();
|
||||
double w = secondPoint.getX() - x;
|
||||
double d = secondPoint.getY() - y;
|
||||
Rectangle2D front = new Rectangle2D.Double(x, y - s - h, w, h);
|
||||
Rectangle2D back = new Rectangle2D.Double(x, y + d + s, w, h);
|
||||
if (getSides() == Sides.FRONT_AND_BACK) {
|
||||
return new Rectangle2D[] {front, back};
|
||||
}
|
||||
return new Rectangle2D[] {front, back, new Rectangle2D.Double(x - s - h, y, h, d),
|
||||
new Rectangle2D.Double(x + w + s, y, h, d)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels()));
|
||||
int radius = (int) edgeRadius.convertToPixels();
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
int x = (int) Math.round(firstPoint.getX());
|
||||
int y = (int) Math.round(firstPoint.getY());
|
||||
int width = (int) (secondPoint.getX() - firstPoint.getX());
|
||||
int length = (int) (secondPoint.getY() - firstPoint.getY());
|
||||
int radius = (int) getEdgeRadius().convertToPixels();
|
||||
Rectangle2D[] sidePanels = getSidePanels();
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
g2d.setColor(color);
|
||||
if (radius == 0) {
|
||||
g2d.fillRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
g2d.fillRect(x, y, width, length);
|
||||
} else {
|
||||
g2d.fillRoundRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
g2d.fillRoundRect(x, y, width, length, radius, radius);
|
||||
}
|
||||
for (Rectangle2D panel : sidePanels) {
|
||||
g2d.fill(panel);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
// the panels drawn so far are the whole area of the enclosure
|
||||
drawingObserver.stopTracking();
|
||||
}
|
||||
// Do not track any changes that follow because the whole rect has been
|
||||
// tracked so far.
|
||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor);
|
||||
g2d.setColor(componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor);
|
||||
if (radius == 0) {
|
||||
g2d.drawRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
g2d.drawRect(x, y, width, length);
|
||||
} else {
|
||||
g2d.drawRoundRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
g2d.drawRoundRect(x, y, width, length, radius, radius);
|
||||
}
|
||||
for (Rectangle2D panel : sidePanels) {
|
||||
g2d.draw(panel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
updateCorners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Radius")
|
||||
public Size getEdgeRadius() {
|
||||
if (edgeRadius == null) {
|
||||
edgeRadius = DEFAULT_RADIUS;
|
||||
}
|
||||
return edgeRadius;
|
||||
}
|
||||
|
||||
@@ -100,12 +250,70 @@ public class ChassisPanel extends AbstractShape {
|
||||
this.edgeRadius = edgeRadius;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Size height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Sides getSides() {
|
||||
if (sides == null) {
|
||||
sides = Sides.ALL;
|
||||
}
|
||||
return sides;
|
||||
}
|
||||
|
||||
public void setSides(Sides sides) {
|
||||
this.sides = sides;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getSpacing() {
|
||||
if (spacing == null) {
|
||||
spacing = DEFAULT_SPACING;
|
||||
}
|
||||
return spacing;
|
||||
}
|
||||
|
||||
public void setSpacing(Size spacing) {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int factor = 32 / width;
|
||||
g2d.setColor(LIGHT_METAL_COLOR);
|
||||
g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor);
|
||||
g2d.setColor(LIGHT_METAL_COLOR.darker());
|
||||
g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor);
|
||||
int flap = 6 / factor;
|
||||
int left = 2 / factor + flap;
|
||||
int top = 2 / factor + flap;
|
||||
int topWidth = width - 2 * left;
|
||||
int topHeight = height - 2 * top;
|
||||
int[][] panels = {{left, top, topWidth, topHeight}, {left, top - flap, topWidth, flap},
|
||||
{left, top + topHeight, topWidth, flap}, {left - flap, top, flap, topHeight},
|
||||
{left + topWidth, top, flap, topHeight}};
|
||||
for (int[] panel : panels) {
|
||||
g2d.setColor(LIGHT_METAL_COLOR);
|
||||
g2d.fillRect(panel[0], panel[1], panel[2], panel[3]);
|
||||
g2d.setColor(LIGHT_METAL_COLOR.darker());
|
||||
g2d.drawRect(panel[0], panel[1], panel[2], panel[3]);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Sides {
|
||||
ALL("All"), FRONT_AND_BACK("Front and Back"), NONE("None");
|
||||
|
||||
private final String label;
|
||||
|
||||
Sides(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Dial Scale", author = "Branislav Stojkovic", category = "Misc",
|
||||
@ComponentDescriptor(name = "Dial Scale", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "DS", description = "Control panel dial scale", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class DialScale extends AbstractComponent<String> {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
|
||||
@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "ELC", description = "Elliptical chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class EllipticalCutout extends AbstractShape {
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "POLYC", description = "Polygonal chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class PolygonalCutout extends AbstractShape {
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "RECTC", description = "Rectangular chassis cutout, with or without rounded edges",
|
||||
zOrder = IDIYComponent.CHASSIS + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import org.diylc.core.gerber.IGerberDrawingObserver;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Drill Hole", category = "Electro-Mechanical", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Drill Hole", category = "Hardware", author = "Branislav Stojkovic",
|
||||
description = "Drill hole marker for PCB, chassis or faceplate", instanceNamePrefix = "Hole",
|
||||
zOrder = IDIYComponent.BOARD + 0.1, bomPolicy = BomPolicy.NEVER_SHOW,
|
||||
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB",
|
||||
|
||||
+1
-3
@@ -26,7 +26,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -49,8 +48,7 @@ import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing")
|
||||
@AiNote("It has no standing mode: keep the control points at least 'Length' apart, or the body is drawn past the holes")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Electrolytic Capacitor (Axial)", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Electrolytic Capacitor (Axial)", author = "Branislav Stojkovic",
|
||||
category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Axial electrolytic capacitor, similar to Sprague Atom, F&T, etc",
|
||||
zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class,
|
||||
|
||||
+1
-3
@@ -24,7 +24,6 @@ import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.components.passive.CapacitorDatasheetService.CapacitorDatasheet;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -35,8 +34,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing")
|
||||
@AiNote("If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point, or over the second with 'Reverse (standing)'; to keep it lying on a tighter footprint, reduce 'Length'")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Film Capacitor (Axial)", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Film Capacitor (Axial)", author = "Branislav Stojkovic",
|
||||
category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Axial film capacitor, similar to Mallory 150s", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class, enableDatasheet = true,
|
||||
|
||||
+1
-3
@@ -12,7 +12,6 @@ import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.PotentiometerSchematicFactory;
|
||||
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
@@ -31,8 +30,7 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(schematicFactory = PotentiometerSchematicFactory.class,
|
||||
name = "Potentiometer (Miniature)", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Potentiometer (Miniature)", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.SINGLE_CLICK, instanceNamePrefix = "VR",
|
||||
description = "9mm Alpha style miniature potentiometers", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = MiniaturePotentiometerTransformer.class)
|
||||
|
||||
+1
-3
@@ -33,7 +33,6 @@ import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.PotentiometerSchematicFactory;
|
||||
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
@@ -60,8 +59,7 @@ import org.diylc.utils.Constants;
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the other two lugs run to the right of it 'Spacing' apart, and the other orientations rotate this around the anchor")
|
||||
@AiNote("Orient the pot so its lugs face the rest of the circuit: they face down in DEFAULT, left in _90, up in _180 and right in _270")
|
||||
@AiNote("Unless told otherwise, use one of two standard sizes, picked by the type of circuit and the space available: the 25mm pot, which the defaults already describe ('Diameter' 1in, 'Spacing' 0.3in), or the 16mm pot ('Diameter' 16mm, 'Spacing' 0.2in)")
|
||||
@ComponentDescriptor(schematicFactory = PotentiometerSchematicFactory.class,
|
||||
name = "Potentiometer", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Potentiometer", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.SINGLE_CLICK, instanceNamePrefix = "VR",
|
||||
description = "Metal body panel mount potentiometer with solder lugs or PCB terminals (Alpha, CTS, Bourns)", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = PotentiometerTransformer.class, enableCache = true)
|
||||
|
||||
+1
-3
@@ -27,7 +27,6 @@ import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.AiNote;
|
||||
@@ -39,8 +38,7 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@AiNote("'Length' and 'Width' are the disc as seen from above: 'Length' is its diameter and 'Width' its thickness")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Ceramic Capacitor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Ceramic Capacitor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Standard radial ceramic capacitor", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-3
@@ -29,7 +29,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -49,8 +48,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("'Diameter' is the can as seen from above; 'Height' is drawn only when 'Folded' lays the can on its side")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Electrolytic Capacitor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Electrolytic Capacitor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Vertically mounted electrolytic capacitor, polarized or bipolar", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class, enableDatasheet = true, datasheetCreationStepCount = 3)
|
||||
|
||||
+1
-3
@@ -26,7 +26,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.components.passive.CapacitorDatasheetService.CapacitorDatasheet;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -39,8 +38,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@AiNote("The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads")
|
||||
@AiNote("'Length' and 'Width' are the body as seen from above: 'Length' runs along the line between the leads and 'Width' across it, i.e. the datasheet width and thickness; body height is not drawn")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Film Capacitor (Radial)", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Film Capacitor (Radial)", author = "Branislav Stojkovic",
|
||||
category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Radial film capacitor, similar to Sprague Orange Drop",
|
||||
zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class,
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.schematic.InductorSchematicFactory;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -47,8 +46,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("'Diameter' is the body as seen from above; 'Height' is drawn only when 'Folded' lays the part on its side")
|
||||
@ComponentDescriptor(schematicFactory = InductorSchematicFactory.class,
|
||||
name = "Inductor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Inductor (Radial)", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "L",
|
||||
description = "Vertically mounted ferrite core inductor", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-3
@@ -26,7 +26,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.components.passive.CapacitorDatasheetService.CapacitorDatasheet;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -39,8 +38,7 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.core.measures.Voltage;
|
||||
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Mica Capacitor (Radial)", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Mica Capacitor (Radial)", author = "Branislav Stojkovic",
|
||||
category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Standard radial mica capacitor", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class, enableDatasheet = true,
|
||||
|
||||
@@ -32,12 +32,12 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.schematic.ResistorSchematicFactory;
|
||||
import org.diylc.common.ResistorColorCode;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.annotations.AiNote;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
@@ -49,11 +49,13 @@ import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing")
|
||||
@AiNote("If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'")
|
||||
@ComponentDescriptor(schematicFactory = ResistorSchematicFactory.class,
|
||||
name = "Resistor", author = "Branislav Stojkovic", category = "Passive",
|
||||
@AiNote("A datasheet model sets the body size, shape and colors of a resistor family at one power rating but never the resistance; set 'Power Rating' together with the model to pick the matching size")
|
||||
@ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "Resistor layout symbol",
|
||||
zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class, enableCache = true)
|
||||
public class Resistor extends AbstractLeadedComponent<Resistance> implements IGerberComponentSimple {
|
||||
zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class, enableCache = true,
|
||||
enableDatasheet = true, datasheetCreationStepCount = 2)
|
||||
public class Resistor extends AbstractLeadedComponent<Resistance>
|
||||
implements IGerberComponentSimple, IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -77,6 +79,41 @@ public class Resistor extends AbstractLeadedComponent<Resistance> implements IGe
|
||||
this.borderColor = BORDER_COLOR;
|
||||
}
|
||||
|
||||
public Resistor(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: family, power, body length, body width, shape, color code, body color, border color;
|
||||
// the resistance is not part of a row because the body size depends only on family and power
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
setPowerNew(org.diylc.core.measures.Power.parseCapacitance(model[1]));
|
||||
setLength(parseDatasheetSize(model[2]));
|
||||
setWidth(parseDatasheetSize(model[3]));
|
||||
setShape(parseDatasheetEnum(ResistorShape.values(), model[4]));
|
||||
setColorCode(parseDatasheetEnum(ResistorColorCode.values(), model[5]));
|
||||
setBodyColor(Color.decode(model[6]));
|
||||
setBorderColor(Color.decode(model[7]));
|
||||
}
|
||||
|
||||
// sizes are in mm unless a unit follows the number, as some families are specified in inches
|
||||
private static Size parseDatasheetSize(String value) {
|
||||
String[] parts = value.split(" ");
|
||||
SizeUnit unit = parts.length > 1 ? SizeUnit.valueOf(parts[1]) : SizeUnit.mm;
|
||||
return new Size(Double.parseDouble(parts[0]), unit);
|
||||
}
|
||||
|
||||
private static <E extends Enum<E>> E parseDatasheetEnum(E[] values, String name) {
|
||||
for (E value : values) {
|
||||
if (value.toString().equalsIgnoreCase(name)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown datasheet value: " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsStandingMode() {
|
||||
return true;
|
||||
|
||||
+1
-3
@@ -29,7 +29,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.CapacitorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -47,8 +46,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("'Diameter' is the body as seen from above; 'Height' is drawn only when 'Folded' lays the part on its side")
|
||||
@ComponentDescriptor(schematicFactory = CapacitorSchematicFactory.class,
|
||||
name = "Tantalum Capacitor", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Tantalum Capacitor", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
|
||||
description = "Vertically mounted tantalum capacitor", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-3
@@ -28,7 +28,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.schematic.InductorSchematicFactory;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.CreationMethod;
|
||||
@@ -42,8 +41,7 @@ import org.diylc.core.measures.Resistance;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(schematicFactory = InductorSchematicFactory.class,
|
||||
name = "Inductor (Toroidal)", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Inductor (Toroidal)", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "L",
|
||||
description = "Ferrite core toroidal inductor mounted vertically", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-3
@@ -30,7 +30,6 @@ import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.PotentiometerSchematicFactory;
|
||||
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
@@ -51,8 +50,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the third lug is 0.2in below it (0.4in for FLAT_XLARGE) and the wiper sits halfway between them, offset to the right by 0.2in for FLAT_SMALL and FLAT_XSMALL, 0.4in for FLAT_SMALL2 and FLAT_LARGE, 0.5in for FLAT_XLARGE, 0.1in for VERTICAL_OFFSET, 0.2in for VERTICAL_OFFSET_BIG_GAP and not at all for VERTICAL_INLINE. The other orientations rotate this around the anchor")
|
||||
@ComponentDescriptor(schematicFactory = PotentiometerSchematicFactory.class,
|
||||
name = "Trimmer Potentiometer", author = "Branislav Stojkovic", category = "Passive",
|
||||
@ComponentDescriptor(name = "Trimmer Potentiometer", author = "Branislav Stojkovic", category = "Passive",
|
||||
creationMethod = CreationMethod.SINGLE_CLICK, instanceNamePrefix = "VR",
|
||||
description = "Various types of board mounted trimmer potentiometers", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = TrimmerTransformer.class)
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
/*
|
||||
|
||||
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.components.schematic;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
/**
|
||||
* Generic rectangular IC-style schematic symbol with configurable terminals on each of the four
|
||||
* sides, similar to KiCad's generic symbol. Used as the default fallback representation for physical
|
||||
* components that do not declare a dedicated schematic factory.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@ComponentDescriptor(name = "Box", author = "DIYLC", category = "Schematic Symbols",
|
||||
instanceNamePrefix = "U", description = "Generic schematic box with configurable terminals",
|
||||
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.SHOW_ALL_NAMES,
|
||||
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Schematic")
|
||||
public class SchematicBox extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
public static Color BODY_COLOR = Color.white;
|
||||
public static Color BORDER_COLOR = Color.black;
|
||||
public static Color PIN_COLOR = Color.black;
|
||||
|
||||
private String leftNodes = "1,2";
|
||||
private String rightNodes = "3,4";
|
||||
private String topNodes = "";
|
||||
private String bottomNodes = "";
|
||||
|
||||
private String value = "";
|
||||
private Display display = Display.BOTH;
|
||||
private Color bodyColor = BODY_COLOR;
|
||||
private Color borderColor = BORDER_COLOR;
|
||||
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
|
||||
|
||||
transient private List<String> nodeLabels;
|
||||
|
||||
public SchematicBox() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
private static List<String> parseNodes(String csv) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
if (csv == null)
|
||||
return result;
|
||||
for (String token : csv.split(",")) {
|
||||
String trimmed = token.trim();
|
||||
if (!trimmed.isEmpty())
|
||||
result.add(trimmed);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int leftCount() {
|
||||
return parseNodes(leftNodes).size();
|
||||
}
|
||||
|
||||
private int rightCount() {
|
||||
return parseNodes(rightNodes).size();
|
||||
}
|
||||
|
||||
private int topCount() {
|
||||
return parseNodes(topNodes).size();
|
||||
}
|
||||
|
||||
private int bottomCount() {
|
||||
return parseNodes(bottomNodes).size();
|
||||
}
|
||||
|
||||
private double pinSpacing() {
|
||||
return PIN_SPACING.convertToPixels();
|
||||
}
|
||||
|
||||
private double bodyWidth() {
|
||||
double spacing = pinSpacing();
|
||||
int horizontal = Math.max(topCount(), bottomCount());
|
||||
return Math.max((horizontal + 1) * spacing, 4 * spacing);
|
||||
}
|
||||
|
||||
private double bodyHeight() {
|
||||
double spacing = pinSpacing();
|
||||
int vertical = Math.max(leftCount(), rightCount());
|
||||
return Math.max((vertical + 1) * spacing, 2 * spacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recomputes the pin geometry from the anchor (control point 0) and the configured node counts.
|
||||
* Ordering: left side (top to bottom), right side (top to bottom), top side (left to right),
|
||||
* bottom side (left to right).
|
||||
*
|
||||
* <p>
|
||||
* This is called on construction and whenever the node lists change — <b>not</b> from
|
||||
* {@link #setControlPoint}. During a drag the presenter translates every control point by the
|
||||
* same delta (because {@link #canPointMoveFreely} is {@code false}), which already keeps the pins
|
||||
* on the box edge, so recomputing there would double-apply the delta. When the pin count is
|
||||
* unchanged the existing {@link Point2D} objects are mutated in place so references held by the
|
||||
* drawing/selection code stay valid.
|
||||
* </p>
|
||||
*/
|
||||
private void updateControlPoints() {
|
||||
nodeLabels = null;
|
||||
double spacing = pinSpacing();
|
||||
double leadLength = spacing;
|
||||
double firstPinX = controlPoints[0].getX();
|
||||
double firstPinY = controlPoints[0].getY();
|
||||
|
||||
double bodyX = firstPinX + leadLength;
|
||||
double bodyY = firstPinY - spacing;
|
||||
double bodyW = bodyWidth();
|
||||
double bodyH = bodyHeight();
|
||||
|
||||
List<Point2D> points = new ArrayList<Point2D>();
|
||||
// left
|
||||
for (int i = 0; i < leftCount(); i++) {
|
||||
points.add(new Point2D.Double(firstPinX, bodyY + spacing * (i + 1)));
|
||||
}
|
||||
// right
|
||||
for (int i = 0; i < rightCount(); i++) {
|
||||
points.add(new Point2D.Double(bodyX + bodyW + leadLength, bodyY + spacing * (i + 1)));
|
||||
}
|
||||
// top
|
||||
for (int i = 0; i < topCount(); i++) {
|
||||
points.add(new Point2D.Double(bodyX + spacing * (i + 1), bodyY - leadLength));
|
||||
}
|
||||
// bottom
|
||||
for (int i = 0; i < bottomCount(); i++) {
|
||||
points.add(new Point2D.Double(bodyX + spacing * (i + 1), bodyY + bodyH + leadLength));
|
||||
}
|
||||
if (points.isEmpty()) {
|
||||
points.add(new Point2D.Double(firstPinX, firstPinY));
|
||||
}
|
||||
// keep index 0 exactly where it was
|
||||
points.set(0, new Point2D.Double(firstPinX, firstPinY));
|
||||
|
||||
if (controlPoints.length == points.size()) {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
controlPoints[i].setLocation(points.get(i));
|
||||
}
|
||||
} else {
|
||||
controlPoints = points.toArray(new Point2D[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getNodeLabels() {
|
||||
if (nodeLabels == null) {
|
||||
nodeLabels = new ArrayList<String>();
|
||||
nodeLabels.addAll(parseNodes(leftNodes));
|
||||
nodeLabels.addAll(parseNodes(rightNodes));
|
||||
nodeLabels.addAll(parseNodes(topNodes));
|
||||
nodeLabels.addAll(parseNodes(bottomNodes));
|
||||
}
|
||||
return nodeLabels;
|
||||
}
|
||||
|
||||
private Rectangle2D getBodyRectangle() {
|
||||
double spacing = pinSpacing();
|
||||
double leadLength = spacing;
|
||||
double bodyX = controlPoints[0].getX() + leadLength;
|
||||
double bodyY = controlPoints[0].getY() - spacing;
|
||||
return new Rectangle2D.Double(bodyX, bodyY, bodyWidth(), bodyHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip()))
|
||||
return;
|
||||
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
Rectangle2D body = getBodyRectangle();
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(body);
|
||||
g2d.setComposite(oldComposite);
|
||||
|
||||
Color finalBorder =
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor;
|
||||
g2d.setColor(finalBorder);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(body);
|
||||
|
||||
// pins
|
||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: PIN_COLOR);
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
Point2D p = controlPoints[i];
|
||||
Point2D edge = nearestEdgePoint(p, body);
|
||||
g2d.drawLine((int) Math.round(p.getX()), (int) Math.round(p.getY()), (int) Math.round(edge.getX()),
|
||||
(int) Math.round(edge.getY()));
|
||||
}
|
||||
|
||||
// pin labels
|
||||
Font smallFont = project.getFont().deriveFont((float) (project.getFont().getSize() * 0.8));
|
||||
g2d.setFont(smallFont);
|
||||
List<String> labels = getNodeLabels();
|
||||
for (int i = 0; i < controlPoints.length && i < labels.size(); i++) {
|
||||
Point2D edge = nearestEdgePoint(controlPoints[i], body);
|
||||
double lx = edge.getX();
|
||||
double ly = edge.getY();
|
||||
// nudge label inward
|
||||
if (Math.abs(edge.getX() - body.getMinX()) < 1)
|
||||
lx += smallFont.getSize();
|
||||
else if (Math.abs(edge.getX() - body.getMaxX()) < 1)
|
||||
lx -= smallFont.getSize();
|
||||
if (Math.abs(edge.getY() - body.getMinY()) < 1)
|
||||
ly += smallFont.getSize() * 0.7;
|
||||
else if (Math.abs(edge.getY() - body.getMaxY()) < 1)
|
||||
ly -= smallFont.getSize() * 0.7;
|
||||
StringUtils.drawCenteredText(g2d, labels.get(i), lx, ly, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
// body label
|
||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR);
|
||||
g2d.setFont(project.getFont());
|
||||
String label = getLabelForDisplay();
|
||||
if (label != null && !label.isEmpty()) {
|
||||
StringUtils.drawCenteredText(g2d, label, body.getCenterX(), body.getCenterY(),
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
private String getLabelForDisplay() {
|
||||
switch (display) {
|
||||
case NAME:
|
||||
return getName();
|
||||
case VALUE:
|
||||
return value;
|
||||
case NONE:
|
||||
return "";
|
||||
case BOTH:
|
||||
default:
|
||||
return (getName() == null ? "" : getName()) + (value == null || value.isEmpty() ? "" : " " + value);
|
||||
}
|
||||
}
|
||||
|
||||
private static Point2D nearestEdgePoint(Point2D p, Rectangle2D body) {
|
||||
double x = p.getX();
|
||||
double y = p.getY();
|
||||
if (x <= body.getMinX())
|
||||
return new Point2D.Double(body.getMinX(), clamp(y, body.getMinY(), body.getMaxY()));
|
||||
if (x >= body.getMaxX())
|
||||
return new Point2D.Double(body.getMaxX(), clamp(y, body.getMinY(), body.getMaxY()));
|
||||
if (y <= body.getMinY())
|
||||
return new Point2D.Double(clamp(x, body.getMinX(), body.getMaxX()), body.getMinY());
|
||||
return new Point2D.Double(clamp(x, body.getMinX(), body.getMaxX()), body.getMaxY());
|
||||
}
|
||||
|
||||
private static double clamp(double v, double min, double max) {
|
||||
return Math.max(min, Math.min(max, v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int margin = 4 * width / 32;
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect(margin * 2, margin, width - margin * 4, height - margin * 2);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.drawRect(margin * 2, margin, width - margin * 4, height - margin * 2);
|
||||
g2d.drawLine(0, height / 3, margin * 2, height / 3);
|
||||
g2d.drawLine(0, height * 2 / 3, margin * 2, height * 2 / 3);
|
||||
g2d.drawLine(width - margin * 2, height / 2, width, height / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
// Move only the requested point. The presenter drags every control point of the box together
|
||||
// (canPointMoveFreely == false), so the pins stay on the edge without a recompute here.
|
||||
controlPoints[index].setLocation(point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
List<String> labels = getNodeLabels();
|
||||
return index < labels.size() ? labels.get(index) : Integer.toString(index + 1);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Left Nodes")
|
||||
public String getLeftNodes() {
|
||||
return leftNodes;
|
||||
}
|
||||
|
||||
public void setLeftNodes(String leftNodes) {
|
||||
this.leftNodes = leftNodes;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Right Nodes")
|
||||
public String getRightNodes() {
|
||||
return rightNodes;
|
||||
}
|
||||
|
||||
public void setRightNodes(String rightNodes) {
|
||||
this.rightNodes = rightNodes;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Top Nodes")
|
||||
public String getTopNodes() {
|
||||
return topNodes;
|
||||
}
|
||||
|
||||
public void setTopNodes(String topNodes) {
|
||||
this.topNodes = topNodes;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Bottom Nodes")
|
||||
public String getBottomNodes() {
|
||||
return bottomNodes;
|
||||
}
|
||||
|
||||
public void setBottomNodes(String bottomNodes) {
|
||||
this.bottomNodes = bottomNodes;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Body")
|
||||
public Color getBodyColor() {
|
||||
return bodyColor;
|
||||
}
|
||||
|
||||
public void setBodyColor(Color bodyColor) {
|
||||
this.bodyColor = bodyColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+136
-39
@@ -30,16 +30,22 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.Arrays;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractLabeledComponent;
|
||||
import org.diylc.components.AbstractMakerBoard;
|
||||
import org.diylc.components.transform.DIL_ICTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
@@ -55,11 +61,15 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the first row of pins runs down from it 'Pin Spacing' apart, the second row sits 'Row Spacing' to the right and the notch is at the anchor's end. The other orientations rotate this around the anchor")
|
||||
@AiNote("'Pin Names' is a comma-separated list of pin names in pin-number order, starting with pin 1 next to the notch; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package, e.g. GND_1 and GND_2, while 1IN- and 2IN- are inputs of two separate sections")
|
||||
@AiNote("A datasheet model is a part number such as TL072 or NE555 and sets 'Pins', 'Row Spacing', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model")
|
||||
@ComponentDescriptor(name = "DIP IC", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "IC", description = "Dual-in-line package IC",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE,
|
||||
transformer = DIL_ICTransformer.class, enableCache = true)
|
||||
public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberComponentSimple {
|
||||
transformer = DIL_ICTransformer.class, enableCache = true, enableDatasheet = true,
|
||||
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
|
||||
public class DIL_IC extends AbstractLabeledComponent<String>
|
||||
implements IGerberComponentSimple, IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -72,7 +82,9 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
public static int EDGE_RADIUS = 6;
|
||||
public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in);
|
||||
public static Size INDENT_SIZE = new Size(0.07d, SizeUnit.in);
|
||||
public static DisplayNumbers DISPLAY_NUMBERS = DisplayNumbers.NO;
|
||||
public static DisplayNumbers DISPLAY_NUMBERS = DisplayNumbers.NAMES;
|
||||
// the smaller font lets names sit closer to their pins than on a maker board
|
||||
public static Size PIN_NAME_OFFSET = new Size(1.35d, SizeUnit.mm);
|
||||
|
||||
private String value = "";
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
@@ -86,6 +98,7 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
private Color indentColor = INDENT_COLOR;
|
||||
private DisplayNumbers displayNumbers = DISPLAY_NUMBERS;
|
||||
private String pinNames = null;
|
||||
// new Point(0, pinSpacing.convertToPixels()),
|
||||
// new Point(0, 2 * pinSpacing.convertToPixels()),
|
||||
// new Point(0, 3 * pinSpacing.convertToPixels()),
|
||||
@@ -97,12 +110,29 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
// new Point(3 * pinSpacing.convertToPixels(), 3 *
|
||||
// pinSpacing.convertToPixels()) };
|
||||
transient private Area[] body;
|
||||
transient private String[] parsedPinNames;
|
||||
|
||||
public DIL_IC() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
public DIL_IC(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: group, part number, row spacing, then one name per pin in pin-number order, so the
|
||||
// pin count is the number of names
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
setValue(model[1]);
|
||||
setRowSpacing(Size.parseSize(model[2]));
|
||||
setPinCount(PinCount.valueOf("_" + (model.length - 3)));
|
||||
setPinNames(String.join(",", Arrays.copyOfRange(model, 3, model.length)));
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getValue() {
|
||||
return value;
|
||||
@@ -425,9 +455,14 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
}
|
||||
}
|
||||
|
||||
if (getDisplayNumbers() == DisplayNumbers.NAMES) {
|
||||
drawPinNames(g2d);
|
||||
}
|
||||
|
||||
// draw pin numbers
|
||||
if (getDisplayNumbers() != DisplayNumbers.NO) {
|
||||
if (getDisplayNumbers() != DisplayNumbers.NO && getDisplayNumbers() != DisplayNumbers.NAMES) {
|
||||
int pinSize = (int) PIN_SIZE.convertToPixels();
|
||||
g2d.setFont(project.getFont().deriveFont((float) (project.getFont().getSize2D() * 0.66)));
|
||||
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
Point2D point = controlPoints[i];
|
||||
@@ -454,16 +489,68 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
textY2 = textY2 - pinSize;
|
||||
}
|
||||
|
||||
g2d.setFont(project.getFont().deriveFont((float) (project.getFont().getSize2D() * 0.66)));
|
||||
String pinNumber = Integer.toString(getPinNumber(i));
|
||||
if (i >= pinCount.getValue() / 2) {
|
||||
g2d.drawString(getControlPointNodeName(i), textX1, textY1);
|
||||
g2d.drawString(pinNumber, textX1, textY1);
|
||||
} else {
|
||||
g2d.drawString(getControlPointNodeName(i), textX2, textY2);
|
||||
g2d.drawString(pinNumber, textX2, textY2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Names are printed the way maker boards print theirs: centred just inside the body from their
|
||||
// pin and running along the row, which leaves the middle of even a 0.3 in body to the name/value
|
||||
// label. Each name has one pin pitch along the row, so a name that would touch the previous one
|
||||
// in its row or run past the end of the body is left out rather than overprinted.
|
||||
private void drawPinNames(Graphics2D g2d) {
|
||||
g2d.setFont(ICPinNames.PIN_NAME_FONT);
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics(ICPinNames.PIN_NAME_FONT);
|
||||
double labelOffset = PIN_NAME_OFFSET.convertToPixels();
|
||||
double pitch = pinSpacing.convertToPixels();
|
||||
int half = pinCount.getValue() / 2;
|
||||
Point2D firstRow = controlPoints[0];
|
||||
Point2D secondRow = controlPoints[half];
|
||||
double rowDistance = firstRow.distance(secondRow);
|
||||
double acrossX = (secondRow.getX() - firstRow.getX()) / rowDistance;
|
||||
double acrossY = (secondRow.getY() - firstRow.getY()) / rowDistance;
|
||||
boolean rowsVertical = Math.abs(acrossX) > Math.abs(acrossY);
|
||||
// along the row the body reaches half a pitch past the first and the last pin
|
||||
double bodyStart = -pitch / 2 + 1;
|
||||
double bodyEnd = (half - 0.5) * pitch - 1;
|
||||
double previousEnd = bodyStart - ICPinNames.PIN_NAME_GAP;
|
||||
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
if (i == half) {
|
||||
previousEnd = bodyStart - ICPinNames.PIN_NAME_GAP;
|
||||
}
|
||||
String name = getPinName(getPinNumber(i));
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
String label = AbstractMakerBoard.getDisplayPinLabel(name);
|
||||
double alongRow = (i % half) * pitch;
|
||||
double halfWidth = fontMetrics.stringWidth(label) / 2d;
|
||||
if (alongRow - halfWidth < previousEnd + ICPinNames.PIN_NAME_GAP || alongRow + halfWidth > bodyEnd) {
|
||||
continue;
|
||||
}
|
||||
previousEnd = alongRow + halfWidth;
|
||||
double dirX = i < half ? acrossX : -acrossX;
|
||||
double dirY = i < half ? acrossY : -acrossY;
|
||||
double x = controlPoints[i].getX() + dirX * labelOffset;
|
||||
double y = controlPoints[i].getY() + dirY * labelOffset;
|
||||
AffineTransform oldTransform = g2d.getTransform();
|
||||
// the two rows are mirrored so each name reads away from its pin, as on a maker board; rows
|
||||
// that run horizontally keep their names level so that neither reads upside down
|
||||
if (rowsVertical) {
|
||||
g2d.rotate(dirX > 0 ? Math.PI / 2 : -Math.PI / 2, x, y);
|
||||
}
|
||||
StringUtils.drawCenteredText(g2d, label, x, y, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
g2d.setTransform(oldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int radius = 6 * width / 32;
|
||||
@@ -527,7 +614,7 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
this.indentColor = indentColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Display Pin #s")
|
||||
@EditableProperty(name = "Pin Labels")
|
||||
public DisplayNumbers getDisplayNumbers() {
|
||||
if (displayNumbers == null) {
|
||||
displayNumbers = DisplayNumbers.NO;
|
||||
@@ -539,6 +626,42 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
this.displayNumbers = numbers;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin Names")
|
||||
public String getPinNames() {
|
||||
return pinNames;
|
||||
}
|
||||
|
||||
public void setPinNames(String pinNames) {
|
||||
this.pinNames = pinNames;
|
||||
parsedPinNames = null;
|
||||
}
|
||||
|
||||
// the physical pin number of a control point; control points run down the first row and then
|
||||
// down the second, whereas DIP numbering comes back up the second row
|
||||
private int getPinNumber(int index) {
|
||||
int pinCount = this.pinCount.getValue();
|
||||
int half = pinCount / 2;
|
||||
int position = index + 1;
|
||||
boolean secondRow = position > half;
|
||||
switch (getDisplayNumbers()) {
|
||||
case CONNECTOR:
|
||||
return secondRow ? 2 * (position - half) : 2 * position - 1;
|
||||
case DIP_MIRROR:
|
||||
return secondRow ? position - half : pinCount - position + 1;
|
||||
case CONNECTOR_MIRROR:
|
||||
return secondRow ? 2 * (position - half) - 1 : 2 * position;
|
||||
default:
|
||||
return secondRow ? pinCount + half - position + 1 : position;
|
||||
}
|
||||
}
|
||||
|
||||
private String getPinName(int pinNumber) {
|
||||
if (parsedPinNames == null) {
|
||||
parsedPinNames = ICPinNames.parse(getPinNames());
|
||||
}
|
||||
return ICPinNames.get(parsedPinNames, pinNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
@@ -569,35 +692,9 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
index++;
|
||||
|
||||
if (displayNumbers == DisplayNumbers.DIP) {
|
||||
if (index > pinCount.getValue() / 2) {
|
||||
return Integer.toString(pinCount.getValue() * 3 / 2 - index + 1);
|
||||
} else {
|
||||
return Integer.toString(index);
|
||||
}
|
||||
} else if (displayNumbers == DisplayNumbers.CONNECTOR) {
|
||||
if (index > pinCount.getValue() / 2) {
|
||||
return Integer.toString(index - pinCount.getValue() + index);
|
||||
} else {
|
||||
return Integer.toString(index * 2 - 1);
|
||||
}
|
||||
} else if (displayNumbers == DisplayNumbers.DIP_MIRROR) {
|
||||
if (index > pinCount.getValue() / 2) {
|
||||
return Integer.toString((index - pinCount.getValue() / 2));
|
||||
} else {
|
||||
return Integer.toString(pinCount.getValue() - index + 1);
|
||||
}
|
||||
} else if (displayNumbers == DisplayNumbers.CONNECTOR_MIRROR) {
|
||||
if (index > pinCount.getValue() / 2) {
|
||||
return Integer.toString(index - pinCount.getValue() + index - 1);
|
||||
} else {
|
||||
return Integer.toString(2 * index);
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.toString(index);
|
||||
int pinNumber = getPinNumber(index);
|
||||
String name = getPinName(pinNumber);
|
||||
return name == null ? Integer.toString(pinNumber) : name;
|
||||
}
|
||||
|
||||
public static enum PinCount {
|
||||
@@ -616,8 +713,8 @@ public class DIL_IC extends AbstractLabeledComponent<String> implements IGerberC
|
||||
|
||||
public enum DisplayNumbers {
|
||||
|
||||
NO("No"), DIP("DIP"), CONNECTOR("Connector"), DIP_MIRROR("DIP (Mirrored)"), CONNECTOR_MIRROR(
|
||||
"Connector (Mirrored)");
|
||||
NO("None"), NAMES("Names"), DIP("DIP"), CONNECTOR("Connector"), DIP_MIRROR("DIP (Mirrored)"),
|
||||
CONNECTOR_MIRROR("Connector (Mirrored)");
|
||||
|
||||
private String label;
|
||||
|
||||
|
||||
+1
-3
@@ -26,7 +26,6 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.DiodeSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
@@ -44,8 +43,7 @@ import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing")
|
||||
@AiNote("If the control points are closer together than 'Length' (0.2in by default) the part is drawn standing, its body over the first point, or over the second with 'Reverse (standing)'; to keep it lying on a tighter footprint, reduce 'Length'")
|
||||
@ComponentDescriptor(schematicFactory = DiodeSchematicFactory.class,
|
||||
name = "Diode (glass)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Diode (glass)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D",
|
||||
description = "Glass diode, like most small signal diodes.", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class, enableCache = true)
|
||||
|
||||
+1
-3
@@ -26,7 +26,6 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.DiodeSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
@@ -44,8 +43,7 @@ import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing")
|
||||
@AiNote("If the control points are closer together than 'Length' (0.25in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'")
|
||||
@ComponentDescriptor(schematicFactory = DiodeSchematicFactory.class,
|
||||
name = "Diode (plastic)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Diode (plastic)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D",
|
||||
description = "Plastic diode, like most rectifier, zener, schottky, etc.", zOrder = IDIYComponent.COMPONENT,
|
||||
transformer = SimpleComponentTransformer.class, enableCache = true)
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
|
||||
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.components.semiconductors;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.components.AbstractMakerBoard;
|
||||
|
||||
/**
|
||||
* Pin names shared by the IC packages. A package keeps its names as one comma-separated string in
|
||||
* pin-number order, pin 1 first, so the names survive a change of pin count and read back as typed.
|
||||
*/
|
||||
public final class ICPinNames {
|
||||
|
||||
// a size below the maker boards' pin font, as IC pin names are longer than a board's silkscreen
|
||||
// and get only one pin pitch each
|
||||
public static Font PIN_NAME_FONT = new Font(AbstractMakerBoard.SILK_FONT_FAMILY, Font.PLAIN, 6);
|
||||
public static int PIN_NAME_GAP = 2;
|
||||
|
||||
private ICPinNames() {}
|
||||
|
||||
public static String[] parse(String pinNames) {
|
||||
return pinNames == null ? new String[0] : pinNames.split(",", -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param names names as returned by {@link #parse(String)}
|
||||
* @param pinNumber 1-based pin number
|
||||
* @return the trimmed name of the pin, or null if it has none
|
||||
*/
|
||||
public static String get(String[] names, int pinNumber) {
|
||||
if (pinNumber < 1 || pinNumber > names.length) {
|
||||
return null;
|
||||
}
|
||||
String name = names[pinNumber - 1].trim();
|
||||
return name.isEmpty() ? null : name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a pin label outside the package, starting just beyond whichever reaches further in the
|
||||
* given direction, the body or the pin itself, and reading away from the package. The direction
|
||||
* is one of the four axis directions; text pointing left or down is right-aligned so that it never
|
||||
* reads upside down.
|
||||
*
|
||||
* @param pin the pin the label belongs to
|
||||
* @param dirX x component of the unit direction away from the package
|
||||
* @param dirY y component of the unit direction away from the package
|
||||
* @param bodyBounds bounds of the package body
|
||||
* @param pinRadius half the drawn pin size
|
||||
*/
|
||||
public static void drawOutside(Graphics2D g2d, String text, Point2D pin, double dirX, double dirY,
|
||||
Rectangle2D bodyBounds, double pinRadius) {
|
||||
boolean horizontal = Math.abs(dirX) > Math.abs(dirY);
|
||||
double pinReach = (horizontal ? pin.getX() * dirX : pin.getY() * dirY) + pinRadius;
|
||||
double bodyReach = horizontal ? (dirX > 0 ? bodyBounds.getMaxX() : -bodyBounds.getMinX())
|
||||
: (dirY > 0 ? bodyBounds.getMaxY() : -bodyBounds.getMinY());
|
||||
double start = Math.max(pinReach, bodyReach) + PIN_NAME_GAP;
|
||||
double x = horizontal ? start * dirX : pin.getX();
|
||||
double y = horizontal ? pin.getY() : start * dirY;
|
||||
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||
int width = fontMetrics.stringWidth(text);
|
||||
float baseline = (fontMetrics.getAscent() - fontMetrics.getDescent()) / 2f;
|
||||
AffineTransform oldTransform = g2d.getTransform();
|
||||
g2d.translate(x, y);
|
||||
double forward;
|
||||
if (horizontal) {
|
||||
forward = dirX;
|
||||
} else {
|
||||
g2d.rotate(-Math.PI / 2);
|
||||
forward = -dirY;
|
||||
}
|
||||
g2d.drawString(text, forward > 0 ? 0 : -width, baseline);
|
||||
g2d.setTransform(oldTransform);
|
||||
}
|
||||
}
|
||||
+220
-113
@@ -30,16 +30,20 @@ import java.awt.Rectangle;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Arrays;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
|
||||
import org.diylc.common.*;
|
||||
import org.diylc.components.AbstractMakerBoard;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.AiNote;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
@@ -48,11 +52,16 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The leads are staggered in two rows and numbered alternately along the package: pin 1 is the first control point, pins 1, 3, 5, ... form the row bent forward in front of the body, away from the heatsink tab, and pins 2, 4, ... the row that leaves the body from underneath. 'Type' picks the package: Multiwatt 11 for LM3886 or TDA7265, Multiwatt 15 for TDA7293 or TDA7294")
|
||||
@AiNote("'Pin Names' is a comma-separated list of pin names in pin-number order; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package")
|
||||
@AiNote("A datasheet model is a part number such as LM3886 and sets 'Type', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model")
|
||||
@ComponentDescriptor(name = "Multiwatt IC", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "IC", description = "Multiwatt package IC typically used for audio amplifiers of high power applications",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE,
|
||||
enableCache = true)
|
||||
public class MultiwattIC extends AbstractTransparentComponent<String> implements IGerberComponentSimple {
|
||||
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
|
||||
datasheetModelColumn = 1)
|
||||
public class MultiwattIC extends AbstractTransparentComponent<String>
|
||||
implements IGerberComponentSimple, IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -67,12 +76,11 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
public static Size PIN_SIZE = new Size(0.7d, SizeUnit.mm);
|
||||
public static Size THICKNESS = new Size(5d, SizeUnit.mm);
|
||||
public static Size TAB_THICKNESS = new Size(1.6d, SizeUnit.mm);
|
||||
// Multiwatt packages use 0.1 inch (2.54mm) spacing between pins in the same row
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
// from the back of the tab to the lead row that leaves the body from underneath; the other row is
|
||||
// bent forward clear of the body
|
||||
public static Size BACK_TO_NEAR_ROW = new Size(4.55d, SizeUnit.mm);
|
||||
// Multiwatt packages have staggered pins with 0.2 inch (5.08mm) row spacing
|
||||
public static Size ROW_SPACING = new Size(0.2d, SizeUnit.in);
|
||||
// Lead offset due to bent leads
|
||||
public static Size LEAD_OFFSET = new Size(4d, SizeUnit.mm);
|
||||
|
||||
private String value = "";
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
@@ -84,7 +92,10 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
private Color tabColor = TAB_COLOR;
|
||||
private Color tabBorderColor = TAB_BORDER_COLOR;
|
||||
private String pinNames = null;
|
||||
private PinLabels pinLabels = null;
|
||||
transient private Area[] body;
|
||||
transient private String[] parsedPinNames;
|
||||
|
||||
public MultiwattIC() {
|
||||
super();
|
||||
@@ -92,6 +103,27 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
this.alphaPercent = new Percentage(100);
|
||||
}
|
||||
|
||||
public MultiwattIC(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: group, part number, then one name per pin in pin-number order; the pin count picks
|
||||
// the package type
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
int pinCount = model.length - 2;
|
||||
MultiwattType modelType = Arrays.stream(MultiwattType.values())
|
||||
.filter(t -> t.getPinCount() == pinCount)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException("No Multiwatt package with " + pinCount
|
||||
+ " pins"));
|
||||
setValue(model[1]);
|
||||
setType(modelType);
|
||||
setPinNames(String.join(",", Arrays.copyOfRange(model, 2, model.length)));
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getValue() {
|
||||
return value;
|
||||
@@ -175,7 +207,7 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
int pinsRight = type.getPinsRight();
|
||||
controlPoints = new Point2D.Double[pinCount];
|
||||
controlPoints[0] = firstPoint;
|
||||
double pinSpacing = PIN_SPACING.convertToPixels();
|
||||
double pinSpacing = type.getRowPitch().convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
// Update control points for staggered layout
|
||||
double dx1, dy1, dx2, dy2;
|
||||
@@ -234,91 +266,68 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
public Area[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Area[2];
|
||||
double x = controlPoints[0].getX();
|
||||
double y = controlPoints[0].getY();
|
||||
double pinSize = PIN_SIZE.convertToPixels();
|
||||
double pinSpacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double tabThickness = TAB_THICKNESS.convertToPixels();
|
||||
double leadOffset = LEAD_OFFSET.convertToPixels();
|
||||
double pinSpacing = type.getRowPitch().convertToPixels();
|
||||
int pinsLeft = type.getPinsLeft();
|
||||
int pinsRight = type.getPinsRight();
|
||||
// Calculate height accounting for staggered pins (right row offset by half spacing)
|
||||
double leftRowHeight = (pinsLeft - 1) * pinSpacing;
|
||||
double rightRowHeight = (pinsRight - 1 + 0.5) * pinSpacing; // Account for half-spacing offset
|
||||
double maxHeight = Math.max(leftRowHeight, rightRowHeight) + pinSpacing; // Add spacing for last pin
|
||||
double bodyX, bodyY, bodyWidth, bodyHeight;
|
||||
double tabX, tabY, tabWidth, tabHeight;
|
||||
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
bodyWidth = rowSpacing - pinSize;
|
||||
bodyHeight = maxHeight;
|
||||
// Offset body to the left by lead offset (bent leads)
|
||||
bodyX = x + pinSize / 2 - leadOffset;
|
||||
bodyY = y - pinSpacing / 2;
|
||||
// Tab on the left side (where there are more pins) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY;
|
||||
tabWidth = tabThickness;
|
||||
tabHeight = bodyHeight;
|
||||
break;
|
||||
case _90:
|
||||
bodyWidth = maxHeight;
|
||||
bodyHeight = rowSpacing - pinSize;
|
||||
// Body positioned between the two pin rows
|
||||
// Left pins extend to negative X, body starts from leftmost pin
|
||||
// For _90: left pins go left (negative X), so leftmost is at x - (pinsLeft-1)*pinSpacing
|
||||
// Offset body upward by lead offset (bent leads)
|
||||
bodyX = x - (pinsLeft - 1) * pinSpacing - pinSpacing / 2;
|
||||
bodyY = y + pinSize / 2 - leadOffset;
|
||||
// Tab on the top side (where there are more pins - left row at y) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY;
|
||||
tabWidth = bodyWidth;
|
||||
tabHeight = tabThickness;
|
||||
break;
|
||||
case _180:
|
||||
bodyWidth = rowSpacing - pinSize;
|
||||
bodyHeight = maxHeight;
|
||||
// Body positioned between the two pin rows
|
||||
// For _180: left pins go up (negative Y), right pins at x - rowSpacing
|
||||
// Left row is at x, right row is at x - rowSpacing
|
||||
// Pins extend upward from y, so body should start from top of pin array
|
||||
// Offset body to the right by lead offset (bent leads)
|
||||
bodyX = x - rowSpacing + pinSize / 2 + leadOffset;
|
||||
bodyY = y - (pinsLeft - 1) * pinSpacing - pinSpacing / 2;
|
||||
// Tab on the right side (where there are more pins - left row at x) inside the body bounds
|
||||
tabX = bodyX + bodyWidth - tabThickness;
|
||||
tabY = bodyY;
|
||||
tabWidth = tabThickness;
|
||||
tabHeight = bodyHeight;
|
||||
break;
|
||||
case _270:
|
||||
bodyWidth = maxHeight;
|
||||
bodyHeight = rowSpacing - pinSize;
|
||||
// Body positioned between the two pin rows
|
||||
// For _270: left pins go right (positive X), so leftmost is at x
|
||||
// Left row is at y, right row is at y - rowSpacing
|
||||
// Similar to _90 but mirrored
|
||||
// Offset body downward by lead offset (bent leads)
|
||||
bodyX = x - pinSpacing / 2;
|
||||
bodyY = y - rowSpacing + pinSize / 2 + leadOffset;
|
||||
// Tab on the bottom side (where there are more pins - left row at y) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY + bodyHeight - tabThickness;
|
||||
tabWidth = bodyWidth;
|
||||
tabHeight = tabThickness;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
body[0] = new Area(new Rectangle2D.Double(bodyX, bodyY, bodyWidth, bodyHeight));
|
||||
body[1] = new Area(new Rectangle2D.Double(tabX, tabY, tabWidth, tabHeight));
|
||||
double rightRowHeight = (pinsRight - 1 + 0.5) * pinSpacing;
|
||||
double length = Math.max(leftRowHeight, rightRowHeight) + pinSpacing;
|
||||
double start = -pinSpacing / 2;
|
||||
double back = ROW_SPACING.convertToPixels() + BACK_TO_NEAR_ROW.convertToPixels();
|
||||
body[0] = new Area(
|
||||
toDrawing(start, start + length, back - THICKNESS.convertToPixels(), back));
|
||||
body[1] = new Area(
|
||||
toDrawing(start, start + length, back - TAB_THICKNESS.convertToPixels(), back));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
// The rectangle spanning the given distances along the rows and across them, measured from the
|
||||
// first pin with the second row on the positive side, turned to the orientation.
|
||||
private Rectangle2D toDrawing(double alongFrom, double alongTo, double acrossFrom,
|
||||
double acrossTo) {
|
||||
double alongX;
|
||||
double alongY;
|
||||
double acrossX;
|
||||
double acrossY;
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
alongX = 0;
|
||||
alongY = 1;
|
||||
acrossX = 1;
|
||||
acrossY = 0;
|
||||
break;
|
||||
case _90:
|
||||
alongX = -1;
|
||||
alongY = 0;
|
||||
acrossX = 0;
|
||||
acrossY = 1;
|
||||
break;
|
||||
case _180:
|
||||
alongX = 0;
|
||||
alongY = -1;
|
||||
acrossX = -1;
|
||||
acrossY = 0;
|
||||
break;
|
||||
case _270:
|
||||
alongX = 1;
|
||||
alongY = 0;
|
||||
acrossX = 0;
|
||||
acrossY = -1;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
Point2D first = controlPoints[0];
|
||||
double x1 = first.getX() + alongX * alongFrom + acrossX * acrossFrom;
|
||||
double y1 = first.getY() + alongY * alongFrom + acrossY * acrossFrom;
|
||||
double x2 = first.getX() + alongX * alongTo + acrossX * acrossTo;
|
||||
double y2 = first.getY() + alongY * alongTo + acrossY * acrossTo;
|
||||
return new Rectangle2D.Double(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1),
|
||||
Math.abs(y2 - y1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
@@ -337,20 +346,8 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
double pinX = point.getX();
|
||||
double pinY = point.getY();
|
||||
|
||||
// Check if pin is inside the body
|
||||
boolean insideBody = mainArea.contains(pinX, pinY);
|
||||
|
||||
if (insideBody) {
|
||||
// Draw pin as square inside body
|
||||
Rectangle2D rect = new Rectangle2D.Double(pinX - pinSize / 2,
|
||||
pinY - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(rect);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.draw(rect);
|
||||
} else {
|
||||
// pins under the body are drawn on top of it further down
|
||||
if (!mainArea.contains(pinX, pinY)) {
|
||||
// Draw rectangular lead from body edge to pin position
|
||||
double bodyX = bodyBounds.getX();
|
||||
double bodyY = bodyBounds.getY();
|
||||
@@ -460,6 +457,25 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(mainArea);
|
||||
|
||||
// the near row leaves through the bottom of the body, so its pins are drawn over the body to
|
||||
// stay visible whatever its alpha
|
||||
if (!outlineMode) {
|
||||
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
|
||||
for (Point2D point : controlPoints) {
|
||||
if (mainArea.contains(point.getX(), point.getY())) {
|
||||
Rectangle2D rect = new Rectangle2D.Double(point.getX() - pinSize / 2,
|
||||
point.getY() - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(rect);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.draw(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw label.
|
||||
g2d.setFont(project.getFont());
|
||||
Color finalLabelColor;
|
||||
@@ -492,6 +508,44 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
int x = (int) (bounds.getX() + (bounds.width - textWidth) / 2);
|
||||
int y = (int) (bounds.getY() + (bounds.height - textHeight) / 2 + fontMetrics.getAscent());
|
||||
g2d.drawString(label, x, y);
|
||||
|
||||
if (getPinLabels() != PinLabels.NONE) {
|
||||
g2d.setColor(finalBorderColor);
|
||||
drawPinLabels(g2d, mainArea.getBounds2D());
|
||||
}
|
||||
}
|
||||
|
||||
// Labels read forward, square to the rows, away from the tab. A pin under the body is labelled
|
||||
// from the front edge of the body, in the gap between the two forward leads either side of it;
|
||||
// a forward pin past the end of its lead. The stagger keeps the two sets apart.
|
||||
private void drawPinLabels(Graphics2D g2d, Rectangle2D bodyBounds) {
|
||||
g2d.setFont(ICPinNames.PIN_NAME_FONT);
|
||||
int pinsLeft = type.getPinsLeft();
|
||||
double acrossX = controlPoints[pinsLeft].getX() - controlPoints[0].getX();
|
||||
double acrossY = controlPoints[pinsLeft].getY() - controlPoints[0].getY();
|
||||
// the stagger adds half a pitch along the row, so the row offset is the larger component
|
||||
if (Math.abs(acrossX) > Math.abs(acrossY)) {
|
||||
acrossX = Math.signum(acrossX);
|
||||
acrossY = 0;
|
||||
} else {
|
||||
acrossX = 0;
|
||||
acrossY = Math.signum(acrossY);
|
||||
}
|
||||
double pinRadius = PIN_SIZE.convertToPixels() / 2;
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
String label;
|
||||
if (getPinLabels() == PinLabels.NUMBERS) {
|
||||
label = Integer.toString(getPinNumber(i));
|
||||
} else {
|
||||
String name = getPinName(getPinNumber(i));
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
label = AbstractMakerBoard.getDisplayPinLabel(name);
|
||||
}
|
||||
ICPinNames.drawOutside(g2d, label, controlPoints[i], -acrossX, -acrossY, bodyBounds,
|
||||
pinRadius);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -500,7 +554,7 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
int pinSize = 2 * width / 32;
|
||||
int leftPinX = width / 6 + 9; // Move left pins 9px to the right (4px + 3px + 2px)
|
||||
int rightPinX = 5 * width / 6;
|
||||
int leadOffset = (int) (LEAD_OFFSET.convertToPixels() * width / 100); // Scale lead offset for icon
|
||||
int leadOffset = (int) (BACK_TO_NEAR_ROW.convertToPixels() * width / 100); // Scale lead offset for icon
|
||||
int bodyX = leftPinX + pinSize - leadOffset + 2; // Offset body to the left, then move 2px to the right
|
||||
int bodyWidth = (rightPinX - bodyX - pinSize) / 2 + 2; // Thinner body, make 2px thicker
|
||||
int bodyHeight = height - 2 * margin;
|
||||
@@ -508,13 +562,13 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
|
||||
// Calculate pin spacing to use all vertical space
|
||||
// Use same spacing for both rows, with front row offset by half spacing
|
||||
int backPins = 4;
|
||||
int frontPins = 3;
|
||||
// Use the spacing that fits the back row (more pins)
|
||||
int pinSpacing = (bodyHeight - pinSize) / (backPins - 1);
|
||||
int backStartY = margin + pinSize / 2 + 1; // Move pins 1px down
|
||||
// Front pins start with half spacing offset for staggered effect
|
||||
int frontStartY = margin + pinSize / 2 + pinSpacing / 2 + 1; // Move pins 1px down
|
||||
// the forward row, bent clear of the body, is the one with more pins
|
||||
int backPins = 3;
|
||||
int frontPins = 4;
|
||||
int pinSpacing = (bodyHeight - pinSize) / (frontPins - 1);
|
||||
int frontStartY = margin + pinSize / 2 + 1; // Move pins 1px down
|
||||
// Back pins start with half spacing offset for staggered effect
|
||||
int backStartY = margin + pinSize / 2 + pinSpacing / 2 + 1; // Move pins 1px down
|
||||
|
||||
// Draw thin body between pin rows
|
||||
g2d.setColor(BODY_COLOR);
|
||||
@@ -522,14 +576,14 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect(bodyX, bodyY, bodyWidth, bodyHeight);
|
||||
|
||||
// Draw heat sink tab on left side (where there are more pins)
|
||||
// Draw heat sink tab on left side, away from the forward row
|
||||
int tabWidth = pinSize * 2;
|
||||
g2d.setColor(TAB_COLOR);
|
||||
g2d.fillRect(bodyX, bodyY, tabWidth, bodyHeight);
|
||||
g2d.setColor(TAB_BORDER_COLOR);
|
||||
g2d.drawRect(bodyX, bodyY, tabWidth, bodyHeight);
|
||||
|
||||
// Draw 4 pins in the back (left row, more pins) as squares - inside body
|
||||
// Draw 3 pins in the back as squares - inside body
|
||||
g2d.setColor(PIN_COLOR);
|
||||
for (int i = 0; i < backPins; i++) {
|
||||
int pinY = backStartY + i * pinSpacing - pinSize / 2;
|
||||
@@ -539,7 +593,7 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
g2d.setColor(PIN_COLOR);
|
||||
}
|
||||
|
||||
// Draw 3 pins in the front (right row, fewer pins) with leads going left to body
|
||||
// Draw 4 pins in the front with leads going left to body
|
||||
// Use same spacing as back row, just offset by half spacing
|
||||
g2d.setColor(PIN_COLOR);
|
||||
for (int i = 0; i < frontPins; i++) {
|
||||
@@ -628,6 +682,49 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
this.tabBorderColor = tabBorderColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin Names")
|
||||
public String getPinNames() {
|
||||
return pinNames;
|
||||
}
|
||||
|
||||
public void setPinNames(String pinNames) {
|
||||
this.pinNames = pinNames;
|
||||
parsedPinNames = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin Labels")
|
||||
public PinLabels getPinLabels() {
|
||||
if (pinLabels == null) {
|
||||
pinLabels = PinLabels.NAMES;
|
||||
}
|
||||
return pinLabels;
|
||||
}
|
||||
|
||||
public void setPinLabels(PinLabels pinLabels) {
|
||||
this.pinLabels = pinLabels;
|
||||
}
|
||||
|
||||
// the leads alternate between the rows along the package, so the forward row holds the odd pin
|
||||
// numbers and the row under the body the even ones
|
||||
private int getPinNumber(int index) {
|
||||
int pinsLeft = type.getPinsLeft();
|
||||
return index < pinsLeft ? 2 * index + 1 : 2 * (index - pinsLeft) + 2;
|
||||
}
|
||||
|
||||
private String getPinName(int pinNumber) {
|
||||
if (parsedPinNames == null) {
|
||||
parsedPinNames = ICPinNames.parse(getPinNames());
|
||||
}
|
||||
return ICPinNames.get(parsedPinNames, pinNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
int pinNumber = getPinNumber(index);
|
||||
String name = getPinName(pinNumber);
|
||||
return name == null ? Integer.toString(pinNumber) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
double minX = Integer.MAX_VALUE;
|
||||
@@ -652,18 +749,28 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
|
||||
public static enum MultiwattType {
|
||||
// Multiwatt-11: 6 pins on left, 5 pins on right (staggered)
|
||||
MULTIWATT_11(11, 6, 5),
|
||||
MULTIWATT_11(11, 6, 5, new Size(1.7d, SizeUnit.mm), "Multiwatt 11"),
|
||||
// Multiwatt-15: 8 pins on left, 7 pins on right (staggered)
|
||||
MULTIWATT_15(15, 8, 7);
|
||||
MULTIWATT_15(15, 8, 7, new Size(1.27d, SizeUnit.mm), "Multiwatt 15");
|
||||
|
||||
private final int pinCount;
|
||||
private final int pinsLeft;
|
||||
private final int pinsRight;
|
||||
// distance between consecutive leads along the package, i.e. from one row to the other
|
||||
private final Size leadPitch;
|
||||
private final String title;
|
||||
|
||||
MultiwattType(int pinCount, int pinsLeft, int pinsRight) {
|
||||
MultiwattType(int pinCount, int pinsLeft, int pinsRight, Size leadPitch, String title) {
|
||||
this.pinCount = pinCount;
|
||||
this.pinsLeft = pinsLeft;
|
||||
this.pinsRight = pinsRight;
|
||||
this.leadPitch = leadPitch;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
// neighbouring leads of the same row are two lead pitches apart
|
||||
public Size getRowPitch() {
|
||||
return leadPitch.scale(2);
|
||||
}
|
||||
|
||||
public int getPinCount() {
|
||||
@@ -680,7 +787,7 @@ public class MultiwattIC extends AbstractTransparentComponent<String> implements
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Multiwatt " + pinCount;
|
||||
return title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -19,16 +19,19 @@
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.schematic;
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import org.diylc.components.semiconductors.DiodeSymbol;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
public enum PinLabels {
|
||||
NONE("None"), NAMES("Names"), NUMBERS("Numbers");
|
||||
|
||||
/** Maps physical diodes to a {@link DiodeSymbol}. */
|
||||
public class DiodeSchematicFactory extends AbstractSimpleSchematicFactory {
|
||||
private String title;
|
||||
|
||||
private PinLabels(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDIYComponent<?> createSymbol() {
|
||||
return new DiodeSymbol();
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,16 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.Arrays;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
|
||||
import org.diylc.common.*;
|
||||
import org.diylc.components.AbstractMakerBoard;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.components.transform.SIL_ICTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDatasheetSupport;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
@@ -54,11 +57,15 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the pins run straight down from it 'Pin Spacing' apart and the indent is at the anchor's end of the body. The other orientations rotate this around the anchor")
|
||||
@AiNote("The first control point is pin 1. 'Pin Names' is a comma-separated list of pin names in pin-number order; a pin without a name is called by its number. Pins named alike up to a trailing '_1', '_2' are one net inside the package, while 1IN and 2IN are separate channels")
|
||||
@AiNote("A datasheet model is a part number such as LA4440 and sets 'Pins', 'Pin Spacing', 'Pin Names' and 'Value'. Set 'Value' to the same part number together with the model")
|
||||
@ComponentDescriptor(name = "SIP IC", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "IC", description = "Single-in-line package IC",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = SIL_ICTransformer.class,
|
||||
enableCache = true)
|
||||
public class SIL_IC extends AbstractTransparentComponent<String> implements IGerberComponentSimple {
|
||||
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
|
||||
datasheetModelColumn = 1)
|
||||
public class SIL_IC extends AbstractTransparentComponent<String>
|
||||
implements IGerberComponentSimple, IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -83,6 +90,8 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
private Color borderColor = BORDER_COLOR;
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
private Color indentColor = INDENT_COLOR;
|
||||
private String pinNames = null;
|
||||
private PinLabels pinLabels = null;
|
||||
// new Point(0, pinSpacing.convertToPixels()),
|
||||
// new Point(0, 2 * pinSpacing.convertToPixels()),
|
||||
// new Point(0, 3 * pinSpacing.convertToPixels()),
|
||||
@@ -94,6 +103,7 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
// new Point(3 * pinSpacing.convertToPixels(), 3 *
|
||||
// pinSpacing.convertToPixels()) };
|
||||
transient private Area[] body;
|
||||
transient private String[] parsedPinNames;
|
||||
|
||||
public SIL_IC() {
|
||||
super();
|
||||
@@ -101,6 +111,22 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
this.alphaPercent = new Percentage(100);
|
||||
}
|
||||
|
||||
public SIL_IC(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: group, part number, pin spacing, then one name per pin in pin-number order, so the
|
||||
// pin count is the number of names
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
setValue(model[1]);
|
||||
setPinSpacing(Size.parseSize(model[2]));
|
||||
setPinCount(PinCount.valueOf("_" + (model.length - 3)));
|
||||
setPinNames(String.join(",", Arrays.copyOfRange(model, 3, model.length)));
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getValue() {
|
||||
return value;
|
||||
@@ -230,7 +256,7 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
int thickness = getClosestOdd(THICKNESS.convertToPixels());
|
||||
double width;
|
||||
double height;
|
||||
double pinSpacing = (int) this.pinSpacing.convertToPixels();
|
||||
double pinSpacing = this.pinSpacing.convertToPixels();
|
||||
Area indentation = null;
|
||||
int indentationSize = getClosestOdd(INDENT_SIZE.convertToPixels());
|
||||
switch (orientation) {
|
||||
@@ -364,6 +390,40 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
int x = (int) (bounds.getX() + (bounds.width - textWidth) / 2);
|
||||
int y = (int) (bounds.getY() + (bounds.height - textHeight) / 2 + fontMetrics.getAscent());
|
||||
g2d.drawString(label, x, y);
|
||||
|
||||
if (getPinLabels() != PinLabels.NONE) {
|
||||
g2d.setColor(finalBorderColor);
|
||||
drawPinLabels(g2d, mainArea.getBounds2D());
|
||||
}
|
||||
}
|
||||
|
||||
// Labels sit beside the body, square to the row and reading away from it, on the side the row
|
||||
// turns to clockwise: right of a row running down, below one running left.
|
||||
private void drawPinLabels(Graphics2D g2d, Rectangle2D bodyBounds) {
|
||||
if (controlPoints.length < 2) {
|
||||
return;
|
||||
}
|
||||
g2d.setFont(ICPinNames.PIN_NAME_FONT);
|
||||
if (g2d.getFontMetrics().getAscent() > pinSpacing.convertToPixels()) {
|
||||
return;
|
||||
}
|
||||
double rowDistance = controlPoints[0].distance(controlPoints[1]);
|
||||
double alongX = (controlPoints[1].getX() - controlPoints[0].getX()) / rowDistance;
|
||||
double alongY = (controlPoints[1].getY() - controlPoints[0].getY()) / rowDistance;
|
||||
double pinRadius = PIN_SIZE.convertToPixels() / 2;
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
String label;
|
||||
if (getPinLabels() == PinLabels.NUMBERS) {
|
||||
label = Integer.toString(i + 1);
|
||||
} else {
|
||||
String name = getPinName(i + 1);
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
label = AbstractMakerBoard.getDisplayPinLabel(name);
|
||||
}
|
||||
ICPinNames.drawOutside(g2d, label, controlPoints[i], alongY, -alongX, bodyBounds, pinRadius);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -429,6 +489,41 @@ public class SIL_IC extends AbstractTransparentComponent<String> implements IGer
|
||||
public void setIndentColor(Color indentColor) {
|
||||
this.indentColor = indentColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin Names")
|
||||
public String getPinNames() {
|
||||
return pinNames;
|
||||
}
|
||||
|
||||
public void setPinNames(String pinNames) {
|
||||
this.pinNames = pinNames;
|
||||
parsedPinNames = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin Labels")
|
||||
public PinLabels getPinLabels() {
|
||||
if (pinLabels == null) {
|
||||
pinLabels = PinLabels.NAMES;
|
||||
}
|
||||
return pinLabels;
|
||||
}
|
||||
|
||||
public void setPinLabels(PinLabels pinLabels) {
|
||||
this.pinLabels = pinLabels;
|
||||
}
|
||||
|
||||
private String getPinName(int pinNumber) {
|
||||
if (parsedPinNames == null) {
|
||||
parsedPinNames = ICPinNames.parse(getPinNames());
|
||||
}
|
||||
return ICPinNames.get(parsedPinNames, pinNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
String name = getPinName(index + 1);
|
||||
return name == null ? Integer.toString(index + 1) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
|
||||
+1
-3
@@ -34,7 +34,6 @@ import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.TransistorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -55,8 +54,7 @@ import org.diylc.utils.Constants;
|
||||
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the third pin is 2 x 'Pin spacing' below it and the middle pin 'Pin spacing' below and 'Pin spacing' to the left, a triangle under the round can. 'Folded' puts the three pins in a straight line down from the anchor and lays the body flat on the right of them. The other orientations rotate this around the anchor")
|
||||
@AiNote("On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in to land all three pins on holes")
|
||||
@ComponentDescriptor(schematicFactory = TransistorSchematicFactory.class,
|
||||
name = "Transistor (TO-1)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Transistor (TO-1)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "Q", description = "Transistor with small metal body",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO1Transformer.class,
|
||||
enableCache = true)
|
||||
|
||||
+1
-3
@@ -34,7 +34,6 @@ import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.TransistorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -52,8 +51,7 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(schematicFactory = TransistorSchematicFactory.class,
|
||||
name = "Transistor (TO-126)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Transistor (TO-126)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "Q", description = "Transistors with a hole for heat sink mounting",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class,
|
||||
enableCache = true)
|
||||
|
||||
+1
-3
@@ -34,7 +34,6 @@ import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.TransistorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -56,8 +55,7 @@ import org.diylc.utils.Constants;
|
||||
@AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the three pins run straight down from it 0.1in apart, and the other orientations rotate this around the anchor")
|
||||
@AiNote("Seen from above, the metal tab is on the right of the pin row in DEFAULT orientation and the printed front faces left; 'Folded' lays the body flat on the right of the pin row, 'Lead Length' away from it, with the tab and its mounting hole at the far end")
|
||||
@AiNote("'Pinout' values list the pins as a datasheet does, facing the printed front with the legs down, left to right; pick the value that matches the part's datasheet as written")
|
||||
@ComponentDescriptor(schematicFactory = TransistorSchematicFactory.class,
|
||||
name = "Transistor (TO-220)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Transistor (TO-220)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "Q", description = "Transistors with metal tab for heat sink mounting",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class,
|
||||
enableCache = true)
|
||||
|
||||
+1
-3
@@ -35,7 +35,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.TransistorSchematicFactory;
|
||||
|
||||
import org.diylc.awt.TwoCircleTangent;
|
||||
import org.diylc.common.*;
|
||||
@@ -53,8 +52,7 @@ import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(schematicFactory = TransistorSchematicFactory.class,
|
||||
name = "Transistor (TO-3)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Transistor (TO-3)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "Q", description = "Transistor with large metal body",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true)
|
||||
public class TransistorTO3 extends AbstractLabeledComponent<String> {
|
||||
|
||||
+1
-3
@@ -34,7 +34,6 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.schematic.TransistorSchematicFactory;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
@@ -57,8 +56,7 @@ import org.diylc.utils.Constants;
|
||||
@AiNote("Seen from above, the flat face is on the left of the pin row in DEFAULT orientation; 'Folded' lays the body flat on the right of the pin row instead")
|
||||
@AiNote("'Pinout' values list the pins as a datasheet does, facing the flat side with the legs down, left to right; pick the value that matches the part's datasheet as written")
|
||||
@AiNote("On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in, or use two or three jumpers acting as flexible leads and connecting TO-92 terminals to the holes on the board")
|
||||
@ComponentDescriptor(schematicFactory = TransistorSchematicFactory.class,
|
||||
name = "Transistor (TO-92)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
@ComponentDescriptor(name = "Transistor (TO-92)", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "Q", description = "Transistor with small plastic or epoxy body",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO92Transformer.class,
|
||||
enableCache = true)
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class AbstractShape extends AbstractTransparentComponent<Void> {
|
||||
|
||||
protected Color color = COLOR;
|
||||
protected Color borderColor = BORDER_COLOR;
|
||||
protected Size borderThickness = new Size(0.2d, SizeUnit.mm);
|
||||
protected Size borderThickness = new Size(1.0, SizeUnit.px);
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getColor() {
|
||||
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Base class for the common case of a single-symbol, straight pin-for-pin mapping between a physical
|
||||
* component and its schematic symbol (resistors, capacitors, inductors, diodes, two- and
|
||||
* three-terminal parts, ...). The n-th sticky control point of the physical component is mapped to
|
||||
* the n-th electrical control point of the symbol.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public abstract class AbstractSimpleSchematicFactory implements ISchematicFactory {
|
||||
|
||||
/** @return a fresh, unconfigured schematic symbol instance. */
|
||||
protected abstract IDIYComponent<?> createSymbol();
|
||||
|
||||
/** @return number of electrical (net-carrying) control points to map, in index order. */
|
||||
protected int electricalPinCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SchematicSymbolMapping> createSchematicSymbols(IDIYComponent<?> physicalComponent) {
|
||||
IDIYComponent<?> symbol = createSymbol();
|
||||
symbol.setId(UUID.randomUUID());
|
||||
symbol.setName(physicalComponent.getName());
|
||||
copyValue(physicalComponent, symbol);
|
||||
// leaded symbols are born with a one-inch lead span, which leaves far more bare lead than body
|
||||
// and runs into whatever sits in the neighbouring cell; pull them in to the schematic pitch
|
||||
SchematicBuilder.applyPitch(symbol, false, false);
|
||||
|
||||
List<Integer> physicalPins = new ArrayList<Integer>();
|
||||
for (int i = 0; i < physicalComponent.getControlPointCount()
|
||||
&& physicalPins.size() < electricalPinCount(); i++) {
|
||||
if (physicalComponent.isControlPointSticky(i)
|
||||
&& physicalComponent.getControlPointNodeName(i) != null) {
|
||||
physicalPins.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, Integer> pinMapping = new HashMap<Integer, Integer>();
|
||||
for (int schematicIndex = 0; schematicIndex < physicalPins.size()
|
||||
&& schematicIndex < symbol.getControlPointCount(); schematicIndex++) {
|
||||
pinMapping.put(physicalPins.get(schematicIndex), schematicIndex);
|
||||
}
|
||||
|
||||
List<SchematicSymbolMapping> result = new ArrayList<SchematicSymbolMapping>();
|
||||
result.add(new SchematicSymbolMapping(symbol, pinMapping, null));
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void copyValue(IDIYComponent<?> physical, IDIYComponent<?> symbol) {
|
||||
try {
|
||||
((IDIYComponent<Object>) symbol).setValue(physical.getValue());
|
||||
} catch (Throwable t) {
|
||||
// symbol value type differs from the physical component's; skip
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import org.diylc.components.passive.CapacitorSymbol;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/** Maps physical capacitors to a {@link CapacitorSymbol}. */
|
||||
public class CapacitorSchematicFactory extends AbstractSimpleSchematicFactory {
|
||||
|
||||
@Override
|
||||
protected IDIYComponent<?> createSymbol() {
|
||||
return new CapacitorSymbol();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.components.schematic.SchematicBox;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Default {@link ISchematicFactory} used for every physical component type that does not declare a
|
||||
* dedicated factory. It inspects the sticky control points of the component, creates a
|
||||
* {@link SchematicBox} with one labeled terminal per node and copies the component's name and value.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class GenericBoxSchematicFactory implements ISchematicFactory {
|
||||
|
||||
@Override
|
||||
public List<SchematicSymbolMapping> createSchematicSymbols(IDIYComponent<?> physicalComponent) {
|
||||
List<Integer> pinIndices = new ArrayList<Integer>();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
for (int i = 0; i < physicalComponent.getControlPointCount(); i++) {
|
||||
if (!physicalComponent.isControlPointSticky(i)) {
|
||||
continue;
|
||||
}
|
||||
String nodeName = physicalComponent.getControlPointNodeName(i);
|
||||
if (nodeName == null) {
|
||||
continue;
|
||||
}
|
||||
pinIndices.add(i);
|
||||
labels.add(nodeName);
|
||||
}
|
||||
if (pinIndices.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
SchematicBox box = new SchematicBox();
|
||||
box.setName(physicalComponent.getName());
|
||||
String value = physicalComponent.getValueForDisplay();
|
||||
box.setValue(value == null ? "" : value);
|
||||
box.setDisplay(Display.BOTH);
|
||||
box.setTopNodes("");
|
||||
box.setBottomNodes("");
|
||||
|
||||
int half = (labels.size() + 1) / 2;
|
||||
List<String> left = labels.subList(0, half);
|
||||
List<String> right = labels.subList(half, labels.size());
|
||||
box.setLeftNodes(String.join(",", left));
|
||||
box.setRightNodes(String.join(",", right));
|
||||
|
||||
// SchematicBox control point order is left (top to bottom) then right (top to bottom), which is
|
||||
// exactly the order we appended the labels in, so the k-th physical pin maps to schematic
|
||||
// control point k.
|
||||
Map<Integer, Integer> pinMapping = new HashMap<Integer, Integer>();
|
||||
for (int k = 0; k < pinIndices.size(); k++) {
|
||||
pinMapping.put(pinIndices.get(k), k);
|
||||
}
|
||||
|
||||
List<SchematicSymbolMapping> result = new ArrayList<SchematicSymbolMapping>();
|
||||
result.add(new SchematicSymbolMapping(box, pinMapping, null));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import org.diylc.components.passive.InductorSymbol;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/** Maps physical inductors to a {@link InductorSymbol}. */
|
||||
public class InductorSchematicFactory extends AbstractSimpleSchematicFactory {
|
||||
|
||||
@Override
|
||||
protected IDIYComponent<?> createSymbol() {
|
||||
return new InductorSymbol();
|
||||
}
|
||||
}
|
||||
@@ -1,510 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.netlist.Group;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.schematic.SchematicBuilder.SymbolEntry;
|
||||
import org.diylc.schematic.flow.FlowHints;
|
||||
import org.diylc.schematic.flow.FlowRole;
|
||||
import org.diylc.schematic.flow.SignalFlowAnalyzer;
|
||||
|
||||
/**
|
||||
* Arranges schematic symbols in columns that follow the direction the signal travels, so that the
|
||||
* drawing reads from input on the left to output on the right.
|
||||
*
|
||||
* <p>
|
||||
* The circuit becomes a graph of components joined by its nets. Two kinds of net are kept out of that
|
||||
* graph: the ones carrying a declared rail, and the single busiest net, which in practice is ground.
|
||||
* Ground reaches nearly every part of a circuit, so leaving it in makes every component adjacent to
|
||||
* every other and flattens the whole drawing into one column - and most projects never place a ground
|
||||
* symbol, so it cannot be recognised by its label alone.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Where {@link SignalFlowAnalyzer} can tell that one component drives another the edge is directed,
|
||||
* and columns come from the longest path through those edges. Real projects rarely carry that
|
||||
* information - a transistor only reports its legs once someone has set its pin-out - so when
|
||||
* direction is absent the columns come from distance across the graph instead, measured from the far
|
||||
* end of its longest chain. That always spreads a connected circuit out, which is the one thing the
|
||||
* layout must never fail to do.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Every collection here keeps insertion order. The same project has to produce the same drawing every
|
||||
* time, and hash ordering would quietly make the layout depend on object identity.
|
||||
* </p>
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class LayeredPlacement {
|
||||
|
||||
/** Gap between one column and the next, in pixels. */
|
||||
public static final double COLUMN_GAP = 130d;
|
||||
/** Gap between symbols stacked within a column, in pixels. */
|
||||
public static final double ROW_GAP = 60d;
|
||||
public static final double MARGIN = 120d;
|
||||
/** Grid step the finished positions are snapped to. */
|
||||
public static final double GRID = 10d;
|
||||
|
||||
private static final int ORDERING_SWEEPS = 6;
|
||||
|
||||
private final SignalFlowAnalyzer flowAnalyzer = new SignalFlowAnalyzer();
|
||||
|
||||
/** One placed component: the physical part, the symbols it produced, and where it ended up. */
|
||||
private static class Vertex {
|
||||
|
||||
final UUID id;
|
||||
final IDIYComponent<?> physical;
|
||||
final List<SymbolEntry> entries;
|
||||
final Set<UUID> drives = new LinkedHashSet<UUID>();
|
||||
final Set<UUID> drivenBy = new LinkedHashSet<UUID>();
|
||||
final Set<UUID> neighbours = new LinkedHashSet<UUID>();
|
||||
|
||||
int layer;
|
||||
double barycentre;
|
||||
|
||||
Vertex(IDIYComponent<?> physical, List<SymbolEntry> entries) {
|
||||
this.id = physical.getId();
|
||||
this.physical = physical;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
boolean isDirected() {
|
||||
return !drives.isEmpty() || !drivenBy.isEmpty();
|
||||
}
|
||||
|
||||
/** @return where the part sits on the board, used to break ties so the schematic echoes it. */
|
||||
double physicalY() {
|
||||
return physical.getControlPointCount() == 0 ? 0 : physical.getControlPoint(0).getY();
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<UUID, Vertex> vertices = new LinkedHashMap<UUID, Vertex>();
|
||||
|
||||
/**
|
||||
* Places every symbol of every eligible component. The symbols must already have been given their
|
||||
* attitude, because the column widths are measured from their current geometry.
|
||||
*/
|
||||
public void place(List<IDIYComponent<?>> eligible,
|
||||
Map<UUID, List<SymbolEntry>> entriesByPhysicalId, Netlist netlist) {
|
||||
buildVertices(eligible, entriesByPhysicalId);
|
||||
if (vertices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
buildEdges(netlist);
|
||||
breakFeedbackLoops();
|
||||
assignLayers();
|
||||
spreadUndirectedVertices();
|
||||
if (distinctLayerCount() < 2) {
|
||||
// nothing in the circuit said which way the signal runs, so fall back to plain distance
|
||||
layerByDistance();
|
||||
}
|
||||
assignCoordinates(orderWithinLayers());
|
||||
}
|
||||
|
||||
private void buildVertices(List<IDIYComponent<?>> eligible,
|
||||
Map<UUID, List<SymbolEntry>> entriesByPhysicalId) {
|
||||
for (IDIYComponent<?> physical : eligible) {
|
||||
List<SymbolEntry> entries = entriesByPhysicalId.get(physical.getId());
|
||||
if (entries != null && !entries.isEmpty()) {
|
||||
vertices.put(physical.getId(), new Vertex(physical, entries));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns each ordinary net into edges.
|
||||
*
|
||||
* <p>
|
||||
* Direction has to carry across the passive parts that sit between active devices: a collector
|
||||
* reaches the next stage's base through a coupling capacitor, so the two are never on one net and a
|
||||
* rule that only looked for an output and an input on the same net would find nothing at all.
|
||||
* Anything driving a net therefore drives every other member of it, and every member drives
|
||||
* whatever takes the net as an input.
|
||||
* </p>
|
||||
*/
|
||||
private void buildEdges(Netlist netlist) {
|
||||
if (netlist == null) {
|
||||
return;
|
||||
}
|
||||
Group backbone = SchematicBuilder.backboneNet(netlist);
|
||||
Map<UUID, FlowHints> hintCache = new LinkedHashMap<UUID, FlowHints>();
|
||||
for (Group group : netlist.getSortedGroups()) {
|
||||
if (group == backbone || SchematicBuilder.railLabelOf(group) != null) {
|
||||
continue;
|
||||
}
|
||||
List<UUID> members = new ArrayList<UUID>();
|
||||
List<UUID> drivers = new ArrayList<UUID>();
|
||||
List<UUID> receivers = new ArrayList<UUID>();
|
||||
for (Node node : group.getSortedNodes()) {
|
||||
UUID id = node.getComponent().getId();
|
||||
if (!vertices.containsKey(id)) {
|
||||
continue;
|
||||
}
|
||||
if (!members.contains(id)) {
|
||||
members.add(id);
|
||||
}
|
||||
FlowRole role = roleOf(node, hintCache);
|
||||
if (role == FlowRole.OUTPUT && !drivers.contains(id)) {
|
||||
drivers.add(id);
|
||||
} else if (role == FlowRole.INPUT && !receivers.contains(id)) {
|
||||
receivers.add(id);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < members.size(); i++) {
|
||||
for (int j = i + 1; j < members.size(); j++) {
|
||||
vertices.get(members.get(i)).neighbours.add(members.get(j));
|
||||
vertices.get(members.get(j)).neighbours.add(members.get(i));
|
||||
}
|
||||
}
|
||||
for (UUID member : members) {
|
||||
for (UUID driver : drivers) {
|
||||
link(driver, member);
|
||||
}
|
||||
for (UUID receiver : receivers) {
|
||||
link(member, receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void link(UUID from, UUID to) {
|
||||
if (from.equals(to)) {
|
||||
return;
|
||||
}
|
||||
vertices.get(from).drives.add(to);
|
||||
vertices.get(to).drivenBy.add(from);
|
||||
}
|
||||
|
||||
private FlowRole roleOf(Node node, Map<UUID, FlowHints> hintCache) {
|
||||
UUID id = node.getComponent().getId();
|
||||
FlowHints hints;
|
||||
if (hintCache.containsKey(id)) {
|
||||
hints = hintCache.get(id);
|
||||
} else {
|
||||
hints = flowAnalyzer.analyze(node.getComponent());
|
||||
hintCache.put(id, hints);
|
||||
}
|
||||
return hints == null ? FlowRole.NEUTRAL : hints.getRole(node.getPointIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the edges that close a loop, so that the graph can be layered at all.
|
||||
*
|
||||
* <p>
|
||||
* Feedback is not an anomaly here: an op-amp with a feedback network, or a transistor with a
|
||||
* bootstrapped or degenerated bias, produces a cycle in every real circuit of interest. Removing
|
||||
* the edge that closes the loop keeps the forward path intact, which is the one that determines how
|
||||
* the drawing reads.
|
||||
* </p>
|
||||
*/
|
||||
private void breakFeedbackLoops() {
|
||||
Set<UUID> visited = new LinkedHashSet<UUID>();
|
||||
Set<UUID> onPath = new LinkedHashSet<UUID>();
|
||||
for (UUID id : new ArrayList<UUID>(vertices.keySet())) {
|
||||
if (!visited.contains(id)) {
|
||||
removeBackEdges(id, visited, onPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeBackEdges(UUID id, Set<UUID> visited, Set<UUID> onPath) {
|
||||
visited.add(id);
|
||||
onPath.add(id);
|
||||
Vertex vertex = vertices.get(id);
|
||||
for (UUID next : new ArrayList<UUID>(vertex.drives)) {
|
||||
if (onPath.contains(next)) {
|
||||
vertex.drives.remove(next);
|
||||
vertices.get(next).drivenBy.remove(id);
|
||||
} else if (!visited.contains(next)) {
|
||||
removeBackEdges(next, visited, onPath);
|
||||
}
|
||||
}
|
||||
onPath.remove(id);
|
||||
}
|
||||
|
||||
/** Longest path layering over the acyclic graph: a component sits one column after its drivers. */
|
||||
private void assignLayers() {
|
||||
Map<UUID, Integer> remaining = new LinkedHashMap<UUID, Integer>();
|
||||
List<UUID> ready = new ArrayList<UUID>();
|
||||
for (Vertex vertex : vertices.values()) {
|
||||
vertex.layer = 0;
|
||||
remaining.put(vertex.id, vertex.drivenBy.size());
|
||||
if (vertex.drivenBy.isEmpty()) {
|
||||
ready.add(vertex.id);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ready.size(); i++) {
|
||||
Vertex vertex = vertices.get(ready.get(i));
|
||||
for (UUID next : vertex.drives) {
|
||||
Vertex target = vertices.get(next);
|
||||
target.layer = Math.max(target.layer, vertex.layer + 1);
|
||||
int left = remaining.get(next) - 1;
|
||||
remaining.put(next, left);
|
||||
if (left == 0) {
|
||||
ready.add(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the parts that no rule could give a direction to - the resistors and capacitors that make
|
||||
* up most of a circuit - towards the components they sit between, so they do not all pile up in the
|
||||
* first column.
|
||||
*/
|
||||
private void spreadUndirectedVertices() {
|
||||
for (int sweep = 0; sweep < ORDERING_SWEEPS; sweep++) {
|
||||
boolean changed = false;
|
||||
for (Vertex vertex : vertices.values()) {
|
||||
if (vertex.isDirected() || vertex.neighbours.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
double sum = 0;
|
||||
int count = 0;
|
||||
for (UUID neighbour : vertex.neighbours) {
|
||||
sum += vertices.get(neighbour).layer;
|
||||
count++;
|
||||
}
|
||||
int target = (int) Math.round(sum / count);
|
||||
if (target != vertex.layer) {
|
||||
vertex.layer = target;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!changed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int distinctLayerCount() {
|
||||
Set<Integer> layers = new LinkedHashSet<Integer>();
|
||||
for (Vertex vertex : vertices.values()) {
|
||||
layers.add(vertex.layer);
|
||||
}
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Spreads the circuit out by distance when nothing declared a direction.
|
||||
*
|
||||
* <p>
|
||||
* Each connected island is measured from one end of its longest chain - found by walking to the
|
||||
* furthest vertex and then measuring from there - and every component takes its column from how far
|
||||
* along it sits. The result is not electrically meaningful the way a driven chain is, but it does
|
||||
* lay the circuit out along its own longest path, which is far closer to a schematic than a single
|
||||
* stack of parts.
|
||||
* </p>
|
||||
*/
|
||||
private void layerByDistance() {
|
||||
Set<UUID> remaining = new LinkedHashSet<UUID>(vertices.keySet());
|
||||
while (!remaining.isEmpty()) {
|
||||
UUID seed = remaining.iterator().next();
|
||||
Map<UUID, Integer> reach = distancesFrom(seed);
|
||||
UUID far = furthest(reach);
|
||||
Map<UUID, Integer> distances = distancesFrom(far);
|
||||
for (Map.Entry<UUID, Integer> entry : distances.entrySet()) {
|
||||
vertices.get(entry.getKey()).layer = entry.getValue();
|
||||
remaining.remove(entry.getKey());
|
||||
}
|
||||
// a vertex with no connections at all is its own island
|
||||
remaining.remove(seed);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<UUID, Integer> distancesFrom(UUID start) {
|
||||
Map<UUID, Integer> distances = new LinkedHashMap<UUID, Integer>();
|
||||
List<UUID> queue = new ArrayList<UUID>();
|
||||
distances.put(start, 0);
|
||||
queue.add(start);
|
||||
for (int i = 0; i < queue.size(); i++) {
|
||||
UUID current = queue.get(i);
|
||||
int next = distances.get(current) + 1;
|
||||
for (UUID neighbour : vertices.get(current).neighbours) {
|
||||
if (!distances.containsKey(neighbour)) {
|
||||
distances.put(neighbour, next);
|
||||
queue.add(neighbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
|
||||
private static UUID furthest(Map<UUID, Integer> distances) {
|
||||
UUID best = null;
|
||||
int bestDistance = -1;
|
||||
for (Map.Entry<UUID, Integer> entry : distances.entrySet()) {
|
||||
if (entry.getValue() > bestDistance) {
|
||||
bestDistance = entry.getValue();
|
||||
best = entry.getKey();
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders each column so that symbols sit near the ones they connect to, which is what keeps the
|
||||
* wires between columns from crossing. Ties fall back to the part's position on the board, so the
|
||||
* schematic keeps a family resemblance to the layout it came from.
|
||||
*/
|
||||
private Map<Integer, List<Vertex>> orderWithinLayers() {
|
||||
Map<Integer, List<Vertex>> byLayer = new LinkedHashMap<Integer, List<Vertex>>();
|
||||
List<Vertex> sorted = new ArrayList<Vertex>(vertices.values());
|
||||
sorted.sort(Comparator.comparingInt((Vertex v) -> v.layer)
|
||||
.thenComparingDouble(Vertex::physicalY));
|
||||
for (Vertex vertex : sorted) {
|
||||
List<Vertex> column = byLayer.get(vertex.layer);
|
||||
if (column == null) {
|
||||
column = new ArrayList<Vertex>();
|
||||
byLayer.put(vertex.layer, column);
|
||||
}
|
||||
column.add(vertex);
|
||||
}
|
||||
|
||||
Map<UUID, Integer> position = new LinkedHashMap<UUID, Integer>();
|
||||
for (List<Vertex> column : byLayer.values()) {
|
||||
for (int i = 0; i < column.size(); i++) {
|
||||
position.put(column.get(i).id, i);
|
||||
}
|
||||
}
|
||||
for (int sweep = 0; sweep < ORDERING_SWEEPS; sweep++) {
|
||||
for (List<Vertex> column : byLayer.values()) {
|
||||
for (Vertex vertex : column) {
|
||||
vertex.barycentre = barycentreOf(vertex, position);
|
||||
}
|
||||
column.sort(Comparator.comparingDouble((Vertex v) -> v.barycentre)
|
||||
.thenComparingDouble(Vertex::physicalY));
|
||||
for (int i = 0; i < column.size(); i++) {
|
||||
position.put(column.get(i).id, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return byLayer;
|
||||
}
|
||||
|
||||
private double barycentreOf(Vertex vertex, Map<UUID, Integer> position) {
|
||||
double sum = 0;
|
||||
int count = 0;
|
||||
for (UUID neighbour : vertex.neighbours) {
|
||||
Integer at = position.get(neighbour);
|
||||
if (at != null) {
|
||||
sum += at;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count == 0 ? position.get(vertex.id) : sum / count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns columns and orders into pixel positions. Each column is as wide as its widest symbol, and a
|
||||
* symbol is placed by its bounding box rather than by a control point, so that a part standing
|
||||
* upright cannot hang out of its cell.
|
||||
*/
|
||||
private void assignCoordinates(Map<Integer, List<Vertex>> byLayer) {
|
||||
List<Integer> layers = new ArrayList<Integer>(byLayer.keySet());
|
||||
Collections.sort(layers);
|
||||
double x = MARGIN;
|
||||
for (Integer layer : layers) {
|
||||
List<Vertex> column = byLayer.get(layer);
|
||||
double columnWidth = 0;
|
||||
for (Vertex vertex : column) {
|
||||
columnWidth = Math.max(columnWidth, boundsOf(vertex.entries).getWidth());
|
||||
}
|
||||
double y = MARGIN;
|
||||
for (Vertex vertex : column) {
|
||||
Rectangle2D bounds = boundsOf(vertex.entries);
|
||||
// centre the symbol in its column so that a narrow part sits under a wide one
|
||||
double offsetX = x + (columnWidth - bounds.getWidth()) / 2;
|
||||
moveBoundsTo(vertex.entries, bounds, snap(offsetX), snap(y));
|
||||
y += bounds.getHeight() + ROW_GAP;
|
||||
}
|
||||
x += columnWidth + COLUMN_GAP;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return the box spanned by every control point of every symbol the component produced. */
|
||||
private static Rectangle2D boundsOf(List<SymbolEntry> entries) {
|
||||
double minX = Double.MAX_VALUE;
|
||||
double minY = Double.MAX_VALUE;
|
||||
double maxX = -Double.MAX_VALUE;
|
||||
double maxY = -Double.MAX_VALUE;
|
||||
for (SymbolEntry entry : entries) {
|
||||
for (int i = 0; i < entry.symbol.getControlPointCount(); i++) {
|
||||
Point2D p = entry.symbol.getControlPoint(i);
|
||||
minX = Math.min(minX, p.getX());
|
||||
minY = Math.min(minY, p.getY());
|
||||
maxX = Math.max(maxX, p.getX());
|
||||
maxY = Math.max(maxY, p.getY());
|
||||
}
|
||||
}
|
||||
if (minX > maxX) {
|
||||
return new Rectangle2D.Double(0, 0, 0, 0);
|
||||
}
|
||||
return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
private static void moveBoundsTo(List<SymbolEntry> entries, Rectangle2D bounds, double x,
|
||||
double y) {
|
||||
double dx = x - bounds.getX();
|
||||
double dy = y - bounds.getY();
|
||||
for (SymbolEntry entry : entries) {
|
||||
translate(entry.symbol, dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves every control point by the same offset. The targets are worked out before anything is
|
||||
* written, because a rigid component such as SchematicBox rebuilds its remaining points when one of
|
||||
* them is set and would otherwise apply the offset twice.
|
||||
*/
|
||||
private static void translate(IDIYComponent<?> component, double dx, double dy) {
|
||||
int count = component.getControlPointCount();
|
||||
Point2D[] targets = new Point2D[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
Point2D p = component.getControlPoint(i);
|
||||
targets[i] = new Point2D.Double(p.getX() + dx, p.getY() + dy);
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
component.setControlPoint(targets[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
private static double snap(double value) {
|
||||
return Math.round(value / GRID) * GRID;
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import org.diylc.components.passive.PotentiometerSymbol;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Maps physical potentiometers to a {@link PotentiometerSymbol}. The
|
||||
* three package legs are mapped to the symbol legs in index order; if a particular package uses a
|
||||
* different pin-out the user can rotate/relabel the resulting symbol.
|
||||
*/
|
||||
public class PotentiometerSchematicFactory extends AbstractSimpleSchematicFactory {
|
||||
|
||||
@Override
|
||||
protected IDIYComponent<?> createSymbol() {
|
||||
return new PotentiometerSymbol();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int electricalPinCount() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import org.diylc.components.passive.ResistorSymbol;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/** Maps physical resistors to a {@link ResistorSymbol}. */
|
||||
public class ResistorSchematicFactory extends AbstractSimpleSchematicFactory {
|
||||
|
||||
@Override
|
||||
protected IDIYComponent<?> createSymbol() {
|
||||
return new ResistorSymbol();
|
||||
}
|
||||
}
|
||||
@@ -1,707 +0,0 @@
|
||||
/*
|
||||
|
||||
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.schematic;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.OrientationHV;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.connectivity.OrthogonalLine;
|
||||
import org.diylc.components.misc.CommonNode;
|
||||
import org.diylc.components.misc.GroundSymbol;
|
||||
import org.diylc.core.IContinuity;
|
||||
import org.diylc.core.ICommonNode;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.ISwitch;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.SchematicView;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.netlist.Group;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.NetlistBuilder;
|
||||
import org.diylc.netlist.NetlistException;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.ContinuityArea;
|
||||
|
||||
/**
|
||||
* Generates the initial {@link SchematicView} for a layout {@link Project}. Every eligible physical
|
||||
* component is turned into one or more schematic symbols via its {@link ISchematicFactory} (or the
|
||||
* {@link GenericBoxSchematicFactory} fallback), symbols are placed on a connection-density aware
|
||||
* grid and the nets from the layout netlist are drawn as {@link OrthogonalLine}s.
|
||||
*
|
||||
* <p>
|
||||
* Nets that carry a common node (ground, supply rails) are not wired up at all. Each pin on such a
|
||||
* net gets its own ground or common-node stub drawn right next to it, which is how schematics are
|
||||
* conventionally drawn and keeps the densest net in the circuit from crossing the whole drawing.
|
||||
* </p>
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class SchematicBuilder {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(SchematicBuilder.class);
|
||||
|
||||
/** Grid step, in pixels, used for symbol placement. */
|
||||
public static final double GRID = 90d;
|
||||
/** Horizontal/vertical spacing between grid cells, in pixels. */
|
||||
public static final double CELL_SIZE = 220d;
|
||||
public static final double MARGIN = 120d;
|
||||
|
||||
/**
|
||||
* Pin-to-pin span given to every two-terminal symbol. {@link AbstractLeadedComponent} defaults to
|
||||
* a one-inch span (200px) while the schematic symbol bodies are only 0.05in to 0.3in long, so the
|
||||
* default leaves 70 to 95 pixels of bare lead on each side — more lead than body, running well
|
||||
* into the neighbouring cell. Half an inch clears the longest body with a short stub either side
|
||||
* and lands on the 0.1in schematic grid.
|
||||
*/
|
||||
public static final double SYMBOL_PITCH = new Size(0.5d, SizeUnit.in).convertToPixels();
|
||||
|
||||
/** The label {@link GroundSymbol} reports; every other common-node label is treated as a supply. */
|
||||
private static final String GROUND_LABEL = "GND";
|
||||
|
||||
/** Smallest net that may be taken for the ground backbone. */
|
||||
private static final int MIN_BACKBONE_SIZE = 4;
|
||||
|
||||
private final Map<Class<? extends ISchematicFactory>, ISchematicFactory> factoryCache =
|
||||
new HashMap<Class<? extends ISchematicFactory>, ISchematicFactory>();
|
||||
private final GenericBoxSchematicFactory genericFactory = new GenericBoxSchematicFactory();
|
||||
private final WireRouter router = new WireRouter();
|
||||
|
||||
/**
|
||||
* One schematic symbol produced from a physical component together with the physical->schematic
|
||||
* pin mapping that produced it.
|
||||
*/
|
||||
static class SymbolEntry {
|
||||
final IDIYComponent<?> symbol;
|
||||
final Map<Integer, Integer> pinMapping;
|
||||
|
||||
SymbolEntry(IDIYComponent<?> symbol, Map<Integer, Integer> pinMapping) {
|
||||
this.symbol = symbol;
|
||||
this.pinMapping = pinMapping;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Everything the wiring pass produces: the routed wires for ordinary signal nets, and the ground
|
||||
* and supply stubs that stand in for the rail nets.
|
||||
*/
|
||||
static class Wiring {
|
||||
|
||||
private final List<OrthogonalLine> wires = new ArrayList<OrthogonalLine>();
|
||||
private final List<IDIYComponent<?>> stubs = new ArrayList<IDIYComponent<?>>();
|
||||
|
||||
List<OrthogonalLine> getWires() {
|
||||
return wires;
|
||||
}
|
||||
|
||||
List<IDIYComponent<?>> getStubs() {
|
||||
return stubs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the schematic and stores it on {@code project.getOrCreateSchematicView()}, replacing any
|
||||
* previous content.
|
||||
*
|
||||
* @param project the layout project
|
||||
* @param continuityAreas continuity areas from the drawing manager (may be empty)
|
||||
*/
|
||||
public void build(Project project, List<ContinuityArea> continuityAreas) {
|
||||
Netlist netlist = extractNetlist(project, continuityAreas);
|
||||
|
||||
List<IDIYComponent<?>> schematicComponents = new ArrayList<IDIYComponent<?>>();
|
||||
Map<UUID, List<UUID>> physicalToSchematicMap = new LinkedHashMap<UUID, List<UUID>>();
|
||||
Map<UUID, List<SymbolEntry>> entriesByPhysicalId = new LinkedHashMap<UUID, List<SymbolEntry>>();
|
||||
|
||||
List<IDIYComponent<?>> eligible = new ArrayList<IDIYComponent<?>>();
|
||||
for (IDIYComponent<?> physical : project.getComponents()) {
|
||||
if (!isEligible(physical)) {
|
||||
continue;
|
||||
}
|
||||
eligible.add(physical);
|
||||
List<SymbolEntry> entries = createSymbols(physical);
|
||||
if (entries.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<UUID> symbolIds = new ArrayList<UUID>();
|
||||
for (SymbolEntry entry : entries) {
|
||||
schematicComponents.add(entry.symbol);
|
||||
symbolIds.add(entry.symbol.getId());
|
||||
}
|
||||
physicalToSchematicMap.put(physical.getId(), symbolIds);
|
||||
entriesByPhysicalId.put(physical.getId(), entries);
|
||||
}
|
||||
|
||||
placeSymbols(eligible, entriesByPhysicalId, netlist);
|
||||
|
||||
Wiring wiring = createWires(netlist, entriesByPhysicalId);
|
||||
schematicComponents.addAll(wiring.getStubs());
|
||||
schematicComponents.addAll(wiring.getWires());
|
||||
|
||||
schematicComponents.sort(SCHEMATIC_ORDER);
|
||||
|
||||
SchematicView view = project.getOrCreateSchematicView();
|
||||
view.getComponents().clear();
|
||||
view.getComponents().addAll(schematicComponents);
|
||||
view.setPhysicalToSchematicMap(physicalToSchematicMap);
|
||||
resizeCanvasToFit(view);
|
||||
}
|
||||
|
||||
Netlist extractNetlist(Project project, List<ContinuityArea> continuityAreas) {
|
||||
try {
|
||||
List<Netlist> netlists = NetlistBuilder.extractNetlists(false, project,
|
||||
continuityAreas == null ? new ArrayList<ContinuityArea>() : continuityAreas);
|
||||
if (netlists == null || netlists.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return netlists.get(0);
|
||||
} catch (NetlistException e) {
|
||||
LOG.warn("Could not extract netlist for schematic generation: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ eligibility */
|
||||
|
||||
static boolean isEligible(IDIYComponent<?> component) {
|
||||
if (component instanceof ICommonNode) {
|
||||
// ground and supply nodes are not placed as symbols of their own; every pin on their net gets
|
||||
// a freshly generated stub during wiring instead
|
||||
return false;
|
||||
}
|
||||
if (component instanceof ISwitch) {
|
||||
return true; // switches are drawn as symbols (netlist is built with includeSwitches=false)
|
||||
}
|
||||
if (component instanceof IContinuity) {
|
||||
return false; // wires, traces, solder bridges, board strips
|
||||
}
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
if (component.isControlPointSticky(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ symbol creation */
|
||||
|
||||
List<SymbolEntry> createSymbols(IDIYComponent<?> physical) {
|
||||
ISchematicFactory factory = resolveFactory(physical);
|
||||
List<SchematicSymbolMapping> mappings;
|
||||
try {
|
||||
mappings = factory.createSchematicSymbols(physical);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Schematic factory " + factory.getClass().getSimpleName() + " failed for "
|
||||
+ physical.getName() + ", falling back to generic box", e);
|
||||
mappings = genericFactory.createSchematicSymbols(physical);
|
||||
}
|
||||
List<SymbolEntry> entries = new ArrayList<SymbolEntry>();
|
||||
if (mappings != null) {
|
||||
for (SchematicSymbolMapping mapping : mappings) {
|
||||
if (mapping.getSchematicSymbol() == null) {
|
||||
continue;
|
||||
}
|
||||
if (mapping.getSchematicSymbol().getId() == null) {
|
||||
mapping.getSchematicSymbol().setId(UUID.randomUUID());
|
||||
}
|
||||
entries.add(new SymbolEntry(mapping.getSchematicSymbol(), mapping.getPinMapping()));
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ISchematicFactory resolveFactory(IDIYComponent<?> physical) {
|
||||
ComponentType type = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) physical.getClass());
|
||||
Class<? extends ISchematicFactory> factoryClass =
|
||||
type == null ? null : type.getSchematicFactoryClass();
|
||||
if (factoryClass == null) {
|
||||
return genericFactory;
|
||||
}
|
||||
ISchematicFactory cached = factoryCache.get(factoryClass);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
try {
|
||||
ISchematicFactory factory = factoryClass.getDeclaredConstructor().newInstance();
|
||||
factoryCache.put(factoryClass, factory);
|
||||
return factory;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not instantiate schematic factory " + factoryClass.getName()
|
||||
+ ", using generic box", e);
|
||||
return genericFactory;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ placement */
|
||||
|
||||
private void placeSymbols(List<IDIYComponent<?>> eligible,
|
||||
Map<UUID, List<SymbolEntry>> entriesByPhysicalId, Netlist netlist) {
|
||||
Map<UUID, Map<Integer, String>> railPins = railPins(netlist);
|
||||
|
||||
// attitude first: the placement measures each symbol, so it has to see its final geometry
|
||||
for (IDIYComponent<?> physical : eligible) {
|
||||
List<SymbolEntry> entries = entriesByPhysicalId.get(physical.getId());
|
||||
if (entries != null) {
|
||||
orientSymbols(entries, railPins.get(physical.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
new LayeredPlacement().place(eligible, entriesByPhysicalId, netlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses the resting attitude of every two-terminal symbol of one component. A part with a leg on
|
||||
* a rail is a shunt element and stands upright with that leg pointing at the rail it belongs to;
|
||||
* everything else passes signal along the drawing and lies down.
|
||||
*
|
||||
* @param rails pin index -> rail label for this component, or null when it touches no rail
|
||||
*/
|
||||
static void orientSymbols(List<SymbolEntry> entries, Map<Integer, String> rails) {
|
||||
for (SymbolEntry entry : entries) {
|
||||
String railLabel = null;
|
||||
int railPin = -1;
|
||||
if (rails != null) {
|
||||
for (Map.Entry<Integer, Integer> mapped : entry.pinMapping.entrySet()) {
|
||||
String label = rails.get(mapped.getKey());
|
||||
if (label != null && mapped.getValue() < 2) {
|
||||
railLabel = label;
|
||||
railPin = mapped.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (railLabel == null) {
|
||||
applyPitch(entry.symbol, false, false);
|
||||
continue;
|
||||
}
|
||||
// a ground symbol is drawn downward from its point, so the grounded leg belongs at the bottom;
|
||||
// supply labels sit above the part the way they are drawn on paper
|
||||
boolean railAtBottom = GROUND_LABEL.equals(railLabel);
|
||||
applyPitch(entry.symbol, true, (railPin == 0) == railAtBottom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the two terminals of a leaded symbol so that they sit {@link #SYMBOL_PITCH} apart,
|
||||
* centred on wherever the symbol already is. Rigid multi-pin symbols are left untouched — their
|
||||
* geometry comes from an anchor and a pin spacing, not from the terminals.
|
||||
*
|
||||
* <p>
|
||||
* The midpoint is preserved, which is what keeps the label control point (index 2, positioned
|
||||
* relative to the centre by the constructor) correct without having to move it as well.
|
||||
* </p>
|
||||
*
|
||||
* @param vertical stand the symbol upright rather than lying it down
|
||||
* @param flip put control point 0 at the far end (bottom when upright, right when lying down)
|
||||
*/
|
||||
static void applyPitch(IDIYComponent<?> symbol, boolean vertical, boolean flip) {
|
||||
if (!(symbol instanceof AbstractLeadedComponent) || symbol.getControlPointCount() < 2) {
|
||||
return;
|
||||
}
|
||||
Point2D first = symbol.getControlPoint(0);
|
||||
Point2D second = symbol.getControlPoint(1);
|
||||
double cx = (first.getX() + second.getX()) / 2;
|
||||
double cy = (first.getY() + second.getY()) / 2;
|
||||
double half = SYMBOL_PITCH / 2;
|
||||
Point2D near =
|
||||
vertical ? new Point2D.Double(cx, cy - half) : new Point2D.Double(cx - half, cy);
|
||||
Point2D far = vertical ? new Point2D.Double(cx, cy + half) : new Point2D.Double(cx + half, cy);
|
||||
symbol.setControlPoint(flip ? far : near, 0);
|
||||
symbol.setControlPoint(flip ? near : far, 1);
|
||||
}
|
||||
|
||||
/** Places every symbol of {@code entries} into grid cell {@code slot} of {@code totalSlots}. */
|
||||
static void placeAtGridSlot(List<SymbolEntry> entries, int slot, int totalSlots) {
|
||||
int columns = Math.max(1, (int) Math.ceil(Math.sqrt(Math.max(totalSlots, 1))));
|
||||
int col = slot % columns;
|
||||
int row = slot / columns;
|
||||
double baseX = MARGIN + col * CELL_SIZE;
|
||||
double baseY = MARGIN + row * CELL_SIZE;
|
||||
int sub = 0;
|
||||
for (SymbolEntry entry : entries) {
|
||||
moveAnchorTo(entry.symbol, snap(baseX), snap(baseY + sub * (CELL_SIZE / 2)));
|
||||
sub++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects, per physical component, which of its control points sit on a rail net and under which
|
||||
* label, so that placement can stand shunt parts upright.
|
||||
*/
|
||||
static Map<UUID, Map<Integer, String>> railPins(Netlist netlist) {
|
||||
Map<UUID, Map<Integer, String>> result = new HashMap<UUID, Map<Integer, String>>();
|
||||
if (netlist == null) {
|
||||
return result;
|
||||
}
|
||||
for (Group group : netlist.getGroups()) {
|
||||
String label = railLabelOf(group);
|
||||
if (label == null) {
|
||||
continue;
|
||||
}
|
||||
for (Node node : group.getNodes()) {
|
||||
if (node.getComponent() instanceof ICommonNode) {
|
||||
continue;
|
||||
}
|
||||
result.computeIfAbsent(node.getComponent().getId(), k -> new HashMap<Integer, String>())
|
||||
.put(node.getPointIndex(), label);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link NetlistBuilder} emits a single node per common-node label, so a rail net is recognised by
|
||||
* the one common-node member it carries rather than by its size.
|
||||
*
|
||||
* @return the rail label of the net, or null when it is an ordinary signal net
|
||||
*/
|
||||
static String railLabelOf(Group group) {
|
||||
for (Node node : group.getNodes()) {
|
||||
if (node.getComponent() instanceof ICommonNode) {
|
||||
return ((ICommonNode) node.getComponent()).getCommonNodeLabel();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks out the net that behaves like ground: the busiest one that carries no declared rail.
|
||||
*
|
||||
* <p>
|
||||
* Only about one project in eight places a ground symbol, so in most circuits ground arrives as an
|
||||
* ordinary net that simply happens to touch a large share of the components. Left in the layout
|
||||
* graph it makes every part adjacent to every other and flattens the drawing into a single column;
|
||||
* left in the wiring it is chained from one side of the schematic to the other and crosses
|
||||
* everything in between.
|
||||
* </p>
|
||||
*
|
||||
* @return the backbone net, or null when no net is big enough to be taken for one
|
||||
*/
|
||||
static Group backboneNet(Netlist netlist) {
|
||||
if (netlist == null) {
|
||||
return null;
|
||||
}
|
||||
Group largest = null;
|
||||
int largestSize = 0;
|
||||
for (Group group : netlist.getSortedGroups()) {
|
||||
if (railLabelOf(group) != null) {
|
||||
continue;
|
||||
}
|
||||
int size = group.getNodes().size();
|
||||
if (size > largestSize) {
|
||||
largestSize = size;
|
||||
largest = group;
|
||||
}
|
||||
}
|
||||
return largestSize >= MIN_BACKBONE_SIZE ? largest : null;
|
||||
}
|
||||
|
||||
/** Translates every control point of the component so that control point 0 lands on the target. */
|
||||
static void moveAnchorTo(IDIYComponent<?> component, double targetX, double targetY) {
|
||||
int count = component.getControlPointCount();
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
Point2D anchor = component.getControlPoint(0);
|
||||
double dx = targetX - anchor.getX();
|
||||
double dy = targetY - anchor.getY();
|
||||
// Snapshot the target positions before mutating: some components (e.g. SchematicBox) recompute
|
||||
// all of their control points when control point 0 is set, so reading getControlPoint(i) inside
|
||||
// the loop after that would double-apply the offset.
|
||||
Point2D[] targets = new Point2D[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
Point2D p = component.getControlPoint(i);
|
||||
targets[i] = new Point2D.Double(p.getX() + dx, p.getY() + dy);
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
component.setControlPoint(targets[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
private static double snap(double value) {
|
||||
return Math.round(value / GRID) * GRID;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ wiring */
|
||||
|
||||
Wiring createWires(Netlist netlist, Map<UUID, List<SymbolEntry>> entriesByPhysicalId) {
|
||||
Wiring wiring = new Wiring();
|
||||
if (netlist == null) {
|
||||
return wiring;
|
||||
}
|
||||
|
||||
Map<UUID, Rectangle2D> bodies = symbolBodies(entriesByPhysicalId);
|
||||
// wires already routed become obstacles for the ones that follow, so a dense net does not end up
|
||||
// drawing every connection on top of the last
|
||||
List<Line2D> placed = new ArrayList<Line2D>();
|
||||
Group backbone = backboneNet(netlist);
|
||||
|
||||
for (Group group : netlist.getSortedGroups()) {
|
||||
List<Pin> pins = new ArrayList<Pin>();
|
||||
for (Node node : group.getNodes()) {
|
||||
UUID physicalId = node.getComponent().getId();
|
||||
List<SymbolEntry> entries = entriesByPhysicalId.get(physicalId);
|
||||
if (entries == null) {
|
||||
continue;
|
||||
}
|
||||
for (SymbolEntry entry : entries) {
|
||||
Integer schematicIndex = entry.pinMapping.get(node.getPointIndex());
|
||||
if (schematicIndex == null || schematicIndex >= entry.symbol.getControlPointCount()) {
|
||||
continue;
|
||||
}
|
||||
Point2D location = entry.symbol.getControlPoint(schematicIndex);
|
||||
pins.add(new Pin(entry.symbol, schematicIndex,
|
||||
new Point2D.Double(location.getX(), location.getY())));
|
||||
}
|
||||
}
|
||||
|
||||
String railLabel = railLabelOf(group);
|
||||
if (railLabel == null && group == backbone) {
|
||||
// an unlabelled ground net says the same thing drawn as stubs as it does chained across the
|
||||
// whole drawing, and every stub ties back to the same net, so nothing is claimed that is not
|
||||
// already true of the circuit
|
||||
railLabel = GROUND_LABEL;
|
||||
}
|
||||
if (railLabel != null) {
|
||||
// rails are never routed: a lone stub on each pin says the same thing without dragging the
|
||||
// busiest net in the circuit across the drawing
|
||||
for (Pin pin : pins) {
|
||||
wiring.getStubs().add(createRailStub(railLabel, pin.location));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pins.size() < 2) {
|
||||
continue;
|
||||
}
|
||||
// chain the pins after sorting left-to-right, top-to-bottom
|
||||
pins.sort(Comparator.comparingDouble((Pin p) -> p.location.getX())
|
||||
.thenComparingDouble(p -> p.location.getY()));
|
||||
for (int i = 0; i < pins.size() - 1; i++) {
|
||||
Pin a = pins.get(i);
|
||||
Pin b = pins.get(i + 1);
|
||||
OrthogonalLine wire = createWire(a, b, bodies, placed);
|
||||
wiring.getWires().add(wire);
|
||||
placed.addAll(segmentsOf(wire));
|
||||
}
|
||||
}
|
||||
return wiring;
|
||||
}
|
||||
|
||||
/** Creates the ground or supply symbol that stands in for one pin's connection to a rail. */
|
||||
private static IDIYComponent<?> createRailStub(String label, Point2D location) {
|
||||
IDIYComponent<?> stub;
|
||||
if (GROUND_LABEL.equals(label)) {
|
||||
stub = new GroundSymbol();
|
||||
} else {
|
||||
CommonNode node = new CommonNode();
|
||||
node.setValue(label);
|
||||
stub = node;
|
||||
}
|
||||
stub.setId(UUID.randomUUID());
|
||||
stub.setControlPoint(copyOf(location), 0);
|
||||
return stub;
|
||||
}
|
||||
|
||||
private static class Pin {
|
||||
final IDIYComponent<?> symbol;
|
||||
final int pinIndex;
|
||||
final Point2D location;
|
||||
|
||||
Pin(IDIYComponent<?> symbol, int pinIndex, Point2D location) {
|
||||
this.symbol = symbol;
|
||||
this.pinIndex = pinIndex;
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects two pins with a wire whose single bend point is placed so that the wire leaves the
|
||||
* first pin along the axis that pin faces. {@link OrthogonalLine} derives the rest of the route
|
||||
* from that one point, and keeps deriving it as the sticky endpoints follow the symbols around.
|
||||
*/
|
||||
private OrthogonalLine createWire(Pin a, Pin b, Map<UUID, Rectangle2D> bodies,
|
||||
List<Line2D> placed) {
|
||||
List<Rectangle2D> obstacles = new ArrayList<Rectangle2D>();
|
||||
for (Map.Entry<UUID, Rectangle2D> entry : bodies.entrySet()) {
|
||||
// the wire starts and ends on these two symbols, so their own boxes are not obstacles
|
||||
if (!entry.getKey().equals(a.symbol.getId()) && !entry.getKey().equals(b.symbol.getId())) {
|
||||
obstacles.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
WireRouter.Route route = router.route(a.location, exitDirection(a.symbol, a.location),
|
||||
b.location, exitDirection(b.symbol, b.location), obstacles, placed);
|
||||
|
||||
OrthogonalLine wire = new OrthogonalLine();
|
||||
wire.setId(UUID.randomUUID());
|
||||
wire.setStartDirection(route.getStartDirection());
|
||||
wire.setControlPoint(copyOf(a.location), 0);
|
||||
wire.setControlPoint(route.getBendPoint(), 1);
|
||||
wire.setControlPoint(copyOf(b.location), 2);
|
||||
return wire;
|
||||
}
|
||||
|
||||
/** @return the boxes spanned by each symbol's control points, keyed by symbol id. */
|
||||
private static Map<UUID, Rectangle2D> symbolBodies(
|
||||
Map<UUID, List<SymbolEntry>> entriesByPhysicalId) {
|
||||
Map<UUID, Rectangle2D> bodies = new LinkedHashMap<UUID, Rectangle2D>();
|
||||
for (List<SymbolEntry> entries : entriesByPhysicalId.values()) {
|
||||
for (SymbolEntry entry : entries) {
|
||||
Rectangle2D bounds = boundsOf(entry.symbol);
|
||||
if (bounds != null) {
|
||||
bodies.put(entry.symbol.getId(), bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bodies;
|
||||
}
|
||||
|
||||
private static Rectangle2D boundsOf(IDIYComponent<?> symbol) {
|
||||
int count = symbol.getControlPointCount();
|
||||
if (count == 0) {
|
||||
return null;
|
||||
}
|
||||
double minX = Double.MAX_VALUE;
|
||||
double minY = Double.MAX_VALUE;
|
||||
double maxX = -Double.MAX_VALUE;
|
||||
double maxY = -Double.MAX_VALUE;
|
||||
for (int i = 0; i < count; i++) {
|
||||
Point2D p = symbol.getControlPoint(i);
|
||||
minX = Math.min(minX, p.getX());
|
||||
minY = Math.min(minY, p.getY());
|
||||
maxX = Math.max(maxX, p.getX());
|
||||
maxY = Math.max(maxY, p.getY());
|
||||
}
|
||||
return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
private static List<Line2D> segmentsOf(OrthogonalLine wire) {
|
||||
List<Point2D> vertices = WireRouter.vertices(wire.getControlPoint(0), wire.getControlPoint(1),
|
||||
wire.getControlPoint(2), wire.getStartDirection());
|
||||
List<Line2D> segments = new ArrayList<Line2D>();
|
||||
for (int i = 1; i < vertices.size(); i++) {
|
||||
segments.add(new Line2D.Double(vertices.get(i - 1), vertices.get(i)));
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Works out which way a wire should leave a pin.
|
||||
*
|
||||
* <p>
|
||||
* A two terminal symbol has an axis of its own and its leads run along it, so a wire has to carry
|
||||
* on in that direction or it will bend the moment it leaves the lead. Anything else - a box, a
|
||||
* transistor - has its pins pointing away from the body, which the centroid finds well enough.
|
||||
* </p>
|
||||
*/
|
||||
static OrientationHV exitDirection(IDIYComponent<?> symbol, Point2D pinLocation) {
|
||||
int n = symbol.getControlPointCount();
|
||||
if (n == 0) {
|
||||
return OrientationHV.HORIZONTAL;
|
||||
}
|
||||
if (symbol instanceof AbstractLeadedComponent && n >= 2) {
|
||||
Point2D first = symbol.getControlPoint(0);
|
||||
Point2D second = symbol.getControlPoint(1);
|
||||
return Math.abs(second.getX() - first.getX()) >= Math.abs(second.getY() - first.getY())
|
||||
? OrientationHV.HORIZONTAL
|
||||
: OrientationHV.VERTICAL;
|
||||
}
|
||||
double cx = 0;
|
||||
double cy = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
cx += symbol.getControlPoint(i).getX();
|
||||
cy += symbol.getControlPoint(i).getY();
|
||||
}
|
||||
cx /= n;
|
||||
cy /= n;
|
||||
double dx = pinLocation.getX() - cx;
|
||||
double dy = pinLocation.getY() - cy;
|
||||
return Math.abs(dx) >= Math.abs(dy) ? OrientationHV.HORIZONTAL : OrientationHV.VERTICAL;
|
||||
}
|
||||
|
||||
private static Point2D copyOf(Point2D p) {
|
||||
return new Point2D.Double(p.getX(), p.getY());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ misc */
|
||||
|
||||
static void resizeCanvasToFit(SchematicView view) {
|
||||
double maxX = 0;
|
||||
double maxY = 0;
|
||||
for (IDIYComponent<?> component : view.getComponents()) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
Point2D p = component.getControlPoint(i);
|
||||
maxX = Math.max(maxX, p.getX());
|
||||
maxY = Math.max(maxY, p.getY());
|
||||
}
|
||||
}
|
||||
maxX += MARGIN;
|
||||
maxY += MARGIN;
|
||||
if (maxX > view.getWidth().convertToPixels()) {
|
||||
view.setWidth(new Size(maxX, SizeUnit.px));
|
||||
}
|
||||
if (maxY > view.getHeight().convertToPixels()) {
|
||||
view.setHeight(new Size(maxY, SizeUnit.px));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint and hit-test order for the schematic view. Wires go underneath the symbols, and not where
|
||||
* their {@link IDIYComponent#WIRING} z-order would otherwise put them, because the canvas hands a
|
||||
* click to the last matching component in this list. A wire runs right up to the pin it connects
|
||||
* to and its hit area is widened to three pixels, so a wire drawn on top would swallow the clicks
|
||||
* meant for the symbol underneath it and the user could not drag the symbol at all.
|
||||
*/
|
||||
static final Comparator<IDIYComponent<?>> SCHEMATIC_ORDER =
|
||||
Comparator.comparingInt((IDIYComponent<?> c) -> c instanceof OrthogonalLine ? 0 : 1)
|
||||
.thenComparingDouble(SchematicBuilder::zOrderOf);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static double zOrderOf(IDIYComponent<?> component) {
|
||||
ComponentType type = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
return type == null ? IDIYComponent.COMPONENT : type.getZOrder();
|
||||
}
|
||||
|
||||
/** Convenience overload used by callers that already have the drawing manager's areas. */
|
||||
public static void generate(Project project, Collection<ContinuityArea> continuityAreas) {
|
||||
new SchematicBuilder().build(project,
|
||||
continuityAreas == null ? new ArrayList<ContinuityArea>()
|
||||
: new ArrayList<ContinuityArea>(continuityAreas));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user