1
0

Outlines rewrite actually done

This commit is contained in:
Bán Dénes 2022-01-16 20:36:19 +01:00
parent 4844a044df
commit d6f83232a8
23 changed files with 288 additions and 1034 deletions

View File

@ -49,6 +49,7 @@
### Patch
- Check unexpected keys at top level, too
- Better error handling for the fillet option?
- Implement `glue.extra`
- Integration and end2end tests to get coverage to 100%

View File

@ -1,9 +1,11 @@
const u = require('./utils')
const a = require('./assert')
const anchor_lib = require('./anchor')
const Point = require('./point')
const anchor = anchor_lib.parse
const _true = () => true
const _false = () => false
const _and = arr => p => arr.map(e => e(p)).reduce((a, b) => a && b)
const _or = arr => p => arr.map(e => e(p)).reduce((a, b) => a || b)
@ -78,20 +80,19 @@ const simple = (exp, name, units) => {
const complex = (config, name, units, aggregator=_or) => {
// default is all points
if (config === undefined) {
return _true
}
// otherwise we branch by type
const type = a.type(config)()
// we branch by type
const type = a.type(config)(units)
switch(type) {
// boolean --> either all or nothing
case 'boolean':
return config ? _true : _false
// base case is a string, meaning a simple/single filter
// string --> base case, meaning a simple/single filter
case 'string':
return simple(config, name, units)
// arrays are aggregated with alternating and/or conditions
// array --> aggregated simple filters with alternating and/or conditions
case 'array':
const alternate = aggregator == _and ? _or : _and
return aggregator(config.map(elem => complex(elem, name, units, alternate)))
@ -101,12 +102,22 @@ const complex = (config, name, units, aggregator=_or) => {
}
}
const contains_object = (val) => {
if (a.type(val)() == 'object') return true
if (a.type(val)() == 'array') return val.some(el => contains_object(el))
return false
}
exports.parse = (config, name, points={}, units={}, include_mirrors=false) => {
let result = []
// if a filter decl is an object, it is an anchor
if (a.type(config)() == 'object') {
// if a filter decl is undefined, it's just the default point at [0, 0]
if (config === undefined) {
result.push(new Point())
// if a filter decl is an object, or an array that contains an object at any depth, it is an anchor
} else if (contains_object(config)) {
result.push(anchor(config, name, points)(units))
if (include_mirrors) {
// this is strict: if the ref of the anchor doesn't have a mirror pair, it will error out

View File

@ -32,16 +32,16 @@ const rectangle = (config, name, points, outlines, units) => {
// prepare params
a.unexpected(config, `${name}`, ['size', 'corner', 'bevel'])
const size = a.wh(params.size, `${export_name}.size`)(units)
const size = a.wh(config.size, `${name}.size`)(units)
const rec_units = prep.extend({
sx: size[0],
sy: size[1]
}, units)
const corner = a.sane(params.corner || 0, `${export_name}.corner`, 'number')(rec_units)
const bevel = a.sane(params.bevel || 0, `${export_name}.bevel`, 'number')(rec_units)
const corner = a.sane(config.corner || 0, `${name}.corner`, 'number')(rec_units)
const bevel = a.sane(config.bevel || 0, `${name}.bevel`, 'number')(rec_units)
// return shape function
return (point, bound) => {
// return shape function and its units
return [(point, bound) => {
const error = (dim, val) => `Rectangle for "${name}" isn't ${dim} enough for its corner and bevel (${val} - 2 * ${corner} - 2 * ${bevel} <= 0)!`
const [w, h] = size
@ -65,7 +65,7 @@ const rectangle = (config, name, points, outlines, units) => {
])
}
if (corner > 0) rect = m.model.outline(rect, corner, 0)
rect = m.model.moveRelative(res, [-cw/2, -ch/2])
rect = m.model.moveRelative(rect, [-cw/2, -ch/2])
if (bound) {
const bbox = {high: [w/2, h/2], low: [-w/2, -h/2]}
rect = binding(rect, bbox, point, rec_units)
@ -73,7 +73,7 @@ const rectangle = (config, name, points, outlines, units) => {
rect = point.position(rect)
return rect
}
}, rec_units]
}
const circle = (config, name, points, outlines, units) => {
@ -85,8 +85,8 @@ const circle = (config, name, points, outlines, units) => {
r: radius
}, units)
// return shape function
return (point, bound) => {
// return shape function and its units
return [(point, bound) => {
let circle = u.circle([0, 0], radius)
if (bound) {
const bbox = {high: [radius, radius], low: [-radius, -radius]}
@ -94,7 +94,7 @@ const circle = (config, name, points, outlines, units) => {
}
circle = point.position(circle)
return circle
}
}, circ_units]
}
const polygon = (config, name, points, outlines, units) => {
@ -103,10 +103,12 @@ const polygon = (config, name, points, outlines, units) => {
a.unexpected(config, `${name}`, ['points'])
const poly_points = a.sane(config.points, `${name}.points`, 'array')()
// return shape function
return (point, bound) => {
// return shape function and its units
return [(point, bound) => {
const parsed_points = []
let last_anchor = new Point()
// the point starts at [0, 0] as it will be positioned later
// but we keep the metadata for potential mirroring purposes
let last_anchor = new Point(0, 0, 0, point.meta)
let poly_index = -1
for (const poly_point of poly_points) {
const poly_name = `${name}.points[${++poly_index}]`
@ -120,7 +122,7 @@ const polygon = (config, name, points, outlines, units) => {
}
poly = point.position(poly)
return poly
}
}, units]
}
const outline = (config, name, points, outlines, units) => {
@ -131,10 +133,10 @@ const outline = (config, name, points, outlines, units) => {
const fillet = a.sane(config.fillet || 0, `${name}.fillet`, 'number')(units)
const expand = a.sane(config.expand || 0, `${name}.expand`, 'number')(units)
const joints = a.in(a.sane(config.joints || 0, `${name}.joints`, 'number')(units), `${name}.joints`, [0, 1, 2])
const origin = anchor(config.origin, `${name}.origin`, points)(units)
const origin = anchor(config.origin || {}, `${name}.origin`, points)(units)
// return shape function
return (point, bound) => {
// return shape function and its units
return [(point, bound) => {
let o = u.deepcopy(outlines[config.name])
o = origin.unposition(o)
@ -155,7 +157,7 @@ const outline = (config, name, points, outlines, units) => {
o = point.position(o)
return o
}
}, units]
}
const whats = {
@ -182,11 +184,11 @@ exports.parse = (config = {}, points = {}, units = {}) => {
if (a.type(parts)() == 'array') {
parts = {...parts}
}
parts = a.sane(parts, `outlines.${key}`, 'object')()
parts = a.sane(parts, `outlines.${outline_name}`, 'object')()
for (let [part_name, part] of Object.entries(parts)) {
const name = `outlines.${key}.${part_name}`
const name = `outlines.${outline_name}.${part_name}`
// string part-shortcuts are expanded first
if (a.type(part)() == 'string') {
@ -200,8 +202,9 @@ exports.parse = (config = {}, points = {}, units = {}) => {
const bound = part.bound === undefined ? bound_by_default.includes(what) : !!part.bound
const mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean')()
// `where` is delayed until we have all, potentially what-dependent units
// default where is the single default anchor (at [0,0])
const where = units => filter(part.where || {}, `${name}.where`, points, units, mirror)
// default where is [0, 0], as per filter parsing
const original_where = part.where // need to save, so the delete's don't get rid of it below
const where = units => filter(original_where, `${name}.where`, points, units, mirror)
// these keys are then removed, so ops can check their own unexpected keys without interference
delete part.operation

View File

@ -1,16 +1,10 @@
points:
zones:
arst:
columns:
c1:
rows:
r1:
points.zones.matrix: {}
outlines:
exports:
square:
- type: rectangle
size: [5, 5]
square:
- what: rectangle
where: true
size: [5, 5]
cases:
cube:
- name: square
extrude: 5
cube:
- name: square
extrude: 5

View File

@ -7,49 +7,39 @@ models:
- 0
- 0
b:
models:
a:
models: {}
paths:
ShapeLine1:
type: line
origin:
- 0
- 0
b:
paths:
ShapeLine1:
type: line
origin:
- -9
- -9
end:
- 9
- -9
ShapeLine2:
type: line
origin:
- 9
- -9
end:
- 9
- 9
ShapeLine3:
type: line
origin:
- 9
- 9
end:
- -9
- 9
ShapeLine4:
type: line
origin:
- -9
- 9
end:
- -9
- -9
- -9
- -9
end:
- 9
- -9
ShapeLine2:
type: line
origin:
- 0
- 0
- 9
- -9
end:
- 9
- 9
ShapeLine3:
type: line
origin:
- 9
- 9
end:
- -9
- 9
ShapeLine4:
type: line
origin:
- -9
- 9
end:
- -9
- -9
origin:
- 0
- 0

View File

@ -7,49 +7,39 @@ models:
- 0
- 0
b:
models:
a:
models: {}
paths:
ShapeLine1:
type: line
origin:
- 0
- 0
b:
paths:
ShapeLine1:
type: line
origin:
- -9
- -9
end:
- 9
- -9
ShapeLine2:
type: line
origin:
- 9
- -9
end:
- 9
- 9
ShapeLine3:
type: line
origin:
- 9
- 9
end:
- -9
- 9
ShapeLine4:
type: line
origin:
- -9
- 9
end:
- -9
- -9
- -9
- -9
end:
- 9
- -9
ShapeLine2:
type: line
origin:
- 0
- 0
- 9
- -9
end:
- 9
- 9
ShapeLine3:
type: line
origin:
- 9
- 9
end:
- -9
- 9
ShapeLine4:
type: line
origin:
- -9
- 9
end:
- -9
- -9
origin:
- 0
- 0

View File

@ -1,7 +1,7 @@
models:
export:
models:
matrix_col_row:
matrix:
paths:
top:
type: line

View File

@ -1,4 +1,4 @@
matrix_col_row:
matrix:
x: 0
'y': 0
r: 0
@ -19,10 +19,10 @@ matrix_col_row:
padding: 19
skip: false
asym: both
name: matrix_col_row
name: matrix
col:
rows: {}
key: {}
name: col
row: row
colrow: col_row
name: default
row: default
colrow: default_default

View File

@ -2,23 +2,18 @@ units:
a: 28 + u
points:
zones:
matrix:
columns:
col: {}
rows:
row: {}
matrix: null
outlines:
exports:
export:
-
type: keys
side: left
size: 18
_export:
-
type: keys
side: left
size: 18
export:
-
what: rectangle
where: true
size: 18
_export:
-
what: rectangle
where: true
size: 18
cases:
export:
-

View File

@ -1,23 +1,21 @@
units:
a: 28 + u
points.zones.matrix:
columns.col: {}
rows.row: {}
outlines.exports:
outlines:
export:
- type: 'keys'
side: 'left'
- what: rectangle
where: true
size: 18
_export:
- type: 'keys'
side: 'left'
- what: rectangle
where: true
size: 18
cases:
export:
- name: 'export'
- name: export
extrude: 1
_export:
- name: 'export'
- name: export
extrude: 1
pcbs:
export: {}

View File

@ -1,23 +1,21 @@
units:
a: 28 + u
points.zones.matrix:
columns.col: {}
rows.row: {}
outlines.exports:
outlines:
export:
- type: 'keys'
side: 'left'
- what: rectangle
where: true
size: 18
_export:
- type: 'keys'
side: 'left'
- what: rectangle
where: true
size: 18
cases:
export:
- name: 'export'
- name: export
extrude: 1
_export:
- name: 'export'
- name: export
extrude: 1
pcbs:
export: {}

View File

@ -1,9 +1,9 @@
points.zones.matrix:
columns.col: {}
outlines.exports:
outlines:
export:
- type: 'keys'
side: 'left'
- what: rectangle
where: true
size: 18
pcbs:
export: {}

View File

@ -10,46 +10,45 @@ points:
ref: matrix_only_top
distance: 30
outlines:
exports:
test:
keys:
type: keys
side: both
size: 14
bound: false
rb:
type: rectangle
anchor:
- ref: mirror_matrix_only_bottom
# we do NOT specify `affect: xyr` here
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
rt:
type: rectangle
anchor:
- ref: mirror_matrix_only_top
affect: xyr
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
lb:
type: rectangle
anchor:
- ref: matrix_only_bottom
# again, no `affect: xyr`
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
lt:
type: rectangle
anchor:
- ref: matrix_only_top
affect: xyr
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
test:
keys:
what: rectangle
where: true
size: 14
bound: false
rb:
what: rectangle
where:
- ref: mirror_matrix_only_bottom
# we do NOT specify `affect: xyr` here
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
rt:
what: rectangle
where:
- ref: mirror_matrix_only_top
affect: xyr
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
lb:
what: rectangle
where:
- ref: matrix_only_bottom
# again, no `affect: xyr`
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack
lt:
what: rectangle
where:
- ref: matrix_only_top
affect: xyr
- shift: [-3,-3]
orient: 30
size: [6,6]
operation: stack

View File

@ -10,15 +10,14 @@ points:
key:
bind: [0, 0, 0, 0]
outlines:
exports:
outline:
main:
type: keys
side: left
size: 20
min:
type: keys
side: left
bound: false
size: 14
operation: subtract
outline:
main:
what: rectangle
where: true
size: 20
min:
what: rectangle
where: true
bound: false
size: 14
operation: subtract

View File

@ -3,24 +3,23 @@ points:
matrix: {}
mirror: 20
outlines:
exports:
outline:
main:
type: keys
side: both
size: 20
bound: false
middle_circle:
type: circle
anchor:
ref:
- matrix
- mirror_matrix
radius: 15
outside_circles:
type: circle
anchor:
ref: matrix
shift: [-10, 10]
radius: 5
mirror: true
outline:
main:
what: rectangle
where: true
size: 20
bound: false
middle_circle:
what: circle
where:
ref:
- matrix
- mirror_matrix
radius: 15
outside_circles:
what: circle
where:
ref: matrix
shift: [-10, 10]
radius: 5
mirror: true

View File

@ -11,12 +11,11 @@ points:
bottom:
top:
outlines:
exports:
base:
- type: keys
side: left
size: cy
fillet:
- type: outline
name: base
fillet: 2
base:
- what: rectangle
where: true
size: cy
fillet:
- what: outline
name: base
fillet: 2

View File

@ -1,50 +0,0 @@
points:
zones:
matrix:
columns:
left.key.bind: [,10,,]
right.key.bind: [,,,10]
rows:
bottom.key.bind: [10,,,]
top.key.bind: [,,10,]
key:
bind: [0, 0, 0, 0]
rotate: -20
mirror:
ref: matrix_right_top
distance: 30
outlines:
glue:
default:
top:
left:
ref: matrix_right_top
shift: [,sy / 2]
right:
ref: mirror_matrix_right_top
shift: [,sy / 2]
bottom:
left:
ref: matrix_right_bottom
shift: [,sy / -2]
right:
ref: mirror_matrix_right_bottom
shift: [,sy / -2]
exports:
outline:
main:
type: keys
side: both
size: 20
min:
type: keys
side: both
bound: false
size: 14
operation: subtract
optout:
main:
type: keys
side: both
size: 20
glue: false

View File

@ -1,146 +0,0 @@
0
SECTION
2
HEADER
9
$INSUNITS
70
4
0
ENDSEC
0
SECTION
2
TABLES
0
TABLE
2
LTYPE
0
LTYPE
72
65
70
64
2
CONTINUOUS
3
______
73
0
40
0
0
ENDTAB
0
TABLE
2
LAYER
0
ENDTAB
0
ENDSEC
0
SECTION
2
ENTITIES
0
LINE
8
0
10
-12.8171276
20
-5.9767248
11
23.8308846
21
-19.3155103
0
LINE
8
0
10
-12.8171276
20
-5.9767248
11
0.5216579
21
30.6712874
0
LINE
8
0
10
0.5216579
20
30.6712874
11
37.1696701
21
17.3325019
0
LINE
8
0
10
23.8308846
20
-19.3155103
11
37.1696701
21
17.3325019
0
LINE
8
0
10
54.8742004
20
-19.3155103
11
91.5222126
21
-5.9767248
0
LINE
8
0
10
78.1834271
20
30.6712874
11
91.5222126
21
-5.9767248
0
LINE
8
0
10
41.5354149
20
17.3325019
11
78.1834271
21
30.6712874
0
LINE
8
0
10
41.5354149
20
17.3325019
11
54.8742004
21
-19.3155103
0
ENDSEC
0
EOF

View File

@ -1,518 +0,0 @@
0
SECTION
2
HEADER
9
$INSUNITS
70
4
0
ENDSEC
0
SECTION
2
TABLES
0
TABLE
2
LTYPE
0
LTYPE
72
65
70
64
2
CONTINUOUS
3
______
73
0
40
0
0
ENDTAB
0
TABLE
2
LAYER
0
ENDTAB
0
ENDSEC
0
SECTION
2
ENTITIES
0
LINE
8
0
10
-12.8171276
20
-5.9767248
11
39.3525425
21
-24.9649308
0
LINE
8
0
10
-12.8171276
20
-5.9767248
11
0.5216579
21
30.6712874
0
LINE
8
0
10
0.5216579
20
30.6712874
11
39.3525425
21
16.5380017
0
LINE
8
0
10
41.5354149
20
17.3325019
11
78.1834271
21
30.6712874
0
LINE
8
0
10
41.5354149
20
17.3325019
11
39.3525425
21
16.5380017
0
LINE
8
0
10
39.3525425
20
-24.9649308
11
91.5222126
21
-5.9767248
0
LINE
8
0
10
78.1834271
20
30.6712874
11
91.5222126
21
-5.9767248
0
LINE
8
0
10
-8.9719893
20
-4.1837073
11
4.1837073
21
-8.9719893
0
LINE
8
0
10
4.1837073
20
-8.9719893
11
8.9719893
21
4.1837073
0
LINE
8
0
10
8.9719893
20
4.1837073
11
-4.1837073
21
8.9719893
0
LINE
8
0
10
-4.1837073
20
8.9719893
11
-8.9719893
21
-4.1837073
0
LINE
8
0
10
-2.4736066
20
13.6704525
11
10.68209
21
8.8821705
0
LINE
8
0
10
10.68209
20
8.8821705
11
15.470372
21
22.0378671
0
LINE
8
0
10
15.470372
20
22.0378671
11
2.3146754
21
26.8261491
0
LINE
8
0
10
2.3146754
20
26.8261491
11
-2.4736066
21
13.6704525
0
LINE
8
0
10
8.8821705
20
-10.68209
11
22.0378671
21
-15.470372
0
LINE
8
0
10
22.0378671
20
-15.470372
11
26.8261491
21
-2.3146754
0
LINE
8
0
10
26.8261491
20
-2.3146754
11
13.6704525
21
2.4736066
0
LINE
8
0
10
13.6704525
20
2.4736066
11
8.8821705
21
-10.68209
0
LINE
8
0
10
15.3805532
20
7.1720698
11
28.5362498
21
2.3837878
0
LINE
8
0
10
28.5362498
20
2.3837878
11
33.3245318
21
15.5394844
0
LINE
8
0
10
33.3245318
20
15.5394844
11
20.1688352
21
20.3277664
0
LINE
8
0
10
20.1688352
20
20.3277664
11
15.3805532
21
7.1720698
0
LINE
8
0
10
74.5213777
20
-8.9719893
11
87.6770743
21
-4.1837073
0
LINE
8
0
10
87.6770743
20
-4.1837073
11
82.8887923
21
8.9719893
0
LINE
8
0
10
82.8887923
20
8.9719893
11
69.7330957
21
4.1837073
0
LINE
8
0
10
69.7330957
20
4.1837073
11
74.5213777
21
-8.9719893
0
LINE
8
0
10
68.022995
20
8.8821705
11
81.1786916
21
13.6704525
0
LINE
8
0
10
81.1786916
20
13.6704525
11
76.3904096
21
26.8261491
0
LINE
8
0
10
76.3904096
20
26.8261491
11
63.234713
21
22.0378671
0
LINE
8
0
10
63.234713
20
22.0378671
11
68.022995
21
8.8821705
0
LINE
8
0
10
56.6672179
20
-15.470372
11
69.8229145
21
-10.68209
0
LINE
8
0
10
69.8229145
20
-10.68209
11
65.0346325
21
2.4736066
0
LINE
8
0
10
65.0346325
20
2.4736066
11
51.8789359
21
-2.3146754
0
LINE
8
0
10
51.8789359
20
-2.3146754
11
56.6672179
21
-15.470372
0
LINE
8
0
10
50.1688352
20
2.3837878
11
63.3245318
21
7.1720698
0
LINE
8
0
10
63.3245318
20
7.1720698
11
58.5362498
21
20.3277664
0
LINE
8
0
10
58.5362498
20
20.3277664
11
45.3805532
21
15.5394844
0
LINE
8
0
10
45.3805532
20
15.5394844
11
50.1688352
21
2.3837878
0
ENDSEC
0
EOF

View File

@ -3,27 +3,26 @@ points:
matrix: {}
mirror: 20
outlines:
exports:
outline:
main:
type: keys
side: both
size: 20
bound: false
middle_poly:
type: polygon
points:
- ref:
- matrix
- mirror_matrix
shift: [0, 20]
- shift: [20, -40]
- shift: [-40, 0]
outside_polys:
type: polygon
points:
- ref: matrix
shift: [-10, 15]
- shift: [5, -10]
- shift: [-10, 0]
mirror: true
outline:
main:
what: rectangle
where: true
size: 20
bound: false
middle_poly:
what: polygon
where.ref:
- matrix
- mirror_matrix
points:
- shift: [0, 20]
- shift: [20, -40]
- shift: [-40, 0]
outside_polys:
what: polygon
where.ref: matrix
points:
- shift: [-10, 15]
- shift: [5, -10]
- shift: [-10, 0]
mirror: true

View File

@ -3,25 +3,24 @@ points:
matrix: {}
mirror: 20
outlines:
exports:
outline:
main:
type: keys
side: both
size: 20
bound: false
middle_rect:
type: rectangle
anchor:
ref:
- matrix
- mirror_matrix
shift: [0, sy/2]
size: [20, 40]
outside_rects:
type: rectangle
anchor:
ref: matrix
shift: [-10, 10]
size: 10
mirror: true
outline:
main:
what: rectangle
where: true
size: 20
bound: false
middle_rect:
what: rectangle
where:
ref:
- matrix
- mirror_matrix
shift: [0, sy/2]
size: [20, 40]
outside_rects:
what: rectangle
where:
ref: matrix
shift: [-10, 10]
size: 10
mirror: true

View File

@ -1,16 +1,9 @@
points:
zones:
matrix:
columns:
one:
rows:
only:
points.zones.matrix:
outlines:
exports:
edge:
- type: keys
side: left
size: [u, u]
edge:
- what: rectangle
where: true
size: u
pcbs:
main:
outlines:
@ -33,5 +26,5 @@ pcbs:
type: anchor_test
anchors:
end:
ref: matrix_one_only
ref: matrix
shift: [10, 10]

View File

@ -13,10 +13,11 @@ describe('Filter', function() {
const names = points => points.map(p => p.meta.name)
it('similar', function() {
// no points filter to no points
filter(undefined, '', undefined).should.deep.equal([])
// and undefined config doesn't filter anything
filter(undefined, '', points).should.deep.equal(Object.values(points))
// an undefined config leads to a default point
filter(undefined, '', points).should.deep.equal([new Point()])
// true shouldn't filter anything, while false should filter everything
filter(true, '', points).should.deep.equal(Object.values(points))
filter(false, '', points).should.deep.equal([])
// objects just propagate to anchor (and then wrap in array for consistency)
filter({}, '', points).should.deep.equal([anchor({}, '', points)()])
// simple name string