From 05d7ee88fdbb1139b55bec71d644db6e0180bcec Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 29 Feb 2020 20:13:49 -0500 Subject: [PATCH] add round bed support. split worker/work code --- js/kiri-lang.js | 2 + js/kiri-work.js | 466 +++++++----------------- js/kiri-worker.js | 225 ++++++++++++ js/kiri.js | 18 +- js/license.js | 2 +- js/moto-space.js | 137 ++++--- js/web-server.js | 6 +- notes.md | 1 - web/kiri/filter/FDM/Atom.v2 | 1 + web/kiri/filter/FDM/DeltaMaker.2T | 1 + web/kiri/filter/FDM/DeltaMaker.Original | 1 + 11 files changed, 462 insertions(+), 398 deletions(-) create mode 100644 js/kiri-worker.js diff --git a/js/kiri-lang.js b/js/kiri-lang.js index c90801e3..0d5274a3 100644 --- a/js/kiri-lang.js +++ b/js/kiri-lang.js @@ -65,6 +65,8 @@ var gs_kiri_lang = exports; dev_orgc_desc: "bed origin center", dev_orgt: "origin top", dev_orgt_desc: "part z origin top", + dev_bedc: "circular bed", + dev_bedc_desc: "device bed is circular", dev_fanp: "fan power", dev_fanp_desc: "set cooling fan power", dev_prog: "progress", diff --git a/js/kiri-work.js b/js/kiri-work.js index 869534ef..c5a6adf2 100644 --- a/js/kiri-work.js +++ b/js/kiri-work.js @@ -1,339 +1,141 @@ -/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */ +/** Copyright Stewart Allen -- All Rights Reserved */ +"use strict"; -if (self.window) { +// this code runs in kiri's main loop +if (!self.kiri) self.kiri = {}; - if (!self.kiri) self.kiri = {}; +let loc = self.location, + host = loc.hostname, + port = loc.port, + proto = loc.protocol, + pre = host.indexOf(".space") > 0 || host === "localhost" ? + proto + "//" + host + ":" + port : "", + time = function() { return new Date().getTime() }, + KIRI = self.kiri, + BASE = self.base, + seqid = 1, + running = {}, + slicing = {}, + worker = null; - var loc = self.location, - host = loc.hostname, - port = loc.port, - proto = loc.protocol, - pre = host.indexOf(".space") > 0 || host === "localhost" ? - proto + "//" + host + ":" + port : - "", - time = function() { return new Date().getTime() }, - KIRI = self.kiri, - BASE = self.base, - seqid = 1, - running = {}, - slicing = {}, - worker = null; +// new moto.Ajax(function(body) { +// console.log({body:body}); +// let blob = new Blob([body], {type : 'application/json'}); +// worker = new Worker(URL.createObjectURL(blob)); +// }).request(pre + "/code/worker.js/"); - // new moto.Ajax(function(body) { - // console.log({body:body}); - // var blob = new Blob([body], {type : 'application/json'}); - // worker = new Worker(URL.createObjectURL(blob)); - // }).request(pre + "/code/worker.js/"); +function send(fn, data, onreply, async, zerocopy) { + let seq = seqid++; - function send(fn, data, onreply, async, zerocopy) { - var seq = seqid++; - - running[seq] = {fn:onreply, async:async||false}; - - worker.postMessage({ - seq: seq, - task: fn, - time: time(), - data: data - }, zerocopy); - } - - KIRI.work = { - isSlicing : function() { - var current = 0; - for (var key in slicing) { current++ } - return current > 0; - }, - - restart : function() { - if (worker) worker.terminate(); - - for (var key in slicing) { - slicing[key]({error: "cancelled slicing"}); - } - slicing = {}; - running = {}; - - worker = new Worker(pre + "/code/worker.js/" + exports.VERSION); - - worker.onmessage = function(e) { - var now = time(), - reply = e.data, - record = running[reply.seq], - onreply = record.fn; - - if (reply.done) delete running[reply.seq]; - - // calculate and replace recv time - reply.time_recv = now - reply.time_recv; - - onreply(reply.data, reply); - }; - }, - - decimate : function(vertices, callback) { - var vertices = vertices.buffer.slice(0); - send("decimate", vertices, function(output) { - callback(output); - }); - }, - - clear : function(widget) { - send("clear", widget ? {id:widget.id} : {}, function(reply) { - // console.log({clear:reply}); - }); - }, - - slice : function(settings, widget, callback) { - var vertices = widget.getGeoVertices().buffer.slice(0); - slicing[widget.id] = callback; - send("slice", { - id: widget.id, - settings: settings, - vertices: vertices, - position: widget.mesh.position - }, function(reply) { - if (reply.done || reply.error) delete slicing[widget.id]; - callback(reply); - }, null, [vertices]); - }, - - printSetup : function(settings, callback) { - send("printSetup", {settings:settings}, function(reply) { - callback(reply); - }); - }, - - printGCode : function(callback) { - var gcode = [], - start = BASE.util.time(); - send("printGCode", {}, function(reply) { - if (reply.line) { - gcode.push(reply.line); - } else { - if (!reply.gcode) reply.gcode = gcode.join("\n"); - // console.log({printGCode:(BASE.util.time() - start)}); - callback(reply); - } - }); - }, - - sliceToGCode : function(settings, vertices, callback) { - var wid = new Date().toString(36); - var vertices = widget.getGeoVertices().buffer.slice(0); - send("slice", {settings:settings, id:wiwd, vertices:vertices, position:{x:0,y:0,z:0}}, function(reply) { - send("printSetup", {settings:settings}, function(reply) { - send("printGCode", {}, function(reply) { - callback(reply); - }); - }, null, [vertices]); - callback(reply); - }); - } - }; - - // start first worker - KIRI.work.restart(); - -} else { - - module = { exports: {} }; - - var loc = self.location, - host = loc.hostname, - ver = exports.VERSION, - time = function() { return new Date().getTime() }; - - console.log("kiri | init work | " + ver); - - // when running the server in 'web' mode, the obfuscated code is served as a - // unified ball via /code/work.js -- otherwise, map "localhost" to "debug" - // to debug unobfuscated code. if not, /js/ paths will 404. - if (host !== 'grid.space' && host !== 'debug') { - try { - [ - "license","ext-n3d","ext-clip","add-array", - "add-three","geo","geo-point","geo-debug","geo-bounds", - "geo-line","geo-slope","geo-polygon","geo-polygons","geo-gyroid", - "kiri-fill","kiri-slice","kiri-slicer","kiri-driver-fdm","kiri-driver-cam", - "kiri-driver-laser","kiri-widget","kiri-pack","kiri-print","kiri-codec" - ].forEach(function(scr) { - importScripts(["/js/",scr,".js","/v"+ver].join('')); - }) - } catch (e) { - console.log("unable to load worker scripts. kiri is likely in debug mode."); - } - } else { - importScripts("/code/work.js/"+ver); - base.debug.disable(); - } - - var base = self.base, - moto = self.moto, - dbug = base.debug, - util = base.util, - kiri = self.kiri, - Widget = kiri.Widget, - currentPrint, - cache = {}; - - var dispatch = { - decimate: function(vertices, send) { - vertices = new Float32Array(vertices), - vertices = Widget.pointsToVertices(Widget.verticesToPoints(vertices, true)); - send.done(vertices); - }, - - slice: function(data, send) { - var settings = data.settings, - vertices = new Float32Array(data.vertices), - position = data.position, - points = Widget.verticesToPoints(vertices); - - send.data({update:0.05, updateStatus:"slicing"}); - - var widget = kiri.newWidget(data.id).setPoints(points), - last = util.time(), - now; - - // do it here so cancel can work - cache[data.id] = widget; - - // fake mesh object to satisfy printing - widget.mesh = { - widget: widget, - position: position - }; - - widget.slice(settings, function(error) { - if (error) { - delete cache[data.id]; - send.data({error: error}); - } else { - var slices = widget.slices || []; - send.data({send_start: time()}); - send.data({ - topo: settings.synth.sendTopo ? widget.topo : null, - stats: widget.stats, - slices: slices.length - }); - slices.forEach(function(slice,index) { - send.data({index: index, slice: slice.encode()}); - }) - send.data({send_end: time()}); - } - send.done({done: true}); - // cache results for future printing - // cache[data.id] = widget; - }, function(update, msg) { - now = util.time(); - if (now - last < 10 && update < 0.99) return; - // on update - send.data({update: (0.05 + update * 0.95), updateStatus: msg}); - last = now; - }); - }, - - printSetup: function(data, send) { - var widgets = [], key; - for (key in cache) { - if (cache.hasOwnProperty(key)) widgets.push(cache[key]); - } - - send.data({update:0.05, updateStatus:"preview"}); - - currentPrint = kiri.newPrint(data.settings, widgets, data.id); - currentPrint.setup(false, function(update, msg) { - send.data({ - update: update, - updateStatus: msg - }); - }, function() { - send.done({ - done: true, - output: currentPrint.encodeOutput() - }); - }); - }, - - printGCode: function(data, send) { - currentPrint.exportGCode(false, function(gcode) { - send.done({ - gcode: gcode, - lines: currentPrint.lines, - bytes: currentPrint.bytes, - bounds: currentPrint.bounds, - distance: currentPrint.distance, - time: currentPrint.time - }); - }, function(line) { - send.data({line:line}); - }); - }, - - clear: function(data, send) { - if (!data.id) { - cache = {}; - currentPrint = null; - send.done({ clear: true }); - return; - } - var had = cache[data.id] !== undefined; - delete cache[data.id]; - send.done({ - id: data.id, - had: had, - has: cache[data.id] !== undefined - }); - }, - }; - - self.onmessage = function(e) { - var time_recv = util.time(), - msg = e.data, - run = dispatch[msg.task], - send = { - data : function(data,direct) { - self.postMessage({ - seq: msg.seq, - task: msg.task, - done: false, - data: data - },direct); - }, - done : function(data,direct) { - self.postMessage({ - seq: msg.seq, - task: msg.task, - done: true, - data: data - },direct); - } - }; - - if (run) { - var time_xfer = (time_recv - msg.time), - output = run(msg.data, send), - time_send = util.time(), - time_proc = time_send - time_recv; - - if (output) self.postMessage({ - seq: msg.seq, - task: msg.task, - time_send: time_xfer, - time_proc: time_proc, - // replaced on reply side - time_recv: util.time(), - data: output - }); - } else { - console.log({kiri_msg:e}); - } - }; - - // catch clipper alerts and convert to console messages - self.alert = function(o) { - console.log(o); - }; + running[seq] = {fn:onreply, async:async||false}; + worker.postMessage({ + seq: seq, + task: fn, + time: time(), + data: data + }, zerocopy); } + +KIRI.work = { + isSlicing : function() { + let current = 0; + for (let key in slicing) { + current++; + } + return current > 0; + }, + + restart : function() { + if (worker) { + worker.terminate(); + } + + for (let key in slicing) { + slicing[key]({error: "cancelled slicing"}); + } + + slicing = {}; + running = {}; + worker = new Worker(pre + "/code/worker.js/" + exports.VERSION); + + worker.onmessage = function(e) { + let now = time(), + reply = e.data, + record = running[reply.seq], + onreply = record.fn; + + if (reply.done) { + delete running[reply.seq]; + } + + // calculate and replace recv time + reply.time_recv = now - reply.time_recv; + + onreply(reply.data, reply); + }; + }, + + decimate : function(vertices, callback) { + vertices = vertices.buffer.slice(0); + send("decimate", vertices, function(output) { + callback(output); + }); + }, + + clear : function(widget) { + send("clear", widget ? {id:widget.id} : {}, function(reply) { + // console.log({clear:reply}); + }); + }, + + slice : function(settings, widget, callback) { + let vertices = widget.getGeoVertices().buffer.slice(0); + slicing[widget.id] = callback; + send("slice", { + id: widget.id, + settings: settings, + vertices: vertices, + position: widget.mesh.position + }, function(reply) { + if (reply.done || reply.error) delete slicing[widget.id]; + callback(reply); + }, null, [vertices]); + }, + + printSetup : function(settings, callback) { + send("printSetup", {settings:settings}, function(reply) { + callback(reply); + }); + }, + + printGCode : function(callback) { + let gcode = []; + let start = BASE.util.time(); + send("printGCode", {}, function(reply) { + if (reply.line) { + gcode.push(reply.line); + } else { + if (!reply.gcode) reply.gcode = gcode.join("\n"); + // console.log({printGCode:(BASE.util.time() - start)}); + callback(reply); + } + }); + }, + + sliceToGCode : function(settings, vertices, callback) { + vertices = widget.getGeoVertices().buffer.slice(0); + let wid = new Date().toString(36); + send("slice", {settings:settings, id:wiwd, vertices:vertices, position:{x:0,y:0,z:0}}, function(reply) { + send("printSetup", {settings:settings}, function(reply) { + send("printGCode", {}, function(reply) { + callback(reply); + }); + }, null, [vertices]); + callback(reply); + }); + } +}; + +// start worker +KIRI.work.restart(); diff --git a/js/kiri-worker.js b/js/kiri-worker.js new file mode 100644 index 00000000..29464751 --- /dev/null +++ b/js/kiri-worker.js @@ -0,0 +1,225 @@ +/** Copyright Stewart Allen -- All Rights Reserved */ +"use strict"; + +// this code runs in the web worker +module = { exports: {} }; + +let loc = self.location, + ver = exports.VERSION, + time = function() { return new Date().getTime() }; + host = loc.hostname, + debug = (host !== 'grid.space' && host !== 'debug'); + +console.log("kiri | init work | " + ver); + +// when running the server in 'web' mode, the obfuscated code is served as a +// unified ball via /code/work.js -- otherwise, map "localhost" to "debug" +// to debug unobfuscated code. if not, /js/ paths will 404. +if (debug) { + try { + [ + "license", + "ext-n3d", + "ext-clip", + "add-array", + "add-three", + "geo", + "geo-point", + "geo-debug", + "geo-bounds", + "geo-line", + "geo-slope", + "geo-polygon", + "geo-polygons", + "geo-gyroid", + "kiri-fill", + "kiri-slice", + "kiri-slicer", + "kiri-driver-fdm", + "kiri-driver-cam", + "kiri-driver-laser", + "kiri-widget", + "kiri-pack", + "kiri-print", + "kiri-codec" + ].forEach(function(scr) { + importScripts(["/js/",scr,".js","/v"+ver].join('')); + }) + } catch (e) { + console.log("unable to load worker scripts. kiri is likely in debug mode."); + } +} else { + importScripts("/code/work.js/"+ver); +} + +let base = self.base, + moto = self.moto, + dbug = base.debug, + util = base.util, + kiri = self.kiri, + Widget = kiri.Widget, + currentPrint, + cache = {}; + +if (!debug) { + base.debug.disable(); +} + +let dispatch = { + decimate: function(vertices, send) { + vertices = new Float32Array(vertices), + vertices = Widget.pointsToVertices(Widget.verticesToPoints(vertices, true)); + send.done(vertices); + }, + + slice: function(data, send) { + let settings = data.settings, + vertices = new Float32Array(data.vertices), + position = data.position, + points = Widget.verticesToPoints(vertices); + + send.data({update:0.05, updateStatus:"slicing"}); + + let widget = kiri.newWidget(data.id).setPoints(points), + last = util.time(), + now; + + // do it here so cancel can work + cache[data.id] = widget; + + // fake mesh object to satisfy printing + widget.mesh = { + widget: widget, + position: position + }; + + widget.slice(settings, function(error) { + if (error) { + delete cache[data.id]; + send.data({error: error}); + } else { + let slices = widget.slices || []; + send.data({send_start: time()}); + send.data({ + topo: settings.synth.sendTopo ? widget.topo : null, + stats: widget.stats, + slices: slices.length + }); + slices.forEach(function(slice,index) { + send.data({index: index, slice: slice.encode()}); + }) + send.data({send_end: time()}); + } + send.done({done: true}); + // cache results for future printing + // cache[data.id] = widget; + }, function(update, msg) { + now = util.time(); + if (now - last < 10 && update < 0.99) return; + // on update + send.data({update: (0.05 + update * 0.95), updateStatus: msg}); + last = now; + }); + }, + + printSetup: function(data, send) { + let widgets = [], key; + for (key in cache) { + if (cache.hasOwnProperty(key)) widgets.push(cache[key]); + } + + send.data({update:0.05, updateStatus:"preview"}); + + currentPrint = kiri.newPrint(data.settings, widgets, data.id); + currentPrint.setup(false, function(update, msg) { + send.data({ + update: update, + updateStatus: msg + }); + }, function() { + send.done({ + done: true, + output: currentPrint.encodeOutput() + }); + }); + }, + + printGCode: function(data, send) { + currentPrint.exportGCode(false, function(gcode) { + send.done({ + gcode: gcode, + lines: currentPrint.lines, + bytes: currentPrint.bytes, + bounds: currentPrint.bounds, + distance: currentPrint.distance, + time: currentPrint.time + }); + }, function(line) { + send.data({line:line}); + }); + }, + + clear: function(data, send) { + if (!data.id) { + cache = {}; + currentPrint = null; + send.done({ clear: true }); + return; + } + let had = cache[data.id] !== undefined; + delete cache[data.id]; + send.done({ + id: data.id, + had: had, + has: cache[data.id] !== undefined + }); + }, +}; + +self.onmessage = function(e) { + let time_recv = util.time(), + msg = e.data, + run = dispatch[msg.task], + send = { + data : function(data,direct) { + self.postMessage({ + seq: msg.seq, + task: msg.task, + done: false, + data: data + },direct); + }, + done : function(data,direct) { + self.postMessage({ + seq: msg.seq, + task: msg.task, + done: true, + data: data + },direct); + } + }; + + if (run) { + let time_xfer = (time_recv - msg.time), + output = run(msg.data, send), + time_send = util.time(), + time_proc = time_send - time_recv; + + if (output) self.postMessage({ + seq: msg.seq, + task: msg.task, + time_send: time_xfer, + time_proc: time_proc, + // replaced on reply side + time_recv: util.time(), + data: output + }); + } else { + console.log({kiri_msg:e}); + } +}; + +// catch clipper alerts and convert to console messages +self.alert = function(o) { + console.log(o); +}; diff --git a/js/kiri.js b/js/kiri.js index 717a7a69..d9343eae 100644 --- a/js/kiri.js +++ b/js/kiri.js @@ -1,5 +1,4 @@ -/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */ - +/** Copyright Stewart Allen -- All Rights Reserved */ "use strict"; self.kiri = (self.kiri || {}); @@ -37,6 +36,7 @@ self.kiri.license = exports.LICENSE; bedWidth: 1, bedDepth: 1, bedHeight: 1, + bedRound: 1, maxHeight: 1, extrudeAbs: 1, filamentSize: 1, @@ -253,6 +253,7 @@ self.kiri.license = exports.LICENSE; bedWidth: 300, // FDM/CAM/Laser bedDepth: 175, // FDM/CAM/Laser bedHeight: 2.5, // display only (deprecate) + bedRound: false, // FDM maxHeight: 150, // FDM filamentSize: 1.75, // FDM nozzleSize: 0.4, // FDM @@ -2069,6 +2070,7 @@ self.kiri.license = exports.LICENSE; var dev = settings.device, width, depth, height = Math.round(Math.max(dev.bedHeight, dev.bedWidth/100, dev.bedDepth/100)); + SPACE.platform.setRound(dev.bedRound); SPACE.platform.setGZOff(height/2 - 0.1); SPACE.platform.setSize( width = parseInt(dev.bedWidth), @@ -2441,11 +2443,6 @@ self.kiri.license = exports.LICENSE; UI.ctrlRight.style.display = show ? 'block' : 'none'; } - function eat(ev) { - ev.cancelBubble = true; - ev.preventDefault(); - } - /** ****************************************************************** * LETS_GET_THIS_PARTY_STARTED() ******************************************************************* */ @@ -2482,6 +2479,7 @@ self.kiri.license = exports.LICENSE; showSlices(); }); SPACE.platform.onMove(saveSettings); + SPACE.platform.setRound(true); set(UI, { container: container, @@ -2523,6 +2521,7 @@ self.kiri.license = exports.LICENSE; setDeviceExtrusion: UC.newBoolean(LANG.dev_extab, onBooleanClick, {title:LANG.dev_extab_desc}), setDeviceOrigin: UC.newBoolean(LANG.dev_orgc, onBooleanClick, {title:LANG.dev_orgc_desc}), setDeviceOriginTop: UC.newBoolean(LANG.dev_orgt, onBooleanClick, {title:LANG.dev_orgt_desc, modes:CAM}), + setDeviceRound: UC.newBoolean(LANG.dev_bedc, onBooleanClick, {title:LANG.dev_bedc_desc, modes:FDM}), setDevice: UC.newGroup("gcode", $('device')), setDeviceFan: UC.newInput(LANG.dev_fanp, {title:LANG.dev_fanp_desc, modes:FDM, size:15}), @@ -3254,6 +3253,7 @@ self.kiri.license = exports.LICENSE; settings: { bed_width: parseInt(UI.setDeviceWidth.value) || 300, bed_depth: parseInt(UI.setDeviceDepth.value) || 175, + bed_circle: UI.setDeviceRound.checked, build_height: parseInt(UI.setDeviceHeight.value) || 150, nozzle_size: parseFloat(UI.setDeviceNozzle.value) || 0.4, filament_diameter: parseFloat(UI.setDeviceFilament.value) || 1.75, @@ -3295,11 +3295,11 @@ self.kiri.license = exports.LICENSE; local = isLocalDevice(devicename), dproc = settings.devproc[devicename], mode = getMode(); - settings.device = { bedHeight: 2.5, bedWidth: valueOf(set.bed_width, 300), bedDepth: valueOf(set.bed_depth, 175), + bedRound: valueOf(set.bed_circle, false), maxHeight: valueOf(set.build_height, 150), nozzleSize: valueOf(set.nozzle_size, 0.4), filamentSize: valueOf(set.filament_diameter, 1.75), @@ -3336,6 +3336,7 @@ self.kiri.license = exports.LICENSE; UI.setDeviceHeight.value = dev.maxHeight; UI.setDeviceExtrusion.checked = dev.extrudeAbs; UI.setDeviceOrigin.checked = proc.outputOriginCenter; + UI.setDeviceRound.checked = dev.bedRound; // FDM UI.setDeviceFan.value = dev.gcodeFan; UI.setDeviceTrack.value = dev.gcodeTrack; @@ -3363,6 +3364,7 @@ self.kiri.license = exports.LICENSE; UI.setDeviceExtrusion, UI.setDeviceOrigin, UI.setDeviceOriginTop, + UI.setDeviceRound, UI.setDeviceFan, UI.setDeviceTrack, UI.setDeviceLayer, diff --git a/js/license.js b/js/license.js index dffbdeb0..8e019c09 100644 --- a/js/license.js +++ b/js/license.js @@ -1,7 +1,7 @@ var exports = { COPYRIGHT:"Copyright (C) 2014-2019 Stewart Allen - All Rights Reserved", LICENSE:"See the license.md file included with the source distribution", - VERSION:"1.6.3" + VERSION:"1.6.4" }; if (!module) var module = {}; module.exports = exports; diff --git a/js/moto-space.js b/js/moto-space.js index 5c21ea4c..df75b6ea 100644 --- a/js/moto-space.js +++ b/js/moto-space.js @@ -1,12 +1,11 @@ -/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */ - +/** Copyright Stewart Allen -- All Rights Reserved */ "use strict"; -var gs_moto_space = exports; +let gs_moto_space = exports; (function() { - var WIN = window, + let WIN = window, DOC = document, SCENE = new THREE.Scene(), WORLD = new THREE.Group(), @@ -58,7 +57,16 @@ var gs_moto_space = exports; light5, camera, renderer, - container; + container, + isRound = false, + platformMaterial = new THREE.MeshPhongMaterial({ + color: 0xcccccc, + specular: 0xcccccc, + shininess: 5, + transparent: true, + opacity: 0.6, + side: THREE.DoubleSide + }); /** ****************************************************************** * TWEENing Functions @@ -72,7 +80,7 @@ var gs_moto_space = exports; tweenit(); function tweenCamPan(x,y,z) { - var pos = viewControl.getPosition(); + let pos = viewControl.getPosition(); pos.panX = x; pos.panY = y; pos.panZ = z; @@ -80,7 +88,7 @@ var gs_moto_space = exports; } function tweenCam(pos) { - var tf = function () { + let tf = function () { viewControl.setPosition(this); refresh(); }; @@ -91,7 +99,7 @@ var gs_moto_space = exports; } function tweenPlatform(w,h,d) { - var from = {x: platform.scale.x, y: platform.scale.y, z: platform.scale.z}, + let from = {x: platform.scale.x, y: platform.scale.y, z: platform.scale.z}, to = {x:w, y:h, z:d}, gridMajor = gridUnitMajor, gridMinor = gridUnitMinor, @@ -128,14 +136,14 @@ var gs_moto_space = exports; } function addEventHandlers(el, pairs) { - for (var i=0; i= -w && i <= w) { - if (i % unitMajor === 0) majors.append({x:i, y:-h, z:zp}).append({x:i, y:h, z:zp}); - else if (minors && i % unitMinor === 0) minors.append({x:i, y:-h, z:zp}).append({x:i, y:h, z:zp}); + let oh = isRound ? Math.sqrt(1-(i/xo)*(i/xo)) * h : h; + if (i % unitMajor === 0) majors.append({x:i, y:-oh, z:zp}).append({x:i, y:oh, z:zp}); + else if (minors && i % unitMinor === 0) minors.append({x:i, y:-oh, z:zp}).append({x:i, y:oh, z:zp}); } } for (i = -yo; i <= yo; i++) { if (i >= -h && i <= h) { - if (i % unitMajor === 0) majors.append({x:-w, y:i, z:zp}).append({x:w, y:i, z:zp}); - else if (minors && i % unitMinor === 0) minors.append({x:-w, y:i, z:zp}).append({x:w, y:i, z:zp}); + let ow = isRound ? Math.sqrt(1-(i/yo)*(i/yo)) * w : w; + if (i % unitMajor === 0) majors.append({x:-ow, y:i, z:zp}).append({x:ow, y:i, z:zp}); + else if (minors && i % unitMinor === 0) minors.append({x:-ow, y:i, z:zp}).append({x:ow, y:i, z:zp}); } } gridView.add(makeLinesFromPoints(majors, colorMajor || 0x999999, 1)); @@ -259,7 +275,7 @@ var gs_moto_space = exports; function keyHandler(evt) { if (!defaultKeys || inputHasFocus()) return false; if (evt.metaKey) return false; - var handled = true; + let handled = true; switch (evt.charCode) { case cca('z'): Space.view.reset(); @@ -296,7 +312,7 @@ var gs_moto_space = exports; function makeLinesFromPoints(points, color, width) { if (points.length % 2 != 0) throw "invalid line : "+points.length; - var geo = new THREE.Geometry(), + let geo = new THREE.Geometry(), i = 0, p1, p2, mesh; while (i < points.length) { p1 = points[i++]; @@ -313,8 +329,8 @@ var gs_moto_space = exports; } function intersect(objects, recurse) { - var lookAt = new THREE.Vector3(mouse.x, mouse.y, 0.0).unproject(camera); - var ray = new THREE.Raycaster(camera.position, lookAt.sub(camera.position).normalize()); + let lookAt = new THREE.Vector3(mouse.x, mouse.y, 0.0).unproject(camera); + let ray = new THREE.Raycaster(camera.position, lookAt.sub(camera.position).normalize()); return ray.intersectObjects(objects, recurse); } @@ -326,16 +342,16 @@ var gs_moto_space = exports; if (event.target === renderer.domElement) { DOC.activeElement.blur(); event.preventDefault(); - var selection = null, + let selection = null, trackTo = alignedTracking ? trackPlane : platform; if (mouseDownSelect) selection = mouseDownSelect(); if (selection && selection.length > 0) { trackTo.visible = true; - var int = intersect(selection.slice().append(trackTo), false); + let int = intersect(selection.slice().append(trackTo), false); trackTo.visible = false; if (int.length > 0) { - var trackInt, selectInt; - for (var i=0; i 0) { - var int = intersect(selection, selectRecurse); + let int = intersect(selection, selectRecurse); if (int.length > 0) { mouseUpSelect(int[0], event); refresh = true; @@ -396,10 +412,10 @@ var gs_moto_space = exports; } function onMouseMove(event) { - var int, vis; + let int, vis; if (viewControl.enabled) { event.preventDefault(); - var selection = mouseHover ? mouseHover() : null; + let selection = mouseHover ? mouseHover() : null; if (selection && selection.length > 0) { int = intersect(selection, selectRecurse); if (int.length > 0) mouseHover(int[0], event); @@ -413,13 +429,13 @@ var gs_moto_space = exports; } } else if (mouseDragPoint && mouseDrag && mouseDrag()) { event.preventDefault(); - var trackTo = alignedTracking ? trackPlane : platform; + let trackTo = alignedTracking ? trackPlane : platform; trackTo.visible = true; int = intersect([trackTo], false); trackTo.visible = false; if (int.length > 0 && int[0].object === trackTo) { - var delta = mouseDragPoint.clone().sub(int[0].point); - var offset = mouseDragStart.clone().sub(int[0].point); + let delta = mouseDragPoint.clone().sub(int[0].point); + let offset = mouseDragStart.clone().sub(int[0].point); mouseDragPoint = int[0].point; mouseDrag({x: -delta.x, y: delta.z}, offset.multiplyVectors(offset, trackDelta)); requestRefresh(); @@ -435,7 +451,7 @@ var gs_moto_space = exports; * Space Object ******************************************************************* */ - var Space = { + let Space = { alignTracking: alignTracking, addEventListener: addEventListener, addEventHandlers: addEventHandlers, @@ -480,7 +496,31 @@ var gs_moto_space = exports; size: function() { return platform.scale }, isVisible: function() { return platform.visible }, - showGrid: function(b) { gridView.visible = b } + showGrid: function(b) { gridView.visible = b }, + + setRound: function(bool) { + let current = platform; + isRound = bool; + if (bool) { + platform = new THREE.Mesh( + new THREE.CylinderGeometry(.5, .5, 1, 60), + platformMaterial + ); + platform.rotation.x = 0; + } else { + platform = new THREE.Mesh( + new THREE.BoxGeometry(1, 1, 1), + platformMaterial + ); + platform.rotation.x = -PI2; + } + + platform.position.y = current.position.y; + platform.visible = current.visible; + + SCENE.remove(current); + SCENE.add(platform); + } }, view: { @@ -567,14 +607,7 @@ var gs_moto_space = exports; platform = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), - new THREE.MeshPhongMaterial({ - color: 0xcccccc, - specular: 0xcccccc, - shininess: 5, - transparent: true, - opacity: 0.6, - side: THREE.DoubleSide - }) + platformMaterial ); platform.position.y = platformZOff; @@ -588,7 +621,7 @@ var gs_moto_space = exports; trackPlane.visible = false; trackPlane.rotation.x = PI2; - var sky = new THREE.Mesh( + let sky = new THREE.Mesh( new THREE.BoxGeometry(50000, 50000, 50000, 1, 1, 1), new THREE.MeshBasicMaterial({ color: skyColor, side: THREE.DoubleSide }) ), diff --git a/js/web-server.js b/js/web-server.js index 4ca580a6..0671aeb1 100644 --- a/js/web-server.js +++ b/js/web-server.js @@ -1,6 +1,4 @@ -/** - * Copyright Stewart Allen -- All Rights Reserved - */ +/** Copyright Stewart Allen -- All Rights Reserved */ Array.prototype.contains = function(v) { return this.indexOf(v) >= 0; @@ -844,7 +842,7 @@ let ver = require('../js/license.js'), ], worker : [ "license", - "kiri-work" + "kiri-worker" ] }, code = {}, diff --git a/notes.md b/notes.md index c9704811..ad83ffc1 100644 --- a/notes.md +++ b/notes.md @@ -1,6 +1,5 @@ # Kiri:Moto todo -* circular bed support for delta printers * hide the bed with a checkbox? indication of part outside printable area? * set page background color? or dark mode? * better small screen support (on screen button for hiding side panels, compact selectors) diff --git a/web/kiri/filter/FDM/Atom.v2 b/web/kiri/filter/FDM/Atom.v2 index dfc61222..dd16941f 100644 --- a/web/kiri/filter/FDM/Atom.v2 +++ b/web/kiri/filter/FDM/Atom.v2 @@ -21,6 +21,7 @@ "origin_center": true, "bed_width": 210, "bed_depth": 210, + "bed_circle": true, "build_height": 320 } } diff --git a/web/kiri/filter/FDM/DeltaMaker.2T b/web/kiri/filter/FDM/DeltaMaker.2T index 6b00a725..3520c616 100644 --- a/web/kiri/filter/FDM/DeltaMaker.2T +++ b/web/kiri/filter/FDM/DeltaMaker.2T @@ -25,6 +25,7 @@ "origin_center": true, "bed_width": 240, "bed_depth": 240, + "bed_circle": true, "build_height": 480 } } diff --git a/web/kiri/filter/FDM/DeltaMaker.Original b/web/kiri/filter/FDM/DeltaMaker.Original index 947a0d34..b079deac 100644 --- a/web/kiri/filter/FDM/DeltaMaker.Original +++ b/web/kiri/filter/FDM/DeltaMaker.Original @@ -25,6 +25,7 @@ "origin_center": true, "bed_width": 240, "bed_depth": 240, + "bed_circle": true, "build_height": 260 } }