kad

package module
v0.0.0-...-102c242 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2022 License: AGPL-3.0 Imports: 17 Imported by: 0

README

KAD - Keyboard Automated Design

GoDoc

KAD is the SVG CAD engine which powers the mechanical keyboard CAD generation site builder.swillkb.com. If you are going to use this library, you should probably review the documentation site for the published builder in order to understand what all the different features are. The documentation site is available and kept up to date at builder-docs.swillkb.com.

KAD is a Golang library to aid in the design of mechanical keyboard plates and cases. The keyboard layout uses the standard format developed by the www.keyboard-layout-editor.com project. KAD is designed to produce SVG files which can be taken to a laser or water cutting fabrication shop to be cut. KAD supports a huge number of features, including but not limited it; 4 switch types, 4 stabilizer types, 3 case types, rounded corners, padding, mount holes, usb cutouts, etc...

Get Started

$ go get github.com/swill/kad
Installing DXF dependencies on MacOS

You need Homebrew installed.

$ brew install pstoedit
$ brew install caskformula/caskformula/inkscape --HEAD --branch-0.92

Example

Usage
package main

import (
	"encoding/json"
	"log"

	"github.com/swill/kad"
)

func main() {
	// you can define settings and the layout in JSON
	json_bytes := []byte(`{
		"switch-type":3,
		"stab-type":1,
		"layout":[
			["Num Lock","/","*","-"],
			[{"f":3},"7\nHome","8\n↑","9\nPgUp",{"h":2}," "],
			["4\n←","5","6\n→"],["1\nEnd","2\n↓","3\nPgDn",{"h":2},"Enter"],
			[{"w":2},"0\nIns",".\nDel"]
		],
		"case": {
			"case-type":"sandwich",
			"mount-holes-num":4,
			"mount-holes-size":3,
			"mount-holes-edge":6
		},
		"top-padding":9,
		"left-padding":9,
		"right-padding":9,
		"bottom-padding":9
	}`)

	// create a new KAD instance
	cad := kad.New()

	// populate the 'cad' instance with the JSON contents
	err := json.Unmarshal(json_bytes, cad)
	if err != nil {
		log.Fatalf("Failed to parse json data into the KAD file\nError: %s", err.Error())
	}

	// and you can define settings via the KAD instance
	cad.Hash = "usage_example"      // the name of the design
	cad.FileStore = kad.STORE_LOCAL // store the files locally
	cad.FileDirectory = "./"        // the path location where the files will be saved
	cad.FileServePath = "/"         // the url path for the 'results' (don't worry about this)

	// here are some more settings defined for this case
	cad.Case.UsbWidth = 12 // all dimension are in 'mm'
	cad.Fillet = 3         // 3mm radius on the rounded corners of the case

	// lets draw the SVG files now
	err = cad.Draw()
	if err != nil {
		log.Fatal("Failed to Draw the KAD file\nError: %s", err.Error())
	}
}

For more usage examples, check the ./test/ folder.

Output
Top Layer Switch Layer
Top Layer Switch Layer
Closed Layer Open Layer
Closed Layer Open Layer
Bottom Layer
Bottom Layer

License

KAD generates SVG CAD files based on a keyboard layout described in JSON.

Copyright (C) 2015-2016  Will Stevens (swill)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Documentation

Index

Constants

View Source
const (
	CASE_NONE        = ""
	CASE_POKER       = "poker"
	CASE_SANDWICH    = "sandwich"
	TOPLAYER         = "top"
	SWITCHLAYER      = "switch"
	BOTTOMLAYER      = "bottom"
	CLOSEDLAYER      = "closed"
	OPENLAYER        = "open"
	TOPLAYER_NAME    = "Top Layer"
	SWITCHLAYER_NAME = "Switch Layer"
	BOTTOMLAYER_NAME = "Bottom Layer"
	CLOSEDLAYER_NAME = "Closed Layer"
	OPENLAYER_NAME   = "Open Layer"
)
View Source
const (
	PRECISION   float64 = 1000
	OVERLAP             = 0.001
	STORE_SWIFT         = "swift"
	STORE_LOCAL         = "local"
)
View Source
const (
	SWITCHMX         = 1
	SWITCHMXALPS     = 2
	SWITCHMXH        = 3
	SWITCHALPS       = 4
	STABREMOVE       = 0
	STABCHERRYCOSTAR = 1
	STABCHERRY       = 2
	STABCOSTAR       = 3
	STABALPS         = 4
)
View Source
const (
	CLIP_DIST = 0.7 // In order to just clean duplicate points: .7*.7 = 0.49 < 0.5
)

Variables

This section is empty.

Functions

func GetAlpsStabOffset

func GetAlpsStabOffset(size float64) (float64, error)

func GetCherryStabOffset

func GetCherryStabOffset(size float64) (float64, error)

func SurfaceArea

func SurfaceArea(paths []Path) float64

Types

type Bounds

type Bounds struct {
	Xmin float64
	Xmax float64
	Ymin float64
	Ymax float64
}

type Case

type Case struct {
	Type             string  `json:"case-type"`
	HoleDiameter     float64 `json:"mount-holes-size"`
	Holes            int     `json:"mount-holes-num"`
	EdgeWidth        float64 `json:"mount-holes-edge"`
	LeftWidth        float64
	RightWidth       float64
	TopWidth         float64
	BottomWidth      float64
	Xholes           int
	Yholes           int
	RemovePokerSlots bool    `json:"poker-slots-remove"`
	UsbLocation      float64 `json:"usb-location"`
	UsbWidth         float64 `json:"usb-width"`
}

type CustomPolygon

type CustomPolygon struct {
	Diameter float64  `json:"diameter"`
	Height   float64  `json:"height"`
	Layers   []string `json:"layers"`
	Op       string   `json:"op"`
	Points   string   `json:"points"`
	Polygon  string   `json:"polygon"`
	Radius   float64  `json:"radius"`
	RelTo    string   `json:"rel_to"`
	RelAbs   string   `json:"-"`
	Width    float64  `json:"width"`
}

type Export

type Export struct {
	Ext string `json:"ext"`
	Url string `json:"url"`
}

type KAD

type KAD struct {
	Hash           string
	UOM            string
	U1             float64 `json:"key-unit"`
	DMZ            float64
	Width          float64
	Height         float64
	LayoutCenter   Point
	CaseCenter     Point
	Fillet         float64 `json:"fillet"`
	Kerf           float64 `json:"kerf"`
	Xoff           float64
	TopPad         float64         `json:"top-padding"`
	LeftPad        float64         `json:"left-padding"`
	RightPad       float64         `json:"right-padding"`
	BottomPad      float64         `json:"bottom-padding"`
	Xgrow          float64         `json:"grow_x"`
	Ygrow          float64         `json:"grow_y"`
	SwitchType     int             `json:"switch-type"`
	StabType       int             `json:"stab-type"`
	Case           Case            `json:"case"`
	CustomPolygons []CustomPolygon `json:"custom"`
	RawLayout      []interface{}   `json:"layout"`
	Layout         [][]Key         `json:"-"` // ignore in 'unmarshal'
	Svgs           map[string]SvgWrapper
	Layers         map[string]*Layer
	SvgStyle       string
	LineColor      string  `json:"line-color"`
	LineWeight     float64 `json:"line-weight"`
	Result         Result
	Bounds         Bounds
	Swift          *swift.Connection
	SwiftBucket    string
	FileStore      string
	FileDirectory  string
	FileServePath  string
}

func New

func New() *KAD

func (*KAD) Draw

func (k *KAD) Draw() error

Draw the SVGs needed for this layout.

func (*KAD) DrawHoles

func (k *KAD) DrawHoles()

Draw the holes for the KAD based on the type of case selected.

func (*KAD) DrawLayout

func (k *KAD) DrawLayout()

Draw the switch and stabilizer openings for this KAD layout.

func (*KAD) DrawOutputFiles

func (k *KAD) DrawOutputFiles() error

Initialize the SVG files and their File writers.

func (*KAD) FinalizeLayerDimensions

func (k *KAD) FinalizeLayerDimensions()

Finalize the polygons before they go for file processing

func (*KAD) FinalizePolygons

func (k *KAD) FinalizePolygons()

Finalize the polygons before they go for file processing

func (*KAD) GetPokerHoles

func (k *KAD) GetPokerHoles() Path

Get the Path for a Poker case hole placement.

func (*KAD) GetSandwichHoles

func (k *KAD) GetSandwichHoles() Path

Get the Path for a Sandwich case hole placement.

func (*KAD) InitCaseEdges

func (k *KAD) InitCaseEdges()

func (*KAD) InitCaseLayers

func (k *KAD) InitCaseLayers()

func (*KAD) ParseLayout

func (k *KAD) ParseLayout() error

Parse the layout and populate all the important information in the KAD object.

func (*KAD) ParsePoints

func (k *KAD) ParsePoints(points_str, rel_to_str string, rel_center bool) []Path

Parse the points passed in for custom polygons

func (*KAD) StoreLocalFiles

func (k *KAD) StoreLocalFiles()

Store and serve the generated SVG files locally.

func (*KAD) StoreSwiftFiles

func (k *KAD) StoreSwiftFiles()

Store the generated SVG files in an object store.

func (*KAD) UpdateBounds

func (k *KAD) UpdateBounds(path Path, init bool)

determine the size of the canvas by checking the bounds of the keys.

func (*KAD) UpdateLayerDimensions

func (k *KAD) UpdateLayerDimensions()

update the dimensions of the kad based on what has been added

type Key

type Key struct {
	Width         float64 `json:"w"`  // width in key units
	Height        float64 `json:"h"`  // height in key units
	AltWidth      float64 `json:"w2"` // alternate width in key units for strangely shaped keys
	AltHeight     float64 `json:"h2"` // alternate height in key units for strangely shaped keys
	Xrel          float64 `json:"x"`  // x relative position in key units
	Yrel          float64 `json:"y"`  // y relative position in key units
	Xabs          float64 `json:"rx"` // x absolute position in key units
	Yabs          float64 `json:"ry"` // y absolute position in key units
	Xalt          float64 `json:"x2"` // x relative position in key units for strangely shaped keys
	Yalt          float64 `json:"y2"` // y relative position in key units for strangely shaped keys
	Type          int     `json:"_t"` // switch type as int
	Stab          int     `json:"_s"` // stab type as int
	Kerf          float64 `json:"_k"` // kerf for this key
	Custom        string  `json:"_c"` // center point as custom index
	Stacked       bool
	Bounds        Path
	Rotate        float64 `json:"_r"`  // rotate switch opening in degrees
	RotateStab    float64 `json:"_rs"` // rotate stabilizer opening in degrees
	RotateCluster float64 `json:"r"`   // rotate the following cluster of keys (in degrees)
}

func (*Key) Draw

func (key *Key) Draw(k *KAD, c Point, ctx Key, init bool)

Draw an individual switch/stabilizer opening.

func (*Key) DrawAlpsStab

func (key *Key) DrawAlpsStab(k *KAD, c Point, ctx Key, vertical, flip_stab bool)

draw the alps stabilizer

func (*Key) DrawCherryCostarStab

func (key *Key) DrawCherryCostarStab(k *KAD, c Point, ctx Key, vertical, flip_stab bool)

path for cherry + costar stabilizer

func (*Key) DrawCherryStab

func (key *Key) DrawCherryStab(k *KAD, c Point, ctx Key, vertical, flip_stab bool)

path for cherry stabilizer

func (*Key) DrawCostarStab

func (key *Key) DrawCostarStab(k *KAD, c Point, ctx Key, vertical, flip_stab bool)

draw the costar stabilizer

type Layer

type Layer struct {
	CutPolys  []Path
	KeepPolys []Path
	Width     float64
	Height    float64
}

type Path

type Path []Point

func CirclePolygon

func CirclePolygon(cx, cy, r float64, s int) Path

create a circle as a polygon with each quarter made up of 's' segments.

func FromClipperPath

func FromClipperPath(cp clipper.Path) Path

func RoundRectanglePolygon

func RoundRectanglePolygon(cx, cy, w, h, r float64, s int) Path

create a rectangle as a polygon with optional rounded corners. set 'r' and 's' to zero to have a non-rounded corner.

func SuperellipsePolygon

func SuperellipsePolygon(cx, cy, r float64, s int) Path

create a superellipse as a polygon with each quarter made up of 's' segments.

func (Path) Copy

func (ps Path) Copy() Path

Copies the Path

func (Path) Rel

func (ps Path) Rel(r Point)

Sets the path to the absolute positioning of the Path relative to an origin Point 'r'.

func (Path) RotatePath

func (ps Path) RotatePath(r float64, a Point)

Rotates each point in a set and rotates them 'r' degrees around 'a'.

func (Path) SplitOnAxis

func (ps Path) SplitOnAxis() ([]float64, []float64)

SplitOnAxis path to be drawn by SVGo

func (Path) ToClipperPath

func (ps Path) ToClipperPath() clipper.Path

type Point

type Point struct {
	X, Y float64
}

type Result

type Result struct {
	HasLayers bool                      `json:"has_layers"`
	Plates    []string                  `json:"plates"`
	Formats   []string                  `json:"formats"`
	Details   map[string]*ResultDetails `json:"details"`
}

type ResultDetails

type ResultDetails struct {
	Name    string   `json:"name"`
	Width   float64  `json:"width"`
	Height  float64  `json:"height"`
	Area    float64  `json:"area"`
	Exports []Export `json:"exports"`
}

type SvgWrapper

type SvgWrapper struct {
	File *os.File
	Svg  *svg.SVG
}

type UploadCtl

type UploadCtl struct {
	Export    *Export
	FailedExt string
	DelFile   string
	Error     error
	Attempt   int
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL