Skip to content

Commit

Permalink
Start custom connectors, fix trackball models for eternity
Browse files Browse the repository at this point in the history
  • Loading branch information
rianadon committed Jul 9, 2024
1 parent 829c1e3 commit fe171b8
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 71 deletions.
9 changes: 4 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"monaco-editor": "^0.37.1",
"pako": "^2.1.0",
"qrious": "^4.0.2",
"replicad": "^0.15.1",
"replicad": "^0.17.0",
"simplicial-complex-boundary": "^1.0.1",
"svd-js": "^1.1.1",
"svelte-easy-popover": "^1.0.0",
Expand Down
49 changes: 21 additions & 28 deletions src/lib/geometry/microcontrollers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Cuttleform } from '$lib/worker/config'
import { convertToMaybeCustomConnectors, type Cuttleform } from '$lib/worker/config'
import { Vector } from '$lib/worker/modeling/transformation'

import { PLATE_HEIGHT, screwInsertDimensions } from '$lib/worker/model'
Expand Down Expand Up @@ -258,35 +258,28 @@ interface BoardOffset {
export type Connector = 'trrs'

export function boardOffsetInfo(config: Cuttleform): BoardOffset {
if (!config.connector) return { connectors: [] }
switch (config.connector) {
case 'trrs':
return {
connectors: [
{
model: 'trrs',
offset: config.microcontroller && BOARD_PROPERTIES[config.microcontroller].sizeName == 'Large'
? new Vector(-16.5, 0, 2.5) // Extra space for large microcontrollers
: new Vector(-14.5, 0, 2.5),
size: new Vector(6.1, 12.2, 5),
boundingBoxZ: 6,
rails: {
width: RAIL_WIDTH,
backstop: true,
clamps: [
{ side: 'left', radius: 0.4 },
{ side: 'right', radius: 0.4 },
{ side: 'back', radius: RAIL_RADIUS * 1.5 },
],
},
},
let elements: BoardElement[] = []
const connectors = convertToMaybeCustomConnectors(config)
if (connectors.find(c => c.preset == 'trrs')) {
elements.push({
model: 'trrs',
offset: config.microcontroller && BOARD_PROPERTIES[config.microcontroller].sizeName == 'Large'
? new Vector(-16.5, 0, 2.5) // Extra space for large microcontrollers
: new Vector(-14.5, 0, 2.5),
size: new Vector(6.1, 12.2, 5),
boundingBoxZ: 6,
rails: {
width: RAIL_WIDTH,
backstop: true,
clamps: [
{ side: 'left', radius: 0.4 },
{ side: 'right', radius: 0.4 },
{ side: 'back', radius: RAIL_RADIUS * 1.5 },
],
}
case 'usb':
return { connectors: [] }
default:
throw new Error(`Connector type ${config.connector} is not supported`)
},
})
}
return { connectors: elements }
}

export function boardElements(config: Cuttleform, layout: boolean): BoardElement[] {
Expand Down
8 changes: 4 additions & 4 deletions src/lib/worker/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ export async function generate(config: Cuttleform, geo: Geometry, stitchWalls: b
console.timeEnd('Creating holes')
console.time('Creating connector')
// let connector = null
if (config.connector && connOrigin) {
if (connOrigin) {
// connector = makeConnector(config, config.connector, connOrigin)
walls = cutWithConnector(config, walls, config.connector, connOrigin)
walls = cutWithConnector(config, walls, connOrigin)
}
console.timeEnd('Creating connector')
console.time('Creating screw inserts')
Expand Down Expand Up @@ -269,8 +269,8 @@ export async function cutWall(config: Cuttleform) {
await ensureOC()
const geo = newGeometry(config)
let walls = makeWalls(config, geo.allWallCriticalPoints(), geo.worldZ, geo.bottomZ).toSolid(false, false)
if (config.connector && geo.connectorOrigin) {
walls = cutWithConnector(config, walls, config.connector, geo.connectorOrigin)
if (geo.connectorOrigin) {
walls = cutWithConnector(config, walls, geo.connectorOrigin)
}
const result = meshWithVolumeAndSupport(walls, geo.bottomZ)
// walls.delete()
Expand Down
19 changes: 17 additions & 2 deletions src/lib/worker/config.cosmos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import ETrsf, { Constant, fullMirrorETrsf, type MatrixOptions, mirror } from '$l
// import { deserialize } from 'src/routes/beta/lib/serialize'
import { flippedKey } from '$lib/geometry/keycaps'
import { PART_INFO, socketSize } from '$lib/geometry/socketsParts'
import { type ClusterName, type ClusterSide, type ClusterType, type Connector, decodeClusterFlags, encodeClusterFlags, type ScrewFlags } from '$target/cosmosStructs'
import type { Curvature } from '$target/proto/cosmos'
import { Matrix4, Vector3 } from 'three'
import { type ClusterName, type ClusterSide, type ClusterType, type Connector, decodeClusterFlags, encodeClusterFlags, type ScrewFlags } from '../../../target/cosmosStructs'
import type { Curvature } from '../../../target/proto/cosmos'
import {
type AnyShell,
curvature,
Expand All @@ -23,6 +23,21 @@ import { decodePartType, encodePartType, KEYBOARD_DEFAULTS } from './config.seri
import Trsf from './modeling/transformation'
import { capitalize, DefaultMap, objEntries, objKeys, sum, TallyMap, trimUndefined } from './util'

export type CustomConnector = {
preset?: undefined
width: number
height: number
x: number
y: number
radius: number
}
export type ConnectorMaybeCustom = {
preset: 'usb'
size: 'slim' | 'average' | 'big'
} | {
preset: 'trrs'
} | CustomConnector

export interface PartType {
type?: CuttleKey['type']
aspect?: number
Expand Down
2 changes: 1 addition & 1 deletion src/lib/worker/config.serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export function encodeShell(shell: Cuttleform['shell']): Keyboard['shell'] {
if (opts.tiltShell[key] == TILT_DEFAULTS[key]) delete opts.tiltShell[key]
}
}
throw new Error('Shell type not supported')
throw new Error(`Shell type ${shell.type} not supported`)
}

interface FullKeyboard extends Required<Keyboard> {
Expand Down
25 changes: 18 additions & 7 deletions src/lib/worker/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type manuform from '$assets/manuform.json'
import { socketSize } from '$lib/geometry/socketsParts'
import type { CuttleKey, MicrocontrollerName } from '$target/cosmosStructs'
import { StiltsGeometry } from '@pro/stiltsGeo'
import { Matrix4, Vector3 } from 'three'
import {
CONNECTOR,
CONNECTOR_SIZE,
Expand All @@ -23,10 +21,12 @@ import {
SCREW_SIZE,
SCREW_TYPE,
SWITCH,
} from '../../../target/proto/cuttleform'
} from '$target/proto/cuttleform'
import { StiltsGeometry } from '@pro/stiltsGeo'
import { Matrix4, Vector3 } from 'three'
import type { FullGeometry } from '../../routes/beta/lib/viewers/viewer3dHelpers'
import { BaseGeometry, BlockGeometry, TiltGeometry } from './cachedGeometry'
import type { CosmosCluster, CosmosKey, CosmosKeyboard } from './config.cosmos'
import type { ConnectorMaybeCustom, CosmosCluster } from './config.cosmos'
import { estimatedBB, estimatedCenter } from './geometry'
import { DEFAULT_MWT_FACTOR } from './geometry.thickWebs'
import Trsf from './modeling/transformation'
Expand All @@ -39,7 +39,7 @@ type DeepRequired<T> = Required<
}
>

export type { CuttleKey } from 'target/cosmosStructs'
export type { CuttleKey } from '$target/cosmosStructs'
export type CuttleformProto = DeepRequired<CuttleformProtoP>

// const MANUFORM_KEYCAP_TYPE = "xda"
Expand All @@ -62,8 +62,11 @@ export interface SpecificCuttleform<S> {
keys: CuttleKey[]
/** The basis on which to compute */
keyBasis: Keycap['profile']
connector: 'usb' | 'trrs' | null
connectorSizeUSB: 'slim' | 'average' | 'big'
connectors: ConnectorMaybeCustom[]
/** @deprecated */
connector?: 'usb' | 'trrs' | null
/** @deprecated */
connectorSizeUSB?: 'slim' | 'average' | 'big'
/** The index of the wall by which the connector is placed. */
connectorIndex: number
/** The indices of the walls at which to place screw inserts. */
Expand Down Expand Up @@ -1547,3 +1550,11 @@ export function fullEstimatedSize(geo: FullGeometry | undefined): Full<[number,
}
}
}

export function convertToMaybeCustomConnectors(c: Cuttleform): ConnectorMaybeCustom[] {
if (c.connector === null) return []
if (c.connector && !c.connectorSizeUSB) throw new Error('connectorSizeUSB not defined')
if (c.connector === 'usb') return [{ preset: 'usb', size: c.connectorSizeUSB! }]
if (c.connector === 'trrs') return [{ preset: 'trrs' }, { preset: 'usb', size: c.connectorSizeUSB! }]
return c.connectors
}
47 changes: 41 additions & 6 deletions src/lib/worker/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { makeStiltsPlate, makeStiltsPlateSimpleMesh, splitStiltsScrewInserts } f
import { cast, CornerFinder, downcast, draw, drawCircle, Drawing, drawRoundedRectangle, Face, loft, type Point, type Sketch, Sketcher, Solid } from 'replicad'
import type { TiltGeometry } from './cachedGeometry'
import { createTriangleMap } from './concaveman'
import type { Cuttleform, Geometry } from './config'
import { convertToMaybeCustomConnectors, type Cuttleform, type Geometry } from './config'
import type { ConnectorMaybeCustom, CustomConnector } from './config.cosmos'
import {
bezierPatch,
type CriticalPoints,
Expand Down Expand Up @@ -771,6 +772,28 @@ function rectangleForUSB(c: Cuttleform) {
}
}

function convertToCustomConnectors(c: Cuttleform, conn: ConnectorMaybeCustom): CustomConnector {
if (conn.preset == 'trrs') {
return {
width: 6.4,
height: 6.4,
radius: 3.2,
x: c.microcontroller && BOARD_PROPERTIES[c.microcontroller].sizeName == 'Large' ? -16.5 : -14.5,
y: 5,
}
}
if (conn.preset == 'usb') {
return {
width: { slim: 10.5, average: 12, big: 13 }[conn.size],
height: { slim: 6.5, average: 7, big: 8 }[conn.size],
radius: 3,
x: 0,
y: 5,
}
}
return conn
}

export const connectors: Record<string, { positive: (c: Cuttleform) => Solid | null; negative: (c: Cuttleform) => Solid }> = {
rj9: {
positive(c: Cuttleform) {
Expand Down Expand Up @@ -830,11 +853,23 @@ export const connectors: Record<string, { positive: (c: Cuttleform) => Solid | n
},
}

export function cutWithConnector(c: Cuttleform, wall: Solid, conn: keyof typeof connectors, origin: Trsf) {
if (!conn) return wall
const pos = connectors[conn].positive(c)
if (pos) return wall.cut(origin.transform(pos))
return wall.cut(origin.transform(connectors[conn].negative(c)))
export function cutWithConnector(c: Cuttleform, wall: Solid, origin: Trsf) {
// if (!conn) return wall
// const pos = connectors[conn].positive(c)
// if (pos) return wall.cut(origin.transform(pos))
// return wall.cut(origin.transform(connectors[conn].negative(c)))
const connectors = convertToMaybeCustomConnectors(c).map(conn => convertToCustomConnectors(c, conn))
if (connectors.length == 0) return wall

const connectorSketches = connectors.map(k =>
(k.width == k.radius * 2 && k.height == k.radius * 2 ? drawCircle(k.radius) : drawRoundedRectangle(k.width, k.height, k.radius))
.translate(k.x, k.y)
)
const fusedSketch = connectorSketches.reduce((a, b) => a.fuse(b))
return wall.cut(origin.transform(
fusedSketch.sketchOnPlane('XZ').extrude(c.wallThickness * 10)
.translate(0, c.wallThickness * 10, 0) as Solid,
))
}

export function makeConnector(c: Cuttleform, conn: keyof typeof connectors, origin: Point) {
Expand Down
17 changes: 2 additions & 15 deletions src/lib/worker/socketsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,6 @@ try {
keyUrls = undefined
}

async function importSTEPFixed(b: Blob) {
const oc = getOC()
const model = await importSTEP(b)
const props = new oc.GProp_GProps_1()
oc.BRepGProp.VolumeProperties_2(model.wrapped, props, 0.01, false, true)
// Flip all faces if mass is negative
if (props.Mass() < 0) {
model.wrapped.Reverse()
}
props.delete()
return model
}

const keyCacher = makeAsyncCacher(async (key: CuttleKey) => {
if (key.type == 'blank') return makeBaseBox(key.size?.width ?? 18.5, key.size?.height ?? 18.5, 5).translateZ(-5)
const url = 'partOverride' in PART_INFO[key.type]
Expand All @@ -35,9 +22,9 @@ const keyCacher = makeAsyncCacher(async (key: CuttleKey) => {
if (!urls[url]) throw new Error(`Model for url ${url} does not exist`)
return keyUrls
? await fetch(urls[url].default).then(r => r.blob())
.then(r => importSTEPFixed(r) as Promise<Solid>)
.then(r => importSTEP(r) as Promise<Solid>)
: (await import(process.env.FS!)).readFile(urls[url].default)
.then(r => importSTEPFixed(new Blob([r])) as Promise<Solid>)
.then(r => importSTEP(new Blob([r])) as Promise<Solid>)
})

const extendedKeyCacher = makeAsyncCacher(async (key: CuttleKey) => {
Expand Down
1 change: 0 additions & 1 deletion src/model_gen/modeling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ export function serialize(filename: string, model: AnyShape) {

const writer = new oc.STEPControl_Writer_1()
oc.Interface_Static.SetIVal('write.step.schema', 5)
oc.Interface_Static.SetIVal('write.surfacecurve.mode', 0)
writer.Model(true).delete()
const progress = new oc.Message_ProgressRange_1()

Expand Down
3 changes: 2 additions & 1 deletion src/model_gen/typeFootprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ function footprintOfType(params: {

if (type.isArray()) {
const subType = type.getArrayElementTypeOrThrow()
return `${next(subType)}[]`
const formatted = next(subType)
return formatted.includes('|') ? `(${formatted})[]` : formatted + '[]'
}

if (type.isTuple()) {
Expand Down

0 comments on commit fe171b8

Please sign in to comment.