Outlines progress
This commit is contained in:
parent
fad615045a
commit
8da97611e4
3 changed files with 106 additions and 19 deletions
26
README.md
26
README.md
|
@ -369,21 +369,15 @@ Note that this outline is still parametric, so that we can specify different wid
|
||||||
|
|
||||||
Now we can configure what we want to "export" as outlines from this phase, given by the combination/subtraction of the following primitives:
|
Now we can configure what we want to "export" as outlines from this phase, given by the combination/subtraction of the following primitives:
|
||||||
|
|
||||||
- `all` : the combined outline that we've just created. Its parameters include:
|
- `keys` : the combined outline that we've just created. Its parameters include:
|
||||||
|
- `side: left | right | both | glue | raw` : the part we want to use
|
||||||
|
- `left` and `right` are just the appropriate side of the laid out keys, without the glue.
|
||||||
|
- `both` means both sides, held together by the glue
|
||||||
|
- `glue` means an "ideal" version of the glue (meaning that instead of the `outline.glue` we defined above, we get `both` - `left` - `right`, so the _exact_ middle piece we would have needed to glue everything together
|
||||||
|
- `raw` is the raw glue shape we defined above under `outline.glue`
|
||||||
- `size: num | [num_x, num_y]` : the width/height of the rectangles to lay onto the points
|
- `size: num | [num_x, num_y]` : the width/height of the rectangles to lay onto the points
|
||||||
- `corner: num # default = 0)` : corner radius of the rectangle
|
- `corner: num # default = 0)` : corner radius of the rectangles
|
||||||
- `bevel: num # default = 0)` : corner bevel of the rectangle, can be combined with rounding
|
- `bevel: num # default = 0)` : corner bevel of the rectangles, can be combined with rounding
|
||||||
- `keys` : only one side of the laid out keys, without the glue. Parameters:
|
|
||||||
- everything we could specify for `all`
|
|
||||||
- `side: left | right` : the side we want
|
|
||||||
- `glue` : just the glue, but the "ideal" version of it. This means that instead of the `glue` we defined above, we get `all` - `left` - `right`, so the _exact_ middle piece we would have needed to glue everything together. Parameters:
|
|
||||||
- everything we could specify for `all` (since those are needed for the calculation)
|
|
||||||
- `raw: boolean # default = false)` : optionally, we could choose to get the "raw" (i.e., the non-idealized) glue as well
|
|
||||||
- `ref` : a previously defined outline, see below.
|
|
||||||
- `name: outline_name` : the name of the referenced outline
|
|
||||||
|
|
||||||
Additionally, we can use primitive shapes:
|
|
||||||
|
|
||||||
- `rectangle` : an independent rectangle primitive. Parameters:
|
- `rectangle` : an independent rectangle primitive. Parameters:
|
||||||
- `ref: <point reference>` : what position and rotation to consider as the origin
|
- `ref: <point reference>` : what position and rotation to consider as the origin
|
||||||
- `rotate: num` : extra rotation
|
- `rotate: num` : extra rotation
|
||||||
|
@ -395,6 +389,8 @@ Additionally, we can use primitive shapes:
|
||||||
- `polygon` : an independent polygon primitive. Parameters:
|
- `polygon` : an independent polygon primitive. Parameters:
|
||||||
- `ref`, `rotate`, and `shift` are the same as above
|
- `ref`, `rotate`, and `shift` are the same as above
|
||||||
- `points: [[x, y], ...]` : the points of the polygon
|
- `points: [[x, y], ...]` : the points of the polygon
|
||||||
|
- `ref` : a previously defined outline, see below.
|
||||||
|
- `name: outline_name` : the name of the referenced outline
|
||||||
|
|
||||||
Using these, we define exports as follows:
|
Using these, we define exports as follows:
|
||||||
|
|
||||||
|
@ -408,7 +404,7 @@ exports:
|
||||||
```
|
```
|
||||||
|
|
||||||
Operations are performed in order, and the resulting shape is exported as an output.
|
Operations are performed in order, and the resulting shape is exported as an output.
|
||||||
Additionally, it is going to be available to further export declarations (using the `ref` type) under the name specified (`my_name`, in this case).
|
Additionally, it is going to be available for further export declarations to use (through the `ref` type) under the name specified (`my_name`, in this case).
|
||||||
If we only want to use it as a building block for further exports, we can start the name with an underscore (e.g., `_my_name`) to prevent it from being actually exported.
|
If we only want to use it as a building block for further exports, we can start the name with an underscore (e.g., `_my_name`) to prevent it from being actually exported.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@ const detect_unexpected = exports.detect_unexpected = (obj, name, expected) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.in = (raw, name, arr) => {
|
||||||
|
assert(arr.includes(raw), `Field "${name}" should be one of [${arr.join(', ')}]!`)
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
const numarr = exports.numarr = (raw, name, length) => {
|
const numarr = exports.numarr = (raw, name, length) => {
|
||||||
assert(type(raw) == 'array' && raw.length == length, `Field "${name}" should be an array of length ${length}!`)
|
assert(type(raw) == 'array' && raw.length == length, `Field "${name}" should be an array of length ${length}!`)
|
||||||
raw = raw.map(val => val || 0)
|
raw = raw.map(val => val || 0)
|
||||||
|
|
|
@ -158,17 +158,103 @@ const parse_glue = exports._parse_glue = (config = {}, points = {}) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.waypoints = a.sane(config.waypoints || [], 'outline.glue.waypoints', 'array')
|
||||||
|
let wi = 0
|
||||||
|
config.waypoints = config.waypoints.map(w => {
|
||||||
|
const name = `outline.glue.waypoints[${++wi}]`
|
||||||
|
a.detect_unexpected(w, name, ['percent', 'width'])
|
||||||
|
w.percent = a.sane(w.percent, name + '.percent', 'number')
|
||||||
|
w.width = a.wh(w.width, name + '.width')
|
||||||
|
return w
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: handle glue.extra (or revoke it from the docs)
|
||||||
|
|
||||||
|
return (export_name, params) => {
|
||||||
|
|
||||||
|
a.detect_unexpected(params, `outline.exports.${export_name}`, ['side', 'size', 'corner', 'bevel'])
|
||||||
|
params.side = a.in(params.side, `outline.exports.${export_name}.side`, ['left', 'right', 'both', 'glue', 'raw'])
|
||||||
|
params.size = a.wh(params.size, `outline.exports.${export_name}.size`)
|
||||||
|
params.corner = a.sane(params.corner || 0, `outline.exports.${export_name}.corner`, 'number')
|
||||||
|
params.bevel = a.sane(params.bevel || 0, `outline.exports.${export_name}.bevel`, 'number')
|
||||||
|
|
||||||
|
let glue
|
||||||
|
if (['both', 'glue', 'raw'].includes(params.side)) {
|
||||||
|
|
||||||
|
const get_line = (anchor) => {
|
||||||
|
if (a.type(anchor) == 'number') {
|
||||||
|
return u.line([anchor, -1000], [anchor, 1000])
|
||||||
|
}
|
||||||
|
|
||||||
|
let from = anchor.clone()
|
||||||
|
let to = anchor.add([anchor.meta.mirrored ? -1 : 1, 0])
|
||||||
|
to = to.rotate(anchor.r, anchor.p).p
|
||||||
|
|
||||||
config.bottom = a.sane(config.bottom, 'outline.glue.bottom', 'object')
|
return u.line(from, to)
|
||||||
config.bottom.left = a.anchor(config.bottom.left, 'outline.glue.bottom.left', points)
|
}
|
||||||
if (a.type(config.bottom.right) != 'number') {
|
|
||||||
config.bottom.right = a.anchor(config.bottom.right, 'outline.glue.bottom.right', points)
|
const tll = get_line(config.top.left)
|
||||||
|
const trl = get_line(config.top.right)
|
||||||
|
const tip = m.path.converge(tll, trl)
|
||||||
|
const tlp = u.eq(tll.origin, tip) ? tll.end : tll.origin
|
||||||
|
const trp = u.eq(trl.origin, tip) ? trl.end : trl.origin
|
||||||
|
|
||||||
|
const bll = get_line(config.bottom.left)
|
||||||
|
const brl = get_line(config.bottom.right)
|
||||||
|
const bip = m.path.converge(bll, brl)
|
||||||
|
const blp = u.eq(bll.origin, bip) ? bll.end : bll.origin
|
||||||
|
const brp = u.eq(brl.origin, bip) ? brl.end : brl.origin
|
||||||
|
|
||||||
|
const left_waypoints = []
|
||||||
|
const right_waypoints = []
|
||||||
|
|
||||||
|
for (const w of config.waypoints) {
|
||||||
|
const percent = w.percent / 100
|
||||||
|
const center_x = tip[0] + percent * (bip[0] - tip[0])
|
||||||
|
const center_y = tip[1] + percent * (bip[1] - tip[1])
|
||||||
|
const left_x = center_x - (w.left || w.width / 2)
|
||||||
|
const right_x = center_x + (w.right || w.width / 2)
|
||||||
|
left_waypoints.push([left_x, center_y])
|
||||||
|
right_waypoints.unshift([right_x, center_y])
|
||||||
|
}
|
||||||
|
|
||||||
|
let waypoints
|
||||||
|
const is_split = a.type(config.top.right) == 'number'
|
||||||
|
if (is_split) {
|
||||||
|
waypoints = [tip, tlp]
|
||||||
|
.concat(left_waypoints)
|
||||||
|
.concat([blp, bip])
|
||||||
|
} else {
|
||||||
|
waypoints = [trp, tip, tlp]
|
||||||
|
.concat(left_waypoints)
|
||||||
|
.concat([blp, bip, brp])
|
||||||
|
.concat(right_waypoints)
|
||||||
|
}
|
||||||
|
|
||||||
|
glue = u.poly(waypoints)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const parse_exports = exports._parse_exports = (config = {}, points = {}) => {
|
||||||
|
|
||||||
|
config = a.sane(config, 'outline.exports', 'object')
|
||||||
|
for (const [key, val] of Object.entries(config)) {
|
||||||
|
params.op = a.in(params.op || 'add', `outline.exports.${key}.op`, ['add', 'sub', 'diff'])
|
||||||
|
params.type = a.in(params.type, `outline.exports.${key}.type`, ['add', 'sub', 'diff'])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.parse = (config = {}, points = {}) => {
|
exports.parse = (config = {}, points = {}) => {
|
||||||
a.detect_unexpected(config, 'outline', ['glue', 'exports'])
|
a.detect_unexpected(config, 'outline', ['glue', 'exports'])
|
||||||
const glue = parse_glue(config.glue, points)
|
const glue = parse_glue(config.glue, points)
|
||||||
|
|
||||||
|
config = a.sane(config, 'outline.exports', 'object')
|
||||||
|
for (const [key, val] of Object.entries(config)) {
|
||||||
|
params.op = a.in(params.op || 'add', `outline.exports.${key}.op`, ['add', 'sub', 'diff'])
|
||||||
|
params.type = a.in(params.type, `outline.exports.${key}.type`, ['add', 'sub', 'diff'])
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue