diff --git a/hunks/debug/logNumbers.js b/hunks/debug/logNumbers.js index a74ed3391291d8448c28116707be5e00cc023058..814924e2b72d926a4b6aff04c62ecf99556efb69 100644 --- a/hunks/debug/logNumbers.js +++ b/hunks/debug/logNumbers.js @@ -24,17 +24,9 @@ export default function NumberLogger() { let logToConsole = new State('boolean', 'console', false) this.states.push(logToConsole) - this.dom = {} - - this.init = () => { - this.dom = $('<div>').get(0) - } - - this.onload = () => { - //error here - let text = $('<div>').addClass('txt').append('- >').get(0) - $(this.dom).append(text) - } + let dom = this.document() + let text = $('<div>').addClass('txt').append('- >').get(0) + $(dom).append(text) this.loop = () => { // this will be called once every round turn @@ -42,7 +34,7 @@ export default function NumberLogger() { if (tolog.io()) { // an input is occupied, and the exit path is empty let val = tolog.get() - $(this.dom).children('.txt').html(val) + $(text).html(val) if (logToConsole.value === true) { console.log(`logger ${this.ind}`, val) } diff --git a/hunks/image/imageCapture.js b/hunks/image/imageCapture.js new file mode 100644 index 0000000000000000000000000000000000000000..099d5a5f5a62f52567219bac321add6d7ba0982f --- /dev/null +++ b/hunks/image/imageCapture.js @@ -0,0 +1,73 @@ +/* +hunks/image/imagecapture.js + +pull image from webcam, use imagecapture interface for fine tuning + +Jake Read at the Center for Bits and Atoms with Neil Gershenfeld and Leo McElroy +(c) Massachusetts Institute of Technology 2019 + +This work may be reproduced, modified, distributed, performed, and +displayed for any purpose, but must acknowledge the squidworks and cuttlefish projects. +Copyright is retained and must be preserved. The work is provided as is; +no warranty is provided, and users accept all liability. +*/ + +import { + Hunkify, + Input, + Output, + State +} from '../hunks.js' + +export default function RTCWebcam(){ + Hunkify(this) + + let imgOut = this.output('ImageData', 'frame') + + let dom = this.document() + let msg = $(`<div>retrieving video...</div>`).get(0) + $(dom).append(msg) + let video = $('<video>').get(0) + let canvas = $('<canvas>').get(0) // invisible canvas 4 us + + let streaming = false + let context = canvas.getContext('2d') + + this.init = () => { + navigator.mediaDevices.getUserMedia({video: true, audio: false}).then((stream) => { + $(dom).append(video) + video.srcObject = stream + video.play() + video.addEventListener('canplay', (evt) => { + $(msg).empty() + if(!streaming){ + streaming = true + canvas.width = video.videoWidth + canvas.height = video.videoHeight + } + /* + let capture = () => { + context.drawImage(video, 0, 0, canvas.width, canvas.height) + let imgData = context.getImageData(0, 0, canvas.width, canvas.height) + console.log(imgData) + setTimeout(capture, 2000) + } + setTimeout(capture, 2000) + */ + }) + }).catch((err) => { + $(msg).text('error retrieving webcam from system, see logs') + console.error("Webcam Hunk couldn't retrieve a stream:", err) + }) + } + + this.loop = () => { + if(streaming && !imgOut.io()){ + // capture frames as imagedata, onto the virtual canvas, + context.drawImage(video, 0, 0, canvas.width, canvas.height) + // pull img data from that vcanvas -> the output, + imgOut.put(context.getImageData(0,0, canvas.width, canvas.height)) + } + } + +} diff --git a/hunks/image/imgToPath2D.js b/hunks/image/imgToPath2D.js index 6206b0f56f05dee0acdc0ae1dffa9aabb93570b0..f0a90fa98614c0131a1b3b4f46c1e076caa19894 100644 --- a/hunks/image/imgToPath2D.js +++ b/hunks/image/imgToPath2D.js @@ -1,7 +1,7 @@ /* -hunks/image/edgeDetect.js +hunks/image/imgToPath2D.js -find edges +threshold, edges, orient, vectorize, z-clearances and cuts, Jake Read at the Center for Bits and Atoms with Neil Gershenfeld and Leo McElroy (c) Massachusetts Institute of Technology 2019 @@ -27,8 +27,8 @@ export default function imgToPath2D() { let threshValue = this.state("number", "threshold", 0.5) let idealWidth = this.state("number", "width", 220) // machine-space width, - let zUp = this.state('number', 'clearance', 10) - let zDown = this.state('number', 'depth', -5) + let zUp = this.state('number', 'clearance', 8) + let zDown = this.state('number', 'depth', 3) this.init = () => {} @@ -904,6 +904,8 @@ const unfPath = (path, pwidth, mmwidth, zu, zd) => { let unfp = [] // expansion, let scale = mmwidth / pwidth + // first move is to 0,0,clearance + unfp.push([0, 0, zu]) // flatten, adding z-moves for(let leg of path){ // start each leg up top, above the first point, diff --git a/hunks/image/readPNG.js b/hunks/image/readPNG.js index 49013c36fa1a3513be939c867e46e646dcad683f..2ea41e9ca9d87e8f653936efc581fb6954427c7c 100644 --- a/hunks/image/readPNG.js +++ b/hunks/image/readPNG.js @@ -14,14 +14,14 @@ no warranty is provided, and users accept all liability. import { Hunkify, Input, Output, State } from "../hunks.js"; -import { html, svg, render } from "https://unpkg.com/lit-html?module"; - export default function UploadPNG() { // this fn attaches handles to our function-object, Hunkify(this); let imgOut = this.output('ImageData', 'image') let dpiOut = this.output('number', 'dpi') + let widthOut = this.output('number', 'width') + let heightOut = this.output('number', 'height') let trig = this.state('boolean', 'release', false) trig.onChange = (value) => { @@ -37,10 +37,13 @@ export default function UploadPNG() { // local datas, let imageData = null let imageUpdated = false - let idealWidth = 395 + let idealWidth = 285 // and dpi, let imgDpi = 72 let dpiUpdated = false + let whUpdated = false + let width = 0 + let height = 0 // write some startup DOM elements, let button = $('<input type="file" accept="image/png">').on('input', (evt) => { @@ -107,11 +110,13 @@ export default function UploadPNG() { dpiUpdated = true if (imageData) { console.log(imageData) - let width = imageData.width * (imgDpi / 1000) / 25.4 - let height = imageData.height * (imgDpi / 1000) / 25.4 + // this ? + width = (imageData.width / imgDpi) * 25.4 + height = (imageData.height / imgDpi) * 25.4 + whUpdated = true console.warn(`size in mm is w: ${width.toFixed(3)}, h: ${height.toFixed(3)}`) } - console.log('dpi', imgDpi) + console.warn('dpi is: ', imgDpi) } rawReader.readAsArrayBuffer(file) }) @@ -123,9 +128,14 @@ export default function UploadPNG() { imageUpdated = false imgOut.put(imageData) } - if(imgDpi && dpiUpdated && !dpiOut.io()){ + if (imgDpi && dpiUpdated && !dpiOut.io()) { dpiUpdated = false dpiOut.put(imgDpi) } + if (whUpdated && !widthOut.io() && !heightOut.io()) { + whUpdated = false + widthOut.put(width) + heightOut.put(height) + } } } diff --git a/hunks/interface/number.js b/hunks/interface/number.js index 0ff5488a014c61d62bf31a6f0e15e3d557ec19e6..49c31c80cb0e905ff03ed674fc9784c38ac61111 100644 --- a/hunks/interface/number.js +++ b/hunks/interface/number.js @@ -17,37 +17,26 @@ import { State } from '../hunks.js' -function Number() { +export default function Number() { Hunkify(this) - let numout = new Output('number', 'num', this) - this.outputs.push(numout) + let numout = this.output('number', 'num') - let numrep = new State('number', 'numrep', 275074) - this.states.push(numrep) + let numrep = this.state('number', 'numrep', 1000) // as is tradition, - this.dom = {} - - this.init = () => { - // manager calls this once - // it is loaded and state is updated (from program) - console.log('HELLO NUMINPUT') - this.dom = $('<div>').get(0) - //this.dom = document.createElement('div') - } - - this.onload = () => { - let contact = $('<div>').addClass('btn').append('! contact !').get(0) - $(this.dom).append(contact) - contact.addEventListener('click', (evt) => { - numout.put(numrep.value) - }) - } + let dom = this.document() + let contact = $('<div>').addClass('btn').append('! contact !').get(0) + contact.addEventListener('click', (evt) => { + if(numout.io()){ + console.warn('number stream occupied, bailing') + return + } + numout.put(numrep.value) + }) + $(dom).append(contact) this.loop = () => { // } } - -export default Number diff --git a/hunks/interface/threejsPathDisplay.js b/hunks/interface/threejsPathDisplay.js index 05e4b6ebe22c80bbddc9c68a149f42dc33a42708..9c9e67a389991f06e1910b17267f0b93d2322857 100644 --- a/hunks/interface/threejsPathDisplay.js +++ b/hunks/interface/threejsPathDisplay.js @@ -28,9 +28,9 @@ import { MeshLine, MeshLineMaterial } from '../../libs/three_meshline.module.js' export default function ThreeGhosts() { Hunkify(this) - let ptin = this.input('reference', 'point') + let pathIn = this.input('reference', 'point') - let lineWidth = this.state('number', 'line width', 5) + let lineWidth = this.state('number', 'line width', 2) let dom = this.document() @@ -38,8 +38,8 @@ export default function ThreeGhosts() { } - let width = 1000 - let height = 1000 + let width = 600 + let height = 600 let camera = new THREE.PerspectiveCamera(75, width / height, 1, 10000) camera.up.set(0, 0, 1) @@ -74,9 +74,9 @@ export default function ThreeGhosts() { let last = {} this.loop = () => { - if (ptin.io()) { + if (pathIn.io()) { // local copy, - let lp = JSON.parse(JSON.stringify(ptin.get())) + let lp = JSON.parse(JSON.stringify(pathIn.get())) let lw = lineWidth.value // redraw top->bottom every time ? let geometry = new THREE.Geometry() diff --git a/hunks/interface/toggle.js b/hunks/interface/toggle.js index d276be129c9cdcbdbb46f3c0118c9765d021937d..57b8740081cabf3187a834ef07452a7c4049b2a1 100644 --- a/hunks/interface/toggle.js +++ b/hunks/interface/toggle.js @@ -15,38 +15,29 @@ no warranty is provided, and users accept all liability. import { Hunkify, Input, Output, State } from '../hunks.js' export default function Toggle() { - Hunkify(this) - - let onclk = this.output('boolean', 'out') - let nextOut = this.state('boolean', 'next out', true) - - this.dom = {} - - this.init = () => { - // manager calls this once - this.dom = $('<div>').get(0) + Hunkify(this) + + let onclk = this.output('boolean', 'out') + let nextOut = this.state('boolean', 'next out', true) + + let dom = this.document() + let contact = $('<div>').addClass('btn').append('! toggle !').get(0) + contact.addEventListener('click', (evt) => { + if (onclk.io()) { + console.warn("button attempts to push to occupied output") + } else { + if (nextOut.value) { + onclk.put(true) + nextOut.set(false) + } else { + onclk.put(false) + nextOut.set(true) + } } + }) + $(dom).append(contact) - this.onload = (dom) => { - // function equivalent, our .dom element is loaded into ~ the d o m ~ - let contact = $('<div>').addClass('btn').append('! toggle !').get(0) - $(this.dom).append(contact) - contact.addEventListener('click', (evt) => { - if(onclk.io()){ - console.warn("button attempts to push to occupied output") - } else { - if(nextOut.value){ - onclk.put(true) - nextOut.set(false) - } else { - onclk.put(false) - nextOut.set(true) - } - } - }) - } - - this.loop = () => { - // ... nah - } + this.loop = () => { + // ... nah + } } diff --git a/hunks/statemachines/saturn.js b/hunks/statemachines/saturn.js index 3edc10c2d12a56cbab163ec2769b361afea2290f..e47e5cdeadcc2b0467c3b6c9d07f424c258db832 100644 --- a/hunks/statemachines/saturn.js +++ b/hunks/statemachines/saturn.js @@ -58,17 +58,17 @@ export default function Saturn() { // here's a case where we might want some type of enum ish thing let isIncrementalMode = this.state('boolean', 'incremental mode', false) - let accelState = this.state('number', 'acceleration (u/s/s)', 20) + let accelState = this.state('number', 'acceleration (u/s/s)', 5) accelState.onChange = (val) => { if(val > 30){ val = 30 - } else if (val < 5){ - val = 5 + } else if (val < 2){ + val = 2 } accelState.set(val) accel = accelState.value } - let speedState = this.state('number', 'speed (u/s)', 100) + let speedState = this.state('number', 'speed (u/s)', 50) speedState.onChange = (val) => { if (val > 200){ val = 200 diff --git a/hunks/view.js b/hunks/view.js index 2bee4c445b6dd83f4ddbdb6124c117acaf006daa..0abc3220ba8e26c27f6e293bedd58f50cf8b12ca 100644 --- a/hunks/view.js +++ b/hunks/view.js @@ -156,7 +156,7 @@ export default function View() { // an oddity, we occasionally change positions, this.hasDefPositionUpdate = false let setDefReposition = (index) => { - window.check = true + window.check = true this.hasDefPositionUpdate = true if (defs[index]) { defs[index].hasPositionUpdate = true @@ -821,7 +821,7 @@ export default function View() { and then handle etcs afterwards, i.e. probably just cleaning up .clean() (ha) */ this.refresh = () => { - console.log(`REFRESH ${this.name}`) + console.warn(`REFRESH ${this.name}`) // well, I won't say it's clean or beautiful, but we are interested in keeping the // positions of things intact, so I am here for this: let psns = [] @@ -998,6 +998,8 @@ export default function View() { if (df.position) hnk.position = df.position if (df.type == 'link') { if (df.interior()) { + // WARN: the link-state hack, needs link work / protocol work + hnk.states[0].value = false hnk.contains = await df.interior().save() // this should recurse, yeah ? } } @@ -1122,6 +1124,7 @@ export default function View() { } this.reinstate = async (system, debug) => { + console.warn(`${this.name} begins reinstate`) // ensure we are up-to-date w/ current state, await this.refresh() // and and, @@ -1142,6 +1145,7 @@ export default function View() { await interior.reinstate(spec.contains) } } + console.warn(`${this.name} finish reinstate`) resolve() } catch (err) { console.error(err) diff --git a/hunks/x_adhoc/center.js b/hunks/x_adhoc/center.js index 90a9f02e20c4c1b7a10957b042998655f2db85ee..a1d42679c4dad1ee90b43c00eb3c5e735ccf42d1 100644 --- a/hunks/x_adhoc/center.js +++ b/hunks/x_adhoc/center.js @@ -29,21 +29,17 @@ export default function HotSpotHunter(){ let opX = this.output('number', 'x') let opY = this.output('number', 'y') - console.log('REG?', REG) + let dom = this.document() - this.dom = $('<div>').get(0) // one to draw into: let canvas = $('<canvas>').get(0) let ctx = canvas.getContext('2d') - canvas.width = 395 - canvas.height = 395 + canvas.width = 285 + canvas.height = 285 // and ah virtual friend: let vc = $('<canvas>').get(0) let vctx = vc.getContext('2d') - - this.onload = () => { - $(this.dom).append(canvas) - } + $(dom).append(canvas) this.loop = () => { if(ipImg.io() && !opX.io() && !opY.io()){ diff --git a/hunks/x_adhoc/correlate.js b/hunks/x_adhoc/correlate.js index 7b0a93daf12e192cef2a87cf01f42192cde5d031..e00483b8692e56c44abd97f50fce93db8e2fa3b7 100644 --- a/hunks/x_adhoc/correlate.js +++ b/hunks/x_adhoc/correlate.js @@ -167,6 +167,8 @@ export default function Correlate() { let imgIn = this.input('ImageData', 'frame') let resOut = this.output('ImageData', 'correlation') + let invert = this.state('boolean', 'invert', true) + let canvasA = $('<canvas>').get(0) canvasA.width = 24 canvasA.height = 24 @@ -177,7 +179,9 @@ export default function Correlate() { let canvasB = $('<canvas>').get(0) let ctxB = canvasB.getContext('2d') - this.dom = $('<div>').get(0) + let dom = this.document() + $(dom).append(canvasA) + $(dom).append(canvasB) let webWorker @@ -194,11 +198,6 @@ export default function Correlate() { }) } - this.onload = () => { - $(this.dom).append(canvasA) - $(this.dom).append(canvasB) - } - this.loop = () => { if (imgIn.io() && !running) { /* @@ -225,14 +224,22 @@ export default function Correlate() { //let a = ctxB.getImageData(b.width / 2, b.height / 2, 25, 25) // and write that out, to debug ... //ctxA.putImageData(a, 0, 0) - ctxA.fillStyle = 'white' - ctxA.fillRect(0,0,24,24) - ctxA.fillStyle = 'black' + if(invert.value){ + ctxA.fillStyle = 'black' + ctxA.fillRect(0,0,24,24) + ctxA.fillStyle = 'white' + ctxA.fillRect(0,0,12,12) + ctxA.fillRect(12,12,24,24) + } else { + ctxA.fillStyle = 'white' + ctxA.fillRect(0,0,24,24) + ctxA.fillStyle = 'black' + ctxA.fillRect(0,0,12,12) + ctxA.fillRect(12,12,24,24) + } // ctxA.arc(12,12,8, 0, 2*Math.PI) // ctxA.fillStyle = 'black' // ctxA.fill() - ctxA.fillRect(0,0,12,12) - ctxA.fillRect(12,12,24,24) let a = ctxA.getImageData(0,0,24,24) webWorker.postMessage({a: a, b: b}) running = true diff --git a/hunks/x_adhoc/pathGap.js b/hunks/x_adhoc/pathGap.js new file mode 100644 index 0000000000000000000000000000000000000000..78c2c742b1b57cbbf0da732b52b5981cb60a057f --- /dev/null +++ b/hunks/x_adhoc/pathGap.js @@ -0,0 +1,67 @@ +/* +hunks/adhoc/tpath.js + +canned paths, for testing motion control systems + +Jake Read at the Center for Bits and Atoms with Neil Gershenfeld and Leo McElroy +(c) Massachusetts Institute of Technology 2019 + +This work may be reproduced, modified, distributed, performed, and +displayed for any purpose, but must acknowledge the squidworks and cuttlefish projects. +Copyright is retained and must be preserved. The work is provided as is; +no warranty is provided, and users accept all liability. +*/ + +import { + Hunkify, + Input, + Output, + State +} from '../hunks.js' + +export default function PathGap(){ + Hunkify(this) + + let path = [] + + // we intake big paths, + let inPath = this.input('reference', 'path') + // we output positions one-at-a-time, + let outPosn = this.output('array', 'position') + // and output the remaining path, in case we would like to re-render ... + let outPath = this.output('reference', 'remaining') + + // we have stop / start here, and reset + let runner = this.state('boolean', 'running', false) + runner.onChange = (val) => { + runner.set(val) + } + let reset = this.state('boolean', 'reset', false) + reset.onChange = (val) => { + path = [] + reset.set(false) + } + + // copies out, one at a time, fc pressure + this.loop = () => { + // if no path, and path available, pull + if(inPath.io()){ + if(path.length == 0){ + path = JSON.parse(JSON.stringify(inPath.get())) + } else { + inPath.get() // clear it for our friends, if we don't want it... + } + } + // if we have path and can push outputs, + if(path.length > 0 && runner.value){ + if(!outPosn.io()){ + let op = path.shift() + outPosn.put(op) + // and update the downstream ref, for rendering ... + if(!outPath.io()){ + outPath.put(path) + } + } + } + } +} diff --git a/hunks/x_adhoc/tpath.js b/hunks/x_adhoc/tpath.js index ab7ce883ed84af140185aa8fc0233ee5d5004390..d94682fb567c0f7fd8b024e0349744371f4ea1a8 100644 --- a/hunks/x_adhoc/tpath.js +++ b/hunks/x_adhoc/tpath.js @@ -1,7 +1,7 @@ /* hunks/adhoc/tpath.js -canned paths, for testing motion control systems +canned paths, for testing motion control systems Jake Read at the Center for Bits and Atoms with Neil Gershenfeld and Leo McElroy (c) Massachusetts Institute of Technology 2019 diff --git a/test_files/the-alchemist.png b/test_files/the-alchemist.png new file mode 100644 index 0000000000000000000000000000000000000000..68181087f9f81ffca2ff935f0869231502b770a1 Binary files /dev/null and b/test_files/the-alchemist.png differ diff --git a/view/contextmenu.js b/view/contextmenu.js index 902a373a4212b44c5e758a601a863904c7676a3f..8423331f2039a234511584e1780398e723fa6e51 100644 --- a/view/contextmenu.js +++ b/view/contextmenu.js @@ -34,7 +34,7 @@ let findOrBuild = (evt) => { pos.x = (evt.layerX - pt.x) * (1 / pt.s) pos.y = (evt.layerY - pt.y) * (1 / pt.s) } else { - if (!$(evt.target).is('.subplane')) console.error('poorly placed menu cominatcha') + if (!$(evt.target).is('.subplane')) return plane = evt.target pos.x = evt.layerX + 3 pos.y = evt.layerY - 29 @@ -145,6 +145,7 @@ let changeContextTitle = (text) => { } } } + return }) } @@ -163,7 +164,9 @@ let setupForSave = (se, callback) => { $(tinput).focus() $(tinput).select() $(tinput).on('keyup', (ke) => { + console.log('save key') if (ke.keyCode == 13) { + console.log('keycode 13') callback(tinput.value) } }) @@ -340,6 +343,7 @@ function planeMenu(evt, context) { console.log('ptch', patch) // now we should be ok to ship this home ... setupForSave(ce, (name) => { + console.log('save return, posting...') jQuery.post(`/save/systems/${name}`, patch, (res) => { if (!res.success) { changeContextTitle('error while saving, see logs')