mirror of
https://github.com/mon/PocketVoltex.git
synced 2026-10-11 16:48:21 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fecd6f5834 | ||
|
|
625f6047ba | ||
|
|
7b06663ee7 | ||
|
|
69ab6a7bb6 | ||
|
|
eb0c5dddba | ||
|
|
5bfbd86b63 | ||
|
|
b4d8df78f1 |
@@ -45,11 +45,21 @@ static const PROGMEM sdvx_config_t defaults = {
|
|||||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
||||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
||||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT},
|
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT},
|
||||||
|
.ledBrightness = 31,
|
||||||
|
.startColour = {0, BRIGHTNESS_MAX, 0}, // green
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitConfig(void) {
|
void InitConfig(void) {
|
||||||
// TODO: if config version changes, migrate settings
|
// if config version changes, migrate settings
|
||||||
switch(eeprom_read_word(&eeConfig.configVersion)) {
|
switch(eeprom_read_word(&eeConfig.configVersion)) {
|
||||||
|
// all of these fall through to upgrade each bit as we go
|
||||||
|
case 2:
|
||||||
|
// load in our defaults
|
||||||
|
memcpy_P(&sdvxConfig, &defaults, CONFIG_SIZE);
|
||||||
|
// update the ones that actually need upgrade
|
||||||
|
eeprom_write_byte(&eeConfig.ledBrightness, sdvxConfig.ledBrightness);
|
||||||
|
eeprom_update_block(&sdvxConfig.startColour, &eeConfig.startColour, sizeof(sdvxConfig.startColour));
|
||||||
|
eeprom_write_word(&eeConfig.configVersion, CONFIG_VERSION);
|
||||||
case CONFIG_VERSION: // nothing needs to change
|
case CONFIG_VERSION: // nothing needs to change
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -70,6 +80,11 @@ void UpdateConfig(void) {
|
|||||||
eeprom_update_block(&sdvxConfig, &eeConfig, CONFIG_SIZE);
|
eeprom_update_block(&sdvxConfig, &eeConfig, CONFIG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadDefaults(void) {
|
||||||
|
memcpy_P(&sdvxConfig, &defaults, CONFIG_SIZE);
|
||||||
|
eeprom_update_block(&sdvxConfig, &eeConfig, CONFIG_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
command_response_t HandleConfig(uint8_t* buffer) {
|
command_response_t HandleConfig(uint8_t* buffer) {
|
||||||
command_t *command = (command_t*)buffer;
|
command_t *command = (command_t*)buffer;
|
||||||
switch(command->command) {
|
switch(command->command) {
|
||||||
@@ -89,6 +104,9 @@ command_response_t HandleConfig(uint8_t* buffer) {
|
|||||||
case SETCONFIG:
|
case SETCONFIG:
|
||||||
SetConfig(&command->data.config);
|
SetConfig(&command->data.config);
|
||||||
return IGNORE;
|
return IGNORE;
|
||||||
|
case DEFAULTCONFIG:
|
||||||
|
LoadDefaults();
|
||||||
|
return IGNORE;
|
||||||
case RESET:
|
case RESET:
|
||||||
return REBOOT;
|
return REBOOT;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
#define JOYSTICK_PPR (24 * 4)
|
#define JOYSTICK_PPR (24 * 4)
|
||||||
#define MAGIC_RESET_NUMBER 42
|
#define MAGIC_RESET_NUMBER 42
|
||||||
// divide by 10 for actual version
|
// divide by 10 for actual version
|
||||||
#define FIRMWARE_VERSION 14
|
#define FIRMWARE_VERSION 15
|
||||||
// increment whenever config structure has breaking changes
|
// increment whenever config structure has breaking changes
|
||||||
#define CONFIG_VERSION 2
|
#define CONFIG_VERSION 3
|
||||||
|
|
||||||
// not configurable since they're all the same switches
|
// not configurable since they're all the same switches
|
||||||
#define SWITCH_DEBOUNCE 30
|
#define SWITCH_DEBOUNCE 30
|
||||||
@@ -46,6 +46,10 @@ typedef struct {
|
|||||||
// Reused for both tap or hold, at the end in case I decide to extend
|
// Reused for both tap or hold, at the end in case I decide to extend
|
||||||
uint8_t macroLen; // placeholder not used yet
|
uint8_t macroLen; // placeholder not used yet
|
||||||
uint8_t macroPin[4];
|
uint8_t macroPin[4];
|
||||||
|
|
||||||
|
// added in firmware 1.5
|
||||||
|
uint8_t ledBrightness; // rev6 and up
|
||||||
|
RGB_t startColour;
|
||||||
} ATTR_PACKED sdvx_config_t;
|
} ATTR_PACKED sdvx_config_t;
|
||||||
|
|
||||||
#define CONFIG_SIZE sizeof(sdvx_config_t)
|
#define CONFIG_SIZE sizeof(sdvx_config_t)
|
||||||
@@ -59,6 +63,7 @@ typedef enum {
|
|||||||
GETCONFIG = 1,
|
GETCONFIG = 1,
|
||||||
SETCONFIG = 2,
|
SETCONFIG = 2,
|
||||||
VERSION = 3, // synced with bootloader, DO NOT CHANGE
|
VERSION = 3, // synced with bootloader, DO NOT CHANGE
|
||||||
|
DEFAULTCONFIG = 4,
|
||||||
RESET = MAGIC_RESET_NUMBER
|
RESET = MAGIC_RESET_NUMBER
|
||||||
} command_action_t;
|
} command_action_t;
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM LEDReport[] =
|
|||||||
HID_RI_USAGE_PAGE(8, 0x0A), // Ordinals
|
HID_RI_USAGE_PAGE(8, 0x0A), // Ordinals
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
0x79, STRING_ID_LED_Indiv, //HID_RI_STRING_MINIMUM(8, STRING_ID_LED_Indiv),
|
0x89, STRING_ID_LED_Indiv, //HID_RI_STRING_MINIMUM(8, STRING_ID_LED_Indiv),
|
||||||
0x89, STRING_ID_LED_Indiv + LED_TOTAL_COUNT, //HID_RI_STRING_MAXIMUM(8, STRING_ID_LED_Indiv + LED_COUNT),
|
0x99, STRING_ID_LED_Indiv + LED_TOTAL_COUNT, //HID_RI_STRING_MAXIMUM(8, STRING_ID_LED_Indiv + LED_COUNT),
|
||||||
HID_RI_USAGE_MINIMUM(8, 1), // LED 1
|
HID_RI_USAGE_MINIMUM(8, 1), // LED 1
|
||||||
HID_RI_USAGE_MAXIMUM(8, LED_TOTAL_COUNT), // LED 8 + buttons
|
HID_RI_USAGE_MAXIMUM(8, LED_TOTAL_COUNT), // LED 8 + buttons
|
||||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||||
@@ -368,38 +368,71 @@ const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Po
|
|||||||
const USB_Descriptor_String_t PROGMEM LEDString = USB_STRING_DESCRIPTOR(L"Pocket Voltex LEDs");
|
const USB_Descriptor_String_t PROGMEM LEDString = USB_STRING_DESCRIPTOR(L"Pocket Voltex LEDs");
|
||||||
const USB_Descriptor_String_t PROGMEM ControlsString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Controls");
|
const USB_Descriptor_String_t PROGMEM ControlsString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Controls");
|
||||||
const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Config");
|
const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Config");
|
||||||
// There may be a better way to do this
|
|
||||||
const USB_Descriptor_String_t PROGMEM LEDString_indiv[] = {
|
const USB_Descriptor_String_t PROGMEM
|
||||||
USB_STRING_DESCRIPTOR(L"L1-B"),
|
LEDString_01 = USB_STRING_DESCRIPTOR(L"Top Left R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L1-G"),
|
LEDString_02 = USB_STRING_DESCRIPTOR(L"Top Left G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L1-R"),
|
LEDString_03 = USB_STRING_DESCRIPTOR(L"Top Left B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L2-B"),
|
LEDString_04 = USB_STRING_DESCRIPTOR(L"Top Right R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L2-G"),
|
LEDString_05 = USB_STRING_DESCRIPTOR(L"Top Right G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L2-R"),
|
LEDString_06 = USB_STRING_DESCRIPTOR(L"Top Right B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L3-B"),
|
LEDString_07 = USB_STRING_DESCRIPTOR(L"Upper Left R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L3-G"),
|
LEDString_08 = USB_STRING_DESCRIPTOR(L"Upper Left G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L3-R"),
|
LEDString_09 = USB_STRING_DESCRIPTOR(L"Upper Left B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L4-B"),
|
LEDString_10 = USB_STRING_DESCRIPTOR(L"Upper Right R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L4-G"),
|
LEDString_11 = USB_STRING_DESCRIPTOR(L"Upper Right G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L4-R"),
|
LEDString_12 = USB_STRING_DESCRIPTOR(L"Upper Right B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L5-B"),
|
LEDString_13 = USB_STRING_DESCRIPTOR(L"Lower Left R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L5-G"),
|
LEDString_14 = USB_STRING_DESCRIPTOR(L"Lower Left G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L5-R"),
|
LEDString_15 = USB_STRING_DESCRIPTOR(L"Lower Left B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L6-B"),
|
LEDString_16 = USB_STRING_DESCRIPTOR(L"Lower Right R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L6-G"),
|
LEDString_17 = USB_STRING_DESCRIPTOR(L"Lower Right G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L6-R"),
|
LEDString_18 = USB_STRING_DESCRIPTOR(L"Lower Right B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L7-B"),
|
LEDString_19 = USB_STRING_DESCRIPTOR(L"Bottom Left R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L7-G"),
|
LEDString_20 = USB_STRING_DESCRIPTOR(L"Bottom Left G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L7-R"),
|
LEDString_21 = USB_STRING_DESCRIPTOR(L"Bottom Left B"),
|
||||||
USB_STRING_DESCRIPTOR(L"L8-B"),
|
LEDString_22 = USB_STRING_DESCRIPTOR(L"Bottom Right R"),
|
||||||
USB_STRING_DESCRIPTOR(L"L8-G"),
|
LEDString_23 = USB_STRING_DESCRIPTOR(L"Bottom Right G"),
|
||||||
USB_STRING_DESCRIPTOR(L"L8-R"),
|
LEDString_24 = USB_STRING_DESCRIPTOR(L"Bottom Right B"),
|
||||||
USB_STRING_DESCRIPTOR(L"BT-A"),
|
LEDString_25 = USB_STRING_DESCRIPTOR(L"BT-A"),
|
||||||
USB_STRING_DESCRIPTOR(L"BT-B"),
|
LEDString_26 = USB_STRING_DESCRIPTOR(L"BT-B"),
|
||||||
USB_STRING_DESCRIPTOR(L"BT-C"),
|
LEDString_27 = USB_STRING_DESCRIPTOR(L"BT-C"),
|
||||||
USB_STRING_DESCRIPTOR(L"BT-D"),
|
LEDString_28 = USB_STRING_DESCRIPTOR(L"BT-D"),
|
||||||
USB_STRING_DESCRIPTOR(L"FX-L"),
|
LEDString_29 = USB_STRING_DESCRIPTOR(L"FX-L"),
|
||||||
USB_STRING_DESCRIPTOR(L"FX-R"),
|
LEDString_30 = USB_STRING_DESCRIPTOR(L"FX-R"),
|
||||||
|
LEDString_31 = USB_STRING_DESCRIPTOR(L"START");
|
||||||
|
const USB_Descriptor_String_t *LEDString_indiv[] = {
|
||||||
|
&LEDString_01,
|
||||||
|
&LEDString_02,
|
||||||
|
&LEDString_03,
|
||||||
|
&LEDString_04,
|
||||||
|
&LEDString_05,
|
||||||
|
&LEDString_06,
|
||||||
|
&LEDString_07,
|
||||||
|
&LEDString_08,
|
||||||
|
&LEDString_09,
|
||||||
|
&LEDString_10,
|
||||||
|
&LEDString_11,
|
||||||
|
&LEDString_12,
|
||||||
|
&LEDString_13,
|
||||||
|
&LEDString_14,
|
||||||
|
&LEDString_15,
|
||||||
|
&LEDString_16,
|
||||||
|
&LEDString_17,
|
||||||
|
&LEDString_18,
|
||||||
|
&LEDString_19,
|
||||||
|
&LEDString_20,
|
||||||
|
&LEDString_21,
|
||||||
|
&LEDString_22,
|
||||||
|
&LEDString_23,
|
||||||
|
&LEDString_24,
|
||||||
|
&LEDString_25,
|
||||||
|
&LEDString_26,
|
||||||
|
&LEDString_27,
|
||||||
|
&LEDString_28,
|
||||||
|
&LEDString_29,
|
||||||
|
&LEDString_30,
|
||||||
|
&LEDString_31,
|
||||||
};
|
};
|
||||||
|
|
||||||
void USB_Process_BOS(void) {
|
void USB_Process_BOS(void) {
|
||||||
@@ -499,9 +532,9 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|||||||
Size = pgm_read_byte(&ConfigString.Header.Size);
|
Size = pgm_read_byte(&ConfigString.Header.Size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(DescriptorNumber >= STRING_ID_LED_Indiv) {
|
if(DescriptorNumber >= STRING_ID_LED_Indiv && DescriptorNumber < (STRING_ID_LED_Indiv + LED_TOTAL_COUNT)) {
|
||||||
Address = &(LEDString_indiv[STRING_ID_LED_Indiv - DescriptorNumber]);
|
Address = LEDString_indiv[DescriptorNumber - STRING_ID_LED_Indiv];
|
||||||
Size = pgm_read_byte(&LEDString_indiv[STRING_ID_LED_Indiv - DescriptorNumber].Header.Size);
|
Size = pgm_read_byte(&(LEDString_indiv[DescriptorNumber - STRING_ID_LED_Indiv]->Header.Size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
#define LED_COUNT 8
|
#define LED_COUNT 8
|
||||||
#define LED_PHYSICAL_COUNT (LED_COUNT*3)
|
#define LED_PHYSICAL_COUNT (LED_COUNT*3)
|
||||||
// BT + FX
|
// BT + FX + START
|
||||||
#define LED_VIRTUAL_COUNT 6
|
#define LED_VIRTUAL_COUNT 7
|
||||||
#define LED_TOTAL_COUNT (LED_PHYSICAL_COUNT + LED_VIRTUAL_COUNT)
|
#define LED_TOTAL_COUNT (LED_PHYSICAL_COUNT + LED_VIRTUAL_COUNT)
|
||||||
// Internally how many brightness levels you can use - for higher res fades
|
// Internally how many brightness levels you can use - for higher res fades
|
||||||
#define BRIGHTNESS_LEVELS 256
|
#define BRIGHTNESS_LEVELS 256
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
#include <Config.h>
|
||||||
|
|
||||||
#define R 0
|
#define R 0
|
||||||
#define G 1
|
#define G 1
|
||||||
#define B 2
|
#define B 2
|
||||||
|
|
||||||
// range 0-31
|
|
||||||
#define SK9822_BRIGHTNESS 31
|
|
||||||
|
|
||||||
static const uint8_t SK9822_map[] = {0, 2, 4, 6, 7, 5, 3, 1};
|
static const uint8_t SK9822_map[] = {0, 2, 4, 6, 7, 5, 3, 1};
|
||||||
|
|
||||||
void led_init(void) {
|
void led_init(void) {
|
||||||
@@ -38,7 +37,7 @@ void led_commit(void) {
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < LED_COUNT; i++)
|
for (uint8_t i = 0; i < LED_COUNT; i++)
|
||||||
{
|
{
|
||||||
SPI_write(0xe0|SK9822_BRIGHTNESS); // Maximum global brightness
|
SPI_write(0xe0 | (sdvxConfig.ledBrightness & 31)); // Maximum global brightness
|
||||||
uint8_t offset = SK9822_map[i] * 3;
|
uint8_t offset = SK9822_map[i] * 3;
|
||||||
SPI_write(leds[offset+B]);
|
SPI_write(leds[offset+B]);
|
||||||
SPI_write(leds[offset+G]);
|
SPI_write(leds[offset+G]);
|
||||||
|
|||||||
@@ -210,6 +210,10 @@ int main(void)
|
|||||||
led_set_rgb(ledMap[i-1], &sdvxConfig.fxColour);
|
led_set_rgb(ledMap[i-1], &sdvxConfig.fxColour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// START
|
||||||
|
if(switches[0].state) {
|
||||||
|
led_set_all_rgb(&sdvxConfig.startColour);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// knob lights go above all
|
// knob lights go above all
|
||||||
@@ -409,6 +413,9 @@ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDI
|
|||||||
led_set_rgb(ledMap[i], &sdvxConfig.fxColour);
|
led_set_rgb(ledMap[i], &sdvxConfig.fxColour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(LEDReport->btFx[6]) { // start
|
||||||
|
led_set_all_rgb(&sdvxConfig.startColour);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
avrdude -c usbasp -p atmega16u2 -U lfuse:w:0xde:m -U hfuse:w:0xda:m -U efuse:w:0xfe:m -U flash:w:PocketVoltex_WithBoot.hex:i
|
||||||
@@ -20,7 +20,7 @@ OPTIMIZATION = s
|
|||||||
TARGET = PocketVoltex
|
TARGET = PocketVoltex
|
||||||
SRC = $(TARGET).c asciihid.c Descriptors.c Config.c Encoder.c LED.c LEDPatterns.c Macro.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
SRC = $(TARGET).c asciihid.c Descriptors.c Config.c Encoder.c LED.c LEDPatterns.c Macro.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||||
LUFA_PATH = ../LUFA
|
LUFA_PATH = ../LUFA
|
||||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
|
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -Werror
|
||||||
LD_FLAGS =
|
LD_FLAGS =
|
||||||
|
|
||||||
AVRDUDE = avrdude -c usbasp -p $(MCU)
|
AVRDUDE = avrdude -c usbasp -p $(MCU)
|
||||||
@@ -72,7 +72,7 @@ rfuse:
|
|||||||
wfuse:
|
wfuse:
|
||||||
# no more HWB, boot directly to bootloader
|
# no more HWB, boot directly to bootloader
|
||||||
$(AVRDUDE) -U lfuse:w:0xde:m -U hfuse:w:0xda:m -U efuse:w:0xfe:m
|
$(AVRDUDE) -U lfuse:w:0xde:m -U hfuse:w:0xda:m -U efuse:w:0xfe:m
|
||||||
|
|
||||||
disablereset:
|
disablereset:
|
||||||
$(AVRDUDE) -U lfuse:w:0xde:m -U hfuse:w:0x9a:m -U efuse:w:0xfe:m
|
$(AVRDUDE) -U lfuse:w:0xde:m -U hfuse:w:0x9a:m -U efuse:w:0xfe:m
|
||||||
|
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
Make visible only the layers you care for
|
|
||||||
Select all art:
|
|
||||||
(Layer = 'TopOverlay') And Not IsComponentPrimitive
|
|
||||||
Then move to "Artwork Export" layer
|
|
||||||
|
|
||||||
File -> Export -> DXF/DWG
|
|
||||||
Autocad 2007, DXF, Metric
|
|
||||||
Check "Export pads" "On dedicated hole layers"
|
|
||||||
Tracks "Export with rounded"
|
|
||||||
Primitives to export with zero line width "All"
|
|
||||||
Layers "Currently visible"
|
|
||||||
|
|
||||||
Open dxf in inkscape
|
|
||||||
>Manual scale
|
|
||||||
>Factor 1.0
|
|
||||||
x/y axis origin 0,0
|
|
||||||
|
|
||||||
Select the pad which is the origin
|
|
||||||
Go to transform->move and see where it is in mm by unchecking Relative Move.
|
|
||||||
Offset is pad position + (pad size / 2) + (pad stroke width / 2) (in mm, often 0.1325mm)
|
|
||||||
Reopen file and use new x/y axis origin
|
|
||||||
|
|
||||||
Delete via layer
|
|
||||||
Delete pad layer
|
|
||||||
|
|
||||||
For board shape:
|
|
||||||
Select the 2 curves, right click "Move to layer" keepout
|
|
||||||
Select all
|
|
||||||
Path->Combine
|
|
||||||
Go to node tool (below mouse, left toolbar)
|
|
||||||
Select all again
|
|
||||||
Click "Join selected nodes" in toolbar
|
|
||||||
|
|
||||||
Delete layer 0
|
|
||||||
|
|
||||||
For artwork laser cutting output:
|
|
||||||
Cross reference with altium to make layers for tracks
|
|
||||||
Use filtering, it's fast
|
|
||||||
1.5mm
|
|
||||||
1.2mm
|
|
||||||
1mm
|
|
||||||
0.75mm
|
|
||||||
0.5mm
|
|
||||||
0.254mm
|
|
||||||
Raster Fill
|
|
||||||
|
|
||||||
For tracks:
|
|
||||||
Select all
|
|
||||||
Stroke style -> Width = the track width (use mm)
|
|
||||||
Cap: round
|
|
||||||
Path->Combine
|
|
||||||
Path->Stroke to path
|
|
||||||
|
|
||||||
For raster:
|
|
||||||
Path->Combine each shape
|
|
||||||
Go to node tool (below mouse, left toolbar)
|
|
||||||
Select each shape one-by-one, select all nodes
|
|
||||||
Click "Join selected nodes" in toolbar
|
|
||||||
|
|
||||||
Move everything into 1 layer
|
|
||||||
Path->Union everything for artwork to render properly
|
|
||||||
|
|
||||||
Extensions->Modify Path->Flatten Beziers (flatness 0.1)
|
|
||||||
Save as -> Desktop cutting plotter dxf
|
|
||||||
Use LWPOLYLINE
|
|
||||||
Base unit mm
|
|
||||||
Visible layers only
|
|
||||||
|
|
||||||
|
|
||||||
Finally, once it's inside RDWorks - Select all, Handle->Curve auto close, "Force to close"
|
|
||||||
Otherwise, you will get rendering errors on some letters
|
|
||||||
|
|
||||||
Best engraving - very thin circles - cut, 150mm/s, 14%
|
|
||||||
- POCKET VOLTEX and MACRO text - engrave, 240mm/s, 17%
|
|
||||||
- rest - engrave, 240mm/s, 15%
|
|
||||||
- cutting - 14mm/s, 70%
|
|
||||||
Don't forget 0.05mm interval for engrave
|
|
||||||
@@ -0,0 +1,563 @@
|
|||||||
|
use <imports/font.ttf>
|
||||||
|
use <imports/dimlines.scad>
|
||||||
|
|
||||||
|
include <board_primitives.scad>
|
||||||
|
use <board_shape.scad>
|
||||||
|
use <case.scad>
|
||||||
|
use <utils.scad>
|
||||||
|
|
||||||
|
$fn = 128;
|
||||||
|
|
||||||
|
// palette, adjust actual values if needed
|
||||||
|
black = "black";
|
||||||
|
white = "white";
|
||||||
|
grey = "gray";
|
||||||
|
blue = [0.15,0.5,0.75,1];
|
||||||
|
pink = [0.86,0.24,0.46,1];
|
||||||
|
orange = "orange";
|
||||||
|
|
||||||
|
border_offset = 1;
|
||||||
|
|
||||||
|
// enabled in commandline flags
|
||||||
|
enable_bleed = 0;
|
||||||
|
module bleed_trim() {
|
||||||
|
if(enable_bleed) {
|
||||||
|
board();
|
||||||
|
} else {
|
||||||
|
art_outline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module box_polygon(width, height, inset_len_bot, inset_len_top,
|
||||||
|
inset_len_side, inset = 1.6) {
|
||||||
|
// always nice angles
|
||||||
|
inset_begin = inset > 0 ? inset : -inset;
|
||||||
|
inset_end = inset > 0 ? -inset : inset;
|
||||||
|
bot_off = (width - inset_len_bot) / 2;
|
||||||
|
top_off = (width - inset_len_top) / 2;
|
||||||
|
side_off = (height - inset_len_side) / 2;
|
||||||
|
translate([-width/2, -height/2])
|
||||||
|
polygon([
|
||||||
|
// bottom
|
||||||
|
[0,0],
|
||||||
|
[bot_off,0],
|
||||||
|
[bot_off+inset_begin, inset],
|
||||||
|
[width-bot_off+inset_end,inset],
|
||||||
|
[width-bot_off,0],
|
||||||
|
[width,0],
|
||||||
|
// right
|
||||||
|
[width, side_off],
|
||||||
|
[width-inset, side_off+inset_begin],
|
||||||
|
[width-inset, height-side_off+inset_end],
|
||||||
|
[width, height-side_off],
|
||||||
|
[width, height],
|
||||||
|
// top
|
||||||
|
[width-top_off, height],
|
||||||
|
[width-top_off+inset_end, height-inset],
|
||||||
|
[top_off+inset_begin, height-inset],
|
||||||
|
[top_off,height],
|
||||||
|
[0, height],
|
||||||
|
// left
|
||||||
|
[0, height-side_off],
|
||||||
|
[inset, height-side_off+inset_end],
|
||||||
|
[inset, side_off+inset_begin],
|
||||||
|
[0, side_off],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module box_outline(thick, width, height, inset_len_bot, inset_len_top,
|
||||||
|
inset_len_side, inset = 1.6) {
|
||||||
|
difference() {
|
||||||
|
box_polygon(width, height, inset_len_bot, inset_len_top,
|
||||||
|
inset_len_side, inset);
|
||||||
|
offset(-thick)
|
||||||
|
box_polygon(width, height, inset_len_bot, inset_len_top,
|
||||||
|
inset_len_side, inset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btbox_width = 125;
|
||||||
|
btbox_height = 35;
|
||||||
|
btbox_inset_len_bot = 49.5;
|
||||||
|
btbox_inset_len_top = 69;
|
||||||
|
btbox_inset_len_side = 25;
|
||||||
|
module bt_box_polygon() {
|
||||||
|
translate([0, bt_map[1][1]-1])
|
||||||
|
box_polygon(btbox_width, btbox_height, btbox_inset_len_bot,
|
||||||
|
btbox_inset_len_top, btbox_inset_len_side);
|
||||||
|
}
|
||||||
|
module bt_box_outline() {
|
||||||
|
translate([0, bt_map[1][1]-1])
|
||||||
|
box_outline(0.8, btbox_width, btbox_height, btbox_inset_len_bot,
|
||||||
|
btbox_inset_len_top, btbox_inset_len_side);
|
||||||
|
}
|
||||||
|
|
||||||
|
fxbox_width = 44;
|
||||||
|
fxbox_height = 19;
|
||||||
|
fxbox_inset_len_bot = 20;
|
||||||
|
fxbox_inset_len_top = 20;
|
||||||
|
fxbox_inset_len_side = 10;
|
||||||
|
module fx_box_polygon() {
|
||||||
|
box_polygon(fxbox_width, fxbox_height, fxbox_inset_len_bot,
|
||||||
|
fxbox_inset_len_top, fxbox_inset_len_side);
|
||||||
|
}
|
||||||
|
module fx_box_outline() {
|
||||||
|
box_outline(0.8, fxbox_width, fxbox_height, fxbox_inset_len_bot,
|
||||||
|
fxbox_inset_len_top, fxbox_inset_len_side);
|
||||||
|
}
|
||||||
|
|
||||||
|
module fx_inner() {
|
||||||
|
intersection() {
|
||||||
|
fx()
|
||||||
|
offset(-1.6)
|
||||||
|
fx_box_polygon();
|
||||||
|
|
||||||
|
bleed_trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module fx_outline() {
|
||||||
|
intersection() {
|
||||||
|
fx()
|
||||||
|
fx_box_outline();
|
||||||
|
|
||||||
|
bleed_trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module fx_keepout() {
|
||||||
|
fx()
|
||||||
|
fx_box_polygon();
|
||||||
|
}
|
||||||
|
|
||||||
|
module sdvx_text(string, size=3) {
|
||||||
|
text(string, font="Digital:style=Regular", size=size, halign="center", valign="center");
|
||||||
|
}
|
||||||
|
|
||||||
|
module tick(width, height, radius) {
|
||||||
|
translate([-width/2,radius]) {
|
||||||
|
//square([width,height]);
|
||||||
|
square([width, height-width]);
|
||||||
|
translate([width/2,height-width])
|
||||||
|
circle(d=width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_highlights(offset) {
|
||||||
|
intersection() {
|
||||||
|
bleed_trim();
|
||||||
|
translate(offset)
|
||||||
|
ring(encoder_radius_board-top_plate_shrink, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_ticks() {
|
||||||
|
ticks_radius = encoder_radius + 1.9;
|
||||||
|
ticks = [
|
||||||
|
// ticks per rev, width, height
|
||||||
|
[128, 0.2, 0.75],
|
||||||
|
[64, 0.2, 1.5],
|
||||||
|
[16, 0.4, 2],
|
||||||
|
[8, 0.8, 2.5],
|
||||||
|
[4, 1, 3.3],
|
||||||
|
];
|
||||||
|
intersection() {
|
||||||
|
bleed_trim();
|
||||||
|
union() {
|
||||||
|
encoders()
|
||||||
|
ring(encoder_radius+top_plate_shrink*2, 0.4);
|
||||||
|
|
||||||
|
for(t = ticks) {
|
||||||
|
interval = 360/t[0];
|
||||||
|
for(i = [0:t[0]-1]) {
|
||||||
|
rot = interval * i;
|
||||||
|
encoders()
|
||||||
|
rotate([0,0,rot])
|
||||||
|
tick(t[1], t[2], ticks_radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module perspective_mesh(thick, num_horiz, num_vert, bottom_width, top_width, top_height) {
|
||||||
|
translate([-bottom_width/2,0])
|
||||||
|
for(x = [0:num_horiz]) {
|
||||||
|
logguh = ((x / num_horiz) * 9) + 1; // input 1-10 so log is 0-1
|
||||||
|
height = top_height * log(logguh);
|
||||||
|
polygon([
|
||||||
|
[0, height],
|
||||||
|
[bottom_width, height],
|
||||||
|
[bottom_width, height+thick],
|
||||||
|
[0, height+thick]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
top_offset = (bottom_width - top_width) / 2;
|
||||||
|
translate([-bottom_width/2,0])
|
||||||
|
for(y = [0:num_vert]) {
|
||||||
|
startx = bottom_width / num_vert * y;
|
||||||
|
endx = top_width / num_vert * y;
|
||||||
|
polygon([
|
||||||
|
[startx, 0],
|
||||||
|
[endx - thick/2 + top_offset, top_height],
|
||||||
|
[endx + thick/2 + top_offset, top_height],
|
||||||
|
[startx+thick, 0]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module labels() {
|
||||||
|
// BT
|
||||||
|
for(s = [ for (i = [1:4]) bt_map[i] ]) {
|
||||||
|
translate([s.x, s.y - 13])
|
||||||
|
sdvx_text(s[4]);
|
||||||
|
}
|
||||||
|
// FX
|
||||||
|
for(s = fx_map) {
|
||||||
|
translate([s.x, s.y + 13])
|
||||||
|
sdvx_text(s[4]);
|
||||||
|
}
|
||||||
|
// START
|
||||||
|
s = bt_map[0];
|
||||||
|
translate([s.x + 0.15, s.y - 11.5])
|
||||||
|
sdvx_text(s[4]);
|
||||||
|
|
||||||
|
// MACRO
|
||||||
|
translate(macro_pos + [0,3.5])
|
||||||
|
sdvx_text("MACRO", 1.5);
|
||||||
|
|
||||||
|
// VOL
|
||||||
|
translate([0,-24]) {
|
||||||
|
translate(encoder_map[0] + [0.5,0])
|
||||||
|
sdvx_text("VOL-L", 4);
|
||||||
|
translate(encoder_map[1] + [0,0])
|
||||||
|
sdvx_text("VOL-R", 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module start_arrows() {
|
||||||
|
tri_base = 7;
|
||||||
|
tri_height = 2.5;
|
||||||
|
s = bt_map[0];
|
||||||
|
for(i = [-1:2:1]) {
|
||||||
|
translate([s.x + i*12, s.y - tri_base/2])
|
||||||
|
polygon([
|
||||||
|
[0,0],
|
||||||
|
[0, tri_base],
|
||||||
|
[tri_height*i, tri_base/2]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module start_necklace_half() {
|
||||||
|
thick = 1.5;
|
||||||
|
top_thick = 6;
|
||||||
|
bottom_y = -15.5;
|
||||||
|
pivot_point = 30;
|
||||||
|
top_x = 48.5;
|
||||||
|
top_y = 10;
|
||||||
|
|
||||||
|
intersection() {
|
||||||
|
polygon([
|
||||||
|
[0,bottom_y],
|
||||||
|
[pivot_point+thick, bottom_y],
|
||||||
|
[top_x+top_thick/2, top_y],
|
||||||
|
[top_x-top_thick/2, top_y],
|
||||||
|
[pivot_point, bottom_y+thick],
|
||||||
|
[0, bottom_y+thick],
|
||||||
|
]);
|
||||||
|
bleed_trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module start_necklace() {
|
||||||
|
start_necklace_half();
|
||||||
|
mirror([1,0,0])
|
||||||
|
start_necklace_half();
|
||||||
|
}
|
||||||
|
|
||||||
|
module logo() {
|
||||||
|
w = 16;
|
||||||
|
translate([0,-82.9]) {
|
||||||
|
box_outline(0.3, 23, 2.0, w, w, 2, inset = -0.5);
|
||||||
|
sdvx_text("POCKET VOLTEX", 1.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module macro_arrows() {
|
||||||
|
tri_w = 2;
|
||||||
|
tri_h = 1;
|
||||||
|
tri_off = tri_w/2;
|
||||||
|
|
||||||
|
translate(macro_pos) {
|
||||||
|
for(r = [0:180:180]) {
|
||||||
|
rotate([0,0,r])
|
||||||
|
translate([macro_diam/2 + 0.6,0])
|
||||||
|
polygon([
|
||||||
|
[0,0],
|
||||||
|
[tri_h, tri_off],
|
||||||
|
[tri_h, -tri_off]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is actually straight up disgusting
|
||||||
|
module angled_lines(segments, offset = [0,0], prev) {
|
||||||
|
num_segs = len(segments);
|
||||||
|
if(num_segs > 0) {
|
||||||
|
s = segments[0];
|
||||||
|
difference() {
|
||||||
|
translate(offset) {
|
||||||
|
difference() {
|
||||||
|
rotate([0, 0, s[2]])
|
||||||
|
translate([-s.y/2,-s.y/2])
|
||||||
|
difference() {
|
||||||
|
// extra len for cutting off
|
||||||
|
square([s.x+s.y, s.y]);
|
||||||
|
}
|
||||||
|
if(prev == undef || s.y >= prev.y) {
|
||||||
|
rotate([0,0,90+prev[2]])
|
||||||
|
translate([-s.y,-s.x*2])
|
||||||
|
square([s.y,s.x*4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(num_segs > 1 && (prev == undef || s.y >= prev.y)) {
|
||||||
|
diff = [cos(s[2])*s.x - s.y/2,sin(s[2])*s.x];
|
||||||
|
translate(diff)
|
||||||
|
rotate([0,0,90+segments[1][2]])
|
||||||
|
translate([segments[1].y/2,-s.x/2])
|
||||||
|
square([s.y*2,s.x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(num_segs > 1) {
|
||||||
|
s = segments[0];
|
||||||
|
diff = [cos(s[2])*s.x - s.y/2,sin(s[2])*s.x];
|
||||||
|
|
||||||
|
angled_lines([ for (i = [1:num_segs-1]) segments[i] ],
|
||||||
|
offset + diff,
|
||||||
|
s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module wings_half() {
|
||||||
|
entry_thick = 5;
|
||||||
|
down_thick = 4;
|
||||||
|
exit_thick = 5;
|
||||||
|
gap = 0.5;
|
||||||
|
count = 4;
|
||||||
|
|
||||||
|
entry_x = 27;
|
||||||
|
entry_y = -2;
|
||||||
|
|
||||||
|
down_x = entry_x + 4;
|
||||||
|
down_y = entry_y - 35;
|
||||||
|
|
||||||
|
exit_x = down_x + 20;
|
||||||
|
exit_y = down_y - 5;
|
||||||
|
|
||||||
|
offx = down_thick+gap - 2;
|
||||||
|
offy = entry_thick+gap;
|
||||||
|
|
||||||
|
angle = 55;
|
||||||
|
|
||||||
|
difference() {
|
||||||
|
intersection() {
|
||||||
|
translate([-85,-27])
|
||||||
|
union() {
|
||||||
|
len1 = 20;
|
||||||
|
width1 = 4;
|
||||||
|
ang1 = -10;
|
||||||
|
ang2 = -85;
|
||||||
|
difference() {
|
||||||
|
angled_lines([
|
||||||
|
[len1,width1,ang1],
|
||||||
|
[37,2,-84],
|
||||||
|
[11,2,-20],
|
||||||
|
]);
|
||||||
|
translate([35,-51])
|
||||||
|
rotate([0,0,13])
|
||||||
|
square([60,25]);
|
||||||
|
}
|
||||||
|
for(i = [1:3]) {
|
||||||
|
translate([-i*2,-i*4])
|
||||||
|
angled_lines([
|
||||||
|
[len1,width1, ang1 - i*7],
|
||||||
|
[36-i*3,2,ang2+i],
|
||||||
|
[20+i*2,2,-22+i*3],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
/*for(i=[0:count-1]) {
|
||||||
|
translate([i*offx,i*offy])
|
||||||
|
polygon([
|
||||||
|
[0,0],
|
||||||
|
[entry_x, entry_y],
|
||||||
|
[down_x, down_y],
|
||||||
|
[exit_x, exit_y],
|
||||||
|
|
||||||
|
[exit_x, exit_y+exit_thick],
|
||||||
|
[down_x+down_thick/2, down_y+exit_thick/2],
|
||||||
|
[entry_x, entry_thick+entry_y],
|
||||||
|
[0,entry_thick],
|
||||||
|
]);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
bleed_trim();
|
||||||
|
}
|
||||||
|
offset(border_offset)
|
||||||
|
fx_keepout();
|
||||||
|
offset(border_offset)
|
||||||
|
bt_box_polygon();
|
||||||
|
// kill some bleed in a hacky way
|
||||||
|
translate([0,-15])
|
||||||
|
fx_keepout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module wings() {
|
||||||
|
wings_half();
|
||||||
|
mirror([1,0])
|
||||||
|
wings_half();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*line(length, width=DIM_LINE_WIDTH,
|
||||||
|
height=DIM_HEIGHT,
|
||||||
|
left_arrow=false,
|
||||||
|
right_arrow=false
|
||||||
|
)*/
|
||||||
|
|
||||||
|
module dims_single(width, y_offset) {
|
||||||
|
line_size = 0.4;
|
||||||
|
font_scale = 0.5;
|
||||||
|
|
||||||
|
line_start_y = 48;
|
||||||
|
line_length = y_offset - line_start_y + 5;
|
||||||
|
|
||||||
|
translate([-width/2,-y_offset])
|
||||||
|
dimensions(width, line_size, DIM_FONTSCALE=font_scale);
|
||||||
|
|
||||||
|
reflect()
|
||||||
|
translate([-width/2,-line_start_y])
|
||||||
|
rotate([0,0,-90])
|
||||||
|
line(line_length, width=line_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
module draw_dimensions() {
|
||||||
|
width = board_width();
|
||||||
|
small_width = board_width() - top_plate_shrink*2;
|
||||||
|
|
||||||
|
// we want 2D
|
||||||
|
projection() {
|
||||||
|
dims_single(width, 100);
|
||||||
|
dims_single(small_width, 90);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork_white() {
|
||||||
|
labels();
|
||||||
|
logo();
|
||||||
|
start_arrows();
|
||||||
|
start_necklace();
|
||||||
|
wings();
|
||||||
|
macro_arrows();
|
||||||
|
bt_box_outline();
|
||||||
|
fx_outline();
|
||||||
|
knob_ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork_grey() {
|
||||||
|
// mesh. big difference() to keep it out of the other sections
|
||||||
|
difference() {
|
||||||
|
intersection() {
|
||||||
|
bleed_trim();
|
||||||
|
translate([0,-90])
|
||||||
|
perspective_mesh(0.3, 23, 15/*14*3, 7*3*/, 450, -50, 150);
|
||||||
|
}
|
||||||
|
offset(border_offset) {
|
||||||
|
bt_box_polygon();
|
||||||
|
fx_keepout();
|
||||||
|
labels();
|
||||||
|
start_arrows();
|
||||||
|
start_necklace();
|
||||||
|
wings();
|
||||||
|
rad = encoder_radius_board-top_plate_shrink;
|
||||||
|
encoders() circle(r=rad, center = true);
|
||||||
|
logo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork_orange() {
|
||||||
|
fx_inner();
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork_blue() {
|
||||||
|
knob_highlights(encoder_map[0]);
|
||||||
|
}
|
||||||
|
module artwork_pink() {
|
||||||
|
knob_highlights(encoder_map[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork_2d() {
|
||||||
|
artwork_white();
|
||||||
|
artwork_grey();
|
||||||
|
artwork_orange();
|
||||||
|
artwork_pink();
|
||||||
|
artwork_blue();
|
||||||
|
}
|
||||||
|
|
||||||
|
module artwork() {
|
||||||
|
color(black)
|
||||||
|
linear_extrude(0.05)
|
||||||
|
bleed_trim();
|
||||||
|
|
||||||
|
color(white)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
artwork_white();
|
||||||
|
|
||||||
|
color(grey)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
artwork_grey();
|
||||||
|
|
||||||
|
color(orange)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
artwork_orange();
|
||||||
|
|
||||||
|
color(blue)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
artwork_blue();
|
||||||
|
|
||||||
|
color(pink)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
artwork_pink();
|
||||||
|
|
||||||
|
/*color(black)
|
||||||
|
linear_extrude(0.1)
|
||||||
|
draw_dimensions();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// override in commandline
|
||||||
|
build = "render";
|
||||||
|
if(build == "render") {
|
||||||
|
// correct lighting for fullbright
|
||||||
|
//light_from_above()
|
||||||
|
artwork();
|
||||||
|
} else if(build == "black") {
|
||||||
|
bleed_trim();
|
||||||
|
} else if(build == "white") {
|
||||||
|
artwork_white();
|
||||||
|
} else if(build == "grey") {
|
||||||
|
artwork_grey();
|
||||||
|
} else if(build == "orange") {
|
||||||
|
artwork_orange();
|
||||||
|
} else if(build == "blue") {
|
||||||
|
artwork_blue();
|
||||||
|
} else if(build == "pink") {
|
||||||
|
artwork_pink();
|
||||||
|
} else if(build == "cuts") {
|
||||||
|
art_outline();
|
||||||
|
} else if(build == "dimensions") {
|
||||||
|
draw_dimensions();
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
use <utils.scad>
|
||||||
|
|
||||||
|
black = [0.1,0.1,0.1];
|
||||||
|
blue = [0,0.6,1];
|
||||||
|
// x, y, keycap width in units, colour, text
|
||||||
|
bt_map = [[0,0, 1, blue, "START"],
|
||||||
|
[-42.862,-37.592, 1.25, "white", "BT-A"],
|
||||||
|
[ 42.862,-37.592, 1.25, "white", "BT-D"],
|
||||||
|
[-14.287,-37.592, 1.25, "white", "BT-B"],
|
||||||
|
[ 14.287,-37.592, 1.25, "white", "BT-C"]];
|
||||||
|
fx_map = [[-33.3375,-75.692, 2.25, black, "FX-L"],
|
||||||
|
[ 33.3375,-75.692, 2.25, black, "FX-R"]];
|
||||||
|
|
||||||
|
bolt_map = [[37.4, 6.65],
|
||||||
|
[80.5, -15.5],
|
||||||
|
[80.5, 16.5],
|
||||||
|
[52.732, -82.792]
|
||||||
|
];
|
||||||
|
encoder_map = [[-73,0.5],
|
||||||
|
[ 73,0.5]];
|
||||||
|
// Not the encoders themselves, but the cutout that surrounds them
|
||||||
|
encoder_radius = 13;
|
||||||
|
// and for the board outline
|
||||||
|
encoder_radius_board = 22.222;
|
||||||
|
|
||||||
|
// encoder solder points hit the case unless we cut these out
|
||||||
|
// x, y, hole size
|
||||||
|
encoder_holes = [[-8, 0, 4],
|
||||||
|
[ 8, 0, 4]];
|
||||||
|
// the 3 A/B/Gnd connections
|
||||||
|
// x (mirrored), y, hole size
|
||||||
|
encoder_hull = [5, -10.5, 3];
|
||||||
|
|
||||||
|
// x, y, rotation
|
||||||
|
led_map = [[47.1, -1.7, 0],
|
||||||
|
[65, -30, 90],
|
||||||
|
[57, -68, 45],
|
||||||
|
[12, -80, 0]];
|
||||||
|
led_size = [7.5, 6.5];
|
||||||
|
|
||||||
|
macro_pos = [0,-75.692];
|
||||||
|
macro_diam = 4.8;
|
||||||
|
|
||||||
|
usb_dims = [11, 12];
|
||||||
|
usb_pos = [-26.52, 10.17];
|
||||||
|
|
||||||
|
// So you get a little clear acrylic edge and it looks nice
|
||||||
|
top_plate_shrink = 1;
|
||||||
|
|
||||||
|
fudge = 0.2;
|
||||||
|
|
||||||
|
bolt_diam = 2;
|
||||||
|
bolt_fudge = 0.1;
|
||||||
|
bolt_size = bolt_diam + bolt_fudge;
|
||||||
|
spacer_size = bolt_size + 1.7 + fudge; // extra wiggle
|
||||||
|
|
||||||
|
module bolts() {
|
||||||
|
reflect([1,0,0])
|
||||||
|
for(bolt = bolt_map) {
|
||||||
|
translate(bolt)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module bolts_external() {
|
||||||
|
bolts()
|
||||||
|
circle(d=bolt_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
module bolts_internal() {
|
||||||
|
bolts()
|
||||||
|
circle(d=spacer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
module switches(map, apply_scaling, colour) {
|
||||||
|
for(sw = map) {
|
||||||
|
color(colour ? sw[3] : "gray")
|
||||||
|
translate([sw.x,sw.y])
|
||||||
|
scale([apply_scaling ? sw[2] : 1,1])
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module bt(apply_scaling = false, colour = true) {
|
||||||
|
switches(bt_map, apply_scaling, colour)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module fx(apply_scaling = false, colour = true) {
|
||||||
|
switches(fx_map, apply_scaling, colour)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module switches_all(apply_scaling = false, colour = true) {
|
||||||
|
switches(fx_map, apply_scaling, colour)
|
||||||
|
children();
|
||||||
|
switches(bt_map, apply_scaling, colour)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module encoders() {
|
||||||
|
for(enc = encoder_map) {
|
||||||
|
translate(enc)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module leds() {
|
||||||
|
reflect([1,0,0])
|
||||||
|
for(led = led_map) {
|
||||||
|
translate([led.x, led.y])
|
||||||
|
rotate([0,0,led[2]])
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
include <board_primitives.scad>
|
||||||
|
use <utils.scad>
|
||||||
|
use <cutouts.scad>
|
||||||
|
|
||||||
|
encoder_side_gap = 11;
|
||||||
|
function board_width() = (abs(encoder_map[0][0]) + encoder_side_gap)*2;
|
||||||
|
|
||||||
|
module board_half() {
|
||||||
|
// 1mm gap for the important bits
|
||||||
|
top_gap = 10.16;
|
||||||
|
|
||||||
|
// arbitrary
|
||||||
|
height = 96.64;
|
||||||
|
angled_xoff = 55;
|
||||||
|
|
||||||
|
// calculated
|
||||||
|
width = board_width()/2;
|
||||||
|
|
||||||
|
// main body
|
||||||
|
translate([0, -height + top_gap])
|
||||||
|
difference() {
|
||||||
|
square([width, height]);
|
||||||
|
|
||||||
|
translate([angled_xoff,0])
|
||||||
|
rotate([0,0,-35])
|
||||||
|
square([width, height]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// encoder bits
|
||||||
|
difference() {
|
||||||
|
translate(encoder_map[1])
|
||||||
|
circle(r=encoder_radius_board);
|
||||||
|
|
||||||
|
translate([width, -height/2])
|
||||||
|
square([width, height]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module board() {
|
||||||
|
reflect([1,0,0])
|
||||||
|
board_half();
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_outline() {
|
||||||
|
difference() {
|
||||||
|
board();
|
||||||
|
encoder_cutouts(smooth = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
board();
|
||||||
+29
-23
@@ -1,4 +1,6 @@
|
|||||||
use <case.scad>;
|
use <case.scad>;
|
||||||
|
use <board_primitives.scad>
|
||||||
|
use <board_shape.scad>
|
||||||
|
|
||||||
$fn=128;
|
$fn=128;
|
||||||
|
|
||||||
@@ -13,48 +15,54 @@ else if(produce == 2)
|
|||||||
else if(produce == 3)
|
else if(produce == 3)
|
||||||
padding();
|
padding();
|
||||||
|
|
||||||
knobOffset = 74;
|
knobOffset = 83;
|
||||||
knobY = -83;
|
knobY = -83;
|
||||||
main_thickness = 37.5;
|
main_thickness = 42;
|
||||||
bottom_thickness = 5;
|
bottom_thickness = 5;
|
||||||
padding_thickness = 12;
|
padding_thickness = 14;
|
||||||
|
|
||||||
encoders = [[-64,0.4],
|
|
||||||
[ 64,0.4]];
|
|
||||||
encoderShaftHole = 5.5;
|
encoderShaftHole = 5.5;
|
||||||
|
|
||||||
finger = 20;
|
// to work out viewports for render
|
||||||
fingerX = -75;
|
//echo(str($vpt[0],",",$vpt[1],",",$vpt[2],",",$vpr[0],",",$vpr[1],",",$vpr[2],",",$vpd));
|
||||||
fingerY = -25;
|
|
||||||
|
|
||||||
squeeze = 0; // so things are held tight
|
// x, y, size
|
||||||
|
finger_holes = [
|
||||||
|
[85, -25, 20],
|
||||||
|
[-85, -25, 20],
|
||||||
|
[0, 5, 20],
|
||||||
|
[0, -85, 20],
|
||||||
|
];
|
||||||
|
|
||||||
|
loosen = 3; // so things aren't impossible to remove
|
||||||
gap = 1; // for the top cover
|
gap = 1; // for the top cover
|
||||||
|
|
||||||
size = [180, 140];
|
size = [200, 140];
|
||||||
|
|
||||||
module mainCuts() {
|
module mainCuts() {
|
||||||
difference() {
|
difference() {
|
||||||
translate([0,-30])
|
translate([0,-30])
|
||||||
square(size, center = true);
|
square(size, center = true);
|
||||||
|
|
||||||
offset(delta = -squeeze)
|
offset(delta = loosen)
|
||||||
board();
|
board();
|
||||||
|
|
||||||
translate([-knobOffset, knobY])
|
translate([-knobOffset, knobY])
|
||||||
circle(d = 25 - squeeze);
|
circle(d = 25 + loosen);
|
||||||
translate([knobOffset,knobY])
|
translate([knobOffset,knobY])
|
||||||
circle(d = 25 - squeeze);
|
circle(d = 25 + loosen);
|
||||||
|
|
||||||
translate([0, 15])
|
// not needed any more
|
||||||
square([80, 3], center = true);
|
//translate([0, 15])
|
||||||
|
//square([80, 3], center = true);
|
||||||
|
|
||||||
translate([0, 28])
|
translate([0, 28])
|
||||||
square([100, 13], center = true);
|
square([100, 13], center = true);
|
||||||
|
|
||||||
translate([fingerX,fingerY])
|
for(f = finger_holes) {
|
||||||
circle(d=finger);
|
translate([f.x,f.y])
|
||||||
translate([-fingerX,fingerY])
|
circle(d=f[2]);
|
||||||
circle(d=finger);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,10 +71,8 @@ module padding() {
|
|||||||
offset(delta = -gap)
|
offset(delta = -gap)
|
||||||
board();
|
board();
|
||||||
|
|
||||||
for(e = encoders) {
|
encoders()
|
||||||
translate(e)
|
circle(d=encoderShaftHole);
|
||||||
circle(d=encoderShaftHole);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
call .\build_case.bat
|
||||||
|
call .\build_box.bat
|
||||||
|
call .\build_art_svg.bat
|
||||||
|
call .\build_animation.bat
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
python build_animation.py
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# openscad will not adjust viewports set in code when rendering from the cmdline
|
||||||
|
# what a shame! so we do it here
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from math import floor, ceil
|
||||||
|
|
||||||
|
scad = 'C:\\Program Files\\OpenSCAD\\openscad.exe'
|
||||||
|
folder = 'outputs'
|
||||||
|
|
||||||
|
final_size = [800, 600]
|
||||||
|
render_size = [x*2 for x in final_size]
|
||||||
|
|
||||||
|
def quad_ease_inout(t):
|
||||||
|
return 2*t*t if t<.5 else -1+(4-2*t)*t
|
||||||
|
|
||||||
|
def interpolate(vec, index_float):
|
||||||
|
vec1 = vec[floor(index_float)]
|
||||||
|
vec2 = vec[ceil(index_float)]
|
||||||
|
percent = index_float % 1
|
||||||
|
return [percent*(high-low) + low for low, high in zip(vec1, vec2)]
|
||||||
|
|
||||||
|
def thread_call(args):
|
||||||
|
print(' '.join(args))
|
||||||
|
subprocess.check_output(args)
|
||||||
|
|
||||||
|
def gen_args():
|
||||||
|
interval = 2
|
||||||
|
percents = [i / 100.0 for i in range(0, 100+interval, interval)]
|
||||||
|
|
||||||
|
# vpt[3], vpr[3], vpd[1]
|
||||||
|
anim = [
|
||||||
|
[0, -65.9053, 71.5148, 30, 0, 0, 360],
|
||||||
|
[-16.5687, -50.6543, 84.6026, 66.5,0, -37.8, 550.777]
|
||||||
|
]
|
||||||
|
|
||||||
|
for p in percents:
|
||||||
|
camera = interpolate(anim, quad_ease_inout(p))
|
||||||
|
args = [
|
||||||
|
scad,
|
||||||
|
'-o', "{}/anim_{}.png".format(folder, p),
|
||||||
|
'-D', '$t={}'.format(p),
|
||||||
|
'--imgsize={}'.format(','.join(str(x) for x in render_size)),
|
||||||
|
'--camera={}'.format(','.join(str(x) for x in camera)),
|
||||||
|
'--colorscheme=Tomorrow',
|
||||||
|
'--projection=p',
|
||||||
|
'case.scad',
|
||||||
|
'-D', 'build="render"'
|
||||||
|
]
|
||||||
|
yield args
|
||||||
|
|
||||||
|
from multiprocessing.dummy import Pool as ThreadPool
|
||||||
|
pool = ThreadPool(4)
|
||||||
|
pool.map(thread_call, gen_args())
|
||||||
|
|
||||||
|
def call_and_log(cmd):
|
||||||
|
print(cmd)
|
||||||
|
os.system(cmd)
|
||||||
|
# openscad has no anti-aliasing so let's just do it ourselves
|
||||||
|
pngs = [arg[2] for arg in gen_args()]
|
||||||
|
pngs = ['-delay 200', pngs[0], '-delay 5'] + pngs[1:-1] + ['-delay 200', pngs[-1]]
|
||||||
|
call_and_log('bash -c "convert {pngs} -resize {img_size} \\"{folder}/render_animation.gif\\""'.format(
|
||||||
|
pngs=' '.join(pngs),
|
||||||
|
folder=folder,
|
||||||
|
img_size='x'.join(str(x) for x in final_size)))
|
||||||
|
call_and_log('bash -c "rm {folder}/anim_*.png"'.format(folder=folder))
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
@echo off
|
||||||
|
SET scad="C:\Program Files\OpenSCAD\openscad.exe"
|
||||||
|
SET inkscape="C:\Program Files\Inkscape\inkscape.exe"
|
||||||
|
SET folder=outputs
|
||||||
|
|
||||||
|
for %%i in (black,white,grey,orange,blue,pink,cuts,dimensions) DO (
|
||||||
|
@echo on
|
||||||
|
%scad% -o "%folder%\art_%%i.svg" "artwork.scad" -D enable_bleed=1 -D "build=\"%%i\""
|
||||||
|
)
|
||||||
|
|
||||||
|
python stack_art.py
|
||||||
|
%inkscape% --export-png=outputs/artwork.png --export-dpi=1200 --without-gui outputs/artwork.svg
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
for %%i in (black,white,grey,orange,blue,pink,cuts,dimensions) DO (
|
||||||
|
del "%folder%\art_%%i.svg"
|
||||||
|
)
|
||||||
|
|
||||||
|
REM pause
|
||||||
@@ -3,7 +3,11 @@ SET scad="C:\Program Files\OpenSCAD\openscad.exe"
|
|||||||
SET folder=outputs
|
SET folder=outputs
|
||||||
|
|
||||||
@echo on
|
@echo on
|
||||||
%scad% -o "%folder%\layer0_5mm_box_bottom.dxf" "box.scad" -D produce=1
|
%scad% -o "%folder%\5mm_box_bottom.dxf" "box.scad" -D produce=1
|
||||||
%scad% -o "%folder%\layer1_37.5mm_box_middle.dxf" "box.scad" -D produce=2
|
%scad% -o "%folder%\42mm_box_middle.dxf" "box.scad" -D produce=2
|
||||||
%scad% -o "%folder%\layer1.5_12mm_box_insert.dxf" "box.scad" -D produce=3
|
%scad% -o "%folder%\14mm_box_insert.dxf" "box.scad" -D produce=3
|
||||||
pause
|
|
||||||
|
%scad% -o "%folder%\render_box.png" "box.scad" -D produce=0 --colorscheme=Tomorrow --imgsize=3840,4320 --camera=32.3082,9.69532,33.9842,45.9,0,314.3,839.47 --projection=p
|
||||||
|
bash -c "convert '%folder%/render_box.png' -resize 960x1080 '%folder%/render_box.png'"
|
||||||
|
|
||||||
|
REM pause
|
||||||
@@ -1,17 +1,37 @@
|
|||||||
@echo off
|
|
||||||
SET scad="C:\Program Files\OpenSCAD\openscad.exe"
|
SET scad="C:\Program Files\OpenSCAD\openscad.exe"
|
||||||
SET folder=outputs
|
SET folder=outputs
|
||||||
|
|
||||||
REM fiducials are for stacking layers - my software centers the piece,
|
REM fiducials are for stacking layers - my software centers the piece,
|
||||||
REM which results in imperfect alignment. Delete them afterwards
|
REM which results in imperfect alignment. Delete them afterwards
|
||||||
REM set to 0 if your software can handle coords properly
|
REM set to 0 if your software can handle coords properly
|
||||||
SET fiducials=1
|
SET fiducials=0
|
||||||
|
|
||||||
for %%i in (bottom_plate,bottom_spacer,top_spacer,top_spacer_engrave,top_plate,top_plate_engrave) DO (
|
REM intitial render
|
||||||
|
for %%i in (bottom_plate,bottom_spacer,top_spacer,top_spacer_engrave,top_reflector,top_plate,art_cutout) DO (
|
||||||
@echo on
|
@echo on
|
||||||
%scad% -o "%folder%\%%i.dxf" "case.scad" -D enable_fiducials=%fiducials% -D "build=\"%%i\""
|
%scad% -o "%folder%\%%i.dxf" "case.scad" -D enable_fiducials=%fiducials% -D "build=\"%%i\""
|
||||||
)
|
)
|
||||||
|
|
||||||
%scad% -o "%folder%\render.png" "case.scad" -D "build=\"render\"" --imgsize=1920,1080 --camera=-9.47,-33.79,17.17,40.30,0.00,313.60,400 --projection=p
|
REM clean polylines for single layers
|
||||||
|
for %%i in (bottom_plate,bottom_spacer,top_plate,top_reflector) DO (
|
||||||
|
@echo on
|
||||||
|
py -2 odmt.py --input "%folder%\%%i.dxf" --output "%folder%\%%i.dxf"
|
||||||
|
)
|
||||||
|
|
||||||
|
REM combine DXF for multiple layers
|
||||||
|
py -2 odmt.py --input "%folder%\top_spacer.dxf" "%folder%\top_spacer_engrave.dxf" --output "%folder%\top_spacer.dxf"
|
||||||
|
|
||||||
|
REM delete the multi-layer leftovers
|
||||||
|
DEL "%folder%\top_spacer_engrave.dxf"
|
||||||
|
|
||||||
|
REM openscad has no anti-aliasing so let's just do it ourselves
|
||||||
|
REM main render
|
||||||
|
%scad% -o "%folder%\render.png" "case.scad" -D "build=\"render\"" --colorscheme=Tomorrow --imgsize=5600,4320 --camera=7.40041,-3.99594,-17.4439,44.5,0,327.6,401.516 --projection=p
|
||||||
|
bash -c "convert '%folder%/render.png' -resize 1400x1080 '%folder%/render.png'"
|
||||||
|
|
||||||
|
REM exploded render
|
||||||
|
%scad% -o "%folder%\render_exploded.png" "case.scad" -D "build=\"render\"" -D $t=1 --colorscheme=Tomorrow --imgsize=3440,4320 --camera=49.3894,45.0844,40.101,66.2,0,320.6,679.971 --projection=p
|
||||||
|
bash -c "convert '%folder%/render_exploded.png' -resize 860x1080 '%folder%/render_exploded.png'"
|
||||||
|
|
||||||
REM pause
|
REM pause
|
||||||
+273
-441
@@ -1,201 +1,214 @@
|
|||||||
|
include <board_primitives.scad>
|
||||||
|
use <board_shape.scad>
|
||||||
|
use <cutouts.scad>
|
||||||
|
use <artwork.scad>
|
||||||
|
|
||||||
use <imports/cherry_mx.scad>
|
use <imports/cherry_mx.scad>
|
||||||
include <imports/mx_keycap.scad>
|
include <imports/mx_keycap.scad>
|
||||||
key_profile_index = 11;
|
key_profile_index = 11;
|
||||||
|
|
||||||
$fn = 512;
|
$fn = 256;
|
||||||
|
|
||||||
black = [0.1,0.1,0.1];
|
|
||||||
blue = [0,0.6,1];
|
|
||||||
// x, y, keycap width in units, rotation, colour
|
|
||||||
switches = [[0,0, 1, 0, blue],
|
|
||||||
[-42.862,-37.592, 1.25, 0, "white"],
|
|
||||||
[ 42.862,-37.592, 1.25, 0, "white"],
|
|
||||||
[-14.287,-37.592, 1.25, 0, "white"],
|
|
||||||
[ 14.287,-37.592, 1.25, 0, "white"],
|
|
||||||
[-37.9,-70.8, 1.75, -22.5, black],
|
|
||||||
[ 37.9,-70.8, 1.75, 22.5, black]];
|
|
||||||
bolts = [[30.025, 6.65],
|
|
||||||
[71, -16.925],
|
|
||||||
[71, 16.5],
|
|
||||||
[42.732, -82.791]
|
|
||||||
];
|
|
||||||
// Not the encoders themselves, but the circle that surrounds them
|
|
||||||
encoders = [[-64,0.4],
|
|
||||||
[ 64,0.4]];
|
|
||||||
encoderRadius = 13;
|
|
||||||
|
|
||||||
// encoder solder points hit the case unless we cut these out
|
|
||||||
// x, y, hole size
|
|
||||||
encoderHoles = [[-8, 0, 4],
|
|
||||||
[ 8, 0, 4]];
|
|
||||||
// the 3 A/B/Gnd connections
|
|
||||||
// x (mirrored), y, hole size
|
|
||||||
encoderHull = [5, -10.5, 3];
|
|
||||||
|
|
||||||
// x, y
|
|
||||||
leds = [[-39.9, -1.4],
|
|
||||||
[-53.6, -26.2],
|
|
||||||
[-54.8, -57.9],
|
|
||||||
[-17.3, -75.7]];
|
|
||||||
ledDims = [6.5, 6.5];
|
|
||||||
|
|
||||||
macroHole = [0,-75.692];
|
|
||||||
macroDiam = 3;
|
|
||||||
|
|
||||||
usbWidth = 9;
|
|
||||||
usbPos = [-21.311, 10.3];
|
|
||||||
// bottom to top, last 2 are white/black sections of the 1 plate
|
|
||||||
plate_thickness = [3, 3, 1.6, 3, 1.5, 0.1];
|
|
||||||
|
|
||||||
fudge = 0.2;
|
|
||||||
|
|
||||||
// So you get a little clear acrylic edge and it looks nice
|
|
||||||
wallOverlap = 1;
|
|
||||||
|
|
||||||
boltDiam = 2;
|
|
||||||
boltFudge = 0.1;
|
|
||||||
boltSize = boltDiam + boltFudge;
|
|
||||||
spacerSize = boltSize + 1.7 + fudge; // extra wiggle
|
|
||||||
|
|
||||||
boltExpand = boltDiam;
|
|
||||||
|
|
||||||
// bolt + half on either side
|
|
||||||
wallStrength = 6;
|
|
||||||
|
|
||||||
// 0 = full spec, 1 = half spec, 2 = plain square
|
|
||||||
holetype = 2;
|
|
||||||
|
|
||||||
// For the animation
|
// For the animation
|
||||||
explodeFactor = 20;
|
explode_factor = 20;
|
||||||
|
|
||||||
module switch(holetype){
|
layer_thickness = [
|
||||||
//Hole size, from Cherry MX data sheet
|
3, // bottom cover
|
||||||
holesize=14;
|
3.5, // bottom spacer
|
||||||
//height of switch clasp cutouts
|
1.6, // PCB
|
||||||
cutoutheight = 3;
|
2, // top spacer
|
||||||
//width of switch clasp cutouts
|
1.5, // top reflector
|
||||||
cutoutwidth = 1;
|
0.1, // artwork
|
||||||
translate([-holesize/2, -holesize/2])
|
1.5, // top cover
|
||||||
if (holetype == 0){
|
1.5, // knob spacer
|
||||||
union(){
|
1.5, // knob cover
|
||||||
square([holesize,holesize]);
|
];
|
||||||
|
|
||||||
translate([-cutoutwidth,1])
|
// to work out viewports for render
|
||||||
square([holesize+2*cutoutwidth,cutoutheight]);
|
//echo(str($vpt[0],",",$vpt[1],",",$vpt[2],",",$vpr[0],",",$vpr[1],",",$vpr[2],",",$vpd));
|
||||||
|
|
||||||
translate([-cutoutwidth,holesize-1-cutoutheight])
|
module bottom_cover() {
|
||||||
square([holesize+2*cutoutwidth,cutoutheight]);
|
difference() {
|
||||||
}
|
board();
|
||||||
} else if (holetype == 1){
|
bolts_external();
|
||||||
union(){
|
}
|
||||||
square([holesize,holesize]);
|
|
||||||
|
|
||||||
translate([-cutoutwidth,1])
|
|
||||||
square([holesize+2*cutoutwidth,holesize-2]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offset(delta = 0.5) // so plate clips can latch
|
|
||||||
square([holesize,holesize]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module switches() {
|
module bottom_spacer() {
|
||||||
for(sw = switches) {
|
difference() {
|
||||||
translate([sw[0], sw[1]])
|
board();
|
||||||
rotate([0,0,sw[3]])
|
bolts_internal();
|
||||||
switch(holetype);
|
switch_socket_holes();
|
||||||
|
mcu_cutout();
|
||||||
|
usb_cutout();
|
||||||
|
encoder_pins();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module pcb() {
|
||||||
|
difference() {
|
||||||
|
board();
|
||||||
|
bolts_internal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_outline_offset() {
|
||||||
|
offset(delta = -top_plate_shrink)
|
||||||
|
top_outline();
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_spacer() {
|
||||||
|
difference() {
|
||||||
|
top_outline();
|
||||||
|
bolts_internal();
|
||||||
|
switch_internal();
|
||||||
|
led_cutouts();
|
||||||
|
macro_internal();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_spacer_engrave() {
|
||||||
|
engraveInterval = 0.05;
|
||||||
|
wallOverlap = 1;
|
||||||
|
// go in intervals of 2 to avoid final implicit union()
|
||||||
|
for(i = [0.05:engraveInterval*2:wallOverlap+engraveInterval]) {
|
||||||
|
difference() {
|
||||||
|
offset(delta=-i)
|
||||||
|
top_outline();
|
||||||
|
|
||||||
|
offset(delta=-(i+engraveInterval))
|
||||||
|
top_outline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_reflector() {
|
||||||
|
difference() {
|
||||||
|
top_outline_offset();
|
||||||
|
bolts_external();
|
||||||
|
switch_internal();
|
||||||
|
macro_internal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module art_outline() {
|
||||||
|
difference() {
|
||||||
|
top_outline_offset();
|
||||||
|
bolts_external();
|
||||||
|
switch_artwork();
|
||||||
|
macro_external();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module top_cover() {
|
||||||
|
difference() {
|
||||||
|
top_outline_offset();
|
||||||
|
bolts_external();
|
||||||
|
switch_external();
|
||||||
|
macro_external();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_spacer() {
|
||||||
|
intersection() {
|
||||||
|
top_outline_offset();
|
||||||
|
|
||||||
|
encoders()
|
||||||
|
circle(r=encoder_radius_board-top_plate_shrink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_cover_panel() {
|
||||||
|
intersection() {
|
||||||
|
offset(delta = -top_plate_shrink)
|
||||||
|
board();
|
||||||
|
|
||||||
|
encoders()
|
||||||
|
circle(r=encoder_radius_board-top_plate_shrink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_cover_holes() {
|
||||||
|
encoders() {
|
||||||
|
circle(d=9.3);
|
||||||
|
|
||||||
|
translate([0,-9])
|
||||||
|
circle(d=3.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_cover() {
|
||||||
|
difference() {
|
||||||
|
// panel
|
||||||
|
knob_cover_panel();
|
||||||
|
|
||||||
|
// panel holes
|
||||||
|
knob_cover_holes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module boop() {
|
||||||
|
difference() {
|
||||||
|
knob_cover_panel();
|
||||||
|
board_half();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module knob_cover_cnc() {
|
||||||
|
difference() {
|
||||||
|
union() {
|
||||||
|
linear_extrude(1.5)
|
||||||
|
difference() {
|
||||||
|
knob_spacer();
|
||||||
|
bolts_external();
|
||||||
|
}
|
||||||
|
|
||||||
|
translate([0,0,1.5])
|
||||||
|
hull() {
|
||||||
|
linear_extrude(0.01)
|
||||||
|
boop();
|
||||||
|
translate([0,0,1.5])
|
||||||
|
linear_extrude(0.01)
|
||||||
|
offset(r=-1.5)
|
||||||
|
boop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linear_extrude(10){
|
||||||
|
bolts_external();
|
||||||
|
knob_cover_holes();
|
||||||
|
}
|
||||||
|
|
||||||
|
translate([0,0,-0.1])
|
||||||
|
linear_extrude(5)
|
||||||
|
board_half();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module macro_model() {
|
||||||
|
translate([0,0,2])
|
||||||
|
rotate([90,0,0])
|
||||||
|
import("imports/KSC521J.stl");
|
||||||
|
}
|
||||||
|
|
||||||
|
module stab_model() {
|
||||||
|
color("gray")
|
||||||
|
rotate([0,0,180])
|
||||||
|
import("imports/mx_pcb_stab_open.stl");
|
||||||
|
}
|
||||||
|
|
||||||
module switch_models() {
|
module switch_models() {
|
||||||
for(sw = switches) {
|
switches_all(colour = false)
|
||||||
translate([sw[0], sw[1]])
|
cherry_mx_model();
|
||||||
rotate([0,0,sw[3]])
|
|
||||||
cherry_mx_model();
|
fx(colour = false)
|
||||||
}
|
stab_model();
|
||||||
}
|
}
|
||||||
|
|
||||||
module switch_keycaps() {
|
module switch_keycaps() {
|
||||||
for(sw = switches) {
|
translate([0,0,11.5])
|
||||||
color(sw[4])
|
switches_all(apply_scaling = true)
|
||||||
translate([sw[0], sw[1], 11.5])
|
key();
|
||||||
rotate([0,0,sw[3]])
|
|
||||||
scale([sw[2],1,1])
|
|
||||||
key();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module bolt_spacers() {
|
|
||||||
for(bolt = bolts) {
|
|
||||||
translate([bolt[0], bolt[1]])
|
|
||||||
circle(d = spacerSize, center = true);
|
|
||||||
|
|
||||||
// mirror
|
|
||||||
translate([-bolt[0], bolt[1]])
|
|
||||||
circle(d = spacerSize, center = true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module bolts() {
|
|
||||||
for(bolt = bolts) {
|
|
||||||
translate([bolt[0], bolt[1]])
|
|
||||||
circle(d = boltSize, center = true);
|
|
||||||
|
|
||||||
// mirror
|
|
||||||
translate([-bolt[0], bolt[1]])
|
|
||||||
circle(d = boltSize, center = true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only used to see if my distances are right
|
|
||||||
module bolts_expansion() {
|
|
||||||
offset(r = boltExpand)
|
|
||||||
bolt_spacers();
|
|
||||||
}
|
|
||||||
|
|
||||||
module enc_smooth() {
|
|
||||||
translate([-10, -9.777])
|
|
||||||
difference() {
|
|
||||||
rotate(-54)
|
|
||||||
translate([-2,0.19])
|
|
||||||
square([4, 2], center=true);
|
|
||||||
|
|
||||||
circle(d=2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module enc_single() {
|
|
||||||
translate([encoders[0][0], encoders[0][1]]) {
|
|
||||||
circle(r=encoderRadius, center = true);
|
|
||||||
// smooth harsh edges
|
|
||||||
enc_smooth();
|
|
||||||
mirror([0,1])
|
|
||||||
enc_smooth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module encoders() {
|
|
||||||
enc_single();
|
|
||||||
mirror([1,0])
|
|
||||||
enc_single();
|
|
||||||
}
|
|
||||||
|
|
||||||
module encoder_holes() {
|
|
||||||
for(enc = encoders) {
|
|
||||||
translate([enc[0], enc[1]]) {
|
|
||||||
// A/B/Gnd
|
|
||||||
hull() {
|
|
||||||
translate([encoderHull[0], encoderHull[1]])
|
|
||||||
circle(d=encoderHull[2], center = true);
|
|
||||||
translate([-encoderHull[0], encoderHull[1]])
|
|
||||||
circle(d=encoderHull[2], center = true);
|
|
||||||
}
|
|
||||||
for(hole = encoderHoles) {
|
|
||||||
translate([hole[0], hole[1]])
|
|
||||||
circle(d=hole[2], center = true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module encoder_knob() {
|
module encoder_knob() {
|
||||||
@@ -209,14 +222,14 @@ module encoder_model(knob = true) {
|
|||||||
import("imports/PEC16.stl");
|
import("imports/PEC16.stl");
|
||||||
|
|
||||||
// Shaft
|
// Shaft
|
||||||
encoderShaft = 6;
|
encoder_shaft = 6;
|
||||||
encoderFlat = 4.5;
|
encoder_flat = 4.5;
|
||||||
translate([0,0,6.5])
|
translate([0,0,6.5])
|
||||||
linear_extrude(20)
|
linear_extrude(20)
|
||||||
intersection() {
|
intersection() {
|
||||||
circle(d = encoderShaft);
|
circle(d = encoder_shaft);
|
||||||
translate([0, (encoderShaft-encoderFlat)/2])
|
translate([0, (encoder_shaft-encoder_flat)/2])
|
||||||
square([encoderShaft, encoderFlat], center = true);
|
square([encoder_shaft, encoder_flat], center = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(knob) {
|
if(knob) {
|
||||||
@@ -225,277 +238,96 @@ module encoder_model(knob = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module encoder_model_full(knob = true) {
|
module animate_layer(index) {
|
||||||
for(enc = encoders) {
|
boom = 20 * quad_ease_inout($t);
|
||||||
translate([enc[0], enc[1]])
|
|
||||||
encoder_model(knob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module led_holes() {
|
|
||||||
led_holes_half();
|
|
||||||
mirror([1,0,0])
|
|
||||||
led_holes_half();
|
|
||||||
}
|
|
||||||
|
|
||||||
module led_holes_half() {
|
|
||||||
for(led = leds) {
|
|
||||||
translate([led[0], led[1]])
|
|
||||||
translate([-ledDims[0]/2, -ledDims[1]/2])
|
|
||||||
square(ledDims);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't do the same thing twice
|
|
||||||
module usb_half() {
|
|
||||||
w = usbWidth / 2;
|
|
||||||
h = wallStrength + fudge*2;
|
|
||||||
curveWidth = h / 2;
|
|
||||||
|
|
||||||
// USB connector origin is at board edge
|
translate([0,0,boom*index + sum(layer_thickness, index)])
|
||||||
translate([0, -h, 0]) {
|
children();
|
||||||
square([w, h]);
|
|
||||||
|
|
||||||
translate([w, curveWidth, 0])
|
|
||||||
difference() {
|
|
||||||
square(curveWidth);
|
|
||||||
translate([curveWidth, 0, 0])
|
|
||||||
circle(r=curveWidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module usb() {
|
module extrude_plate(index) {
|
||||||
usb_half();
|
animate_layer(index)
|
||||||
mirror()
|
linear_extrude(layer_thickness[index])
|
||||||
usb_half();
|
children();
|
||||||
}
|
}
|
||||||
|
|
||||||
module board() {
|
|
||||||
import("imports/BOARD_SHAPE.dxf");
|
|
||||||
}
|
|
||||||
|
|
||||||
module board_encoderhole() {
|
|
||||||
difference() {
|
|
||||||
board();
|
|
||||||
encoders();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module top_plate_outline() {
|
|
||||||
offset(delta = -wallOverlap)
|
|
||||||
difference() {
|
|
||||||
board();
|
|
||||||
encoders();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module top_plate_holes() {
|
|
||||||
switches();
|
|
||||||
bolts();
|
|
||||||
translate([macroHole[0], macroHole[1], 0])
|
|
||||||
circle(d = macroDiam, center = true);
|
|
||||||
}
|
|
||||||
|
|
||||||
module top_plate() {
|
|
||||||
difference() {
|
|
||||||
top_plate_outline();
|
|
||||||
top_plate_holes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module top_ring_outline() {
|
|
||||||
board_encoderhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
// go in intervals of 2 to avoid final implicit union()
|
|
||||||
// start at 0.3 because laser kerf
|
|
||||||
module top_ring_engrave() {
|
|
||||||
engraveInterval = 0.05;
|
|
||||||
wallOverlap = 1;
|
|
||||||
for(i = [0.3:engraveInterval*2:wallOverlap+engraveInterval]) {
|
|
||||||
difference() {
|
|
||||||
offset(delta=-i)
|
|
||||||
top_ring_outline();
|
|
||||||
|
|
||||||
offset(delta=-(i+engraveInterval))
|
|
||||||
top_ring_outline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module top_ring() {
|
|
||||||
difference() {
|
|
||||||
top_ring_outline();
|
|
||||||
switches();
|
|
||||||
led_holes();
|
|
||||||
translate(macroHole)
|
|
||||||
square(10, center = true);
|
|
||||||
bolt_spacers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module pcb() {
|
|
||||||
difference() {
|
|
||||||
board();
|
|
||||||
bolt_spacers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module artwork() {
|
|
||||||
import("imports/Artwork.dxf");
|
|
||||||
}
|
|
||||||
|
|
||||||
module bottom_ring_outline() {
|
|
||||||
difference() {
|
|
||||||
board();
|
|
||||||
translate(usbPos)
|
|
||||||
usb();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module mcu_hole() {
|
|
||||||
polygon([[-13.3, 3.9],
|
|
||||||
[-13.3, -8],
|
|
||||||
[-35.5, -8],
|
|
||||||
[-35.5, 3.9]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
module bottom_ring() {
|
|
||||||
difference() {
|
|
||||||
bottom_ring_outline();
|
|
||||||
bolt_spacers();
|
|
||||||
encoder_holes();
|
|
||||||
mcu_hole();
|
|
||||||
// Room for FX
|
|
||||||
switches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module bottom_plate_outline() {
|
|
||||||
board();
|
|
||||||
}
|
|
||||||
|
|
||||||
module bottom_plate() {
|
|
||||||
difference() {
|
|
||||||
board();
|
|
||||||
bolts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module art_trimmed() {
|
|
||||||
intersection() {
|
|
||||||
// Won't work cause I'm an idiot
|
|
||||||
//offset(delta = -0.5)
|
|
||||||
top_plate();
|
|
||||||
artwork();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is kinda disgusting
|
|
||||||
module full_stack(knobs = true) {
|
module full_stack(knobs = true) {
|
||||||
// quadratic ease out
|
|
||||||
t = $t -1;
|
|
||||||
boom = -explodeFactor * (t*t*t*t - 1);
|
|
||||||
|
|
||||||
color([1, 1, 1, 0.4])
|
color([1, 1, 1, 0.4])
|
||||||
linear_extrude(plate_thickness[0])
|
extrude_plate(0)
|
||||||
bottom_plate();
|
bottom_cover();
|
||||||
translate([0, 0, plate_thickness[0] + boom]) {
|
|
||||||
color([0.8, 0.8, 0.8, 0.4])
|
|
||||||
linear_extrude(plate_thickness[1])
|
|
||||||
bottom_ring();
|
|
||||||
translate([0, 0, plate_thickness[1] + boom]) {
|
|
||||||
color([1,1,1, 1])
|
|
||||||
linear_extrude(plate_thickness[2])
|
|
||||||
pcb();
|
|
||||||
// not-as-pretty model of macro key
|
|
||||||
translate([macroHole[0], macroHole[1], plate_thickness[2]])
|
|
||||||
color([1,0.5,0])
|
|
||||||
cylinder(h = 5.2, d = macroDiam);
|
|
||||||
|
|
||||||
translate([0, 0, plate_thickness[2] + boom]) {
|
|
||||||
// pretty models of stuff
|
|
||||||
translate([0, 0, boom*2]) {
|
|
||||||
color([0.8,0.8,0.8,1])
|
|
||||||
encoder_model_full(knobs);
|
|
||||||
|
|
||||||
switch_models();
|
|
||||||
switch_keycaps();
|
|
||||||
};
|
|
||||||
|
|
||||||
color([1, 1, 1, 0.4])
|
|
||||||
linear_extrude(plate_thickness[3])
|
|
||||||
top_ring();
|
|
||||||
translate([0, 0, plate_thickness[3] + boom]) {
|
|
||||||
color([1,1,1, 1])
|
|
||||||
linear_extrude(plate_thickness[4])
|
|
||||||
top_plate();
|
|
||||||
translate([0, 0, plate_thickness[4]]) {
|
|
||||||
color([0,0,0, 1])
|
|
||||||
linear_extrude(plate_thickness[5]) {
|
|
||||||
difference() {
|
|
||||||
top_plate();
|
|
||||||
art_trimmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
color([0.8, 0.8, 0.8, 0.2])
|
||||||
|
extrude_plate(1)
|
||||||
fiducialPoints = [
|
bottom_spacer();
|
||||||
[-80, -100],
|
|
||||||
[80, -100],
|
color([1,1,1, 1])
|
||||||
[-80, 50],
|
extrude_plate(2)
|
||||||
[80, 50]
|
pcb();
|
||||||
];
|
|
||||||
|
color([0.8, 0.8, 0.8, 0.2])
|
||||||
module fiducials() {
|
extrude_plate(3)
|
||||||
for(f = fiducialPoints) {
|
top_spacer();
|
||||||
translate(f)
|
|
||||||
square(5, center=true);
|
color([1,1,1, 1])
|
||||||
|
extrude_plate(4)
|
||||||
|
top_reflector();
|
||||||
|
|
||||||
|
animate_layer(5)
|
||||||
|
artwork();
|
||||||
|
|
||||||
|
color([0.8, 0.8, 0.8, 0.4])
|
||||||
|
extrude_plate(6)
|
||||||
|
top_cover();
|
||||||
|
|
||||||
|
// this isn't ready yet - need bevel
|
||||||
|
/*color([0.8, 0.8, 0.8, 0.3])
|
||||||
|
extrude_plate(7)
|
||||||
|
knob_spacer();
|
||||||
|
|
||||||
|
color([0.8, 0.8, 0.8, 0.4])
|
||||||
|
extrude_plate(8)
|
||||||
|
knob_cover();*/
|
||||||
|
|
||||||
|
// some nice models
|
||||||
|
animate_layer(2)
|
||||||
|
translate([macro_pos.x, macro_pos.y, layer_thickness[2]])
|
||||||
|
color("gray")
|
||||||
|
macro_model();
|
||||||
|
|
||||||
|
// start at layer 2 but rise up above layer 6
|
||||||
|
translate([0,0,90 * quad_ease_inout($t)])
|
||||||
|
animate_layer(2) {
|
||||||
|
color([0.8,0.8,0.8,1])
|
||||||
|
encoders()
|
||||||
|
encoder_model(knobs);
|
||||||
|
|
||||||
|
switch_models();
|
||||||
|
switch_keycaps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// override in commandline
|
// override in commandline
|
||||||
build = "bottom_spacer";
|
build = "render";
|
||||||
enable_fiducials = 0;
|
|
||||||
if(build == "render") {
|
if(build == "render") {
|
||||||
full_stack();
|
full_stack();
|
||||||
} else if(build == "bottom_plate") {
|
} else if(build == "bottom_plate") {
|
||||||
bottom_plate();
|
bottom_cover();
|
||||||
} else if(build == "bottom_spacer") {
|
} else if(build == "bottom_spacer") {
|
||||||
bottom_ring();
|
bottom_spacer();
|
||||||
} else if(build == "top_spacer") {
|
} else if(build == "top_spacer") {
|
||||||
if(enable_fiducials)
|
top_spacer();
|
||||||
fiducials();
|
} else if(build == "top_reflector") {
|
||||||
top_ring();
|
top_reflector();
|
||||||
} else if(build == "top_spacer_engrave") {
|
} else if(build == "top_spacer_engrave") {
|
||||||
if(enable_fiducials)
|
top_spacer_engrave();
|
||||||
fiducials();
|
|
||||||
top_ring_engrave();
|
|
||||||
} else if(build == "top_plate") {
|
} else if(build == "top_plate") {
|
||||||
if(enable_fiducials)
|
top_cover();
|
||||||
fiducials();
|
} else if(build == "art_cutout") {
|
||||||
top_plate();
|
art_outline();
|
||||||
} else if(build == "top_plate_engrave") {
|
} else if(build == "knob_spacer") {
|
||||||
if(enable_fiducials)
|
knob_spacer();
|
||||||
fiducials();
|
} else if(build == "knob_cover") {
|
||||||
art_trimmed();
|
knob_cover();
|
||||||
}
|
} else if(build == "knob_cover_cnc") {
|
||||||
|
knob_cover_cnc();
|
||||||
// for inspecting individual plates
|
}
|
||||||
//linear_extrude(plate_thickness[0])
|
|
||||||
// bottom_plate();
|
|
||||||
//linear_extrude(plate_thickness[1])
|
|
||||||
// bottom_ring();
|
|
||||||
//linear_extrude(plate_thickness[3])
|
|
||||||
// top_ring();
|
|
||||||
//translate([0,0,plate_thickness[3]])
|
|
||||||
//linear_extrude(1)
|
|
||||||
// top_ring_engrave();
|
|
||||||
//linear_extrude(plate_thickness[4])
|
|
||||||
// top_plate();
|
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
include <board_primitives.scad>
|
||||||
|
use <board_shape.scad>
|
||||||
|
|
||||||
|
// SWITCHES
|
||||||
|
|
||||||
|
module switch_socket_holes() {
|
||||||
|
switches_all() {
|
||||||
|
holesize = [19,11];
|
||||||
|
translate([-holesize.x/2, -3])
|
||||||
|
rounded_square(holesize.x, holesize.y, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fx() {
|
||||||
|
reflect([1,0,0])
|
||||||
|
mirror([0,1,0]) { // my switches have upside down stabs
|
||||||
|
|
||||||
|
translate([11.9,7])
|
||||||
|
circle(d=4.5);
|
||||||
|
|
||||||
|
hull() {
|
||||||
|
translate([11.9,-8.24])
|
||||||
|
circle(d=4);
|
||||||
|
|
||||||
|
translate([11.9,-10])
|
||||||
|
circle(d=4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a = 23.8; // mx datasheet, good for 2/2.25/2.75 units
|
||||||
|
main_box = [6.65,12.3];
|
||||||
|
|
||||||
|
module stabiliser_cutout_offset() {
|
||||||
|
// my switches have upside down stabs
|
||||||
|
mirror([0,1,0])
|
||||||
|
// per datasheet
|
||||||
|
translate([a/2,main_box.y/2 - 6.77])
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module stabiliser_cutout_bare_minimum() {
|
||||||
|
stabiliser_cutout_offset() {
|
||||||
|
// main body of the stabs
|
||||||
|
square(main_box, center=true);
|
||||||
|
|
||||||
|
// cutout for the bar to pivot
|
||||||
|
translate([0,-1.2])
|
||||||
|
square([3, main_box.y], center=true);
|
||||||
|
|
||||||
|
// linking gap to main switch body
|
||||||
|
translate([-a/4,0])
|
||||||
|
square([a/2, main_box.y - 1.6], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module stabiliser_cutout_panel_bits() {
|
||||||
|
// cutout for the side bits on a panel-mount
|
||||||
|
stabiliser_cutout_offset()
|
||||||
|
translate([0.875,3/2-0.5])
|
||||||
|
square([main_box.x, 2.8], center=true);
|
||||||
|
}
|
||||||
|
|
||||||
|
module stabiliser_cutout_external() {
|
||||||
|
stabiliser_cutout_bare_minimum();
|
||||||
|
stabiliser_cutout_panel_bits();
|
||||||
|
}
|
||||||
|
|
||||||
|
module stabiliser_cutout_internal() {
|
||||||
|
// since we want most of it
|
||||||
|
stabiliser_cutout_external();
|
||||||
|
|
||||||
|
// get rid of the fingers at the bottom
|
||||||
|
//resize([20,0,0])
|
||||||
|
//switch_hole(expansion=1);
|
||||||
|
|
||||||
|
stabiliser_cutout_offset() {
|
||||||
|
// space for the bar to move
|
||||||
|
|
||||||
|
translate([-a/4,-2.5])
|
||||||
|
square([a/2, main_box.y], center=true);
|
||||||
|
|
||||||
|
// cut off ugly bottom bits
|
||||||
|
translate([-a/4,-2.5])
|
||||||
|
square([a/2, main_box.y], center=true);
|
||||||
|
|
||||||
|
// also space for the stab itself
|
||||||
|
translate([0,-0.5])
|
||||||
|
square([7.4, 19], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module stabiliser_cutout_artwork() {
|
||||||
|
stabiliser_cutout_bare_minimum();
|
||||||
|
// no panel bits, if you swap to panel mount,
|
||||||
|
// cut a new thing yourself
|
||||||
|
|
||||||
|
// linking gap to main switch body, but bigger
|
||||||
|
// Less flappy bits, nicer cuts
|
||||||
|
extra=0.3;
|
||||||
|
stabiliser_cutout_offset() {
|
||||||
|
translate([-a/4,-extra/2])
|
||||||
|
square([a/2, main_box.y+extra], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module switch_hole(expansion = false) {
|
||||||
|
// from Cherry MX data sheet
|
||||||
|
holesize = 14;
|
||||||
|
|
||||||
|
translate([-holesize/2, -holesize/2])
|
||||||
|
square([holesize,holesize]);
|
||||||
|
|
||||||
|
// expansion for inner layers so the clips have something to grab
|
||||||
|
if(expansion) {
|
||||||
|
expand_hole = [5, 15];
|
||||||
|
translate(-expand_hole/2)
|
||||||
|
square(expand_hole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module switch_external() {
|
||||||
|
switches_all()
|
||||||
|
switch_hole();
|
||||||
|
|
||||||
|
fx()
|
||||||
|
reflect()
|
||||||
|
stabiliser_cutout_external();
|
||||||
|
}
|
||||||
|
|
||||||
|
module switch_internal() {
|
||||||
|
switches_all()
|
||||||
|
switch_hole(expansion = true);
|
||||||
|
|
||||||
|
fx()
|
||||||
|
reflect()
|
||||||
|
stabiliser_cutout_internal();
|
||||||
|
}
|
||||||
|
|
||||||
|
module switch_artwork() {
|
||||||
|
switches_all()
|
||||||
|
switch_hole(expansion = true);
|
||||||
|
|
||||||
|
fx()
|
||||||
|
reflect()
|
||||||
|
stabiliser_cutout_artwork();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ENCODERS
|
||||||
|
|
||||||
|
module encoder_pins() {
|
||||||
|
encoders() {
|
||||||
|
// A/B/Gnd
|
||||||
|
hull() {
|
||||||
|
translate([encoder_hull[0], encoder_hull[1]])
|
||||||
|
circle(d=encoder_hull[2], center = true);
|
||||||
|
translate([-encoder_hull[0], encoder_hull[1]])
|
||||||
|
circle(d=encoder_hull[2], center = true);
|
||||||
|
}
|
||||||
|
for(hole = encoder_holes) {
|
||||||
|
translate([hole[0], hole[1]])
|
||||||
|
circle(d=hole[2], center = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module board_encoders_only() {
|
||||||
|
difference() {
|
||||||
|
board();
|
||||||
|
encoder_cutouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module enc_smooth() {
|
||||||
|
r = 3;
|
||||||
|
intersection() {
|
||||||
|
// the rounded bits
|
||||||
|
difference() {
|
||||||
|
board_encoders_only();
|
||||||
|
minkowski() {
|
||||||
|
offset(delta=-r)
|
||||||
|
board_encoders_only();
|
||||||
|
|
||||||
|
circle(r=r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// only affect the encoders
|
||||||
|
encoders()
|
||||||
|
square(encoder_radius*2.5, center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module encoder_cutouts(smooth = false) {
|
||||||
|
encoders()
|
||||||
|
circle(r=encoder_radius, center = true);
|
||||||
|
|
||||||
|
// smooth harsh edges so you don't cut yourself
|
||||||
|
if(smooth) {
|
||||||
|
enc_smooth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MCU/USB HOLE
|
||||||
|
|
||||||
|
module mcu_cutout() {
|
||||||
|
corners = [[-17, -40],[-16, -1]];
|
||||||
|
polygon([[corners.x[0], corners.y[0]],
|
||||||
|
[corners.x[0], corners.y[1]],
|
||||||
|
[corners.x[1], corners.y[1]],
|
||||||
|
[corners.x[1], corners.y[0]]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module usb_cutout() {
|
||||||
|
wall_strength = 6; // bolt + half on either side
|
||||||
|
w = usb_dims.x / 2;
|
||||||
|
h = wall_strength + fudge*2;
|
||||||
|
curve_width = h / 2;
|
||||||
|
|
||||||
|
translate(usb_pos)
|
||||||
|
reflect()
|
||||||
|
translate([0, -h, 0]) { // USB connector origin is at board edge
|
||||||
|
translate([0,-(usb_dims.y-h)])
|
||||||
|
square([w, usb_dims.y]);
|
||||||
|
|
||||||
|
translate([w, curve_width, 0])
|
||||||
|
difference() {
|
||||||
|
square(curve_width);
|
||||||
|
translate([curve_width, 0, 0])
|
||||||
|
circle(r=curve_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
|
||||||
|
module led_cutouts() {
|
||||||
|
leds()
|
||||||
|
translate(-led_size/2)
|
||||||
|
square(led_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MACRO BUTTON
|
||||||
|
|
||||||
|
module macro_internal() {
|
||||||
|
translate(macro_pos)
|
||||||
|
square(10, center = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
module macro_external() {
|
||||||
|
translate(macro_pos)
|
||||||
|
circle(d=macro_diam);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
|||||||
|
//Draw text
|
||||||
|
scale([4,4,4]) drawtext("Hello World!");
|
||||||
|
|
||||||
|
//Draw character set
|
||||||
|
//scale([2,2,2]) drawtext(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}");
|
||||||
|
|
||||||
|
module drawtext(text) {
|
||||||
|
//Characters
|
||||||
|
chars = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}";
|
||||||
|
|
||||||
|
//Chracter table defining 5x7 characters
|
||||||
|
//Adapted from: http://www.geocities.com/dinceraydin/djlcdsim/chartable.js
|
||||||
|
char_table = [ [ 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
[ 4, 0, 4, 4, 4, 4, 4],
|
||||||
|
[ 0, 0, 0, 0,10,10,10],
|
||||||
|
[10,10,31,10,31,10,10],
|
||||||
|
[ 4,30, 5,14,20,15, 4],
|
||||||
|
[ 3,19, 8, 4, 2,25,24],
|
||||||
|
[13,18,21, 8,20,18,12],
|
||||||
|
[ 0, 0, 0, 0, 8, 4,12],
|
||||||
|
[ 2, 4, 8, 8, 8, 4, 2],
|
||||||
|
[ 8, 4, 2, 2, 2, 4, 8],
|
||||||
|
[ 0, 4,21,14,21, 4, 0],
|
||||||
|
[ 0, 4, 4,31, 4, 4, 0],
|
||||||
|
[ 8, 4,12, 0, 0, 0, 0],
|
||||||
|
[ 0, 0, 0,31, 0, 0, 0],
|
||||||
|
[12,12, 0, 0, 0, 0, 0],
|
||||||
|
[ 0,16, 8, 4, 2, 1, 0],
|
||||||
|
[14,17,25,21,19,17,14],
|
||||||
|
[14, 4, 4, 4, 4,12, 4],
|
||||||
|
[31, 8, 4, 2, 1,17,14],
|
||||||
|
[14,17, 1, 2, 4, 2,31],
|
||||||
|
[ 2, 2,31,18,10, 6, 2],
|
||||||
|
[14,17, 1, 1,30,16,31],
|
||||||
|
[14,17,17,30,16, 8, 6],
|
||||||
|
[ 8, 8, 8, 4, 2, 1,31],
|
||||||
|
[14,17,17,14,17,17,14],
|
||||||
|
[12, 2, 1,15,17,17,14],
|
||||||
|
[ 0,12,12, 0,12,12, 0],
|
||||||
|
[ 8, 4,12, 0,12,12, 0],
|
||||||
|
[ 2, 4, 8,16, 8, 4, 2],
|
||||||
|
[ 0, 0,31, 0,31, 0, 0],
|
||||||
|
[16, 8, 4, 2, 4, 8,16],
|
||||||
|
[ 4, 0, 4, 2, 1,17,14],
|
||||||
|
[14,21,21,13, 1,17,14],
|
||||||
|
[17,17,31,17,17,17,14],
|
||||||
|
[30,17,17,30,17,17,30],
|
||||||
|
[14,17,16,16,16,17,14],
|
||||||
|
[30,17,17,17,17,17,30],
|
||||||
|
[31,16,16,30,16,16,31],
|
||||||
|
[16,16,16,30,16,16,31],
|
||||||
|
[15,17,17,23,16,17,14],
|
||||||
|
[17,17,17,31,17,17,17],
|
||||||
|
[14, 4, 4, 4, 4, 4,14],
|
||||||
|
[12,18, 2, 2, 2, 2, 7],
|
||||||
|
[17,18,20,24,20,18,17],
|
||||||
|
[31,16,16,16,16,16,16],
|
||||||
|
[17,17,17,21,21,27,17],
|
||||||
|
[17,17,19,21,25,17,17],
|
||||||
|
[14,17,17,17,17,17,14],
|
||||||
|
[16,16,16,30,17,17,30],
|
||||||
|
[13,18,21,17,17,17,14],
|
||||||
|
[17,18,20,30,17,17,30],
|
||||||
|
[30, 1, 1,14,16,16,15],
|
||||||
|
[ 4, 4, 4, 4, 4, 4,31],
|
||||||
|
[14,17,17,17,17,17,17],
|
||||||
|
[ 4,10,17,17,17,17,17],
|
||||||
|
[10,21,21,21,17,17,17],
|
||||||
|
[17,17,10, 4,10,17,17],
|
||||||
|
[ 4, 4, 4,10,17,17,17],
|
||||||
|
[31,16, 8, 4, 2, 1,31],
|
||||||
|
[14, 8, 8, 8, 8, 8,14],
|
||||||
|
[ 0, 1, 2, 4, 8,16, 0],
|
||||||
|
[14, 2, 2, 2, 2, 2,14],
|
||||||
|
[ 0, 0, 0, 0,17,10, 4],
|
||||||
|
[31, 0, 0, 0, 0, 0, 0],
|
||||||
|
[ 0, 0, 0, 0, 2, 4, 8],
|
||||||
|
[15,17,15, 1,14, 0, 0],
|
||||||
|
[30,17,17,25,22,16,16],
|
||||||
|
[14,17,16,16,14, 0, 0],
|
||||||
|
[15,17,17,19,13, 1, 1],
|
||||||
|
[14,16,31,17,14, 0, 0],
|
||||||
|
[ 8, 8, 8,28, 8, 9, 6],
|
||||||
|
[14, 1,15,17,15, 0, 0],
|
||||||
|
[17,17,17,25,22,16,16],
|
||||||
|
[14, 4, 4, 4,12, 0, 4],
|
||||||
|
[12,18, 2, 2, 2, 6, 2],
|
||||||
|
[18,20,24,20,18,16,16],
|
||||||
|
[14, 4, 4, 4, 4, 4,12],
|
||||||
|
[17,17,21,21,26, 0, 0],
|
||||||
|
[17,17,17,25,22, 0, 0],
|
||||||
|
[14,17,17,17,14, 0, 0],
|
||||||
|
[16,16,30,17,30, 0, 0],
|
||||||
|
[ 1, 1,15,19,13, 0, 0],
|
||||||
|
[16,16,16,25,22, 0, 0],
|
||||||
|
[30, 1,14,16,15, 0, 0],
|
||||||
|
[ 6, 9, 8, 8,28, 8, 8],
|
||||||
|
[13,19,17,17,17, 0, 0],
|
||||||
|
[ 4,10,17,17,17, 0, 0],
|
||||||
|
[10,21,21,17,17, 0, 0],
|
||||||
|
[17,10, 4,10,17, 0, 0],
|
||||||
|
[14, 1,15,17,17, 0, 0],
|
||||||
|
[31, 8, 4, 2,31, 0, 0],
|
||||||
|
[ 2, 4, 4, 8, 4, 4, 2],
|
||||||
|
[ 4, 4, 4, 4, 4, 4, 4],
|
||||||
|
[ 8, 4, 4, 2, 4, 4, 8] ];
|
||||||
|
|
||||||
|
//Binary decode table
|
||||||
|
dec_table = [ "00000", "00001", "00010", "00011", "00100", "00101",
|
||||||
|
"00110", "00111", "01000", "01001", "01010", "01011",
|
||||||
|
"01100", "01101", "01110", "01111", "10000", "10001",
|
||||||
|
"10010", "10011", "10100", "10101", "10110", "10111",
|
||||||
|
"11000", "11001", "11010", "11011", "11100", "11101",
|
||||||
|
"11110", "11111" ];
|
||||||
|
|
||||||
|
//Process string one character at a time
|
||||||
|
for(itext = [0:len(text)-1]) {
|
||||||
|
//Convert character to index
|
||||||
|
ichar = search(text[itext],chars,1)[0];
|
||||||
|
|
||||||
|
//Decode character - rows
|
||||||
|
for(irow = [0:6]) {
|
||||||
|
//Select value to draw from table
|
||||||
|
val = dec_table[char_table[ichar][irow]];
|
||||||
|
|
||||||
|
//Decode character - cols
|
||||||
|
for(icol = [0:4]) {
|
||||||
|
// Retrieve bit to draw
|
||||||
|
bit = search(val[icol],"01",1)[0];
|
||||||
|
|
||||||
|
if(bit) {
|
||||||
|
//Output cube
|
||||||
|
translate([icol + (6*itext), irow, 0])
|
||||||
|
cube([1.0001,1.0001,1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,784 @@
|
|||||||
|
/* This is a first pass at dimension lines for OpenSCAD. The text generated for
|
||||||
|
* this comes from http://www.thingiverse.com/thing:59817, and I gratefully
|
||||||
|
* acknowledge user PGreenland for creating this dotmatrix style font.
|
||||||
|
*
|
||||||
|
* Download his file first, TextGenerator.scad, before attempting to run this
|
||||||
|
* program.
|
||||||
|
*
|
||||||
|
* What this program does:
|
||||||
|
*
|
||||||
|
* This program can draw lines with arrows and has a primitive dimensioning
|
||||||
|
* element for putting text within arrows. In addition, should the area being
|
||||||
|
* dimensioned be too narrow, there is a provision for putting the text on
|
||||||
|
* either side of the arrows.
|
||||||
|
*
|
||||||
|
* The dimension lines are drawn on the xy plane and are meant to be seen in a
|
||||||
|
* top view.
|
||||||
|
*
|
||||||
|
* =======================================================
|
||||||
|
* Be sure to view this from above -- ctrl-4
|
||||||
|
* =======================================================
|
||||||
|
*
|
||||||
|
* Available:
|
||||||
|
*
|
||||||
|
* Assorted constants to ease the use of dimensioning line. Because there is
|
||||||
|
* no introspection regarding the dimensions of your creations, you will want
|
||||||
|
* to adjust the parameters to fit the context of your creation. You can adjust
|
||||||
|
* the size of the text, lines, etc to match the rest of your objects.
|
||||||
|
*
|
||||||
|
* the following functions or modules are available.
|
||||||
|
*
|
||||||
|
* line(length, width, height=DIM_HEIGHT, left_arrow=false, right_arrow=false)
|
||||||
|
* Can draw a line with the options of including an arrow at either end
|
||||||
|
*
|
||||||
|
* circle_center(radius, size, line_width)
|
||||||
|
* Draws the cross in the center of a circle. There are defaults for the
|
||||||
|
* cross size and line width
|
||||||
|
*
|
||||||
|
* dimensions(length, line_width, loc=DIM_CENTER)
|
||||||
|
* draws text within lines, such as <--- 3.5 --->
|
||||||
|
* with the use of the variable loc you can alter the placement of the text
|
||||||
|
* loc=DIM_CENTER <--- 3.5 ---> this is the default
|
||||||
|
* loc=DIM_LEFT 3.5 <---->
|
||||||
|
* loc=DIM_RIGHT <----> 3.5
|
||||||
|
* loc=DIM_OUTSIDE ---> 3.5 <---
|
||||||
|
*
|
||||||
|
* leader_line(angle, radius, angle_length, horz_line_length,
|
||||||
|
* direction=DIM_RIGHT, line_width, text)
|
||||||
|
*
|
||||||
|
* for use in pointing to the edge of a circle and showing text
|
||||||
|
*
|
||||||
|
* usage of the leader line:
|
||||||
|
* translate to the center of the circle
|
||||||
|
* Typically leader lines have a bend in them. The angle variable is used
|
||||||
|
* to specify the angle from which the line will point to the center of the
|
||||||
|
* circle. The radius specifies the location of the arrow. The
|
||||||
|
* angle_length is distance that the leader line takes until meeting the
|
||||||
|
* horizontal line. Once the angled line meets the horizontal line, that
|
||||||
|
* line will either extend to the right or left. direction and therefore
|
||||||
|
* be either DIM_RIGHT or DIM_LEFT. line_width typically would be whatever
|
||||||
|
* constant you have selected for all your dimensioned lines. Finally, the
|
||||||
|
* text will be the value that you wish to show, such as R 0.500.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Created by Don Smiley
|
||||||
|
*/
|
||||||
|
|
||||||
|
use <TextGenerator.scad>
|
||||||
|
|
||||||
|
// these variables are used within the modules
|
||||||
|
DIM_CENTER = 0;
|
||||||
|
DIM_LEFT = 1;
|
||||||
|
DIM_RIGHT = 2;
|
||||||
|
DIM_OUTSIDE = 3;
|
||||||
|
DIM_HORZ = 0;
|
||||||
|
DIM_VERT = 1;
|
||||||
|
DIM_UPPER_LEFT = 0;
|
||||||
|
DIM_UPPER_RIGHT = 1;
|
||||||
|
DIM_LOWER_LEFT = 2;
|
||||||
|
DIM_LOWER_RIGHT = 3;
|
||||||
|
|
||||||
|
/* Constants related to the annotation lines
|
||||||
|
*
|
||||||
|
* Because the dimension of the part to be documented can vary widely, you
|
||||||
|
* probably are going to need to adjust the parameters to fit the context of
|
||||||
|
* your part.
|
||||||
|
*
|
||||||
|
* For example, the following parameters were used for a part 3.5 units long.
|
||||||
|
* In addition, DIM_HEIGHT is a height meant to be slightly above your tallest
|
||||||
|
* part.
|
||||||
|
*/
|
||||||
|
|
||||||
|
DIM_LINE_WIDTH = .025; // width of dimension lines
|
||||||
|
DIM_SPACE = .1; // a spacing value to make it easier to adjust line spacing etc
|
||||||
|
DIM_HEIGHT = .01; // height of lines
|
||||||
|
|
||||||
|
// refers to the size of the cross within a circle
|
||||||
|
DIM_HOLE_CENTER = DIM_LINE_WIDTH * 6;
|
||||||
|
|
||||||
|
// an approximation that sets the font size relative to the line widths
|
||||||
|
DIM_FONTSCALE = DIM_LINE_WIDTH * .7;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OFFSET = .05; // added to the hole length to extend past the surface of the cube
|
||||||
|
|
||||||
|
module arrow(arr_points, arr_length, height) {
|
||||||
|
// arrow points to the left
|
||||||
|
linear_extrude(height=height, convexity=2)
|
||||||
|
|
||||||
|
polygon(
|
||||||
|
points = [[0, 0],
|
||||||
|
[arr_points, arr_points / 2],
|
||||||
|
[arr_length, 0],
|
||||||
|
[arr_points, -arr_points / 2]],
|
||||||
|
paths = [[0, 1, 2, 3]], convexity = 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
module line(length, width=DIM_LINE_WIDTH,
|
||||||
|
height=DIM_HEIGHT,
|
||||||
|
left_arrow=false,
|
||||||
|
right_arrow=false
|
||||||
|
) {
|
||||||
|
/* This module draws a line that can have an arrow on either end. Because
|
||||||
|
* the intended use is to be viewed strictly from above, the height of the
|
||||||
|
* line is set arbitrarily thin.
|
||||||
|
*
|
||||||
|
* The factors arr_length and arr_points are used to create a proportionate
|
||||||
|
* arrow. Your sense of asthetics may lead you to choose different
|
||||||
|
* numbers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
arr_points = width * 4;
|
||||||
|
arr_length = arr_points * .6;
|
||||||
|
|
||||||
|
union() {
|
||||||
|
if (left_arrow && right_arrow) {
|
||||||
|
translate([arr_length, -width / 2, 0])
|
||||||
|
cube([length - arr_length * 2, width, height], center=false);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (left_arrow) {
|
||||||
|
translate([arr_length, -width / 2, 0])
|
||||||
|
cube([length - arr_length, width, height], center=false);
|
||||||
|
} else {
|
||||||
|
if (right_arrow) {
|
||||||
|
translate([0, -width / 2, 0])
|
||||||
|
cube([length - arr_length, width, height], center=false);
|
||||||
|
} else {
|
||||||
|
translate([0, -width / 2, 0])
|
||||||
|
cube([length, width, height], center=false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_arrow) {
|
||||||
|
arrow(arr_points, arr_length, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right_arrow) {
|
||||||
|
translate([length, 0, 0])
|
||||||
|
rotate([0, 0, 180])
|
||||||
|
arrow(arr_points, arr_length, height);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module circle_center(radius, size=DIM_HOLE_CENTER, line_width=DIM_LINE_WIDTH) {
|
||||||
|
|
||||||
|
translate([-size / 2, 0, 0])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
translate([radius - size / 2, 0, 0])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
translate([-radius - size / 2, 0, 0])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
translate([0, -size / 2, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
translate([0, radius - size / 2, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
translate([0, -radius - size / 2, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(length=size, width=line_width, height=DIM_HEIGHT, left_arrow=false,
|
||||||
|
right_arrow=false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module dimensions(length, line_width=DIM_LINE_WIDTH, loc=DIM_CENTER) {
|
||||||
|
|
||||||
|
|
||||||
|
text = str(length);
|
||||||
|
space = len(text) * DIM_FONTSCALE * 7;
|
||||||
|
|
||||||
|
if (loc == DIM_CENTER) {
|
||||||
|
line(length=length / 2 - space / 2, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=false);
|
||||||
|
translate([(length) / 2 - space / 2 * .9, -DIM_FONTSCALE * 3, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
|
||||||
|
translate([length / 2 + space / 2, 0, 0])
|
||||||
|
line(length=length / 2 - space / 2, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=true);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (loc == DIM_LEFT) {
|
||||||
|
line(length=length, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=true);
|
||||||
|
|
||||||
|
translate([-space, -DIM_FONTSCALE * 3, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
} else {
|
||||||
|
if (loc == DIM_RIGHT) {
|
||||||
|
line(length=length, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=true);
|
||||||
|
|
||||||
|
translate([length + space, -DIM_FONTSCALE * 3, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
} else {
|
||||||
|
if (loc == DIM_OUTSIDE) {
|
||||||
|
|
||||||
|
rotate([0, 180, 0])
|
||||||
|
line(length=length / 2, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=false);
|
||||||
|
|
||||||
|
translate([(length) / 2 - space / 2 * .9,
|
||||||
|
-DIM_FONTSCALE * 3, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
|
||||||
|
translate([length, 0, 0])
|
||||||
|
line(length=length / 2, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module leader_line(angle, radius, angle_length, horz_line_length,
|
||||||
|
direction=DIM_RIGHT, line_width=DIM_LINE_WIDTH, text, do_circle=false) {
|
||||||
|
/* leader_line
|
||||||
|
*
|
||||||
|
* Creates a line that points directly at a center point from the given
|
||||||
|
* radius.
|
||||||
|
* Then, a short horzizontal line is generated, followed by text. The
|
||||||
|
* direction of the horizontal short line defaults to the right, the
|
||||||
|
* choice made by either DIM_RIGHT or DIM_LEFT
|
||||||
|
*/
|
||||||
|
|
||||||
|
text_length = len(text) * DIM_FONTSCALE * 6;
|
||||||
|
space = DIM_FONTSCALE * 6;
|
||||||
|
|
||||||
|
rotate([0, 0, angle])
|
||||||
|
translate([radius, 0, 0])
|
||||||
|
line(length=angle_length, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=true, right_arrow=false);
|
||||||
|
|
||||||
|
rotate([0, 0, angle])
|
||||||
|
translate([radius + angle_length, 0, 0])
|
||||||
|
rotate([0, 0, -angle])
|
||||||
|
union() {
|
||||||
|
if (direction == DIM_RIGHT) {
|
||||||
|
line(length=horz_line_length, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
|
||||||
|
translate([(horz_line_length + space), -DIM_FONTSCALE * 3, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
|
||||||
|
if (do_circle) {
|
||||||
|
translate([(horz_line_length + space + text_length/2),
|
||||||
|
0, 0])
|
||||||
|
difference() {
|
||||||
|
cylinder(h=DIM_HEIGHT, r=text_length + space - line_width,
|
||||||
|
center=true, $fn=100);
|
||||||
|
cylinder(h=.05, r=text_length + space - line_width * 2,
|
||||||
|
center=true, $fn=100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
translate([-horz_line_length, 0, 0])
|
||||||
|
line(length=horz_line_length, width=line_width, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
|
||||||
|
translate([-(horz_line_length + space + text_length),
|
||||||
|
-DIM_FONTSCALE * 3,
|
||||||
|
0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(text);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module titleblock(lines, descs, details) {
|
||||||
|
/* titleblock
|
||||||
|
*
|
||||||
|
* This module accepts the following arrays with formats:
|
||||||
|
*
|
||||||
|
* holds the description of the lines. width is a factor that
|
||||||
|
* expands the line width beyond DIM_LINE_WIDTH
|
||||||
|
*
|
||||||
|
* lines = [[startx, starty, horz/vert, length, width],
|
||||||
|
* [startx, starty, horz/vert, length, width]]
|
||||||
|
*
|
||||||
|
* holds the descriptions of the title blocks. these are meant to sit in
|
||||||
|
* the upper left corner. size, like width above, is a factor that
|
||||||
|
* increases/decreases the size of the font
|
||||||
|
*
|
||||||
|
* descs = [[startx, starty, horz/vert, text, size],
|
||||||
|
* [startx, starty, horz/vert, text, size]]
|
||||||
|
*
|
||||||
|
* holds the detail associated with the part being documented
|
||||||
|
*
|
||||||
|
* details = [[startx, starty, horz/vert, text, size],
|
||||||
|
* [startx, starty, horz/vert, text, size]]
|
||||||
|
*/
|
||||||
|
|
||||||
|
DIM_FONTSCALE = DIM_LINE_WIDTH * .7;
|
||||||
|
|
||||||
|
for (line = lines) {
|
||||||
|
translate([line[0] * DIM_LINE_WIDTH,
|
||||||
|
line[1] * DIM_LINE_WIDTH,
|
||||||
|
0])
|
||||||
|
if (line[2] == DIM_VERT) {
|
||||||
|
rotate([0, 0, -90])
|
||||||
|
line(length=line[3] * DIM_LINE_WIDTH,
|
||||||
|
width=DIM_LINE_WIDTH * line[4], height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
} else {
|
||||||
|
line(length=(line[3] + 1) * DIM_LINE_WIDTH,
|
||||||
|
width=DIM_LINE_WIDTH * line[4], height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (line = descs) {
|
||||||
|
translate([line[0] * DIM_LINE_WIDTH, line[1] * DIM_LINE_WIDTH, 0])
|
||||||
|
if (line[2] == DIM_VERT) {
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
scale([DIM_FONTSCALE * line[4], DIM_FONTSCALE * line[4],
|
||||||
|
DIM_FONTSCALE * line[4]])
|
||||||
|
drawtext(line[3]);
|
||||||
|
} else {
|
||||||
|
scale([DIM_FONTSCALE * line[4], DIM_FONTSCALE * line[4],
|
||||||
|
DIM_FONTSCALE * line[4]])
|
||||||
|
drawtext(line[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (line = details) {
|
||||||
|
translate([line[0] * DIM_LINE_WIDTH, line[1] * DIM_LINE_WIDTH, 0])
|
||||||
|
if (line[2] == DIM_VERT) {
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
scale([DIM_FONTSCALE * line[4], DIM_FONTSCALE * line[4],
|
||||||
|
DIM_FONTSCALE * line[4]])
|
||||||
|
drawtext(line[3]);
|
||||||
|
} else {
|
||||||
|
scale([DIM_FONTSCALE * line[4], DIM_FONTSCALE * line[4],
|
||||||
|
DIM_FONTSCALE * line[4]])
|
||||||
|
drawtext(line[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module sample_titleblock1() {
|
||||||
|
/* sample titleblock
|
||||||
|
*
|
||||||
|
* Note the use of double thickness lines around the perimeter. Any line
|
||||||
|
* can be adjusted to be thinner or thicker.
|
||||||
|
*
|
||||||
|
* Note also that since lines are centered on their widths, some adjustments
|
||||||
|
* for half-width spacing is needed to avoid a jagged look on corners.
|
||||||
|
* You can see that in the horizontal lines in the first section that are
|
||||||
|
* offset by 1, which is the half-width of the outside line.
|
||||||
|
*/
|
||||||
|
title_width = 290;
|
||||||
|
row_height = 15;
|
||||||
|
|
||||||
|
cols = [-1, 50, 114, 200, 215, 260];
|
||||||
|
rows = [0, -row_height, -row_height * 2, -row_height * 3, -row_height * 4];
|
||||||
|
|
||||||
|
// spacing tweaks to fit into the blocks
|
||||||
|
desc_x = 2; // column offset for start of small text
|
||||||
|
desc_y = -5; // row offset for start of small text
|
||||||
|
det_y = -12; // row offset for start of detail text
|
||||||
|
desc_size = .75; // relative size of description text
|
||||||
|
|
||||||
|
lines = [
|
||||||
|
// horizontal lines
|
||||||
|
[cols[0], rows[0], DIM_HORZ, title_width, 2],
|
||||||
|
[cols[0], rows[1], DIM_HORZ, title_width, 1],
|
||||||
|
[cols[2], rows[2], DIM_HORZ, title_width - cols[2] - 1, 1],
|
||||||
|
[cols[3], rows[3], DIM_HORZ, title_width - cols[3] - 1, 1],
|
||||||
|
[cols[0], rows[4] - 1, DIM_HORZ, title_width, 2],
|
||||||
|
|
||||||
|
// vertical lines
|
||||||
|
[0, 0, DIM_VERT, row_height * 4, 2],
|
||||||
|
[cols[1], rows[0], DIM_VERT, row_height, 1],
|
||||||
|
[cols[2], rows[0], DIM_VERT, row_height * 4, 1],
|
||||||
|
[cols[3], rows[0], DIM_VERT, row_height * 4, 1],
|
||||||
|
[cols[4], rows[3], DIM_VERT, row_height, 1],
|
||||||
|
[cols[5], rows[3], DIM_VERT, row_height, 1],
|
||||||
|
[title_width - 1, 0, DIM_VERT, row_height * 4, 2],
|
||||||
|
];
|
||||||
|
|
||||||
|
descs = [
|
||||||
|
[cols[0] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Responsible dep", desc_size],
|
||||||
|
[cols[1] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Technical reference", desc_size],
|
||||||
|
[cols[2] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Creator", desc_size],
|
||||||
|
[cols[3] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Approval person", desc_size],
|
||||||
|
[cols[2] + desc_x, rows[1] + desc_y, DIM_HORZ,
|
||||||
|
"Document type", desc_size],
|
||||||
|
[cols[3] + desc_x, rows[1] + desc_y, DIM_HORZ,
|
||||||
|
"Document status", desc_size],
|
||||||
|
[cols[2] + desc_x, rows[2] + desc_y, DIM_HORZ,
|
||||||
|
"Title", desc_size],
|
||||||
|
[cols[3] + desc_x, rows[2] + desc_y, DIM_HORZ,
|
||||||
|
"Identification number", desc_size],
|
||||||
|
[cols[3] + desc_x, rows[3] + desc_y, DIM_HORZ,
|
||||||
|
"Rev", desc_size],
|
||||||
|
[cols[4] + desc_x, rows[3] + desc_y, DIM_HORZ,
|
||||||
|
"Date of issue", desc_size],
|
||||||
|
[cols[5] + desc_x, rows[3] + desc_y, DIM_HORZ,
|
||||||
|
"Sheet", desc_size]
|
||||||
|
];
|
||||||
|
|
||||||
|
details = [
|
||||||
|
[cols[0] + desc_x, rows[0] + det_y, DIM_HORZ,
|
||||||
|
" ", 1], //Responsible dep.
|
||||||
|
[cols[1] + desc_x, rows[0] + det_y, DIM_HORZ,
|
||||||
|
" ", 1], //Technical reference
|
||||||
|
[cols[2] + desc_x, rows[0] + det_y, DIM_HORZ,
|
||||||
|
"D. Smiley ", 1], //Creator
|
||||||
|
[cols[3] + desc_x, rows[0] + det_y, DIM_HORZ,
|
||||||
|
" ", 1], //Approval person
|
||||||
|
[cols[0] + desc_x + 10, rows[2] + det_y, DIM_HORZ,
|
||||||
|
"My OpenSCAD Project", 1],
|
||||||
|
[cols[2] + desc_x, rows[1] + det_y, DIM_HORZ,
|
||||||
|
" ", 1], //Document type
|
||||||
|
[cols[3] + desc_x, rows[1] + det_y, DIM_HORZ,
|
||||||
|
"First issue", 1], //Document status
|
||||||
|
[cols[2] + desc_x, rows[2] + det_y, DIM_HORZ,
|
||||||
|
"Sample Part", 1], //Title
|
||||||
|
[cols[3] + desc_x, rows[2] + det_y, DIM_HORZ,
|
||||||
|
"123", 1], //Identification number
|
||||||
|
[cols[3] + desc_x, rows[3] + det_y, DIM_HORZ,
|
||||||
|
" ", 1], //Rev
|
||||||
|
[cols[4] + desc_x, rows[3] + det_y, DIM_HORZ,
|
||||||
|
"2013-3-31", 1], //Date of issue
|
||||||
|
[cols[5] + desc_x, rows[3] + det_y, DIM_HORZ,
|
||||||
|
"1/100", 1] //Sheet
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
titleblock(lines, descs, details);
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_revisionblock(revisions) {
|
||||||
|
|
||||||
|
DIM_FONTSCALE = DIM_LINE_WIDTH * .7;
|
||||||
|
|
||||||
|
// revision block headings
|
||||||
|
row_height = 15;
|
||||||
|
revision_width = 100;
|
||||||
|
desc_x = 2;
|
||||||
|
desc_y = -10;
|
||||||
|
desc_size = 1;
|
||||||
|
|
||||||
|
cols = [0, 20, 60, revision_width];
|
||||||
|
rows = [0, -row_height, -row_height * 2];
|
||||||
|
|
||||||
|
// draw
|
||||||
|
lines = [
|
||||||
|
// horizontal lines
|
||||||
|
[cols[0], rows[0], DIM_HORZ, revision_width, 1],
|
||||||
|
[cols[0], rows[1], DIM_HORZ, revision_width, 1],
|
||||||
|
[cols[0], rows[2], DIM_HORZ, revision_width, 1],
|
||||||
|
|
||||||
|
// vertical lines
|
||||||
|
[cols[0], rows[0], DIM_VERT, row_height * 2, 1],
|
||||||
|
[cols[1], rows[0], DIM_VERT, row_height, 1],
|
||||||
|
[cols[2], rows[0], DIM_VERT, row_height, 1],
|
||||||
|
[cols[3], rows[0], DIM_VERT, row_height * 2, 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
descs = [
|
||||||
|
[cols[0] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Rev.", desc_size],
|
||||||
|
[cols[1] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Date", desc_size],
|
||||||
|
[cols[2] + desc_x, rows[0] + desc_y, DIM_HORZ,
|
||||||
|
"Initials", desc_size],
|
||||||
|
[cols[1] + desc_x, rows[1] + desc_y, DIM_HORZ,
|
||||||
|
"Revisions", desc_size],
|
||||||
|
];
|
||||||
|
|
||||||
|
details = [];
|
||||||
|
num_revisions = len(revisions);
|
||||||
|
|
||||||
|
translate([-(revision_width + 40) * DIM_LINE_WIDTH,
|
||||||
|
row_height * 2 * DIM_LINE_WIDTH, 0])
|
||||||
|
union() {
|
||||||
|
titleblock(lines, descs, details);
|
||||||
|
|
||||||
|
// now for the start of actual revisions
|
||||||
|
// do this piecemeal -- draw the vertical first
|
||||||
|
|
||||||
|
for (col = [0: len(cols)]) {
|
||||||
|
translate([cols[col] * DIM_LINE_WIDTH, 0, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(num_revisions * row_height * DIM_LINE_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (row = [0: len(revisions)]) {
|
||||||
|
translate([0, row * row_height * DIM_LINE_WIDTH, 0])
|
||||||
|
line(revision_width * DIM_LINE_WIDTH);
|
||||||
|
|
||||||
|
for (col = [0:2]) {
|
||||||
|
translate([(cols[col] + desc_x) * DIM_LINE_WIDTH,
|
||||||
|
((row + 1) * row_height + desc_y) * DIM_LINE_WIDTH, 0])
|
||||||
|
scale([DIM_FONTSCALE, DIM_FONTSCALE, DIM_FONTSCALE])
|
||||||
|
drawtext(revisions[row][col]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_titleblock2() {
|
||||||
|
|
||||||
|
row_height = 20;
|
||||||
|
|
||||||
|
cols = [-.5, 100, 154, 270];
|
||||||
|
title_width = cols[3];
|
||||||
|
|
||||||
|
rows = [0, -row_height, -row_height * 2, -row_height * 3, -row_height * 4,
|
||||||
|
-row_height * 5, -row_height * 6, -row_height * 7
|
||||||
|
];
|
||||||
|
|
||||||
|
// spacing tweaks to fit into the blocks
|
||||||
|
desc_x = 2; // column offset for start of small text
|
||||||
|
desc_y = -5; // row offset for start of small text
|
||||||
|
det_x = 15; // col offset for start of detail text
|
||||||
|
det_y = -15; // row offset for start of detail text
|
||||||
|
desc_size = .75; // relative size of description text
|
||||||
|
|
||||||
|
|
||||||
|
lines = [
|
||||||
|
// horizontal lines
|
||||||
|
[-.5, 0, DIM_HORZ, title_width, 1],
|
||||||
|
|
||||||
|
[cols[2], rows[1], DIM_HORZ, cols[3] - cols[2] - .5, 1],
|
||||||
|
[cols[0], rows[2], DIM_HORZ, cols[1] - cols[0] - .5, 1],
|
||||||
|
[cols[0], rows[3], DIM_HORZ, cols[3] - .5, 1],
|
||||||
|
[cols[0], rows[4], DIM_HORZ, cols[2] - .5, 1],
|
||||||
|
[cols[0], rows[5], DIM_HORZ, cols[3] - .5, 1],
|
||||||
|
[cols[0], rows[6], DIM_HORZ, cols[2] - .5, 1],
|
||||||
|
[cols[0], rows[7], DIM_HORZ, cols[2] - .5, 1],
|
||||||
|
|
||||||
|
[cols[0], rows[7], DIM_HORZ, title_width, 1],
|
||||||
|
|
||||||
|
// vertical lines
|
||||||
|
[cols[0], rows[0], DIM_VERT, -rows[7], 1],
|
||||||
|
[cols[1], rows[0], DIM_VERT, -rows[7], 1],
|
||||||
|
[cols[2], rows[0], DIM_VERT, -rows[7], 1],
|
||||||
|
[cols[3], rows[0], DIM_VERT, -rows[7], 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
part_desc = ["Material", "Finish", "Weight", "Part No."];
|
||||||
|
doc_desc = ["Drawing Number",
|
||||||
|
"Created by",
|
||||||
|
"Reviewed by",
|
||||||
|
"Date of issue"
|
||||||
|
];
|
||||||
|
|
||||||
|
// aspects of the part
|
||||||
|
part_details = [
|
||||||
|
"My Sample Part", // title
|
||||||
|
"Stainless Steel", // material
|
||||||
|
" ", // finish
|
||||||
|
"2.5", // weight
|
||||||
|
"123", // part no
|
||||||
|
];
|
||||||
|
|
||||||
|
// aspects documenting the creation of the part
|
||||||
|
doc_details = [
|
||||||
|
"33-2", // Drawing No.
|
||||||
|
"D. Smiley", // Created by
|
||||||
|
" ", // Reviewd by
|
||||||
|
"2013-3-31", // Date
|
||||||
|
];
|
||||||
|
|
||||||
|
// the organization making the part
|
||||||
|
org_details = [
|
||||||
|
"My logo",
|
||||||
|
"Canny Machines",
|
||||||
|
"Org Address, phone"
|
||||||
|
];
|
||||||
|
|
||||||
|
descs = [
|
||||||
|
|
||||||
|
// part description
|
||||||
|
[cols[0] + desc_x, rows[2] + desc_y, DIM_HORZ, part_desc[0], desc_size],
|
||||||
|
[cols[0] + desc_x, rows[3] + desc_y, DIM_HORZ, part_desc[1], desc_size],
|
||||||
|
[cols[0] + desc_x, rows[4] + desc_y, DIM_HORZ, part_desc[2], desc_size],
|
||||||
|
[cols[0] + desc_x, rows[5] + desc_y, DIM_HORZ, part_desc[3], desc_size],
|
||||||
|
|
||||||
|
// documentation description
|
||||||
|
[cols[1] + desc_x, rows[3] + desc_y, DIM_HORZ, doc_desc[0], desc_size],
|
||||||
|
[cols[1] + desc_x, rows[4] + desc_y, DIM_HORZ, doc_desc[1], desc_size],
|
||||||
|
[cols[1] + desc_x, rows[5] + desc_y, DIM_HORZ, doc_desc[2], desc_size],
|
||||||
|
[cols[1] + desc_x, rows[6] + desc_y, DIM_HORZ, doc_desc[3], desc_size],
|
||||||
|
];
|
||||||
|
|
||||||
|
details = [
|
||||||
|
[cols[0] + desc_x, rows[0] + det_y, DIM_HORZ, part_details[0], 1.5],
|
||||||
|
[cols[0] + desc_x, rows[2] + det_y, DIM_HORZ, part_details[1], 1],
|
||||||
|
[cols[0] + desc_x, rows[3] + det_y, DIM_HORZ, part_details[2], 1],
|
||||||
|
[cols[0] + desc_x, rows[4] + det_y, DIM_HORZ, part_details[3], 1],
|
||||||
|
[cols[0] + desc_x, rows[5] + det_y, DIM_HORZ, part_details[4], 1],
|
||||||
|
|
||||||
|
[cols[1] + desc_x * 2, rows[3] + det_y, DIM_HORZ, doc_details[0], 1],
|
||||||
|
[cols[1] + desc_x * 2, rows[4] + det_y, DIM_HORZ, doc_details[1], 1],
|
||||||
|
[cols[1] + desc_x * 2, rows[5] + det_y, DIM_HORZ, doc_details[2], 1],
|
||||||
|
[cols[1] + desc_x * 2, rows[6] + det_y, DIM_HORZ, doc_details[3], 1],
|
||||||
|
|
||||||
|
// Organization Details
|
||||||
|
[cols[1] + desc_x, rows[1] + det_y, DIM_HORZ, org_details[0], 1.5],
|
||||||
|
[cols[2] + desc_x, rows[0] + det_y, DIM_HORZ, org_details[1], 1.5],
|
||||||
|
[cols[2] + desc_x, rows[1] + det_y, DIM_HORZ, org_details[2], 1],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
titleblock(lines, descs, details);
|
||||||
|
|
||||||
|
revisions = [
|
||||||
|
["1a", "2013-4-1", "ds"],
|
||||||
|
["1b", "2013-4-2", "ds"],
|
||||||
|
["2a", "2013-4-3", "ds"],
|
||||||
|
["3a", "2013-4-5", "ds"],
|
||||||
|
["4a", "2013-4-15", "ds"],
|
||||||
|
];
|
||||||
|
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
sample_revisionblock(revisions);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_lines(){
|
||||||
|
// sample lines
|
||||||
|
union() {
|
||||||
|
line(length=2, width=DIM_LINE_WIDTH, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
translate([0, -0.25, 0])
|
||||||
|
line(length=2, width=DIM_LINE_WIDTH, height=DIM_HEIGHT, left_arrow=true,
|
||||||
|
right_arrow=false);
|
||||||
|
translate([0, -0.5, 0])
|
||||||
|
line(length=2, width=DIM_LINE_WIDTH, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=true);
|
||||||
|
translate([0, -0.75, 0])
|
||||||
|
line(length=2, width=DIM_LINE_WIDTH, height=DIM_HEIGHT, left_arrow=true,
|
||||||
|
right_arrow=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_dimensions() {
|
||||||
|
|
||||||
|
/* shows all possibilities
|
||||||
|
DIM_CENTER = 0;
|
||||||
|
DIM_LEFT = 1;
|
||||||
|
DIM_RIGHT = 2;
|
||||||
|
DIM_OUTSIDE = 3;
|
||||||
|
*/
|
||||||
|
|
||||||
|
length = 2.5;
|
||||||
|
|
||||||
|
// The following two lines are vertical lines that bracket the dimensions
|
||||||
|
// left arrow
|
||||||
|
translate([0, -1.75, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(length=length, width=DIM_LINE_WIDTH, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
|
||||||
|
// right arrow
|
||||||
|
translate([length, -1.75, 0])
|
||||||
|
rotate([0, 0, 90])
|
||||||
|
line(length=length, width=DIM_LINE_WIDTH, height=DIM_HEIGHT,
|
||||||
|
left_arrow=false, right_arrow=false);
|
||||||
|
|
||||||
|
// The following runs through all the dimension types
|
||||||
|
for (i = [0:4]) {
|
||||||
|
translate([0, -.5 * i, 0])
|
||||||
|
dimensions(length=length, line_width=DIM_LINE_WIDTH, loc=i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_leaderlines() {
|
||||||
|
|
||||||
|
radius = .25;
|
||||||
|
for (i = [0:6]) {
|
||||||
|
leader_line(angle=i * 15, radius=.25, angle_length=(i * .25),
|
||||||
|
horz_line_length=.5, direction=DIM_RIGHT,
|
||||||
|
line_width=DIM_LINE_WIDTH,
|
||||||
|
text=str("leader line angle: ", i * 15 + 90),
|
||||||
|
do_circle=false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = [1:7]) {
|
||||||
|
leader_line(angle=i * 20 + 90, radius=.25,
|
||||||
|
angle_length=.75,
|
||||||
|
horz_line_length=.5, direction=DIM_LEFT,
|
||||||
|
line_width=DIM_LINE_WIDTH,
|
||||||
|
text=str("leader line angle: ", i * 20 + 90));
|
||||||
|
}
|
||||||
|
for (i = [1:4]) {
|
||||||
|
leader_line(angle=-i * 20, radius=.25, angle_length=1.5,
|
||||||
|
horz_line_length=.25, direction=DIM_RIGHT,
|
||||||
|
line_width=DIM_LINE_WIDTH,
|
||||||
|
text=str(i),
|
||||||
|
do_circle=true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module sample_circlecenter() {
|
||||||
|
|
||||||
|
radius = .25;
|
||||||
|
difference() {
|
||||||
|
cube([1, 1, 1], center=true);
|
||||||
|
cylinder(h=1.1, r=radius, center=true, $fn=100);
|
||||||
|
}
|
||||||
|
color("Black")
|
||||||
|
translate([0, 0, .51])
|
||||||
|
circle_center(radius=radius, size=DIM_HOLE_CENTER,
|
||||||
|
line_width=DIM_LINE_WIDTH);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// uncomment these to sample
|
||||||
|
// sample_lines();
|
||||||
|
//
|
||||||
|
// translate([-5.5, 0, 0])
|
||||||
|
// sample_dimensions();
|
||||||
|
//
|
||||||
|
// translate([4, 0, 0])
|
||||||
|
// sample_circlecenter();
|
||||||
|
//
|
||||||
|
// translate([-2, 3, 0])
|
||||||
|
// sample_leaderlines();
|
||||||
|
//
|
||||||
|
// translate([3, 4, 0])
|
||||||
|
// sample_titleblock1();
|
||||||
|
//
|
||||||
|
// translate([0, -2, 0])
|
||||||
|
// sample_titleblock2();
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,244 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
'''
|
||||||
|
@license GPLv3
|
||||||
|
@sources https://github.com/lautr3k/odmt
|
||||||
|
@author Sebastien Mischler <skarab>
|
||||||
|
@author http://www.onlfait.ch
|
||||||
|
'''
|
||||||
|
|
||||||
|
import argparse, os, sys, fnmatch, ezdxf
|
||||||
|
|
||||||
|
# configuration
|
||||||
|
app_name = 'odmt'
|
||||||
|
app_version = '1.0.0'
|
||||||
|
app_description = 'OpenSCAD DXF Merge Tool (odmt) - v' + app_version
|
||||||
|
|
||||||
|
# default i/o
|
||||||
|
input = ['./input']
|
||||||
|
output = './output/merged.dxf'
|
||||||
|
|
||||||
|
# search and ignore files pattern
|
||||||
|
search = ['*.dxf']
|
||||||
|
ignore = ['*_ignore_*']
|
||||||
|
|
||||||
|
# layers indexed colors
|
||||||
|
# http://sub-atomic.com/~moses/acadcolors.html
|
||||||
|
colors = range(10)
|
||||||
|
colors.extend(range(10, 250, 10))
|
||||||
|
colors = map(str, colors)
|
||||||
|
|
||||||
|
# command line parser
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog = app_name,
|
||||||
|
description = app_description)
|
||||||
|
parser.add_argument('--input', '-i',
|
||||||
|
nargs = '+',
|
||||||
|
default = input,
|
||||||
|
metavar = 'path',
|
||||||
|
help = 'input file or directory - default: ['
|
||||||
|
+ ', '.join(input) + ']')
|
||||||
|
parser.add_argument('--output', '-o',
|
||||||
|
default = output,
|
||||||
|
metavar = 'path',
|
||||||
|
help = 'output file - default: ' + output)
|
||||||
|
parser.add_argument('--search',
|
||||||
|
nargs = '+',
|
||||||
|
default = search,
|
||||||
|
metavar = 'pattern',
|
||||||
|
help = 'search file pattern - default: ['
|
||||||
|
+ ', '.join(search) + ']')
|
||||||
|
parser.add_argument('--ignore',
|
||||||
|
nargs = '+',
|
||||||
|
default = ignore,
|
||||||
|
metavar = 'pattern',
|
||||||
|
help = 'ignored file/directory pattern - default: ['
|
||||||
|
+ ', '.join(ignore) + ']')
|
||||||
|
parser.add_argument('--colors',
|
||||||
|
nargs = '+',
|
||||||
|
default = colors,
|
||||||
|
metavar = 'index',
|
||||||
|
help = 'layers indexed colors - default: ['
|
||||||
|
+ ', '.join(colors) + ']')
|
||||||
|
parser.add_argument('--nolayers',
|
||||||
|
action = 'store_true',
|
||||||
|
help = 'if set, all files will be merged into the same layer')
|
||||||
|
parser.add_argument('--version', '-v',
|
||||||
|
action = 'version',
|
||||||
|
version = '%(prog)s ' + app_version)
|
||||||
|
|
||||||
|
# parse the command line
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# local variables assignment
|
||||||
|
input = args.input
|
||||||
|
output = os.path.realpath(args.output)
|
||||||
|
search = args.search
|
||||||
|
ignore = args.ignore
|
||||||
|
colors = map(int, args.colors)
|
||||||
|
nolayers = args.nolayers
|
||||||
|
|
||||||
|
# test output directory
|
||||||
|
output_dir = os.path.dirname(output)
|
||||||
|
|
||||||
|
if os.path.isdir(output_dir) == False:
|
||||||
|
print 'output directory not found :', output_dir
|
||||||
|
sys.exit(1);
|
||||||
|
|
||||||
|
def file_match(input, patterns):
|
||||||
|
'return if input match at least one pattern'
|
||||||
|
for pattern in patterns:
|
||||||
|
if fnmatch.fnmatch(input, pattern):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def dxf_search(input):
|
||||||
|
'scan an input file or directory for DXF file'
|
||||||
|
found = []
|
||||||
|
ignored = []
|
||||||
|
if os.path.isdir(input):
|
||||||
|
for file in os.listdir(input):
|
||||||
|
r = dxf_search(os.path.join(input, file))
|
||||||
|
found.extend(r[0])
|
||||||
|
ignored.extend(r[1])
|
||||||
|
elif os.path.isfile(input):
|
||||||
|
if file_match(input, search):
|
||||||
|
if file_match(input, ignore):
|
||||||
|
ignored.append(input)
|
||||||
|
else:
|
||||||
|
found.append(input)
|
||||||
|
else:
|
||||||
|
ignored.append(input)
|
||||||
|
return found, ignored
|
||||||
|
|
||||||
|
def dxf_parse(file):
|
||||||
|
'''
|
||||||
|
extract all LINE tags from an OpenSCAD DXF file
|
||||||
|
and return an array of POLYLINE points
|
||||||
|
'''
|
||||||
|
counter = 0
|
||||||
|
points = []
|
||||||
|
last_block = []
|
||||||
|
polylines = []
|
||||||
|
|
||||||
|
with open(file) as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip('\n');
|
||||||
|
|
||||||
|
# block start
|
||||||
|
if line == 'LINE':
|
||||||
|
counter = 1;
|
||||||
|
block = [[0, 0], [0, 0]];
|
||||||
|
|
||||||
|
# in the block
|
||||||
|
if counter > 0:
|
||||||
|
# start line
|
||||||
|
if counter == 5:
|
||||||
|
block[0][0] = line
|
||||||
|
if counter == 7:
|
||||||
|
block[0][1] = line
|
||||||
|
# end line
|
||||||
|
if counter == 9:
|
||||||
|
block[1][0] = line
|
||||||
|
if counter == 11:
|
||||||
|
block[1][1] = line
|
||||||
|
# increment
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
# end block
|
||||||
|
if counter == 13:
|
||||||
|
counter = 0
|
||||||
|
|
||||||
|
# discontinued line
|
||||||
|
if len(last_block) and block[0] != last_block[1]:
|
||||||
|
polylines.append(points)
|
||||||
|
points = []
|
||||||
|
|
||||||
|
points.append((block[0][0], block[0][1]))
|
||||||
|
points.append((block[1][0], block[1][1]))
|
||||||
|
last_block = block
|
||||||
|
|
||||||
|
# return polylines
|
||||||
|
if len(points):
|
||||||
|
polylines.append(points)
|
||||||
|
return polylines
|
||||||
|
|
||||||
|
# no polyline found
|
||||||
|
return None
|
||||||
|
|
||||||
|
def dxf_merge(files, colors = range(0, 256), nolayer = False):
|
||||||
|
'merge DXF file and convert continuous line to polyline.'
|
||||||
|
|
||||||
|
# DXF file
|
||||||
|
dwg = ezdxf.new('AC1015')
|
||||||
|
msp = dwg.modelspace()
|
||||||
|
|
||||||
|
# layer vars
|
||||||
|
layer_num = 1
|
||||||
|
|
||||||
|
layer_name = 'layer0'
|
||||||
|
layer_names = []
|
||||||
|
|
||||||
|
layer_colors = iter(colors)
|
||||||
|
layer_color = next(layer_colors)
|
||||||
|
|
||||||
|
# for each files
|
||||||
|
for file in files:
|
||||||
|
# layer name
|
||||||
|
if nolayers == False:
|
||||||
|
layer_name = os.path.basename(file)
|
||||||
|
n = layer_name
|
||||||
|
i = 1
|
||||||
|
while n in layer_names:
|
||||||
|
n = layer_name + '_' + str(i)
|
||||||
|
i += 1
|
||||||
|
layer_names.append(n)
|
||||||
|
layer_name = n
|
||||||
|
|
||||||
|
# create layer
|
||||||
|
if layer_num < 2 or nolayers == False:
|
||||||
|
try:
|
||||||
|
dwg.layers.create(
|
||||||
|
name = layer_name,
|
||||||
|
dxfattribs = {'color': layer_color})
|
||||||
|
except AttributeError: # new syntax
|
||||||
|
dwg.layers.new(
|
||||||
|
name = layer_name,
|
||||||
|
dxfattribs = {'color': layer_color})
|
||||||
|
|
||||||
|
# parse file
|
||||||
|
polylines = dxf_parse(file)
|
||||||
|
if len(polylines):
|
||||||
|
for polyline in polylines:
|
||||||
|
msp.add_lwpolyline(polyline, dxfattribs={'layer': layer_name})
|
||||||
|
|
||||||
|
# next layer color
|
||||||
|
layer_color = next(layer_colors, False)
|
||||||
|
if layer_color == False:
|
||||||
|
layer_colors = iter(colors)
|
||||||
|
layer_color = next(layer_colors)
|
||||||
|
|
||||||
|
# increment layer num
|
||||||
|
layer_num += 1
|
||||||
|
|
||||||
|
#return the dwg object
|
||||||
|
return dwg
|
||||||
|
|
||||||
|
# DXF files
|
||||||
|
input_files = []
|
||||||
|
ignored_files = []
|
||||||
|
|
||||||
|
# make the files tree
|
||||||
|
for item in input:
|
||||||
|
result = dxf_search(os.path.realpath(item))
|
||||||
|
input_files.extend(result[0])
|
||||||
|
ignored_files.extend(result[1])
|
||||||
|
|
||||||
|
# do the serious job
|
||||||
|
dxf_merge(input_files, colors, nolayers).saveas(output)
|
||||||
|
|
||||||
|
# success message
|
||||||
|
print 'input :', '\n\t '.join(input_files)
|
||||||
|
if len(ignored_files):
|
||||||
|
print '\nignored :', '\n\t '.join(ignored_files)
|
||||||
|
print '\noutput :', output
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
class Art(object):
|
||||||
|
def __init__(self, name, colour = None):
|
||||||
|
self.name = name
|
||||||
|
self.colour = colour if colour else name
|
||||||
|
self.load()
|
||||||
|
self.recolour()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path(self):
|
||||||
|
return 'outputs/art_{}.svg'.format(self.name)
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
with open(self.path, 'rb') as f:
|
||||||
|
self.xml = etree.parse(f)
|
||||||
|
self.root = self.xml.getroot()
|
||||||
|
|
||||||
|
self.polygon = self.find_el('path')
|
||||||
|
if self.polygon is None:
|
||||||
|
raise AttributeError('Loaded svg has no path element')
|
||||||
|
|
||||||
|
def find_el(self, el):
|
||||||
|
return self.root.find('{{*}}{}'.format(el))
|
||||||
|
|
||||||
|
def recolour(self):
|
||||||
|
attribs = self.polygon.attrib
|
||||||
|
attribs['stroke'] = 'none'
|
||||||
|
attribs['style'] = 'stroke:none'
|
||||||
|
attribs['fill'] = self.colour
|
||||||
|
attribs['stroke-width'] = '0'
|
||||||
|
|
||||||
|
def set_dims(self, value):
|
||||||
|
self.root.attrib['width'] = str(value[0]) + 'mm'
|
||||||
|
self.root.attrib['height'] = str(value[1]) + 'mm'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def viewbox(self):
|
||||||
|
return [int(x) for x in self.root.attrib['viewBox'].split(' ')]
|
||||||
|
|
||||||
|
@viewbox.setter
|
||||||
|
def viewbox(self, value):
|
||||||
|
self.root.attrib['viewBox'] = ' '.join(str(x) for x in value)
|
||||||
|
|
||||||
|
def add_layer(master, layer_id, layer_name, contents):
|
||||||
|
group = etree.Element('g')
|
||||||
|
group.attrib['{http://www.inkscape.org/namespaces/inkscape}groupmode'] = 'layer'
|
||||||
|
group.attrib['id'] = layer_id
|
||||||
|
group.attrib['{http://www.inkscape.org/namespaces/inkscape}label'] = layer_name
|
||||||
|
for c in contents:
|
||||||
|
group.append(c.polygon)
|
||||||
|
master.root.append(group)
|
||||||
|
|
||||||
|
layers = [
|
||||||
|
Art('black'),
|
||||||
|
Art('white'),
|
||||||
|
Art('grey'),
|
||||||
|
Art('orange'),
|
||||||
|
Art('blue', 'rgb(38,128,192)'),
|
||||||
|
Art('pink', 'rgb(220,64,117)'),
|
||||||
|
Art('cuts', 'rgb(255,0,255)'),
|
||||||
|
Art('dimensions', 'rgb(0,0,0)')
|
||||||
|
]
|
||||||
|
|
||||||
|
master = layers[0]
|
||||||
|
|
||||||
|
title = master.find_el('title')
|
||||||
|
if title is not None:
|
||||||
|
title.text = 'Pocket Voltex Artwork'
|
||||||
|
|
||||||
|
# cuts get stroke instead of fill
|
||||||
|
cuts = layers[-2]
|
||||||
|
cut_attribs = cuts.polygon.attrib
|
||||||
|
cut_attribs['stroke'] = cuts.colour
|
||||||
|
cut_attribs['stroke-width'] = '0.1'
|
||||||
|
cut_attribs['fill'] = 'none'
|
||||||
|
cut_attribs.pop('style')
|
||||||
|
|
||||||
|
# delete layer 0's path
|
||||||
|
master.polygon.getparent().remove(master.polygon)
|
||||||
|
|
||||||
|
# layers with actual names
|
||||||
|
add_layer(master, "layer1", "artwork", layers[:-2])
|
||||||
|
add_layer(master, "layer2", "cuts", [cuts])
|
||||||
|
add_layer(master, "layer3", "dimensions", [layers[-1]])
|
||||||
|
|
||||||
|
# fix viewbox
|
||||||
|
bottom_left_corner = master.viewbox[:2]
|
||||||
|
upper_right_corner = [left+size for left, size in zip(bottom_left_corner, master.viewbox[2:])]
|
||||||
|
for l in layers[1:]:
|
||||||
|
layer_bottom_left = l.viewbox[:2]
|
||||||
|
layer_upper_right = [left+size for left, size in zip(layer_bottom_left, l.viewbox[2:])]
|
||||||
|
for i in range(2):
|
||||||
|
# left start x, y
|
||||||
|
bottom_left_corner[i] = min(bottom_left_corner[i], layer_bottom_left[i])
|
||||||
|
# width and height
|
||||||
|
upper_right_corner[i] = max(upper_right_corner[i], layer_upper_right[i])
|
||||||
|
box = bottom_left_corner + [topright-bottomleft for topright, bottomleft in zip(upper_right_corner, bottom_left_corner)]
|
||||||
|
master.viewbox = box
|
||||||
|
master.set_dims(box[2:])
|
||||||
|
|
||||||
|
out = etree.tostring(master.xml, pretty_print=True)
|
||||||
|
with open('outputs/artwork.svg', 'wb') as f:
|
||||||
|
f.write(out)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
// like mirror, but leaves the original too
|
||||||
|
module reflect(axis) {
|
||||||
|
children();
|
||||||
|
|
||||||
|
mirror(axis)
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module rounded_square(w, h, r) {
|
||||||
|
translate([r,r])
|
||||||
|
minkowski() {
|
||||||
|
square([w,h]-[r*2,r*2]);
|
||||||
|
circle(r=r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module ring(outer_radius, thickness) {
|
||||||
|
difference() {
|
||||||
|
circle(r=outer_radius);
|
||||||
|
circle(r=outer_radius-thickness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// to get consistent colours on our render
|
||||||
|
module light_from_above() {
|
||||||
|
rotate([-40,0,0]) scale([1,1/cos(40),0.01])children();
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum from 0 to end, like python sum(v[:end])
|
||||||
|
function sum(v, end=-1, i=0, r=0) = (i<len(v) && (end < 0 || i < end)) ? sum(v, end, i+1, r+v[i]) : r;
|
||||||
|
|
||||||
|
function lookup3D(index, v) = [
|
||||||
|
lookup(index, [for (el = v) [el[0], el[1].x]]),
|
||||||
|
lookup(index, [for (el = v) [el[0], el[1].y]]),
|
||||||
|
lookup(index, [for (el = v) [el[0], el[1].z]]),
|
||||||
|
];
|
||||||
|
|
||||||
|
function quad_ease_inout(t) = t<.5 ? 2*t*t : -1+(4-2*t)*t;
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
|||||||
|
EESchema-LIBRARY Version 2.3
|
||||||
|
#encoding utf-8
|
||||||
|
#
|
||||||
|
# SK9822
|
||||||
|
#
|
||||||
|
DEF SK9822 D 0 40 Y Y 1 F N
|
||||||
|
F0 "D" 0 100 60 H V C CNN
|
||||||
|
F1 "SK9822" 0 0 60 H V C CNN
|
||||||
|
F2 "" 0 0 60 H I C CNN
|
||||||
|
F3 "" 0 0 60 H I C CNN
|
||||||
|
DRAW
|
||||||
|
S -250 -50 250 -350 0 1 0 f
|
||||||
|
X SDI 1 -450 -100 200 R 50 50 1 1 I
|
||||||
|
X CKI 2 -450 -200 200 R 50 50 1 1 I
|
||||||
|
X GND 3 -450 -300 200 R 50 50 1 1 W
|
||||||
|
X VCC 4 450 -300 200 L 50 50 1 1 W
|
||||||
|
X CKO 5 450 -200 200 L 50 50 1 1 O
|
||||||
|
X SDO 6 450 -100 200 L 50 50 1 1 O
|
||||||
|
ENDDRAW
|
||||||
|
ENDDEF
|
||||||
|
#
|
||||||
|
#End Library
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
(module Cherry-MX-Kailh-only (layer F.Cu) (tedit 5AF00F94)
|
||||||
|
(fp_text reference REF** (at 2.5 5.5) (layer B.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||||
|
)
|
||||||
|
(fp_arc (start 3.815415 4.483532) (end 6.085 4.483532) (angle 90) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_arc (start -0.53 0) (end 2.1 0.85) (angle 73.52157766) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 6.085 4.5) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 2.1 0.85) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end 3.9 6.75) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end -4.815 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 2.755) (end -0.53 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(pad "" np_thru_hole circle (at 3.81 2.54) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -2.54 5.08) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad 1 smd rect (at -6.3 5.08) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
(pad 2 smd rect (at 7.6 2.54) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
(module Encoder_Bourns_PEC16 (layer F.Cu) (tedit 5AF0166B)
|
||||||
|
(fp_text reference REF** (at 0 -5.08) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value Encoder_Bourns_PEC16 (at 0 3.81) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start -8 10.5) (end -8 2.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -6.5 10.5) (end -8 10.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -1.5 10.5) (end -3.5 10.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 3.5 10.5) (end 1.5 10.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 8 10.5) (end 6.5 10.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 8 2.5) (end 8 10.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 8 -7) (end 8 -2.5) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -8 -7) (end 8 -7) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -8 -2.5) (end -8 -7) (layer F.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -10.2 12.4) (end 10.2 12.4) (layer F.CrtYd) (width 0.3))
|
||||||
|
(fp_line (start -10.2 -8.4) (end -10.2 12.4) (layer F.CrtYd) (width 0.3))
|
||||||
|
(fp_line (start 10.2 -8.4) (end -10.2 -8.4) (layer F.CrtYd) (width 0.3))
|
||||||
|
(fp_line (start 10.2 12.4) (end 10.2 -8.4) (layer F.CrtYd) (width 0.3))
|
||||||
|
(fp_circle (center 0 0) (end -1 -1) (layer F.SilkS) (width 0.3))
|
||||||
|
(pad 1 thru_hole circle (at -5 10.5) (size 1.6 1.6) (drill 1.2) (layers *.Cu *.Mask))
|
||||||
|
(pad 2 thru_hole circle (at 5 10.5) (size 1.6 1.6) (drill 1.2) (layers *.Cu *.Mask))
|
||||||
|
(pad 3 thru_hole circle (at 0 10.5) (size 1.6 1.6) (drill 1.2) (layers *.Cu *.Mask))
|
||||||
|
(pad "" thru_hole oval (at 8 0) (size 3.8 3.4) (drill oval 2.8 2.4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" thru_hole oval (at -8 0) (size 3.8 3.4) (drill oval 2.8 2.4) (layers *.Cu *.Mask))
|
||||||
|
(model ${KIPRJMOD}/PocketVoltex.pretty/PEC16-4X20F-SXXXX_sp.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
|
|||||||
|
(module LED_SK9822 (layer F.Cu) (tedit 5B1B5528)
|
||||||
|
(descr http://cdn.sparkfun.com/datasheets/Components/LED/5060BRG4.pdf)
|
||||||
|
(tags "RGB LED 5050-6")
|
||||||
|
(attr smd)
|
||||||
|
(fp_text reference REF** (at 0 -3.5 180) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value LED_SK9822 (at 0 3.3) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start 0 -2.3) (end -0.8 -1.7) (layer F.SilkS) (width 0.15))
|
||||||
|
(fp_line (start 0 -1.1) (end 0 -2.3) (layer F.SilkS) (width 0.15))
|
||||||
|
(fp_line (start -0.8 -1.7) (end 0 -1.1) (layer F.SilkS) (width 0.15))
|
||||||
|
(fp_line (start -2.5 -1.9) (end -1.9 -2.5) (layer F.Fab) (width 0.1))
|
||||||
|
(fp_line (start 2.5 -2.5) (end -2.5 -2.5) (layer F.Fab) (width 0.1))
|
||||||
|
(fp_line (start 2.5 2.5) (end 2.5 -2.5) (layer F.Fab) (width 0.1))
|
||||||
|
(fp_line (start -2.5 2.5) (end 2.5 2.5) (layer F.Fab) (width 0.1))
|
||||||
|
(fp_line (start -2.5 -2.5) (end -2.5 2.5) (layer F.Fab) (width 0.1))
|
||||||
|
(fp_line (start -3.6 -2.7) (end 2.5 -2.7) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start -3.6 -1.6) (end -3.6 -2.7) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 2.5 2.7) (end -2.5 2.7) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 3.65 -2.75) (end -3.65 -2.75) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 3.65 2.75) (end 3.65 -2.75) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -3.65 2.75) (end 3.65 2.75) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -3.65 -2.75) (end -3.65 2.75) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||||
|
(effects (font (size 0.6 0.6) (thickness 0.06)))
|
||||||
|
)
|
||||||
|
(fp_circle (center 0 0) (end 0 -1.9) (layer F.Fab) (width 0.1))
|
||||||
|
(pad 1 smd rect (at -2.4 -1.7 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at -2.4 0 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 3 smd rect (at -2.4 1.7 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 4 smd rect (at 2.4 1.7 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 5 smd rect (at 2.4 0 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 6 smd rect (at 2.4 -1.7 90) (size 1.1 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(model ${KISYS3DMOD}/LEDs.3dshapes/LED_RGB_5050-6.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
|||||||
|
(module SW_Cherry_MX1A_1.00u_PCB_Socket (layer F.Cu) (tedit 5AF00FFB)
|
||||||
|
(descr "Cherry MX keyswitch, MX1A, 1u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
|
||||||
|
(tags "cherry mx keyswitch MX1A 1u PCB")
|
||||||
|
(fp_text value SW_Cherry_MX1A_1.00u_PCB (at 0 7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text user %R (at 0 -7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start -6.35 -6.35) (end 6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 -6.35) (end 6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 6.35) (end -6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -6.35 6.35) (end -6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -7.24 7.24) (end -7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 7.24) (end -7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 -7.24) (end 7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -7.24 -7.24) (end 7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -9.525 -9.525) (end 9.525 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 9.525 -9.525) (end 9.525 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 9.525 9.525) (end -9.525 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -9.525 9.525) (end -9.525 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -6.985 -6.985) (end 6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 -6.985) (end 6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 6.985) (end -6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start -6.985 6.985) (end -6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(pad "" np_thru_hole circle (at 0 0) (size 4 4) (drill 4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at 5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(model ${KISYS3DMOD}/Buttons_Switches_Keyboard.3dshapes/SW_Cherry_MX1A_1.00u_PCB.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
(fp_text reference REF** (at 2.5 5.5) (layer B.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||||
|
)
|
||||||
|
(fp_arc (start 3.815415 4.483532) (end 6.085 4.483532) (angle 90) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_arc (start -0.53 0) (end 2.1 0.85) (angle 73.52157766) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 6.085 4.5) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 2.1 0.85) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end 3.9 6.75) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end -4.815 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 2.755) (end -0.53 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(pad "" np_thru_hole circle (at 3.81 2.54) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -2.54 5.08) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad 1 smd rect (at -6.3 5.08) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
(pad 2 smd rect (at 7.6 2.54) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
(module SW_Cherry_MX1A_1.25u_PCB_Socket (layer F.Cu) (tedit 5AF00F4D)
|
||||||
|
(descr "Cherry MX keyswitch, MX1A, 1.25u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
|
||||||
|
(tags "cherry mx keyswitch MX1A 1.25u PCB")
|
||||||
|
(fp_text value SW_Cherry_MX1A_1.25u_PCB (at 0 7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text user %R (at 0 -7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start -6.35 -6.35) (end 6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 -6.35) (end 6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 6.35) (end -6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -6.35 6.35) (end -6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -7.24 7.24) (end -7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 7.24) (end -7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 -7.24) (end 7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -7.24 -7.24) (end 7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -11.90625 -9.525) (end 11.90625 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 11.90625 -9.525) (end 11.90625 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 11.90625 9.525) (end -11.90625 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -11.90625 9.525) (end -11.90625 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -6.985 -6.985) (end 6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 -6.985) (end 6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 6.985) (end -6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start -6.985 6.985) (end -6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(pad "" np_thru_hole circle (at 0 0) (size 4 4) (drill 4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at 5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(model ${KISYS3DMOD}/Buttons_Switches_Keyboard.3dshapes/SW_Cherry_MX1A_1.25u_PCB.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
(fp_text reference REF** (at 2.5 5.5) (layer B.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||||
|
)
|
||||||
|
(fp_arc (start 3.815415 4.483532) (end 6.085 4.483532) (angle 90) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_arc (start -0.53 0) (end 2.1 0.85) (angle 73.52157766) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 6.085 4.5) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 2.1 0.85) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end 3.9 6.75) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end -4.815 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 2.755) (end -0.53 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(pad "" np_thru_hole circle (at 3.81 2.54) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -2.54 5.08) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad 1 smd rect (at -6.3 5.08) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
(pad 2 smd rect (at 7.6 2.54) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
(module SW_Cherry_MX1A_2.25u_PCB_Socket (layer F.Cu) (tedit 5AF01062)
|
||||||
|
(descr "Cherry MX keyswitch, MX1A, 2.25u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
|
||||||
|
(tags "cherry mx keyswitch MX1A 2.25u PCB")
|
||||||
|
(fp_text value SW_Cherry_MX1A_2.25u_PCB (at 0 7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text user %R (at 0 -7.874) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start -6.35 -6.35) (end 6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 -6.35) (end 6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start 6.35 6.35) (end -6.35 6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -6.35 6.35) (end -6.35 -6.35) (layer F.Fab) (width 0.15))
|
||||||
|
(fp_line (start -7.24 7.24) (end -7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 7.24) (end -7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 7.24 -7.24) (end 7.24 7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -7.24 -7.24) (end 7.24 -7.24) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -21.43125 -9.525) (end 21.43125 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 21.43125 -9.525) (end 21.43125 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start 21.43125 9.525) (end -21.43125 9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -21.43125 9.525) (end -21.43125 -9.525) (layer Dwgs.User) (width 0.15))
|
||||||
|
(fp_line (start -6.985 -6.985) (end 6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 -6.985) (end 6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start 6.985 6.985) (end -6.985 6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(fp_line (start -6.985 6.985) (end -6.985 -6.985) (layer F.SilkS) (width 0.12))
|
||||||
|
(pad "" np_thru_hole circle (at 0 0) (size 4 4) (drill 4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at 5.08 0) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at 11.9 8.24) (size 4 4) (drill 4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -11.9 8.24) (size 4 4) (drill 4) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -11.9 -7) (size 3.05 3.05) (drill 3.05) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at 11.9 -7) (size 3.05 3.05) (drill 3.05) (layers *.Cu *.Mask))
|
||||||
|
(model ${KISYS3DMOD}/Buttons_Switches_Keyboard.3dshapes/SW_Cherry_MX1A_2.25u_PCB.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
(fp_text reference REF** (at 2.5 5.5) (layer B.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||||
|
)
|
||||||
|
(fp_arc (start 3.815415 4.483532) (end 6.085 4.483532) (angle 90) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_arc (start -0.53 0) (end 2.1 0.85) (angle 73.52157766) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 6.085 4.5) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start 2.1 0.85) (end 6.085 0.865) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end 3.9 6.75) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 6.755) (end -4.815 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(fp_line (start -4.815 2.755) (end -0.53 2.755) (layer B.SilkS) (width 0.3))
|
||||||
|
(pad "" np_thru_hole circle (at 3.81 2.54) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -2.54 5.08) (size 3 3) (drill 3) (layers *.Cu *.Mask))
|
||||||
|
(pad 1 smd rect (at -6.3 5.08) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
(pad 2 smd rect (at 7.6 2.54) (size 2.55 2.5) (layers B.Cu B.Paste B.Mask))
|
||||||
|
(model ${KIPRJMOD}/PocketVoltex.pretty/mx_stab_pcb_open.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
(module SW_SPST_KSC-G (layer F.Cu) (tedit 5AF6C0C2)
|
||||||
|
(fp_text reference REF** (at 0 0.5) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value SW_SPST_KSC-G (at 0 -0.5) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(pad 1 smd rect (at 4.45 2) (size 3.1 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 1 smd rect (at -4.45 2) (size 3.1 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at 4.45 -2) (size 3.1 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at -4.45 -2) (size 3.1 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(model ${KIPRJMOD}/PocketVoltex.pretty/KSC5.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
(module SW_SPST_KSC-J (layer F.Cu) (tedit 5B192C9B)
|
||||||
|
(fp_text reference REF** (at 0 0.5) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value SW_SPST_KSC-J (at 0 -0.5) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(pad 1 smd rect (at 2.9 2) (size 2.8 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 1 smd rect (at -2.9 2) (size 2.8 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at 2.9 -2) (size 2.8 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at -2.9 -2) (size 2.8 1) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(model ${KIPRJMOD}/PocketVoltex.pretty/KSC5.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,53 @@
|
|||||||
|
(module USB_C_Receptacle_UJ31-CH-31-SMT-TR (layer F.Cu) (tedit 5AF6C356)
|
||||||
|
(fp_text reference REF** (at 0 5.08) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value USB_C (at 0 7.62) (layer F.Fab)
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_line (start -5 -0.5) (end 5 -0.5) (layer F.CrtYd) (width 0.15))
|
||||||
|
(fp_line (start -5 10.5) (end -5 -0.5) (layer F.CrtYd) (width 0.15))
|
||||||
|
(fp_line (start 5 10.5) (end -5 10.5) (layer F.CrtYd) (width 0.15))
|
||||||
|
(fp_line (start 5 -0.5) (end 5 10.5) (layer F.CrtYd) (width 0.15))
|
||||||
|
(fp_text user "PCB EDGE" (at 0 11) (layer F.Fab)
|
||||||
|
(effects (font (size 0.5 0.5) (thickness 0.07)))
|
||||||
|
)
|
||||||
|
(fp_line (start -4.5 10.26) (end 4.5 10.26) (layer F.Fab) (width 0.15))
|
||||||
|
(pad A1 smd rect (at -2.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A2 smd rect (at -2.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A3 smd rect (at -1.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A4 smd rect (at -1.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A5 smd rect (at -0.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A6 smd rect (at -0.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A7 smd rect (at 0.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A8 smd rect (at 0.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A9 smd rect (at 1.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A10 smd rect (at 1.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A11 smd rect (at 2.25 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad A12 smd rect (at 2.75 0) (size 0.32 0.7) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad "" np_thru_hole circle (at -3.6 0.66) (size 0.85 0.85) (drill 0.85) (layers *.Cu *.Mask))
|
||||||
|
(pad "" np_thru_hole oval (at 3.6 0.66) (size 1.15 0.85) (drill oval 1.15 0.85) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at -4.33 7.86) (size 0.9 1.4) (drill oval 0.6 1.1) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at 4.33 7.86) (size 0.9 1.4) (drill oval 0.6 1.1) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at -4.33 1.91) (size 0.9 1.4) (drill oval 0.6 1.1) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at 4.33 1.91) (size 0.9 1.4) (drill oval 0.6 1.1) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at -4.005 1.66 90) (size 0.9 1.55) (drill oval 0.6 1.25) (layers *.Cu *.Mask))
|
||||||
|
(pad B12 thru_hole circle (at -2.8 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B9 thru_hole circle (at -1.2 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B7 thru_hole circle (at -0.4 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B6 thru_hole circle (at 0.4 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B4 thru_hole circle (at 1.2 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B1 thru_hole circle (at 2.8 1.31) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B11 thru_hole circle (at -2.4 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B10 thru_hole circle (at -1.6 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B8 thru_hole circle (at -0.8 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B5 thru_hole circle (at 0.8 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B3 thru_hole circle (at 1.6 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad B2 thru_hole circle (at 2.4 2.01) (size 0.6 0.6) (drill 0.4) (layers *.Cu *.Mask))
|
||||||
|
(pad S1 thru_hole oval (at 4.005 1.66 90) (size 0.9 1.55) (drill oval 0.6 1.25) (layers *.Cu *.Mask))
|
||||||
|
(model ${KIPRJMOD}/PocketVoltex.pretty/UJ31-CH-31-SMT-TR.wrl
|
||||||
|
(at (xyz 0 0 0))
|
||||||
|
(scale (xyz 1 1 1))
|
||||||
|
(rotate (xyz 0 0 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
(module VIA_0.4mm (layer F.Cu) (tedit 5B1925A5)
|
||||||
|
(fp_text reference REF** (at 0 0.5) (layer F.SilkS) hide
|
||||||
|
(effects (font (size 0.127 0.127) (thickness 0.03175)))
|
||||||
|
)
|
||||||
|
(fp_text value VIA_0.4mm (at 0 -0.5) (layer F.Fab) hide
|
||||||
|
(effects (font (size 0.127 0.127) (thickness 0.03175)))
|
||||||
|
)
|
||||||
|
(pad 1 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.4) (layers *.Cu)
|
||||||
|
(zone_connect 2))
|
||||||
|
)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
(module murata-resonator_SMD_CSTCE16M0V53-R0 (layer F.Cu) (tedit 553BC69A)
|
||||||
|
(descr ./Docs/MURATA__p17e.pdf)
|
||||||
|
(tags "resonator, murata, SMD, CSTCE16M0V53-R0")
|
||||||
|
(fp_text reference X? (at 0 -2.4) (layer F.SilkS)
|
||||||
|
(effects (font (size 1 1) (thickness 0.2)))
|
||||||
|
)
|
||||||
|
(fp_text value VAL** (at 0 2.6) (layer F.SilkS) hide
|
||||||
|
(effects (font (size 1 1) (thickness 0.2)))
|
||||||
|
)
|
||||||
|
(fp_line (start -1.8 1.1) (end -1.8 -1.1) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 1.8 1.1) (end -1.8 1.1) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 1.8 -1.1) (end 1.8 1.1) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start -1.8 -1.1) (end 1.8 -1.1) (layer F.CrtYd) (width 0.05))
|
||||||
|
(fp_line (start 1.6 0.65) (end -1.6 0.65) (layer F.SilkS) (width 0.2))
|
||||||
|
(fp_line (start -1.6 -0.65) (end 1.6 -0.65) (layer F.SilkS) (width 0.2))
|
||||||
|
(fp_line (start 1.6 -0.65) (end 1.6 0.65) (layer F.SilkS) (width 0.2))
|
||||||
|
(fp_line (start -1.6 -0.65) (end -1.6 0.65) (layer F.SilkS) (width 0.2))
|
||||||
|
(pad 1 smd rect (at -0.95 0) (size 0.6 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 2 smd rect (at 0 0) (size 0.6 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
(pad 3 smd rect (at 0.95 0) (size 0.6 2) (layers F.Cu F.Paste F.Mask))
|
||||||
|
)
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
|
|||||||
|
update=16/08/2018 10:39:03 PM
|
||||||
|
version=1
|
||||||
|
last_client=kicad
|
||||||
|
[pcbnew]
|
||||||
|
version=1
|
||||||
|
LastNetListRead=
|
||||||
|
UseCmpFile=1
|
||||||
|
PadDrill=0.600000000000
|
||||||
|
PadDrillOvalY=0.600000000000
|
||||||
|
PadSizeH=1.500000000000
|
||||||
|
PadSizeV=1.500000000000
|
||||||
|
PcbTextSizeV=1.500000000000
|
||||||
|
PcbTextSizeH=1.500000000000
|
||||||
|
PcbTextThickness=0.300000000000
|
||||||
|
ModuleTextSizeV=1.000000000000
|
||||||
|
ModuleTextSizeH=1.000000000000
|
||||||
|
ModuleTextSizeThickness=0.150000000000
|
||||||
|
SolderMaskClearance=0.000000000000
|
||||||
|
SolderMaskMinWidth=0.000000000000
|
||||||
|
DrawSegmentWidth=0.200000000000
|
||||||
|
BoardOutlineThickness=0.100000000000
|
||||||
|
ModuleOutlineThickness=0.150000000000
|
||||||
|
[cvpcb]
|
||||||
|
version=1
|
||||||
|
NetIExt=net
|
||||||
|
[general]
|
||||||
|
version=1
|
||||||
|
[eeschema]
|
||||||
|
version=1
|
||||||
|
LibDir=
|
||||||
|
[schematic_editor]
|
||||||
|
version=1
|
||||||
|
PageLayoutDescrFile=
|
||||||
|
PlotDirectoryName=
|
||||||
|
SubpartIdSeparator=0
|
||||||
|
SubpartFirstId=65
|
||||||
|
NetFmtName=
|
||||||
|
SpiceAjustPassiveValues=0
|
||||||
|
LabSize=50
|
||||||
|
ERC_TestSimilarLabels=1
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
Cherry MX Stabiliser:
|
||||||
|
https://grabcad.com/library/cherry-mx-stabilizer-mx-1
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
Record=TopLevelDocument|FileName=SDVX_Mini.SchDoc
|
|
||||||
Binary file not shown.
-31398
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
|||||||
Reference,Manufacturer,MPN,Quantity,Description
|
|
||||||
C1,YAGEO,CC0603KRX5R5BB105,1,0603 1uf
|
|
||||||
C2,YAGEO,CC0402MRX5R5BB106,1,0603 10uf
|
|
||||||
"C3,C4,C5,C6",YAGEO,CC0603KRX7R9BB103,4,0603 10nF
|
|
||||||
"R1,R2",YAGEO,RC0603JR-0722RL,2,0603 22r
|
|
||||||
R3,YAGEO,RC0603JR-0710KL,1,0603 10k
|
|
||||||
U1,Atmel,ATMEGA16U2-MU,1,MCU
|
|
||||||
J1,suntech,ZX62D-B-5P8,1,usb conn
|
|
||||||
XT1,Murata,CSTCE16M0V53-R0,1,resonator 16MHz
|
|
||||||
S8,C&K,KSC421J 70SH LFS,1,Reset switch
|
|
||||||
"L1,L2,L3,L4,L5,L6,L7,L8",Shenzhen Normand,SK9822,8,"LED, DO NOT USE APA101, MUST BE SK9822"
|
|
||||||
"E1, E2",Bourns,PEC16-4020F-N0024,2,Encoder
|
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
EESchema-DOCLIB Version 2.0
|
||||||
|
#
|
||||||
|
#End Doc Library
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
(sym_lib_table
|
||||||
|
(lib (name PocketVoltex-rescue)(type Legacy)(uri ${KIPRJMOD}/PocketVoltex-rescue.lib)(options "")(descr ""))
|
||||||
|
(lib (name switches)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/switches.lib)(options "")(descr ""))
|
||||||
|
(lib (name relays)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/relays.lib)(options "")(descr ""))
|
||||||
|
(lib (name motors)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/motors.lib)(options "")(descr ""))
|
||||||
|
(lib (name transistors)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/transistors.lib)(options "")(descr ""))
|
||||||
|
(lib (name conn)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/conn.lib)(options "")(descr ""))
|
||||||
|
(lib (name linear)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/linear.lib)(options "")(descr ""))
|
||||||
|
(lib (name regul)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/regul.lib)(options "")(descr ""))
|
||||||
|
(lib (name cmos4000)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/cmos4000.lib)(options "")(descr ""))
|
||||||
|
(lib (name adc-dac)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/adc-dac.lib)(options "")(descr ""))
|
||||||
|
(lib (name memory)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/memory.lib)(options "")(descr ""))
|
||||||
|
(lib (name xilinx)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/xilinx.lib)(options "")(descr ""))
|
||||||
|
(lib (name microcontrollers)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/microcontrollers.lib)(options "")(descr ""))
|
||||||
|
(lib (name dsp)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/dsp.lib)(options "")(descr ""))
|
||||||
|
(lib (name microchip)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/microchip.lib)(options "")(descr ""))
|
||||||
|
(lib (name analog_switches)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/analog_switches.lib)(options "")(descr ""))
|
||||||
|
(lib (name motorola)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/motorola.lib)(options "")(descr ""))
|
||||||
|
(lib (name texas)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/texas.lib)(options "")(descr ""))
|
||||||
|
(lib (name intel)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/intel.lib)(options "")(descr ""))
|
||||||
|
(lib (name digital-audio)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/digital-audio.lib)(options "")(descr ""))
|
||||||
|
(lib (name philips)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/philips.lib)(options "")(descr ""))
|
||||||
|
(lib (name display)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/display.lib)(options "")(descr ""))
|
||||||
|
(lib (name cypress)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/cypress.lib)(options "")(descr ""))
|
||||||
|
(lib (name siliconi)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/siliconi.lib)(options "")(descr ""))
|
||||||
|
(lib (name opto)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/opto.lib)(options "")(descr ""))
|
||||||
|
(lib (name atmel)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/atmel.lib)(options "")(descr ""))
|
||||||
|
(lib (name contrib)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/contrib.lib)(options "")(descr ""))
|
||||||
|
(lib (name valves)(type Legacy)(uri ${KICAD_SYMBOL_DIR}/valves.lib)(options "")(descr ""))
|
||||||
|
(lib (name PocketVoltex)(type Legacy)(uri ${KIPRJMOD}/PocketVoltex.lib)(options "")(descr ""))
|
||||||
|
)
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
RewriteEngine On
|
||||||
|
|
||||||
|
# If we receive a forwarded http request from a proxy...
|
||||||
|
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
|
||||||
|
|
||||||
|
# ...or just a plain old http request directly from the client
|
||||||
|
RewriteCond %{HTTP:X-Forwarded-Proto} =""
|
||||||
|
RewriteCond %{HTTPS} !=on
|
||||||
|
|
||||||
|
# Redirect to https version
|
||||||
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"4" :
|
"4" :
|
||||||
{
|
{
|
||||||
"version": 14,
|
"version": 15,
|
||||||
"board" : 4,
|
"board" : 4,
|
||||||
"md5": "a07ab17b2ac21c9e0f165eac30f40e99",
|
"md5": "fdeec31cc936124b7f21d2bb616c02db",
|
||||||
"changelog" : "Add support for e-AMUSEMENT CLOUD native input"
|
"changelog" : "Add START lights, defaults reset, fix LED strings"
|
||||||
},
|
},
|
||||||
"6" :
|
"6" :
|
||||||
{
|
{
|
||||||
"version": 14,
|
"version": 15,
|
||||||
"board" : 6,
|
"board" : 6,
|
||||||
"md5": "3fc03bf512c04e26a67825ba22a9eac2",
|
"md5": "4e12a16e0ca24441f68b1162a09d27be",
|
||||||
"changelog" : "Batch 2 shipping firmware"
|
"changelog" : "Add START lights, LED brightness, defaults reset, fix LED strings"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,6 @@
|
|||||||
<script type="text/javascript" src="js/md5.min.js"></script>
|
<script type="text/javascript" src="js/md5.min.js"></script>
|
||||||
<script type="text/javascript" src="js/jscolor.min.js"></script>
|
<script type="text/javascript" src="js/jscolor.min.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// because I am bad
|
|
||||||
if (location.protocol != 'https:' && location.hostname != "localhost" && location.hostname != "127.0.0.1") {
|
|
||||||
location.href = 'https:' + window.location.href.substring(window.location.protocol.length);
|
|
||||||
}
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
UsbWrapper_init();
|
UsbWrapper_init();
|
||||||
if(UsbWrapper.hasUSB) {
|
if(UsbWrapper.hasUSB) {
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ var CONFIG_IN_EPADDR = 2;
|
|||||||
var packetSize = 64;
|
var packetSize = 64;
|
||||||
|
|
||||||
var commands = {
|
var commands = {
|
||||||
GETCONFIG : 1,
|
GETCONFIG : 1,
|
||||||
SETCONFIG : 2,
|
SETCONFIG : 2,
|
||||||
VERSION : 3,
|
VERSION : 3,
|
||||||
|
DEFAULTCONFIG : 4,
|
||||||
RESET : 42
|
RESET : 42
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,10 +31,12 @@ var configDisplay = [
|
|||||||
{id: 'macroHold', name: 'Macro longpress'},
|
{id: 'macroHold', name: 'Macro longpress'},
|
||||||
{id: 'macroPin', name: 'Macro PIN'},
|
{id: 'macroPin', name: 'Macro PIN'},
|
||||||
{id: 'lightsOn', name: 'Enable LEDs', children: [
|
{id: 'lightsOn', name: 'Enable LEDs', children: [
|
||||||
|
{id: 'ledBrightness', name: 'LED Brightness', min: 1, max: 31},
|
||||||
{id: 'hidLights', name: 'HID Lights'},
|
{id: 'hidLights', name: 'HID Lights'},
|
||||||
{id: 'keyLights', name: 'Key lights', children: [
|
{id: 'keyLights', name: 'Key lights', children: [
|
||||||
{id: 'btColour', name: 'BT colour'},
|
{id: 'btColour', name: 'BT colour'},
|
||||||
{id: 'fxColour', name: 'FX colour'},
|
{id: 'fxColour', name: 'FX colour'},
|
||||||
|
{id: 'startColour', name: 'START colour'},
|
||||||
]},
|
]},
|
||||||
{id: 'knobLights', name: 'Knob lights', children: [
|
{id: 'knobLights', name: 'Knob lights', children: [
|
||||||
{id: 'knobL', name: 'VOL-L colour'},
|
{id: 'knobL', name: 'VOL-L colour'},
|
||||||
@@ -67,15 +70,10 @@ var settingOrder = [
|
|||||||
'macroHold',
|
'macroHold',
|
||||||
'macroLen',
|
'macroLen',
|
||||||
'macroPin',
|
'macroPin',
|
||||||
|
'ledBrightness',
|
||||||
|
'startColour',
|
||||||
];
|
];
|
||||||
|
|
||||||
var defaultConfig = {
|
|
||||||
switches : [],
|
|
||||||
ledsOn : true,
|
|
||||||
//macroClick : KP_PLUS,
|
|
||||||
macroPin : [0,0,0,0],
|
|
||||||
}
|
|
||||||
|
|
||||||
var visibleLog = function(html) {
|
var visibleLog = function(html) {
|
||||||
console.log(html);
|
console.log(html);
|
||||||
var log = document.getElementById('logview');
|
var log = document.getElementById('logview');
|
||||||
@@ -126,10 +124,12 @@ class ConfigValues {
|
|||||||
this.controlMode = new SettingRadio();
|
this.controlMode = new SettingRadio();
|
||||||
this.btColour = new SettingRGB(BRIGHTNESS_MAX);
|
this.btColour = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
this.fxColour = new SettingRGB(BRIGHTNESS_MAX);
|
this.fxColour = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
|
this.startColour = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
this.breatheColour = new SettingRGB(BRIGHTNESS_MAX);
|
this.breatheColour = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
this.knobL = new SettingRGB(BRIGHTNESS_MAX);
|
this.knobL = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
this.knobR = new SettingRGB(BRIGHTNESS_MAX);
|
this.knobR = new SettingRGB(BRIGHTNESS_MAX);
|
||||||
this.lightsOn = new SettingBool();
|
this.lightsOn = new SettingBool();
|
||||||
|
this.ledBrightness = new SettingSlider();
|
||||||
this.hidLights = new SettingBool();
|
this.hidLights = new SettingBool();
|
||||||
this.keyLights = new SettingBool();
|
this.keyLights = new SettingBool();
|
||||||
this.knobLights = new SettingBool();
|
this.knobLights = new SettingBool();
|
||||||
@@ -333,6 +333,17 @@ class Config {
|
|||||||
return device.transferOut(CONFIG_OUT_EPADDR, data);
|
return device.transferOut(CONFIG_OUT_EPADDR, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadDefaults() {
|
||||||
|
if(!device || !device.opened)
|
||||||
|
return Promise.reject("Device not opened");
|
||||||
|
if(!confirm('Loading defaults cannot be undone. Are you sure?'))
|
||||||
|
return Promise.resolve('Cancelled');
|
||||||
|
var data = new Uint8Array(packetSize);
|
||||||
|
data[0] = commands.DEFAULTCONFIG;
|
||||||
|
return device.transferOut(CONFIG_OUT_EPADDR, data)
|
||||||
|
.then(this.readConfig.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
if(!device || !device.opened)
|
if(!device || !device.opened)
|
||||||
return Promise.reject("Device not opened");
|
return Promise.reject("Device not opened");
|
||||||
@@ -368,6 +379,13 @@ class Config {
|
|||||||
enableUI() {
|
enableUI() {
|
||||||
//document.getElementById('configBox').classList.remove('hidden', 'disabled');
|
//document.getElementById('configBox').classList.remove('hidden', 'disabled');
|
||||||
document.getElementById('connect').classList.add('hidden');
|
document.getElementById('connect').classList.add('hidden');
|
||||||
|
|
||||||
|
var defaults = document.createElement('input');
|
||||||
|
defaults.type = 'button';
|
||||||
|
defaults.value = 'Load defaults';
|
||||||
|
defaults.onclick = this.loadDefaults.bind(this);
|
||||||
|
this.optionsDiv.appendChild(defaults);
|
||||||
|
|
||||||
this.populateSettings(this.optionsDiv, configDisplay);
|
this.populateSettings(this.optionsDiv, configDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,35 @@ class SettingBool extends Setting {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SettingSlider extends Setting {
|
||||||
|
read(buffer) {
|
||||||
|
this.slider.value = buffer.read(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
write(buffer) {
|
||||||
|
buffer.write(this.slider.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
createUI(setting) {
|
||||||
|
var container = document.createElement('div');
|
||||||
|
var slider = document.createElement('input');
|
||||||
|
slider.type = 'range';
|
||||||
|
slider.id = 'slider-' + setting.id;
|
||||||
|
slider.min = setting.min;
|
||||||
|
slider.max = setting.max;
|
||||||
|
slider.oninput = this.fireCallback.bind(this);
|
||||||
|
this.slider = slider;
|
||||||
|
|
||||||
|
var label = document.createElement('label');
|
||||||
|
label.htmlFor = slider.id;
|
||||||
|
label.textContent = setting.name;
|
||||||
|
|
||||||
|
container.appendChild(slider);
|
||||||
|
container.appendChild(label);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SettingRGB extends Setting {
|
class SettingRGB extends Setting {
|
||||||
constructor(maxBright) {
|
constructor(maxBright) {
|
||||||
super();
|
super();
|
||||||
@@ -362,6 +391,7 @@ var scancodes = [
|
|||||||
|
|
||||||
window.SettingPlaceholder = SettingPlaceholder;
|
window.SettingPlaceholder = SettingPlaceholder;
|
||||||
window.SettingBool = SettingBool;
|
window.SettingBool = SettingBool;
|
||||||
|
window.SettingSlider = SettingSlider;
|
||||||
window.SettingRGB = SettingRGB;
|
window.SettingRGB = SettingRGB;
|
||||||
window.SettingRadio = SettingRadio;
|
window.SettingRadio = SettingRadio;
|
||||||
window.SettingKeys = SettingKeys;
|
window.SettingKeys = SettingKeys;
|
||||||
|
|||||||
Reference in New Issue
Block a user