2020-02-29 20:13:49 -05:00
/** Copyright Stewart Allen -- All Rights Reserved */
2017-04-18 17:09:33 -04:00
"use strict" ;
self . kiri = ( self . kiri || { } ) ;
self . kiri . version = exports . VERSION ;
self . kiri . copyright = exports . COPYRIGHT ;
self . kiri . license = exports . LICENSE ;
( function ( ) {
if ( kiri . init ) return ;
2018-01-10 20:04:51 -05:00
function genID ( ) {
while ( true ) {
var k = Math . round ( Math . random ( ) * 9999999999 ) . toString ( 36 ) ;
if ( k . length >= 4 && k . length <= 8 ) return k ;
}
}
2017-04-18 17:09:33 -04:00
var iOS = /(iPad|iPhone|iPod)/g . test ( navigator . userAgent ) ,
// ---------------
MODES = {
FDM : 1 , // fused deposition modeling (also FFF)
LASER : 2 , // laser cutting
CAM : 3 // 3 axis milling/machining
} ,
VIEWS = {
ARRANGE : 1 ,
SLICE : 2 ,
PREVIEW : 3
} ,
2017-11-10 15:02:14 -05:00
// --------------- settings filters (for loading/saving)
2017-04-18 17:09:33 -04:00
sf = {
fdm : {
2017-11-10 15:02:14 -05:00
// fields permitted in FDM:Device
2017-04-18 17:09:33 -04:00
d : {
bedWidth : 1 ,
bedDepth : 1 ,
bedHeight : 1 ,
2020-02-29 20:13:49 -05:00
bedRound : 1 ,
2017-04-18 17:09:33 -04:00
maxHeight : 1 ,
2017-10-10 15:38:47 -04:00
extrudeAbs : 1 ,
2020-03-03 20:06:10 -05:00
originCenter : 1 ,
2017-04-18 17:09:33 -04:00
filamentSize : 1 ,
nozzleSize : 1 ,
gcodePre : 1 ,
gcodePost : 1 ,
2018-01-06 10:55:48 -05:00
gcodeProc : 1 ,
2018-02-01 09:31:03 -05:00
gcodePause : 1 ,
2018-01-06 10:55:48 -05:00
gcodeFExt : 1 ,
2017-04-18 17:09:33 -04:00
gcodeFan : 1 ,
2018-01-02 12:36:03 -05:00
gcodeTrack : 1 ,
gcodeLayer : 1
2017-04-18 17:09:33 -04:00
} ,
2017-11-10 15:02:14 -05:00
// fields permitted in FDM:Process
2017-04-18 17:09:33 -04:00
p : {
processName : 1 ,
sliceHeight : 1 ,
sliceShells : 1 ,
sliceFillAngle : 1 ,
sliceFillOverlap : 1 ,
sliceFillSparse : 1 ,
2019-05-02 15:09:54 -04:00
sliceFillType : 1 ,
2017-04-18 17:09:33 -04:00
sliceSupportEnable : 1 ,
sliceSupportDensity : 1 ,
sliceSupportOffset : 1 ,
2018-01-24 19:01:34 -05:00
sliceSupportGap : 1 ,
2017-04-18 17:09:33 -04:00
sliceSupportSize : 1 ,
sliceSupportArea : 1 ,
sliceSupportExtra : 1 ,
sliceSupportSpan : 1 ,
sliceSolidMinArea : 1 ,
sliceSolidLayers : 1 ,
sliceBottomLayers : 1 ,
sliceTopLayers : 1 ,
2017-12-15 08:54:39 -05:00
firstSliceHeight : 1 ,
firstLayerRate : 1 ,
2018-01-18 21:53:46 -05:00
firstLayerFillRate : 1 ,
2018-01-19 19:23:02 -05:00
firstLayerPrintMult : 1 ,
2019-01-25 09:24:11 -05:00
firstLayerNozzleTemp : 1 ,
2019-03-30 17:06:16 -04:00
firstLayerBedTemp : 1 ,
2018-01-14 14:08:50 -05:00
outputRaft : 1 ,
2018-01-23 18:09:34 -05:00
outputRaftSpacing : 1 ,
2017-04-18 17:09:33 -04:00
outputTemp : 1 ,
outputFanMax : 1 ,
outputBedTemp : 1 ,
outputFeedrate : 1 ,
2017-12-06 21:15:37 -05:00
outputFinishrate : 1 ,
2017-04-18 17:09:33 -04:00
outputSeekrate : 1 ,
outputShellMult : 1 ,
outputFillMult : 1 ,
2017-11-10 15:02:14 -05:00
outputSparseMult : 1 ,
2019-05-25 13:50:00 -04:00
outputFanLayer : 1 ,
2017-04-18 17:09:33 -04:00
outputRetractDist : 1 ,
outputRetractSpeed : 1 ,
2018-01-13 13:18:17 -05:00
outputRetractDwell : 1 ,
2017-04-18 17:09:33 -04:00
outputBrimCount : 1 ,
outputBrimOffset : 1 ,
2018-01-11 08:57:46 -05:00
outputShortPoly : 1 ,
2019-05-04 09:56:21 -04:00
outputMinSpeed : 1 ,
2019-04-02 19:08:19 -07:00
outputCoastDist : 1 ,
outputWipeDistance : 1 ,
2018-03-06 20:57:26 -05:00
sliceMinHeight : 1 ,
2018-02-12 08:42:33 -05:00
// detectThinWalls: 1,
2018-02-07 23:29:52 -05:00
antiBacklash : 1 ,
2018-02-28 10:10:57 -05:00
zHopDistance : 1 ,
2020-03-05 22:26:33 -05:00
polishLayers : 1 ,
polishSpeed : 1 ,
2019-04-23 12:58:40 -04:00
outputLayerRetract : 1 ,
2019-02-11 13:31:17 -05:00
gcodeNozzle : 1 ,
2018-02-21 18:04:27 -05:00
gcodePauseLayers : 1 ,
2018-02-13 21:55:53 -05:00
outputClockwise : 1 ,
outputOriginCenter : 1 ,
outputInvertX : 1 ,
outputInvertY : 1
2017-04-18 17:09:33 -04:00
}
} ,
cam : {
2017-11-10 15:02:14 -05:00
// fields permitted in CAM:Device
2017-04-18 17:09:33 -04:00
d : {
bedWidth : 1 ,
bedDepth : 1 ,
bedHeight : 1 ,
2020-03-03 20:06:10 -05:00
originCenter : 1 ,
2017-04-18 17:09:33 -04:00
spindleMax : 1 ,
gcodePre : 1 ,
gcodePost : 1 ,
gcodeDwell : 1 ,
gcodeChange : 1 ,
2018-04-21 18:06:39 -04:00
gcodeSpindle : 1 ,
2017-04-18 17:09:33 -04:00
gcodeFExt : 1 ,
gcodeSpace : 1 ,
gcodeStrip : 1
} ,
2017-11-10 15:02:14 -05:00
// fields permitted in CAM:Process
2017-04-18 17:09:33 -04:00
p : {
processName : 1 ,
2020-02-05 16:19:36 -05:00
camFastFeed : 1 ,
2017-04-18 17:09:33 -04:00
roughingTool : 1 ,
roughingSpindle : 1 ,
roughingDown : 1 ,
roughingOver : 1 ,
roughingSpeed : 1 ,
roughingPlunge : 1 ,
roughingStock : 1 ,
2020-02-15 11:30:02 -05:00
camPocketOnlyRough : 1 ,
2017-04-18 17:09:33 -04:00
roughingOn : 1 ,
finishingTool : 1 ,
finishingSpindle : 1 ,
finishingDown : 1 ,
finishingOver : 1 ,
finishingAngle : 1 ,
finishingSpeed : 1 ,
finishingPlunge : 1 ,
finishingOn : 1 ,
finishingXOn : 1 ,
finishingYOn : 1 ,
finishCurvesOnly : 1 ,
2020-02-15 11:30:02 -05:00
camPocketOnlyFinish : 1 ,
2017-04-18 17:09:33 -04:00
drillTool : 1 ,
drillSpindle : 1 ,
drillDownSpeed : 1 ,
drillDown : 1 ,
drillDwell : 1 ,
drillLift : 1 ,
drillingOn : 1 ,
2020-03-05 11:53:54 -05:00
camTabsAngle : 1 ,
camTabsCount : 1 ,
2017-04-18 17:09:33 -04:00
camTabsWidth : 1 ,
camTabsHeight : 1 ,
camTabsOn : 1 ,
camPocketOnly : 1 ,
camDepthFirst : 0 ,
camEaseDown : 1 ,
camOriginTop : 1 ,
camTolerance : 1 ,
camZTopOffset : 1 ,
camZBottom : 1 ,
camZClearance : 1 ,
camStockX : 1 ,
camStockY : 1 ,
camStockZ : 1 ,
2020-02-25 20:42:48 -05:00
camStockOffset : 1 ,
2017-04-18 17:09:33 -04:00
outputClockwise : 1 ,
outputOriginCenter : 1 ,
outputInvertX : 1 ,
outputInvertY : 1
}
} ,
laser : {
2017-11-10 15:02:14 -05:00
// fields permitted in Laser:Device
2017-04-18 17:09:33 -04:00
d : {
bedWidth : 1 ,
bedDepth : 1 ,
} ,
2017-11-10 15:02:14 -05:00
// fields permitted in Laser:Process
2017-04-18 17:09:33 -04:00
p : {
processName : 1 ,
laserOffset : 1 ,
laserSliceHeight : 1 ,
2019-05-24 09:06:51 -04:00
laserSliceSingle : 1 ,
2017-04-18 17:09:33 -04:00
outputTileSpacing : 1 ,
outputTileScaling : 1 ,
outputLaserPower : 1 ,
outputLaserSpeed : 1 ,
2019-05-24 09:06:51 -04:00
outputLaserGroup : 1 ,
2017-04-18 17:09:33 -04:00
outputOriginCenter : 1 ,
outputInvertX : 1 ,
outputInvertY : 1
}
}
} ,
2017-11-10 15:02:14 -05:00
// --------------- (default)
2017-04-18 17:09:33 -04:00
settings = {
2019-05-02 15:09:54 -04:00
infill : [
2019-05-02 21:52:54 -04:00
{ name : "vase" } ,
{ name : "hex" } ,
{ name : "grid" } ,
{ name : "gyroid" } ,
{ name : "triangle" }
2019-05-02 15:09:54 -04:00
] ,
2020-03-08 11:04:07 -04:00
units : [
{ name : "mm" } ,
{ name : "in" }
] ,
2018-01-02 20:04:21 -05:00
// CAM only
2020-03-03 20:06:10 -05:00
origin : { } ,
2020-03-01 21:24:14 -05:00
stock : { } ,
2017-04-18 17:09:33 -04:00
tools : [
{
id : 1000 ,
number : 1 ,
type : "endmill" ,
name : "end 1/4" ,
metric : false ,
flute _diam : 0.25 ,
flute _len : 0 ,
shaft _diam : 0.25 ,
shaft _len : 0
} ,
{
id : 1001 ,
number : 2 ,
type : "endmill" ,
name : "end 1/8" ,
metric : false ,
flute _diam : 0.125 ,
flute _len : 0 ,
shaft _diam : 0.125 ,
shaft _len : 0
} ,
{
id : 1002 ,
number : 3 ,
type : "endmill" ,
name : "end 1/16" ,
metric : false ,
flute _diam : 0.0625 ,
flute _len : 0 ,
shaft _diam : 0.0625 ,
shaft _len : 0
}
] ,
2018-01-02 20:04:21 -05:00
// FDM/CAM/Laser
2017-04-18 17:09:33 -04:00
device : {
2018-01-02 20:04:21 -05:00
bedWidth : 300 , // FDM/CAM/Laser
bedDepth : 175 , // FDM/CAM/Laser
bedHeight : 2.5 , // display only (deprecate)
2020-03-03 20:06:10 -05:00
bedRound : false , // FDM
originCenter : false , // FDM/CAM
2018-01-02 20:04:21 -05:00
maxHeight : 150 , // FDM
2017-04-18 17:09:33 -04:00
filamentSize : 1.75 , // FDM
2018-01-02 20:04:21 -05:00
nozzleSize : 0.4 , // FDM
spindleMax : 0 , // CAM
gcodePre : [ ] , // FDM/CAM header script
gcodePost : [ ] , // FDM/CAM footer script
2018-02-01 09:31:03 -05:00
gcodeProc : "" , // FDM post processor script (encoding, etc)
gcodePause : [ ] , // FDM pause script
2018-01-02 20:04:21 -05:00
gcodeFan : "" , // FDM fan command
gcodeTrack : "" , // FDM progress command
gcodeLayer : "" , // FDM layer output
2020-02-05 17:51:48 -05:00
gcodeDwell : [ "G4 P{time}" ] , // CAM dwell script
2018-04-21 18:06:39 -04:00
gcodeChange : [ "M6 T{tool}" ] , // CAM tool change script
gcodeSpindle : [ "M3 S{speed}" ] , // CAM spindle speed
2018-01-02 20:04:21 -05:00
gcodeFExt : "" , // CAM file extension
gcodeSpace : "" , // CAM token spacing
gcodeStrip : true // CAM strip comments
2017-04-18 17:09:33 -04:00
} ,
2018-01-02 20:04:21 -05:00
// FDM/CAM/Laser
2017-04-18 17:09:33 -04:00
process : {
processName : "default" ,
2017-11-10 15:02:14 -05:00
// --- FDM ---
2017-04-18 17:09:33 -04:00
sliceHeight : 0.25 ,
2019-01-18 20:41:10 -05:00
sliceShells : 3 ,
2017-04-18 17:09:33 -04:00
sliceFillAngle : 45 ,
2018-01-14 13:15:05 -05:00
sliceFillOverlap : 0.3 ,
2017-04-18 17:09:33 -04:00
sliceFillSparse : 0.5 ,
2019-05-02 15:09:54 -04:00
sliceFillType : "hex" ,
2017-04-18 17:09:33 -04:00
sliceSupportEnable : false ,
sliceSupportDensity : 0.25 ,
sliceSupportOffset : 1.0 ,
2018-01-24 19:01:34 -05:00
sliceSupportGap : 1 ,
2018-01-16 16:01:53 -05:00
sliceSupportSize : 10 ,
2017-04-18 17:09:33 -04:00
sliceSupportArea : 1 ,
2018-01-16 16:01:53 -05:00
sliceSupportExtra : 0 ,
2017-04-18 17:09:33 -04:00
sliceSupportSpan : 6 ,
2019-01-18 14:23:30 -05:00
sliceSolidMinArea : 1 ,
2018-02-11 07:49:57 -05:00
sliceSolidLayers : 3 ,
2019-01-18 20:41:10 -05:00
sliceBottomLayers : 3 ,
2018-02-11 07:49:57 -05:00
sliceTopLayers : 3 ,
2017-04-18 17:09:33 -04:00
2017-12-15 08:54:39 -05:00
firstSliceHeight : 0.25 ,
firstLayerRate : 30 ,
2018-01-18 21:53:46 -05:00
firstLayerFillRate : 40 ,
2018-01-19 19:23:02 -05:00
firstLayerPrintMult : 1.0 ,
2018-01-14 14:08:50 -05:00
outputRaft : false ,
2018-01-23 18:09:34 -05:00
outputRaftSpacing : 0.2 ,
2019-01-25 09:24:11 -05:00
firstLayerNozzleTemp : 0 ,
2019-03-30 17:06:16 -04:00
firstLayerBedTemp : 0 ,
2017-11-10 15:02:14 -05:00
2018-07-30 23:06:16 +02:00
outputTemp : 200 ,
2017-11-10 15:02:14 -05:00
outputFanMax : 255 ,
outputBedTemp : 0 ,
2018-01-16 16:01:53 -05:00
outputFeedrate : 80 ,
2017-12-06 21:15:37 -05:00
outputFinishrate : 60 ,
2018-01-16 16:01:53 -05:00
outputSeekrate : 100 ,
2019-01-18 20:41:10 -05:00
outputShellMult : 1.2 ,
2018-01-14 13:15:05 -05:00
outputFillMult : 1.2 ,
2019-01-18 20:41:10 -05:00
outputSparseMult : 1.2 ,
2019-05-25 13:50:00 -04:00
outputFanLayer : 1 ,
2018-02-11 07:49:57 -05:00
outputRetractDist : 1.0 ,
2018-01-16 16:01:53 -05:00
outputRetractSpeed : 40 ,
2018-02-11 07:49:57 -05:00
outputRetractDwell : 30 ,
2017-11-10 15:02:14 -05:00
outputBrimCount : 2 ,
2018-02-11 07:49:57 -05:00
outputBrimOffset : 2 ,
2019-05-04 09:56:21 -04:00
outputShortPoly : 50.0 ,
outputMinSpeed : 15.0 ,
2019-04-02 19:08:19 -07:00
outputCoastDist : 0 ,
outputWipeDistance : 0 ,
2018-03-06 20:57:26 -05:00
sliceMinHeight : 0 ,
2017-12-31 11:27:21 -05:00
detectThinWalls : false ,
2019-01-18 20:41:10 -05:00
antiBacklash : 1 ,
zHopDistance : 0.2 ,
2020-03-05 22:26:33 -05:00
polishLayers : 0 ,
polishSpeed : 40 ,
2019-04-23 12:58:40 -04:00
outputLayerRetract : false ,
2019-02-11 13:31:17 -05:00
gcodeNozzle : 0 ,
2018-02-21 18:04:27 -05:00
gcodePauseLayers : "" ,
2017-11-10 15:02:14 -05:00
// --- LASER ---
2017-04-18 17:09:33 -04:00
laserOffset : 0.25 ,
laserSliceHeight : 1 ,
2019-05-24 09:06:51 -04:00
laserSliceSingle : false ,
2017-04-18 17:09:33 -04:00
2019-05-24 09:06:51 -04:00
outputTileSpacing : 1 ,
outputTileScaling : 1 ,
outputLaserPower : 100 ,
outputLaserSpeed : 1000 ,
outputLaserGroup : true ,
2017-11-10 15:02:14 -05:00
// --- CAM ---
2020-02-05 16:19:36 -05:00
camFastFeed : 6000 ,
2017-04-18 17:09:33 -04:00
roughingTool : 1000 ,
roughingSpindle : 1000 ,
roughingDown : 2 ,
roughingOver : 0.5 ,
roughingSpeed : 1000 ,
roughingPlunge : 250 ,
roughingStock : 0 ,
2020-02-15 11:30:02 -05:00
camPocketOnlyRough : false ,
2017-04-18 17:09:33 -04:00
roughingOn : true ,
finishingTool : 1000 ,
finishingSpindle : 1000 ,
finishingDown : 3 ,
finishingOver : 0.5 ,
finishingAngle : 85 ,
finishingSpeed : 800 ,
finishingPlunge : 250 ,
finishingOn : true ,
finishingXOn : true ,
finishingYOn : true ,
finishCurvesOnly : false ,
2020-02-15 11:30:02 -05:00
camPocketOnlyFinish : false ,
2017-04-18 17:09:33 -04:00
drillTool : 1000 ,
drillSpindle : 1000 ,
drillDownSpeed : 250 ,
drillDown : 5 ,
drillDwell : 250 ,
drillLift : 2 ,
drillingOn : false ,
2020-03-05 11:53:54 -05:00
camTabsAngle : 0 ,
camTabsCount : 4 ,
2017-04-18 17:09:33 -04:00
camTabsWidth : 5 ,
camTabsHeight : 5 ,
camTabsOn : false ,
camPocketOnly : false ,
camDepthFirst : false ,
camEaseDown : false ,
camOriginTop : true ,
camTolerance : 0.15 ,
camZTopOffset : 0 ,
camZBottom : 0 ,
camZClearance : 1 ,
camStockX : 0 ,
camStockY : 0 ,
camStockZ : 0 ,
2020-02-25 20:42:48 -05:00
camStockOffset : true ,
2017-04-18 17:09:33 -04:00
outputClockwise : true ,
2017-11-10 15:02:14 -05:00
// --- shared FDM/Laser/CAM ---
2017-04-18 17:09:33 -04:00
outputOriginCenter : true ,
outputInvertX : false ,
outputInvertY : false
} ,
2020-02-10 17:41:59 -05:00
// current process name
cproc : {
FDM : "default" ,
CAM : "default" ,
LASER : "default"
} ,
2017-04-18 17:09:33 -04:00
// saved processes by name
sproc : {
FDM : { } ,
CAM : { } ,
LASER : { }
} ,
// cached device settings by mode
cdev : {
FDM : null ,
CAM : null
} ,
// now they're called devices instead of gcode filters
filter : {
FDM : "Any.Generic.Marlin" ,
CAM : "Any.Generic.Grbl"
} ,
// custom devices by name
devices : {
} ,
2019-04-12 09:45:52 -04:00
// favorite devices
favorites : {
} ,
2018-01-31 10:42:55 -05:00
// map of device to last process setting (name)
devproc : {
} ,
2017-04-18 17:09:33 -04:00
layers : {
layerOutline : true ,
layerTrace : true ,
layerFacing : true ,
layerRough : true ,
layerFinish : true ,
layerFinishX : true ,
layerFinishY : true ,
layerDelta : false ,
layerSolid : false ,
layerSparse : true ,
layerFill : true ,
layerSupport : true ,
2017-11-13 13:00:04 -05:00
layerPrint : false
2017-04-18 17:09:33 -04:00
} ,
synth : {
// set in updateSettingsFromFields()
fillOffsetMult : 0 ,
diffOffsetMult : 0
} ,
controller : {
view : null ,
zoomSpeed : 1.0 ,
2020-02-25 20:42:48 -05:00
reverseZoom : true ,
2020-03-01 19:00:36 -05:00
showOrigin : false ,
2020-02-25 20:42:48 -05:00
freeLayout : true ,
2020-03-08 11:04:07 -04:00
autoLayout : true ,
alignTop : false ,
units : "mm"
2017-04-18 17:09:33 -04:00
} ,
2018-01-10 20:04:51 -05:00
mode : 'FDM' ,
id : genID ( ) ,
ver : 1
2017-04-18 17:09:33 -04:00
} ,
settingsDefault = settings ,
autoDecimate = true ,
// ---------------
SELF = self ,
MOTO = moto ,
KIRI = SELF . kiri ,
BASE = SELF . base ,
UTIL = BASE . util ,
DBUG = BASE . debug ,
2019-04-11 10:47:58 -04:00
LANG = KIRI . lang . current ,
2017-04-18 17:09:33 -04:00
// ---------------
WIN = SELF . window ,
DOC = SELF . document ,
LOC = SELF . location ,
SETUP = parseOpt ( LOC . search . substring ( 1 ) ) ,
2020-03-04 17:40:11 -05:00
HOST = LOC . host . split ( ':' ) ,
LOCAL = HOST [ 0 ] === 'localhost' || HOST [ 0 ] === 'debug' ,
2017-04-18 17:09:33 -04:00
SECURE = isSecure ( LOC . protocol ) ,
// ---------------
SDB = MOTO . KV ,
ODB = KIRI . odb = new MOTO . Storage ( SETUP . d ? SETUP . d [ 0 ] : 'kiri' ) ,
SPACE = KIRI . space = MOTO . Space ,
WIDGETS = KIRI . widgets = [ ] ,
CATALOG = KIRI . catalog = KIRI . openCatalog ( ODB , autoDecimate ) ,
STATS = new Stats ( SDB ) ,
SEED = 'kiri-seed' ,
// ---------------
Widget = kiri . Widget ,
newWidget = kiri . newWidget ,
// ---------------
UI = { } ,
UC = MOTO . ui . prefix ( 'kiri' ) . inputAction ( updateSettings ) . hideAction ( onControlResize ) ,
DEFMODE = SETUP . dm && SETUP . dm . length === 1 ? SETUP . dm [ 0 ] : 'FDM' ,
STARTMODE = SETUP . sm && SETUP . sm . length === 1 ? SETUP . sm [ 0 ] : null ,
MODE = MODES . FDM ,
onEvent = { } ,
2017-10-30 14:21:23 -04:00
screenShot = null ,
2017-04-18 17:09:33 -04:00
currentPrint = null ,
selectedMeshes = [ ] ,
localFilterKey = 'kiri-gcode-filters' ,
localFilters = js2o ( SDB . getItem ( localFilterKey ) ) || [ ] ,
OCTOPRINT = null ,
// ---------------
wireframe _color = 0x444444 ,
wireframe _model _opacity = 0.25 ,
widget _selected _color = 0xbbff00 ,
widget _deselected _color = 0xffff00 ,
widget _slicing _color = 0xffaaaa ,
widget _cam _preview _color = 0x0055bb ,
2018-02-23 22:39:02 -05:00
preview _opacity _cam = 0.25 ,
2017-04-18 17:09:33 -04:00
preview _opacity = 0.0 ,
model _opacity = 1.0 ,
slicing _opacity = 0.5 ,
sliced _opacity = 0.0 ,
sliced _opacity _cam = 0.25 ,
// ---------------
2020-03-07 14:00:41 -05:00
printSeq = parseInt ( SDB [ 'kiri-print-seq' ] || SDB [ 'print-seq' ] || "0" ) + 1 ,
2017-04-18 17:09:33 -04:00
catalogSize = 0 ,
showLayerRange = 0 ,
showLayerValue = 0 ,
showLayerMax = 0 ,
renderMode = 4 ,
viewMode = VIEWS . ARRANGE ,
layoutOnAdd = true ,
2017-11-03 19:55:18 -04:00
deviceLock = false ,
2017-04-18 17:09:33 -04:00
local = SETUP . local ,
mouseMoved = false ,
camStock = null ,
2019-04-12 09:45:52 -04:00
camTopZ = 0 ,
2020-03-01 21:24:14 -05:00
topZ = 0 ,
2020-03-03 20:06:10 -05:00
// origin = {x:0, y:0, z:0},
2019-04-12 09:45:52 -04:00
showFavorites = SDB [ 'dev-favorites' ] === 'true' ;
2017-04-18 17:09:33 -04:00
2020-02-10 17:41:59 -05:00
// seed defaults. will get culled on save
settings . sproc . FDM . default = clone ( settings . process ) ;
settings . sproc . CAM . default = clone ( settings . process ) ;
settings . sproc . LASER . default = clone ( settings . process ) ;
settings . cdev . FDM = clone ( settings . device ) ;
settings . cdev . CAM = clone ( settings . device ) ;
2017-04-18 17:09:33 -04:00
DBUG . enable ( ) ;
if ( SETUP . rm ) renderMode = parseInt ( SETUP . rm [ 0 ] ) ;
2019-04-11 10:47:58 -04:00
if ( SETUP . ln ) KIRI . lang . set ( SETUP . ln [ 0 ] ) ;
2019-04-16 07:45:24 -04:00
var alerts = [ [ ` ${ LANG . version } ${ KIRI . version } ` , Date . now ( ) ] ] ;
2017-04-18 17:09:33 -04:00
KIRI . api = {
ui : UI ,
on : addOnEvent ,
sdb : SDB ,
o2js : o2js ,
js2o : js2o ,
ajax : ajax ,
help : showHelp ,
load : loadWidget ,
2020-03-03 12:05:32 -05:00
alert : alert2 ,
2017-04-18 17:09:33 -04:00
focus : takeFocus ,
stats : STATS ,
import : loadFile ,
catalog : CATALOG ,
getMode : getMode ,
setMode : setMode ,
2020-02-08 21:01:00 -05:00
switchMode : switchMode ,
2017-04-18 17:09:33 -04:00
showModal : showModal ,
hideModal : hideModal ,
showDialog : showDialog ,
hideDialog : hideDialog ,
showCatalog : showCatalog ,
addWidget : platformAdd ,
selectAll : platformSelectAll ,
selectNone : widgetDeselect ,
showProgress : setProgress ,
clearWorker : KIRI . work . clear ,
getSettings : getSettings ,
putSettings : putSettings ,
2020-01-20 22:10:33 -05:00
gridDetect : function ( ) { return false } ,
2018-03-14 10:08:11 -04:00
ghostDetect : function ( ) { return false } ,
2017-04-18 17:09:33 -04:00
hideImport : function ( ) { UI . import . style . display = 'none' } ,
mouse : {
moved : function ( ) { return mouseMoved } ,
movedSet : function ( b ) { mouseMoved = b }
2020-02-25 21:53:48 -05:00
} ,
const : {
MODES ,
VIEWS
2017-04-18 17:09:33 -04:00
}
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Stats accumulator
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function Stats ( db ) {
this . db = db ;
2020-03-07 13:14:22 -05:00
this . obj = js2o ( this . db [ 'stats' ] || '{}' ) ;
2017-04-18 17:09:33 -04:00
var o = this . obj , k ;
for ( k in o ) {
if ( ! o . hasOwnProperty ( k ) ) continue ;
2020-03-07 13:14:22 -05:00
if ( k === 'dn' || k . indexOf ( '-' ) > 0 || k . indexOf ( '_' ) > 0 ) {
delete o [ k ] ;
}
2017-04-18 17:09:33 -04:00
}
}
2020-03-07 12:33:26 -05:00
Stats . prototype . save = function ( quiet ) {
2017-04-18 17:09:33 -04:00
this . db [ 'stats' ] = o2js ( this . obj ) ;
2020-03-07 12:33:26 -05:00
if ( ! quiet ) {
sendOnEvent ( 'stats' , this . obj ) ;
}
2017-04-18 17:09:33 -04:00
return this ;
} ;
2020-03-07 12:33:26 -05:00
2017-04-18 17:09:33 -04:00
Stats . prototype . get = function ( k ) {
return this . obj [ k ] ;
2020-03-07 12:33:26 -05:00
} ;
Stats . prototype . set = function ( k , v , quiet ) {
2017-04-18 17:09:33 -04:00
this . obj [ k ] = v ;
2020-03-07 12:33:26 -05:00
this . save ( quiet ) ;
2017-04-18 17:09:33 -04:00
return this ;
} ;
2020-03-07 12:33:26 -05:00
Stats . prototype . add = function ( k , v , quiet ) {
2017-04-18 17:09:33 -04:00
this . obj [ k ] = ( this . obj [ k ] || 0 ) + ( v || 1 ) ;
2020-03-07 12:33:26 -05:00
this . save ( quiet ) ;
2017-04-18 17:09:33 -04:00
return this ;
} ;
2020-03-07 12:33:26 -05:00
Stats . prototype . del = function ( k , quiet ) {
2017-04-18 17:09:33 -04:00
delete this . obj [ k ] ;
2020-03-07 12:33:26 -05:00
this . save ( quiet ) ;
2017-04-18 17:09:33 -04:00
return this ;
2020-03-07 12:33:26 -05:00
} ;
2017-04-18 17:09:33 -04:00
2020-03-07 15:57:45 -05:00
let inits = parseInt ( SDB . getItem ( 'kiri-init' ) || STATS . get ( 'init' ) || 0 ) + 1 ;
2020-03-07 14:00:41 -05:00
SDB . setItem ( 'kiri-init' , inits ) ;
STATS . set ( 'init' , inits ) ;
2017-04-18 17:09:33 -04:00
STATS . set ( 'kiri' , kiri . version ) ;
2020-03-07 13:14:22 -05:00
if ( kiri . version !== STATS . get ( 'kiri' ) && STATS . get ( 'init' ) > 0 ) {
STATS . set ( 'upgrade' , kiri . version ) ;
}
2017-04-18 17:09:33 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Utility Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2020-03-07 12:33:26 -05:00
function clone ( o ) {
return o ? JSON . parse ( JSON . stringify ( o ) ) : o ;
}
function alert2 ( message , time ) {
if ( message === undefined ) {
return updateAlerts ( true ) ;
}
alerts . push ( [ message , Date . now ( ) , time ] ) ;
updateAlerts ( ) ;
}
function updateAlerts ( clear ) {
if ( clear ) {
alerts = [ ] ;
}
let now = Date . now ( ) ;
// filter out by age
alerts = alerts . filter ( alert => {
return ( now - alert [ 1 ] ) < ( ( alert [ 2 ] || 5 ) * 1000 ) ;
} ) ;
// limit to 5 showing
while ( alerts . length > 5 ) {
alerts . shift ( ) ;
}
if ( alerts . length > 0 ) {
UI . alert . text . innerHTML = alerts . map ( v => [ '<p>' , v [ 0 ] , '</p>' ] . join ( '' ) ) . join ( '' ) ;
UI . alert . dialog . style . display = 'flex' ;
} else {
UI . alert . dialog . style . display = 'none' ;
}
}
function sendOnEvent ( name , data ) {
if ( name && onEvent [ name ] ) onEvent [ name ] . forEach ( function ( fn ) {
fn ( data ) ;
} ) ;
}
function addOnEvent ( name , handler ) {
if ( name && typeof ( name ) === 'string' && typeof ( handler ) === 'function' ) {
onEvent [ name ] = onEvent [ name ] || [ ] ;
onEvent [ name ] . push ( handler ) ;
}
}
function triggerSettingsEvent ( ) {
sendOnEvent ( 'settings' , settings ) ;
}
function oremap ( o , k , p ) {
try {
var ov = o [ k ] ;
delete o [ k ] ;
o [ p + ( k . split ( '-' ) [ 1 ] . toLowerCase ( ) ) ] = ov ;
} catch ( e ) {
console . log ( e )
}
}
2017-04-18 17:09:33 -04:00
function isSecure ( proto ) {
return proto . toLowerCase ( ) . indexOf ( "https" ) === 0 ;
}
function parseOpt ( ov ) {
var opt = { } , kv , kva ;
ov . split ( ',' ) . forEach ( function ( el ) {
kv = el . split ( ':' ) ;
if ( kv . length === 2 ) {
kva = opt [ kv [ 0 ] ] = opt [ kv [ 0 ] ] || [ ] ;
kva . push ( decodeURIComponent ( kv [ 1 ] ) ) ;
}
} ) ;
return opt ;
}
function ajax ( url , fn , rt , po , hd ) {
return new MOTO . Ajax ( fn , rt ) . request ( url , po , hd ) ;
}
function o2js ( o , def ) {
return o ? JSON . stringify ( o ) : def || null ;
}
function js2o ( s , def ) {
try {
return s ? JSON . parse ( s ) : def || null ;
} catch ( e ) {
console . log ( { malformed _json : s } ) ;
return def || null ;
}
}
function ls2o ( key , def ) {
return js2o ( SDB . getItem ( key ) , def ) ;
}
function set ( to , from ) {
for ( var k in from ) {
if ( from . hasOwnProperty ( k ) ) to [ k ] = from [ k ] ;
}
}
function cull ( o , f ) {
for ( var k in o ) {
2020-02-10 17:41:59 -05:00
if ( ! o . hasOwnProperty ( k ) ) {
continue ;
}
if ( ! f . hasOwnProperty ( k ) ) {
delete o [ k ] ;
}
2017-04-18 17:09:33 -04:00
}
}
function setProgress ( value , msg ) {
if ( value ) {
value = UTIL . round ( value * 100 , 4 ) ;
UI . loading . display = 'block' ;
UI . progress . width = value + '%' ;
if ( msg ) UI . prostatus . innerHTML = msg ;
} else {
UI . loading . display = 'none' ;
}
}
function bound ( v , min , max ) {
return Math . max ( min , Math . min ( max , v ) ) ;
}
function setVisibleLayer ( v ) {
showSlices ( showLayerValue = bound ( v , 0 , showLayerMax ) ) ;
}
function meshArray ( ) {
var out = [ ] ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
out . push ( widget . mesh ) ;
} ) ;
return out ;
}
2019-05-07 14:35:39 -04:00
function forAllWidgets ( f ) {
2017-04-18 17:09:33 -04:00
WIDGETS . slice ( ) . forEach ( function ( widget ) {
f ( widget ) ;
} ) ;
}
function forSelectedWidgets ( f ) {
var m = selectedMeshes ;
if ( m . length === 0 && WIDGETS . length === 1 ) m = [ WIDGETS [ 0 ] . mesh ] ;
m . slice ( ) . forEach ( function ( mesh ) { f ( mesh . widget ) } ) ;
}
function forSelectedMeshes ( f ) {
selectedMeshes . slice ( ) . forEach ( function ( mesh ) { f ( mesh ) } ) ;
}
function toggleWireframe ( color , opacity ) {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( w ) { w . toggleWireframe ( color , opacity ) } ) ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function updateSliderMax ( set ) {
var max = 0 ;
if ( viewMode === VIEWS . PREVIEW && currentPrint ) {
max = currentPrint . getLayerCount ( ) ;
} else {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
if ( ! widget . slices ) return ;
2017-11-03 15:56:32 -04:00
max = Math . max ( max , widget . slices . length ) ;
2017-04-18 17:09:33 -04:00
} ) ;
}
2017-11-03 15:56:32 -04:00
max = Math . max ( 0 , max - 1 ) ;
2017-04-18 17:09:33 -04:00
showLayerMax = max ;
if ( UI . layerID . convert ( ) > max || showLayerValue > max ) {
showLayerValue = max ;
UI . layerID . value = max ;
UI . layerSlider . value = showLayerMax ;
}
UI . layerSlider . max = max ;
if ( set ) {
showLayerValue = showLayerMax ;
UI . layerSlider . value = showLayerMax ;
}
}
function hideSlices ( ) {
var showing = false ;
setOpacity ( model _opacity ) ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
widget . setWireframe ( false ) ;
showing = widget . hideSlices ( ) || showing ;
} ) ;
clearPrint ( ) ;
return showing ;
}
function showSlice ( index , range , layer ) {
2018-02-20 16:30:50 -05:00
if ( range ) {
return index <= layer && index > layer - range ;
} else {
return index <= layer ;
}
2017-04-18 17:09:33 -04:00
}
/ * *
* hide or show slice - layers and their sub - elements
*
* @ param { number } [ layer ]
* /
function showSlices ( layer ) {
if ( typeof ( layer ) === 'string' || typeof ( layer ) === 'number' ) {
layer = parseInt ( layer ) ;
} else {
layer = showLayerValue ;
}
layer = bound ( layer , 0 , showLayerMax ) ;
UI . layerID . value = layer ;
UI . layerSlider . value = layer ;
var j ,
slice ,
slices ,
layers ,
range = UI . layerRange . checked ? UI . layerSpan . convert ( ) || 1 : 0 ,
print = UI . layerPrint . checked ;
if ( MODE === MODES . CAM && showLayerRange !== range && range && layer === showLayerMax ) {
layer = 0 ;
}
showLayerRange = range ;
showLayerValue = layer ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
if ( print ) return widget . hideSlices ( ) ;
slices = widget . slices ;
if ( ! slices ) return ;
for ( j = 0 ; j < slices . length ; j ++ ) {
slice = slices [ j ] ;
slice . view . visible = showSlice ( j , range , layer ) ;
layers = slice . layers ;
layers . outline . setVisible (
MODE === MODES . CAM ?
UI . layerOutline . checked && LOCAL :
UI . layerOutline . checked
) ;
layers . trace . setVisible (
MODE === MODES . CAM ?
UI . layerRough . checked :
UI . layerTrace . checked
) ;
layers . bridge . setVisible (
MODE === MODES . CAM ?
UI . layerFinishX . checked :
UI . layerDelta . checked
) ;
layers . flat . setVisible (
MODE === MODES . CAM ?
UI . layerFinishY . checked :
UI . layerDelta . checked
) ;
layers . solid . setVisible (
MODE === MODES . CAM ?
UI . layerFinish . checked :
UI . layerSolid . checked
) ;
layers . fill . setVisible (
MODE === MODES . CAM ?
UI . layerFacing . checked :
UI . layerFill . checked
) ;
layers . sparse . setVisible ( UI . layerSparse . checked ) ;
layers . support . setVisible ( UI . layerSupport . checked ) ;
}
} ) ;
if ( currentPrint ) {
for ( j = 0 ; j < currentPrint . layerView . length ; j ++ ) {
currentPrint . showLayer ( j , print && showSlice ( j , range , layer ) ) ;
}
}
SPACE . update ( ) ;
}
2019-09-17 08:36:20 -04:00
function loadCode ( code , type ) {
2017-04-18 17:09:33 -04:00
setViewMode ( VIEWS . PREVIEW ) ;
clearPrint ( ) ;
setOpacity ( 0 ) ;
currentPrint = kiri . newPrint ( settings , [ ] ) ;
2020-03-01 21:24:14 -05:00
let center = settings . process . outputOriginCenter ;
2020-03-03 20:06:10 -05:00
let origin = settings . origin ;
let offset = {
x : origin . x ,
y : - origin . y ,
z : origin . z
2019-09-17 08:36:20 -04:00
} ;
switch ( type ) {
case 'svg' :
currentPrint . parseSVG ( code , offset ) ;
break ;
default :
currentPrint . parseGCode ( code , offset ) ;
break ;
}
2017-04-18 17:09:33 -04:00
currentPrint . render ( ) ;
SPACE . platform . add ( currentPrint . group ) ;
SPACE . update ( ) ;
UI . layerPrint . checked = true ;
updateSliderMax ( true ) ;
showSlices ( ) ;
}
function preparePrint ( callback ) {
// kick off slicing it hasn't been done already
for ( var i = 0 ; i < WIDGETS . length ; i ++ ) {
if ( ! WIDGETS [ i ] . slices || WIDGETS [ i ] . isModified ( ) ) {
2019-01-18 10:31:22 -05:00
prepareSlices ( function ( ) {
if ( ! WIDGETS [ i ] . slices || WIDGETS [ i ] . isModified ( ) ) {
2019-01-18 16:46:17 -05:00
alert2 ( "nothing to print" ) ;
2019-01-18 10:31:22 -05:00
} else {
preparePrint ( callback ) ;
}
} ) ;
2017-04-18 17:09:33 -04:00
return ;
}
}
2017-10-30 14:21:23 -04:00
setViewMode ( VIEWS . PREVIEW ) ;
2017-04-18 17:09:33 -04:00
clearPrint ( ) ;
saveSettings ( ) ;
if ( MODE === MODES . CAM ) {
setOpacity ( preview _opacity _cam ) ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
widget . setColor ( widget _cam _preview _color ) ;
} ) ;
} else {
setOpacity ( preview _opacity ) ;
}
currentPrint = kiri . newPrint ( settings , WIDGETS ) ;
2017-11-17 13:11:13 -05:00
currentPrint . setup ( true , function ( update , status ) {
2017-04-18 17:09:33 -04:00
// on update
setProgress ( update , status ) ;
} , function ( ) {
setProgress ( 0 ) ;
currentPrint . render ( ) ;
// on done
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _print ` ) ;
2017-04-18 17:09:33 -04:00
SPACE . platform . add ( currentPrint . group ) ;
SPACE . update ( ) ;
UI . layerPrint . checked = true ;
updateSliderMax ( true ) ;
showSlices ( ) ;
if ( typeof ( callback ) === 'function' ) callback ( ) ;
} )
}
function exportPrint ( ) {
if ( ! currentPrint ) {
preparePrint ( exportPrint ) ;
return ;
}
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _export ` ) ;
2017-04-18 17:09:33 -04:00
switch ( settings . mode ) {
case 'LASER' : return exportPrintLaser ( ) ;
case 'FDM' : return exportPrintGCODE ( ) ;
case 'CAM' : return exportPrintGCODE ( ) ;
}
}
function exportPrintGCODE ( ) {
if ( ! currentPrint ) {
preparePrint ( exportPrint ) ;
return ;
}
2017-11-17 13:11:13 -05:00
currentPrint . exportGCode ( true , function ( gcode ) {
2017-04-18 17:09:33 -04:00
exportGCode ( gcode ) ;
} ) ;
}
function exportPrintLaser ( ) {
if ( ! currentPrint ) {
preparePrint ( exportPrintLaser ) ;
return ;
}
var filename = "laser-" + ( new Date ( ) . getTime ( ) . toString ( 36 ) ) ;
function download _svg ( ) {
saveAs ( new Blob (
2017-12-06 14:09:29 -05:00
[ currentPrint . exportSVG ( $ ( 'print-color' ) . value ) ] ,
2017-04-18 17:09:33 -04:00
{ type : "application/octet-stream" } ) ,
$ ( 'print-filename' ) . value + ".svg" ) ;
}
function download _dxf ( ) {
saveAs ( new Blob (
[ currentPrint . exportDXF ( ) ] ,
{ type : "application/octet-stream" } ) ,
$ ( 'print-filename' ) . value + ".dxf" ) ;
}
function download _gcode ( ) {
saveAs ( new Blob (
[ currentPrint . exportLaserGCode ( ) ] ,
{ type : "application/octet-stream" } ) ,
$ ( 'print-filename' ) . value + ".gcode" ) ;
}
ajax ( "/kiri/output-laser.html" , function ( html ) {
2019-05-24 09:06:51 -04:00
let segments = 0 ;
currentPrint . output . forEach ( layer => { segments += layer . length } ) ;
2017-04-18 17:09:33 -04:00
UI . print . innerHTML = html ;
$ ( 'print-filename' ) . value = filename ;
2019-05-24 09:06:51 -04:00
$ ( 'print-lines' ) . value = segments ;
2017-04-18 17:09:33 -04:00
$ ( 'print-close' ) . onclick = hideModal ;
$ ( 'print-svg' ) . onclick = download _svg ;
$ ( 'print-dxf' ) . onclick = download _dxf ;
$ ( 'print-lg' ) . onclick = download _gcode ;
showModal ( 'print' ) ;
} ) ;
}
function exportGCode ( gcode ) {
2020-03-07 14:00:41 -05:00
SDB [ 'kiri-print-seq' ] = printSeq ++ ;
2017-12-07 12:37:49 -05:00
var pre = ( MODE === MODES . CAM ? "cnc-" : "print-" ) + ( printSeq . toString ( ) . padStart ( 3 , "0" ) ) ,
2017-10-30 14:21:23 -04:00
filename = pre , // + (new Date().getTime().toString(36)),
2017-04-18 17:09:33 -04:00
fileext = settings . device . gcodeFExt || "gcode" ,
2018-01-06 10:55:48 -05:00
codeproc = settings . device . gcodeProc ,
2017-04-18 17:09:33 -04:00
octo _host ,
octo _apik ,
grid _host ,
grid _apik ,
2018-01-19 11:10:59 -05:00
grid _target ,
2020-01-21 10:24:56 -05:00
grid _targets = { } ,
grid _local ,
grid _uuid ;
2017-04-18 17:09:33 -04:00
2018-01-06 10:55:48 -05:00
// run gcode post processor function (when supplied and valid)
if ( codeproc && self [ codeproc ] ) {
gcode = self [ codeproc ] ( gcode ) ;
}
2017-04-18 17:09:33 -04:00
function getBlob ( ) {
return new Blob (
[ gcode ] ,
{ type : "application/octet-stream" } ) ;
}
2018-03-14 10:08:11 -04:00
function sendto _octoprint ( ) {
2017-04-18 17:09:33 -04:00
if ( ! ( octo _host && octo _apik ) ) return ;
var form = new FormData ( ) ,
ajax = new XMLHttpRequest ( ) ,
host = octo _host . value . toLowerCase ( ) ,
apik = octo _apik . value ;
if ( host . indexOf ( "http" ) !== 0 ) {
2019-01-18 16:46:17 -05:00
alert2 ( "host missing protocol (http:// or https://)" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
if ( SECURE && ! isSecure ( host ) ) {
2019-01-18 16:46:17 -05:00
alert2 ( "host must begin with 'https' on a secure site" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
SDB [ 'octo-host' ] = host . trim ( ) ;
SDB [ 'octo-apik' ] = apik . trim ( ) ;
filename = $ ( 'print-filename' ) . value ;
form . append ( "file" , getBlob ( ) , filename + "." + fileext ) ;
ajax . onreadystatechange = function ( ) {
if ( ajax . readyState === 4 ) {
var status = ajax . status ;
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _print_octo_ ${ status } ` ) ;
2017-04-18 17:09:33 -04:00
if ( status >= 200 && status < 300 ) {
hideModal ( ) ;
} else {
2019-01-18 16:46:17 -05:00
alert2 ( "octoprint error\nstatus: " + status + "\nmessage: " + ajax . responseText ) ;
2017-04-18 17:09:33 -04:00
}
}
} ;
ajax . upload . addEventListener ( 'progress' , function ( evt ) {
setProgress ( Math . ceil ( evt . loaded / evt . total ) , "sending" ) ;
} ) ;
ajax . open ( "POST" , host + "/api/files/local" ) ;
ajax . setRequestHeader ( "X-Api-Key" , apik ) ;
ajax . send ( form ) ;
}
2018-03-14 10:08:11 -04:00
function gridhost _tracker ( host , key ) {
2017-04-18 17:09:33 -04:00
ajax ( host + "/api/check?key=" + key , function ( data ) {
data = js2o ( data ) ;
DBUG . log ( data ) ;
2019-01-23 16:10:35 -05:00
if ( ! ( data . done || data . error ) ) {
setTimeout ( function ( ) { gridhost _tracker ( host , key ) } , 1000 ) ;
}
2017-04-18 17:09:33 -04:00
} ) ;
}
2020-01-21 10:24:56 -05:00
function gridlocal _probe ( ev , devs ) {
if ( ev && ev . code !== 'Enter' ) return ;
if ( ! devs && KIRI . api . gridDetect ( gridlocal _probe ) ) return ;
grid _local = devs ;
let html = [ ] ;
for ( let uuid in devs ) {
let dev = devs [ uuid ] ;
html . push ( ` <option id="gl- ${ uuid } " value=" ${ uuid } "> ${ dev . stat . device . name } </option> ` ) ;
}
$ ( 'grid-local' ) . innerHTML = html . join ( '\n' ) ;
}
function sendto _gridlocal ( ) {
let uuid = $ ( 'grid-local' ) . value ;
let dev = grid _local [ uuid ] ;
if ( dev ) {
let file = $ ( 'print-filename' ) . value ;
fetch (
` /api/grid_send?uuid= ${ uuid } &file= ${ encodeURIComponent ( file + "." + fileext ) } ` ,
{ method : "POST" , body : gcode }
)
. then ( t => t . text ( ) )
. then ( t => {
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _print_local_ok ` ) ;
2020-01-21 10:24:56 -05:00
console . log ( { grid _spool _said : t } ) ;
} )
. catch ( e => {
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _print_local_err ` ) ;
2020-01-21 10:24:56 -05:00
console . log ( { grid _local _spool _error : e } ) ;
} )
. finally ( ( ) => {
hideModal ( ) ;
} ) ;
}
}
function admin _gridlocal ( ) {
let dev = grid _local [ $ ( 'grid-local' ) . value ] ;
2020-01-27 20:43:25 -05:00
if ( dev && dev . stat && dev . stat . device ) {
let dsd = dev . stat . device ;
window . open ( ` http:// ${ dsd . addr [ 0 ] } : ${ dsd . port || 4080 } ` , "_grid_admin" ) ;
2020-01-21 10:24:56 -05:00
}
}
2018-03-14 14:20:00 -04:00
function gridhost _probe ( ev , host ) {
2018-01-19 11:10:59 -05:00
if ( ev && ev . code !== 'Enter' ) return ;
2017-04-18 17:09:33 -04:00
if ( ! ( grid _host && grid _apik ) ) return ;
2018-03-14 14:20:00 -04:00
if ( host ) grid _host . value = host ;
2017-04-18 17:09:33 -04:00
var xhtr = new XMLHttpRequest ( ) ,
host = grid _host . value ,
apik = grid _apik . value ,
target = grid _target . value ;
2018-01-19 13:00:31 -05:00
if ( ! apik ) $ ( 'gpapik' ) . style . display = 'none' ;
2018-03-14 10:08:11 -04:00
if ( ! host && KIRI . api . ghostDetect ( gridhost _probe ) ) return ;
2019-04-02 20:01:05 -07:00
if ( ! host ) return ;
2018-01-19 11:10:59 -05:00
xhtr . onreadystatechange = function ( ) {
if ( xhtr . readyState === 4 ) {
if ( xhtr . status >= 200 && xhtr . status < 300 ) {
2018-03-06 19:25:30 -05:00
SDB [ 'grid-host' ] = host ;
SDB [ 'grid-apik' ] = apik ;
2018-01-19 11:10:59 -05:00
var res = JSON . parse ( xhtr . responseText ) ;
var sel = false ;
2019-03-26 10:53:13 -04:00
var match = false ;
2019-02-28 09:11:18 -05:00
var first = null ;
2018-01-19 11:10:59 -05:00
var html = [ ] ;
grid _targets = { } ;
for ( var key in res ) {
2019-02-28 09:11:18 -05:00
first = first || key ;
2018-01-19 11:10:59 -05:00
if ( ! SDB [ 'grid-target' ] ) {
SDB [ 'grid-target' ] = key ;
sel = true ;
} else {
sel = SDB [ 'grid-target' ] === key ;
}
2019-03-26 10:53:13 -04:00
match = match || sel ;
2018-01-19 11:10:59 -05:00
grid _targets [ html . length ] = key ;
html . push (
"<option id='gpo-'" + key + " value='" + key + "'" +
( sel ? " selected" : "" ) +
">" +
( res [ key ] . comment || key ) +
"</option>"
) ;
}
2019-03-26 10:53:13 -04:00
if ( ! match ) {
2019-02-28 09:11:18 -05:00
SDB [ 'grid-target' ] = first ;
}
2018-01-19 11:10:59 -05:00
grid _target . innerHTML = html . join ( '\n' ) ;
2018-01-19 13:00:31 -05:00
} else if ( xhtr . status === 401 ) {
$ ( 'gpapik' ) . style . display = '' ;
2018-01-19 11:10:59 -05:00
} else {
2018-03-06 19:25:30 -05:00
SDB . removeItem ( 'grid-host' ) ;
SDB . removeItem ( 'grid-apik' ) ;
2018-03-05 17:14:18 -05:00
console . log ( "invalid grid:host url" ) ;
2018-01-19 11:10:59 -05:00
}
}
} ;
2019-04-30 10:47:18 -04:00
xhtr . open ( "GET" , host + "/api/active?key=" + apik ) ;
2018-01-19 11:10:59 -05:00
xhtr . send ( ) ;
}
2018-03-14 10:08:11 -04:00
function sendto _gridhost ( ) {
2018-01-19 11:10:59 -05:00
if ( ! ( grid _host && grid _apik ) ) return ;
var xhtr = new XMLHttpRequest ( ) ,
host = grid _host . value ,
apik = grid _apik . value ,
target = SDB [ 'grid-target' ] || '' ;
if ( target === '' ) {
2019-01-18 16:46:17 -05:00
alert2 ( 'invalid or missing target' ) ;
2018-01-19 11:10:59 -05:00
return ;
}
2017-04-18 17:09:33 -04:00
if ( host . indexOf ( "http" ) !== 0 ) {
2019-01-18 16:46:17 -05:00
alert2 ( "host missing protocol (http:// or https://)" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
if ( host . indexOf ( "://" ) < 0 ) {
2019-01-18 16:46:17 -05:00
alert2 ( "host:port malformed" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
if ( SECURE && ! isSecure ( host ) ) {
2019-01-18 16:46:17 -05:00
alert2 ( "host must begin with 'https' on a secure site" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
SDB [ 'grid-host' ] = host . trim ( ) ;
SDB [ 'grid-apik' ] = apik . trim ( ) ;
xhtr . onreadystatechange = function ( ) {
if ( xhtr . readyState === 4 ) {
var status = xhtr . status ;
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _print_grid_ ${ status } ` ) ;
2017-04-18 17:09:33 -04:00
if ( status >= 200 && status < 300 ) {
var json = js2o ( xhtr . responseText ) ;
2018-03-14 10:08:11 -04:00
gridhost _tracker ( host , json . key ) ;
2017-04-18 17:09:33 -04:00
ajax ( host + "/api/wait?key=" + json . key , function ( data ) {
data = js2o ( data ) ;
DBUG . log ( data ) ;
2019-01-18 16:46:17 -05:00
alert2 ( "print to " + target + ": " + data . status , 600 ) ;
2017-04-18 17:09:33 -04:00
} ) ;
} else {
2019-01-18 16:46:17 -05:00
alert2 ( "grid:host error\nstatus: " + status + "\nmessage: " + xhtr . responseText , 10000 ) ;
2017-04-18 17:09:33 -04:00
}
setProgress ( 0 ) ;
}
} ;
xhtr . upload . addEventListener ( 'progress' , function ( evt ) {
setProgress ( Math . ceil ( evt . loaded / evt . total ) , "sending" ) ;
} ) ;
filename = $ ( 'print-filename' ) . value ;
2017-10-15 19:43:51 -04:00
xhtr . open ( "POST" ,
host + "/api/print?" +
"filename=" + filename +
"&target=" + target +
"&key=" + apik +
"&time=" + Math . round ( currentPrint . time ) +
2017-10-30 14:21:23 -04:00
"&length=" + Math . round ( currentPrint . distance ) +
"&image=" + filename
2017-10-15 19:43:51 -04:00
) ;
2017-04-18 17:09:33 -04:00
xhtr . setRequestHeader ( "Content-Type" , "text/plain" ) ;
2017-10-31 13:14:35 -04:00
xhtr . send ( screenShot ? [ gcode , screenShot ] . join ( "\0" ) : gcode ) ;
2017-04-18 17:09:33 -04:00
hideModal ( ) ;
}
function download ( ) {
filename = $ ( 'print-filename' ) . value ;
2017-12-07 12:37:49 -05:00
saveAs ( getBlob ( ) , filename + "." + fileext ) ;
2017-04-18 17:09:33 -04:00
}
function pad ( v ) {
v = v . toString ( ) ;
return v . length < 2 ? '0' + v : v ;
}
function calcWeight ( ) {
2020-03-08 11:04:07 -04:00
try {
2017-04-18 17:09:33 -04:00
$ ( 'print-weight' ) . value = (
2020-03-08 11:04:07 -04:00
UTIL . round ( ( Math . PI * UTIL . sqr ( currentPrint . settings . device . filamentSize / 2 ) ) * currentPrint . distance * 1.25 / 1000 , 2 )
2017-04-18 17:09:33 -04:00
) ;
2020-03-08 11:04:07 -04:00
} catch ( e ) { }
2017-04-18 17:09:33 -04:00
}
function calcTime ( ) {
var floor = Math . floor ,
time = floor ( currentPrint . time ) ,
hours = floor ( time / 3600 ) ,
newtime = time - hours * 3600 ,
mins = floor ( newtime / 60 ) ,
secs = newtime - mins * 60 ;
$ ( 'mill-time' ) . value = $ ( 'print-time' ) . value = [ pad ( hours ) , pad ( mins ) , pad ( secs ) ] . join ( ':' ) ;
}
ajax ( "/kiri/output-gcode.html" , function ( html ) {
UI . print . innerHTML = html ;
$ ( 'print-close' ) . onclick = hideModal ;
$ ( 'print-download' ) . onclick = download ;
2018-03-14 10:08:11 -04:00
$ ( 'print-octoprint' ) . onclick = sendto _octoprint ;
$ ( 'print-gridhost' ) . onclick = sendto _gridhost ;
2020-01-21 10:24:56 -05:00
$ ( 'print-gridlocal' ) . onclick = sendto _gridlocal ;
$ ( 'admin-gridlocal' ) . onclick = admin _gridlocal ;
2017-04-18 17:09:33 -04:00
$ ( 'print-filament-row' ) . style . display = MODE === MODES . FDM ? '' : 'none' ;
$ ( 'mill-info' ) . style . display = MODE === MODES . CAM ? '' : 'none' ;
$ ( 'print-filename' ) . value = filename ;
$ ( 'print-filesize' ) . value = currentPrint . bytes ;
$ ( 'print-filament' ) . value = Math . round ( currentPrint . distance ) ;
2018-03-14 10:08:11 -04:00
$ ( 'grid-host' ) . onkeyup = gridhost _probe ;
$ ( 'grid-apik' ) . onkeyup = gridhost _probe ;
2017-04-18 17:09:33 -04:00
calcTime ( ) ;
2020-03-08 11:04:07 -04:00
if ( MODE === MODES . FDM ) calcWeight ( ) ;
2017-04-18 17:09:33 -04:00
octo _host = $ ( 'octo-host' ) ;
octo _apik = $ ( 'octo-apik' ) ;
2019-03-30 13:45:57 -04:00
if ( MODE === MODES . CAM ) {
$ ( 'send-to-octoprint' ) . style . display = 'none' ;
} else {
$ ( 'send-to-octoprint' ) . style . display = '' ;
}
2017-04-18 17:09:33 -04:00
if ( OCTOPRINT ) {
$ ( 'ophost' ) . style . display = 'none' ;
$ ( 'opapik' ) . style . display = 'none' ;
$ ( 'ophint' ) . style . display = 'none' ;
2018-03-14 10:08:11 -04:00
$ ( 'send-to-gridhost' ) . style . display = 'none' ;
2017-04-18 17:09:33 -04:00
}
octo _host . value = SDB [ 'octo-host' ] || '' ;
octo _apik . value = SDB [ 'octo-apik' ] || '' ;
grid _host = $ ( 'grid-host' ) ;
grid _apik = $ ( 'grid-apik' ) ;
grid _target = $ ( 'grid-target' ) ;
2018-01-19 11:10:59 -05:00
grid _target . onchange = function ( ev ) {
SDB [ 'grid-target' ] = grid _targets [ grid _target . selectedIndex ] ;
} ;
2017-04-18 17:09:33 -04:00
grid _host . value = SDB [ 'grid-host' ] || '' ;
grid _apik . value = SDB [ 'grid-apik' ] || '' ;
2018-03-14 10:08:11 -04:00
gridhost _probe ( ) ;
2020-01-21 10:24:56 -05:00
gridlocal _probe ( ) ;
2017-04-18 17:09:33 -04:00
showModal ( 'print' ) ;
} ) ;
}
function clearWidgetCache ( ) {
hideSlices ( ) ;
clearSlices ( ) ;
clearPrint ( ) ;
}
function clearPrint ( ) {
if ( currentPrint ) {
SPACE . platform . remove ( currentPrint . group ) ;
currentPrint = null ;
}
UI . layerPrint . checked = false ;
}
function clearSlices ( ) {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
widget . slices = null ;
} ) ;
}
/ * *
* incrementally slice all meshes then incrementally update them
*
* @ param { Function } callback
* /
function prepareSlices ( callback ) {
2017-10-30 14:21:23 -04:00
if ( viewMode == VIEWS . ARRANGE ) {
screenShot = SPACE . screenshot ( ) ;
screenShot = screenShot . substring ( screenShot . indexOf ( "," ) + 1 ) ;
}
2017-04-18 17:09:33 -04:00
setViewMode ( VIEWS . SLICE ) ;
var selectSave = selectedMeshes . slice ( ) ;
clearPrint ( ) ;
saveSettings ( ) ;
widgetDeselect ( ) ;
var firstMesh = true ,
countdown = WIDGETS . length ,
preserveMax = showLayerMax ,
preserveLayer = showLayerValue ,
totalProgress ,
track = { } ;
// require topo be sent back from worker for local printing
2017-11-17 13:11:13 -05:00
settings . synth . sendTopo = false ;
2017-04-18 17:09:33 -04:00
setOpacity ( slicing _opacity ) ;
// for each widget, slice
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
var segtimes = { } ,
segNumber = 0 ,
2018-03-22 16:48:51 -04:00
errored = false ,
2017-04-18 17:09:33 -04:00
startTime ,
lastMsg ;
// skip non-selected widgets in CAM mode when any widget is selected
if ( MODE === MODES . CAM && selectSave . length > 0 && selectSave . indexOf ( widget . mesh ) < 0 ) return -- countdown ;
widget . stats . progress = 0 ;
widget . setColor ( widget _slicing _color ) ;
2017-12-31 12:57:26 -05:00
widget . slice ( settings , function ( sliced , error ) {
2017-04-18 17:09:33 -04:00
var mark = UTIL . time ( ) ;
// on done
widget . render ( renderMode , MODE === MODES . CAM ) ;
// clear wireframe
widget . setWireframe ( false , wireframe _color , wireframe _model _opacity ) ;
widget . setOpacity ( settings . mode === 'CAM' ? sliced _opacity _cam : sliced _opacity ) ;
widget . setColor ( widget _deselected _color ) ;
// update UI info
if ( sliced ) {
// update segment time
if ( lastMsg ) segtimes [ segNumber + "_" + lastMsg ] = mark - startTime ;
DBUG . log ( segtimes ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( ` ua_ ${ getModeLower ( ) } _slice ` ) ;
2017-04-18 17:09:33 -04:00
updateSliderMax ( true ) ;
if ( preserveMax != showLayerMax ) {
preserveLayer = showLayerMax ;
}
firstMesh = false ;
}
// on the last exit, update ui and call the callback
2018-03-22 16:48:51 -04:00
if ( -- countdown === 0 || error || errored ) {
2017-04-18 17:09:33 -04:00
setProgress ( 0 ) ;
showSlices ( preserveLayer ) ;
setOpacity ( settings . mode === 'CAM' ? sliced _opacity _cam : sliced _opacity ) ;
2018-01-16 09:19:01 -05:00
if ( callback && typeof callback === 'function' ) callback ( ) ;
2017-04-18 17:09:33 -04:00
}
// update slider window
onControlResize ( ) ;
2017-12-31 12:57:26 -05:00
// handle slicing errors
2018-03-22 16:48:51 -04:00
if ( error && ! errored ) {
errored = true ;
2017-12-31 12:57:26 -05:00
setViewMode ( VIEWS . ARRANGE ) ;
setOpacity ( model _opacity ) ;
widgetDeselect ( ) ;
2019-01-18 16:46:17 -05:00
alert2 ( error ) ;
2017-12-31 12:57:26 -05:00
}
2017-04-18 17:09:33 -04:00
} , function ( update , msg ) {
if ( msg !== lastMsg ) {
var mark = UTIL . time ( ) ;
if ( lastMsg ) segtimes [ segNumber + "_" + lastMsg ] = mark - startTime ;
lastMsg = msg ;
startTime = mark ;
segNumber ++ ;
}
// on update
track [ widget . id ] = update ;
totalProgress = 0 ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( w ) {
2017-04-18 17:09:33 -04:00
totalProgress += ( track [ w . id ] || 0 ) ;
} ) ;
setProgress ( totalProgress / WIDGETS . length , msg ) ;
2017-11-17 13:11:13 -05:00
} , true ) ;
2017-04-18 17:09:33 -04:00
} ) ;
}
function fillOffsetMult ( ) {
return 1.0 - bound ( settings . process . sliceFillOverlap , 0 , 0.8 ) ;
}
function diffOffset ( ) {
return ( settings . device . nozzleSize / 2 ) * fillOffsetMult ( ) ;
}
function meshUpdateInfo ( mesh ) {
if ( ! mesh ) {
if ( selectedMeshes . length === 0 ) {
UI . selWidth . innerHTML = '0' ;
UI . selDepth . innerHTML = '0' ;
UI . selHeight . innerHTML = '0' ;
UI . scaleX . value = '' ;
UI . scaleY . value = '' ;
UI . scaleZ . value = '' ;
}
return
}
UI . selWidth . innerHTML = UTIL . round ( mesh . w , 2 ) ;
UI . selDepth . innerHTML = UTIL . round ( mesh . h , 2 ) ;
UI . selHeight . innerHTML = UTIL . round ( mesh . d , 2 ) ;
UI . scaleX . value = 1 ;
UI . scaleY . value = 1 ;
UI . scaleZ . value = 1 ;
}
function setOpacity ( value ) {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( w ) { w . setOpacity ( value ) } ) ;
2020-02-25 20:42:48 -05:00
UI . modelOpacity . value = value * 100 ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function moveSelection ( x , y , z , abs ) {
forSelectedWidgets ( function ( w ) { w . move ( x , y , z , abs ) } ) ;
2020-02-25 20:42:48 -05:00
updateCamStock ( ) ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function scaleSelection ( ev ) {
var dv = parseFloat ( ev . target . value || 1 ) ;
if ( UI . scaleUniform . checked ) {
UI . scaleX . value = dv ;
UI . scaleY . value = dv ;
UI . scaleZ . value = dv ;
}
var x = parseFloat ( UI . scaleX . value || dv ) ,
y = parseFloat ( UI . scaleY . value || dv ) ,
z = parseFloat ( UI . scaleZ . value || dv ) ;
forSelectedWidgets ( function ( w ) {
w . scale ( x , y , z ) ;
meshUpdateInfo ( w . mesh ) ;
} ) ;
UI . scaleX . value = 1 ;
UI . scaleY . value = 1 ;
UI . scaleZ . value = 1 ;
platformComputeMaxZ ( ) ;
2020-02-25 20:42:48 -05:00
updateCamStock ( true ) ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function rotateSelection ( x , y , z ) {
forSelectedWidgets ( function ( w ) { w . rotate ( x , y , z ) } ) ;
platformComputeMaxZ ( ) ;
2020-02-25 20:42:48 -05:00
updateCamStock ( true ) ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function boundsSelection ( ) {
var bounds = new THREE . Box3 ( ) ;
forSelectedWidgets ( function ( widget ) {
bounds . union ( widget . mesh . getBoundingBox ( ) ) ;
} ) ;
return bounds ;
}
function platformComputeMaxZ ( ) {
2020-03-01 21:24:14 -05:00
topZ = 0 ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2020-03-01 21:24:14 -05:00
topZ = Math . max ( topZ , widget . mesh . getBoundingBox ( ) . max . z ) ;
2017-04-18 17:09:33 -04:00
} ) ;
2020-03-01 21:24:14 -05:00
SPACE . platform . setMaxZ ( topZ ) ;
2017-04-18 17:09:33 -04:00
}
function platformAdd ( widget , shift , nolayout ) {
WIDGETS . push ( widget ) ;
SPACE . platform . add ( widget . mesh ) ;
widgetSelect ( widget , shift ) ;
platformComputeMaxZ ( ) ;
if ( nolayout ) return ;
2018-03-25 19:21:07 -04:00
if ( layoutOnAdd ) layoutPlatform ( ) ;
2017-04-18 17:09:33 -04:00
}
function platformDelete ( widget ) {
if ( Array . isArray ( widget ) ) {
var mc = widget . slice ( ) , i ;
for ( i = 0 ; i < mc . length ; i ++ ) {
platformDelete ( mc [ i ] . widget ) ;
}
return ;
}
KIRI . work . clear ( widget ) ;
WIDGETS . remove ( widget ) ;
SPACE . platform . remove ( widget . mesh ) ;
selectedMeshes . remove ( widget . mesh ) ;
updateSliderMax ( ) ;
platformComputeMaxZ ( ) ;
if ( MODE !== MODES . FDM ) layoutPlatform ( ) ;
SPACE . update ( ) ;
2020-02-26 22:02:08 -05:00
UI . selection . style . display = selectedWidgetCount ( ) ? 'inline' : 'none' ;
2017-04-18 17:09:33 -04:00
}
function platformSelectAll ( ) {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( w ) { widgetSelect ( w , true ) } )
2017-04-18 17:09:33 -04:00
}
function widgetSelect ( widget , shift ) {
if ( viewMode !== VIEWS . ARRANGE ) return ;
2017-04-18 22:22:29 -04:00
var mesh = widget . mesh ,
2017-04-18 17:09:33 -04:00
sel = ( selectedMeshes . indexOf ( mesh ) >= 0 ) ;
if ( sel ) {
if ( shift ) {
widgetDeselect ( widget )
} else if ( selectedMeshes . length > 1 ) {
widgetDeselect ( ) ;
widgetSelect ( widget , false ) ;
}
} else {
// prevent selection in slice view
if ( ! mesh . material . visible ) return ;
if ( ! shift ) widgetDeselect ( ) ;
selectedMeshes . push ( mesh ) ;
widget . setColor ( widget _selected _color ) ;
meshUpdateInfo ( mesh ) ;
}
2020-02-25 20:42:48 -05:00
UI . selection . style . display = selectedWidgetCount ( ) ? 'inline' : 'none' ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function selectedWidgetCount ( ) {
return viewMode === VIEWS . ARRANGE ? selectedMeshes . length : 0 ;
}
function widgetDeselect ( widget ) {
if ( viewMode !== VIEWS . ARRANGE ) return ;
if ( ! widget ) {
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
widgetDeselect ( widget ) ;
} ) ;
return ;
}
var mesh = widget . mesh ,
si = selectedMeshes . indexOf ( mesh ) ,
sel = ( si >= 0 ) ;
if ( sel ) selectedMeshes . splice ( si , 1 ) ;
widget . setColor ( widget _deselected _color ) ;
2020-02-25 20:42:48 -05:00
UI . selection . style . display = selectedWidgetCount ( ) ? 'inline' : 'none' ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
meshUpdateInfo ( ) ;
}
function layoutPlatform ( event , space ) {
2020-02-25 20:42:48 -05:00
var auto = UI . autoLayout . checked ,
layout = ( viewMode === VIEWS . ARRANGE && auto ) ,
2018-03-25 19:21:07 -04:00
proc = settings . process ,
2017-04-18 17:09:33 -04:00
modified = false ,
2019-04-15 15:18:53 -04:00
oldmode = viewMode ,
2020-03-01 21:24:14 -05:00
topZ = MODE === MODES . CAM ? camTopZ - proc . camZTopOffset : 0 ;
2017-04-18 17:09:33 -04:00
2018-03-25 19:21:07 -04:00
switch ( MODE ) {
case MODES . CAM :
case MODES . LASER :
space = space || proc . outputTileSpacing || 1 ;
break ;
case MODES . FDM :
space = space || ( proc . sliceSupportExtra || 0 ) + 1 ;
break ;
}
2017-04-18 17:09:33 -04:00
setViewMode ( VIEWS . ARRANGE ) ;
hideSlices ( ) ;
2019-04-15 15:18:53 -04:00
// only auto-layout when in arrange mode
if ( oldmode !== VIEWS . ARRANGE ) {
2020-03-03 20:06:10 -05:00
return SPACE . update ( ) ;
2019-04-15 15:18:53 -04:00
}
2017-04-18 17:09:33 -04:00
// do not layout when switching back from slice view
2020-03-03 20:06:10 -05:00
if ( ! auto || ( ! space && ! layout ) ) {
return SPACE . update ( ) ;
}
2017-04-18 17:09:33 -04:00
2018-03-25 19:21:07 -04:00
// check if any widget has been modified
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( w ) {
2017-04-18 17:09:33 -04:00
modified |= w . isModified ( ) ;
} ) ;
2018-03-25 19:21:07 -04:00
var gap = space ;
2017-04-18 17:09:33 -04:00
// in CNC mode with >1 widget, force layout with spacing @ 1.5x largest tool diameter
if ( MODE === MODES . CAM && WIDGETS . length > 1 ) {
2018-03-25 19:21:07 -04:00
var spacing = space || 1 , CAM = KIRI . driver . CAM ;
2017-04-18 17:09:33 -04:00
if ( proc . roughingOn ) spacing = Math . max ( spacing , CAM . getToolDiameter ( settings , proc . roughingTool ) ) ;
if ( proc . finishingOn || proc . finishingXOn || proc . finishingYOn ) spacing = Math . max ( spacing , CAM . getToolDiameter ( settings , proc . finishingTool ) ) ;
gap = spacing * 1.5 ;
}
var i , m , sz = SPACE . platform . size ( ) ,
mp = [ sz . x , sz . y ] ,
ms = [ mp [ 0 ] / 2 , mp [ 1 ] / 2 ] ,
mi = mp [ 0 ] > mp [ 1 ] ? [ ( mp [ 0 ] / mp [ 1 ] ) * 10 , 10 ] : [ 10 , ( mp [ 1 ] / mp [ 1 ] ) * 10 ] ,
c = meshArray ( ) . sort ( function ( a , b ) { return ( b . w * b . h ) - ( a . w * a . h ) } ) ,
p = new MOTO . Pack ( ms [ 0 ] , ms [ 1 ] , gap ) . fit ( c ) ;
2018-03-25 19:21:07 -04:00
2017-04-18 17:09:33 -04:00
while ( ! p . packed ) {
ms [ 0 ] += mi [ 0 ] ;
ms [ 1 ] += mi [ 1 ] ;
p = new MOTO . Pack ( ms [ 0 ] , ms [ 1 ] , gap ) . fit ( c ) ;
}
2018-03-25 19:21:07 -04:00
2017-04-18 17:09:33 -04:00
for ( i = 0 ; i < c . length ; i ++ ) {
m = c [ i ] ;
m . fit . x += m . w / 2 + p . pad ;
m . fit . y += m . h / 2 + p . pad ;
m . widget . move ( p . max . w / 2 - m . fit . x , p . max . h / 2 - m . fit . y , 0 , true ) ;
2020-03-01 21:24:14 -05:00
// m.widget.setTopZ(topZ);
2017-04-18 17:09:33 -04:00
m . material . visible = true ;
}
2020-02-25 20:42:48 -05:00
if ( MODE === MODES . CAM ) {
updateCamStock ( ) ;
}
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
}
function loadWidget ( url , onload ) {
if ( url . toLowerCase ( ) . indexOf ( ".stl" ) > 0 ) {
loadSTL ( url , onload ) ;
} else {
ajax ( url , function ( vertices ) {
vertices = js2o ( vertices ) . toFloat32 ( ) ;
platformAdd ( newWidget ( ) . loadVertices ( vertices ) ) ;
if ( onload ) onload ( vertices ) ;
} ) ;
}
}
function loadSTL ( url , onload ) {
new MOTO . STL ( ) . load ( url , function ( vertices ) {
platformAdd ( newWidget ( ) . loadVertices ( vertices ) ) ;
if ( onload ) onload ( vertices ) ;
} )
}
function resetSettings ( force ) {
if ( force || confirm ( 'reset all values to system defaults?' ) ) {
settings = settingsDefault ;
updateFields ( ) ;
} ;
}
/ * *
* fill in missing settings from default template to pick up new fields
* that may have been recently added and expected in the code
*
* @ param { Object } osrc
* @ param { Object } odst
* /
function fillMissingSettings ( osrc , odst ) {
var key , val ;
for ( key in osrc ) {
if ( ! osrc . hasOwnProperty ( key ) ) continue ;
val = odst [ key ] ;
if ( typeof val === 'undefined' || val === null || val === '' ) {
odst [ key ] = osrc [ key ] ;
} else if ( typeof osrc [ key ] === 'object' ) {
fillMissingSettings ( osrc [ key ] , odst [ key ] ) ;
}
}
}
/ * *
* @ returns { Object }
* /
function updateFieldsFromSettings ( scope ) {
if ( ! scope ) return console . trace ( "missing scope" ) ;
var key , val ;
fillMissingSettings ( settingsDefault , settings ) ;
2019-05-02 15:09:54 -04:00
settings . infill = settingsDefault . infill ;
2020-03-08 11:04:07 -04:00
settings . units = settingsDefault . units ;
2017-04-18 17:09:33 -04:00
for ( key in scope ) {
if ( ! scope . hasOwnProperty ( key ) ) continue ;
val = scope [ key ] ;
if ( UI . hasOwnProperty ( key ) ) {
var uie = UI [ key ] ,
typ = uie ? uie . type : null ;
if ( typ === 'text' ) {
uie . value = val ;
} else if ( typ === 'checkbox' ) {
uie . checked = val ;
} else if ( typ === 'select-one' ) {
uie . innerHTML = '<option></option>' ;
var chosen = null ;
2019-05-02 15:09:54 -04:00
var source = uie . parentNode . getAttribute ( 'source' ) ;
var list = settings [ source ] ;
list . forEach ( function ( tool , index ) {
let id = tool . id || tool . name ;
if ( val === id ) {
chosen = index + 1 ;
}
2017-04-18 17:09:33 -04:00
var opt = DOC . createElement ( 'option' ) ;
opt . appendChild ( DOC . createTextNode ( tool . name ) ) ;
2019-05-02 15:09:54 -04:00
opt . setAttribute ( 'value' , id ) ;
2017-04-18 17:09:33 -04:00
uie . appendChild ( opt ) ;
} ) ;
if ( chosen ) uie . selectedIndex = chosen ;
}
}
}
return settings ;
}
/ * *
* @ returns { Object }
* /
function updateSettingsFromFields ( scope ) {
if ( ! scope ) return console . trace ( "missing scope" ) ;
var key ,
changed = false ;
// for each key in scope object
for ( key in scope ) {
if ( ! scope . hasOwnProperty ( key ) ) continue ;
if ( UI . hasOwnProperty ( key ) ) {
var nval = null ,
2020-03-04 15:07:06 -05:00
uie = UI [ key ] ;
2017-04-18 17:09:33 -04:00
// skip empty UI values
if ( ! uie || uie === '' ) continue ;
if ( uie . type === 'text' ) {
nval = UI [ key ] . convert ( ) ;
} else if ( uie . type === 'checkbox' ) {
nval = UI [ key ] . checked ;
} else if ( uie . type === 'select-one' ) {
if ( uie . selectedIndex > 0 ) {
2019-05-02 15:09:54 -04:00
nval = uie . options [ uie . selectedIndex ] . value ;
2020-03-04 15:07:06 -05:00
let src = uie . parentNode . getAttribute ( 'source' ) ;
2019-05-02 15:09:54 -04:00
if ( src === 'tools' ) {
nval = parseInt ( nval ) ;
}
2017-04-18 17:09:33 -04:00
}
}
if ( scope [ key ] != nval ) {
scope [ key ] = nval ;
}
}
}
settings . synth . fillOffsetMult = fillOffsetMult ( ) ;
settings . synth . diffOffsetMult = diffOffset ( ) ;
return settings ;
}
2020-03-01 21:24:14 -05:00
function updateWidgetsTopZ ( ) {
2020-03-08 11:04:07 -04:00
let camz = MODE === MODES . CAM && ( settings . stock . z || settings . controller . alignTop ) ;
2020-03-01 21:24:14 -05:00
let ztop = camz ? camTopZ - settings . process . camZTopOffset : 0 ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
widget . setTopZ ( ztop ) ;
} ) ;
}
2020-02-25 20:42:48 -05:00
function updateCamStock ( refresh ) {
let sd = settings . process ;
let offset = UI . camStockOffset . checked ;
2020-03-03 20:06:10 -05:00
let stockSet = sd . camStockX && sd . camStockY && sd . camStockZ ;
camTopZ = topZ ;
2017-04-18 17:09:33 -04:00
// create/inject cam stock if stock size other than default
2020-03-03 20:06:10 -05:00
if ( MODE === MODES . CAM && stockSet && WIDGETS . length ) {
2020-02-25 20:42:48 -05:00
UI . stock . style . display = offset ? 'inline' : 'none' ;
let csx = sd . camStockX ;
let csy = sd . camStockY ;
let csz = sd . camStockZ ;
let csox = 0 ;
let csoy = 0 ;
if ( offset ) {
let min = { x : Infinity , y : Infinity , z : 0 } ;
let max = { x : - Infinity , y : - Infinity , z : - Infinity } ;
forAllWidgets ( function ( widget ) {
let wbnd = widget . getBoundingBox ( refresh ) ;
let wpos = widget . orient . pos ;
min = {
x : Math . min ( min . x , wpos . x + wbnd . min . x ) ,
y : Math . min ( min . y , wpos . y + wbnd . min . y ) ,
z : 0
} ;
max = {
x : Math . max ( max . x , wpos . x + wbnd . max . x ) ,
y : Math . max ( max . y , wpos . y + wbnd . max . y ) ,
z : Math . max ( max . z , wbnd . max . z )
} ;
} ) ;
csx += max . x - min . x ;
csy += max . y - min . y ;
csz += max . z - min . z ;
csox = min . x + ( ( max . x - min . x ) / 2 ) ;
csoy = min . y + ( ( max . y - min . y ) / 2 ) ;
$ ( 'stock-width' ) . innerText = ( csx ) . toFixed ( 2 ) ;
$ ( 'stock-depth' ) . innerText = ( csy ) . toFixed ( 2 ) ;
$ ( 'stock-height' ) . innerText = ( csz ) . toFixed ( 2 ) ;
}
2017-04-18 17:09:33 -04:00
if ( ! camStock ) {
var geo = new THREE . BoxGeometry ( 1 , 1 , 1 ) ;
var mat = new THREE . MeshBasicMaterial ( { color : 0x777777 , opacity : 0.2 , transparent : true , side : THREE . DoubleSide } ) ;
var cube = new THREE . Mesh ( geo , mat ) ;
SPACE . platform . add ( cube ) ;
camStock = cube ;
}
2020-03-01 21:29:00 -05:00
settings . stock = {
x : csx ,
y : csy ,
z : csz
} ;
2020-02-25 20:42:48 -05:00
camStock . scale . x = csx ;
camStock . scale . y = csy ;
camStock . scale . z = csz ;
camStock . position . x = csox ;
camStock . position . y = csoy ;
camStock . position . z = csz / 2 ;
2017-04-18 17:09:33 -04:00
camStock . material . visible = settings . mode === 'CAM' ;
2020-03-01 21:24:14 -05:00
camTopZ = csz ;
updateWidgetsTopZ ( ) ;
2017-04-18 17:09:33 -04:00
SPACE . update ( ) ;
} else if ( camStock ) {
2020-03-01 21:24:14 -05:00
settings . stock = { } ;
2020-02-25 20:42:48 -05:00
UI . stock . style . display = 'none' ;
2017-04-18 17:09:33 -04:00
SPACE . platform . remove ( camStock ) ;
SPACE . update ( ) ;
camStock = null ;
2020-03-01 21:24:14 -05:00
camTopZ = topZ ;
updateWidgetsTopZ ( ) ;
2020-03-08 11:04:07 -04:00
} else if ( settings . controller . alignTop ) {
updateWidgetsTopZ ( ) ;
2017-04-18 17:09:33 -04:00
}
2020-03-01 19:47:34 -05:00
updateOrigin ( ) ;
2017-04-18 17:09:33 -04:00
}
function updateFields ( ) {
updateFieldsFromSettings ( settings . device ) ;
updateFieldsFromSettings ( settings . process ) ;
updateFieldsFromSettings ( settings . layers ) ;
2020-03-08 11:04:07 -04:00
updateFieldsFromSettings ( settings . controller ) ;
2017-04-18 17:09:33 -04:00
}
function updateSettings ( ) {
updateSettingsFromFields ( settings . device ) ;
updateSettingsFromFields ( settings . process ) ;
2020-03-08 11:04:07 -04:00
updateSettingsFromFields ( settings . layers ) ;
updateSettingsFromFields ( settings . controller ) ;
2017-04-18 17:09:33 -04:00
saveSettings ( ) ;
updateCamStock ( ) ;
}
2020-02-10 17:41:59 -05:00
function saveSettings ( ) {
2017-04-18 17:09:33 -04:00
// remove settings invalid for a given mode (cleanup)
cull ( settings , settingsDefault ) ;
switch ( settings . mode ) {
case 'FDM' :
cull ( settings . device , sf . fdm . d ) ;
cull ( settings . process , sf . fdm . p ) ;
break ;
case 'CAM' :
cull ( settings . device , sf . cam . d ) ;
cull ( settings . process , sf . cam . p ) ;
break ;
case 'LASER' :
cull ( settings . device , sf . laser . d ) ;
cull ( settings . process , sf . laser . p ) ;
2020-02-10 17:41:59 -05:00
settings . cdev . LASER = clone ( settings . device ) ;
2017-04-18 17:09:33 -04:00
break ;
}
cull ( settings . cdev . FDM , sf . fdm . d ) ;
cull ( settings . cdev . CAM , sf . cam . d ) ;
// store camera view
var view = SPACE . view . save ( ) ;
if ( view . left || view . up ) settings . controller . view = view ;
SDB . setItem ( 'ws-settings' , JSON . stringify ( settings ) ) ;
}
function saveWorkspace ( ) {
saveSettings ( ) ;
var newWidgets = [ ] ,
oldWidgets = js2o ( SDB . getItem ( 'ws-widgets' ) , [ ] ) ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
newWidgets . push ( widget . id ) ;
oldWidgets . remove ( widget . id ) ;
widget . saveState ( ) ;
} ) ;
SDB . setItem ( 'ws-widgets' , o2js ( newWidgets ) ) ;
oldWidgets . forEach ( function ( wid ) {
Widget . deleteFromState ( wid ) ;
} ) ;
2020-03-03 20:06:10 -05:00
alert2 ( "workspace saved" , 1 ) ;
2017-04-18 17:09:33 -04:00
}
function loadFiles ( files ) {
for ( var i = 0 ; i < files . length ; i ++ ) {
2019-09-17 08:36:20 -04:00
var reader = new FileReader ( ) ,
lower = files [ i ] . name . toLowerCase ( ) ,
2020-02-26 20:23:32 -05:00
israw = lower . indexOf ( ".raw" ) > 0 || lower . indexOf ( '.' ) < 0 ,
2017-04-18 17:09:33 -04:00
isstl = lower . indexOf ( ".stl" ) > 0 ,
2019-09-17 08:36:20 -04:00
issvg = lower . indexOf ( ".svg" ) > 0 ,
2017-04-18 17:09:33 -04:00
isgcode = lower . indexOf ( ".gcode" ) > 0 || lower . indexOf ( ".nc" ) > 0 ;
reader . file = files [ i ] ;
reader . onloadend = function ( e ) {
2020-02-14 09:28:51 -05:00
if ( israw ) platformAdd (
newWidget ( ) . loadVertices ( JSON . parse ( e . target . result ) . toFloat32 ( ) )
) ;
2019-09-17 08:36:20 -04:00
if ( isstl ) platformAdd (
2017-04-18 17:09:33 -04:00
newWidget ( )
. loadVertices ( new MOTO . STL ( ) . parse ( e . target . result ) )
. saveToCatalog ( e . target . file . name )
) ;
2019-09-17 08:36:20 -04:00
if ( isgcode ) loadCode ( e . target . result , 'gcode' ) ;
if ( issvg ) loadCode ( e . target . result , 'svg' ) ;
2017-04-18 17:09:33 -04:00
} ;
reader . readAsBinaryString ( reader . file ) ;
}
}
function loadFile ( ) {
$ ( 'load-file' ) . onchange = function ( event ) {
DBUG . log ( event ) ;
loadFiles ( event . target . files ) ;
} ;
$ ( 'load-file' ) . click ( ) ;
2019-01-18 16:46:17 -05:00
// alert2("drag/drop STL files onto platform to import\nreload page to return to last saved state");
2017-04-18 17:09:33 -04:00
}
// kiri api
function getSettings ( ) {
return settings ;
}
// kiri api
function putSettings ( newset ) {
settings = newset ;
saveSettings ( )
restoreWorkspace ( null , true ) ;
}
2020-03-01 19:00:36 -05:00
function updateOrigin ( ) {
2020-03-01 19:47:34 -05:00
let dev = settings . device ;
let proc = settings . process ;
let x = 0 ;
let y = 0 ;
let z = 0 ;
2020-03-01 21:24:14 -05:00
if ( MODE === MODES . CAM && proc . camOriginTop ) {
z = camTopZ + 0.01 ;
2020-03-03 20:06:10 -05:00
if ( ! camStock ) {
z += proc . camZTopOffset ;
}
2020-03-01 19:47:34 -05:00
}
if ( ! proc . outputOriginCenter ) {
if ( camStock ) {
2020-03-03 20:06:10 -05:00
x = ( - camStock . scale . x / 2 ) + camStock . position . x ;
y = ( camStock . scale . y / 2 ) - camStock . position . y ;
2020-03-01 19:47:34 -05:00
} else {
x = - dev . bedWidth / 2 ;
y = dev . bedDepth / 2 ;
}
2020-03-03 20:06:10 -05:00
} else if ( camStock ) {
x = camStock . position . x ;
y = - camStock . position . y ;
}
settings . origin = { x , y , z } ;
if ( settings . controller . showOrigin ) {
SPACE . platform . setOrigin ( x , y , z ) ;
} else {
SPACE . platform . setOrigin ( ) ;
2020-03-01 19:00:36 -05:00
}
}
2017-04-18 17:09:33 -04:00
function updatePlatformSize ( ) {
var dev = settings . device ,
width , depth ,
height = Math . round ( Math . max ( dev . bedHeight , dev . bedWidth / 100 , dev . bedDepth / 100 ) ) ;
2020-02-29 20:13:49 -05:00
SPACE . platform . setRound ( dev . bedRound ) ;
2017-04-18 17:09:33 -04:00
SPACE . platform . setGZOff ( height / 2 - 0.1 ) ;
SPACE . platform . setSize (
width = parseInt ( dev . bedWidth ) ,
depth = parseInt ( dev . bedDepth ) ,
height
) ;
SPACE . platform . setHidden ( width > 500 || depth > 500 ) ;
2020-03-01 19:00:36 -05:00
updateOrigin ( ) ;
2017-04-18 17:09:33 -04:00
}
function restoreWorkspace ( ondone , skipwidgets ) {
var loaded = 0 ,
toload = ls2o ( 'ws-widgets' , [ ] ) ,
newset = ls2o ( 'ws-settings' ) ,
camera = ls2o ( 'ws-camera' ) ,
2020-03-03 20:06:10 -05:00
position = true ;
2017-04-18 17:09:33 -04:00
if ( newset ) {
fillMissingSettings ( settingsDefault , newset ) ;
settings = newset ;
// override camera from settings
if ( settings . controller . view ) {
camera = settings . controller . view ;
SDB . removeItem ( 'ws-camera' ) ;
UI . reverseZoom . checked = settings . controller . reverseZoom ;
}
// merge custom filters from localstorage into settings
localFilters . forEach ( function ( fname ) {
var fkey = "gcode-filter-" + fname , ov = ls2o ( fkey ) ;
if ( ov ) settings . devices [ fname ] = ov ;
SDB . removeItem ( fkey )
} ) ;
SDB . removeItem ( localFilterKey ) ;
// save updated settings
saveSettings ( ) ;
}
updateFields ( ) ;
updatePlatformSize ( ) ;
updateCamStock ( ) ;
SPACE . view . reset ( ) ;
if ( camera ) SPACE . view . load ( camera ) ;
else setTimeout ( SPACE . view . home , 100 ) ;
if ( skipwidgets ) return ;
2019-05-07 14:35:39 -04:00
forAllWidgets ( function ( widget ) {
2017-04-18 17:09:33 -04:00
platformDelete ( widget ) ;
} ) ;
toload . forEach ( function ( widgetid ) {
Widget . loadFromState ( widgetid , function ( widget ) {
2020-03-03 20:06:10 -05:00
if ( widget ) {
platformAdd ( widget , 0 , position ) ;
}
2017-04-18 17:09:33 -04:00
if ( ++ loaded === toload . length ) {
widgetDeselect ( ) ;
2020-03-03 20:06:10 -05:00
if ( ondone ) {
ondone ( ) ;
2020-03-08 11:04:07 -04:00
// if ((newset || settings).mode != 'CAM') {
2020-03-03 20:06:10 -05:00
setTimeout ( ( ) => {
updateWidgetsTopZ ( ) ;
SPACE . update ( ) ;
} , 1 ) ;
2020-03-08 11:04:07 -04:00
// };
2020-03-03 20:06:10 -05:00
}
2017-04-18 17:09:33 -04:00
}
2020-03-03 20:06:10 -05:00
} , position ) ;
2017-04-18 17:09:33 -04:00
} ) ;
return toload . length > 0 ;
}
function clearWorkspace ( ) {
// free up worker cache/mem
KIRI . work . clear ( ) ;
platformSelectAll ( ) ;
platformDelete ( selectedMeshes ) ;
}
function modalShowing ( ) {
2020-02-06 16:22:43 -05:00
var showing = $ ( 'modal' ) . style . display !== 'none' ;
2018-02-01 09:31:03 -05:00
return showing || UC . isPopped ( ) ;
2017-04-18 17:09:33 -04:00
}
function showModal ( which ) {
UI . modal . style . display = 'block' ;
2020-02-06 16:22:43 -05:00
[ "print" , "help" , "local" ] . forEach ( function ( modal ) {
2017-04-18 17:09:33 -04:00
UI [ modal ] . style . display = ( modal === which ? 'block' : 'none' ) ;
} ) ;
}
function hideDialog ( ) {
showDialog ( null ) ;
}
function showDialog ( which , force ) {
2018-02-02 09:02:07 -05:00
if ( UC . isPopped ( ) ) {
UC . hidePop ( ) ;
return ;
}
2017-04-18 17:09:33 -04:00
[ "catalog" , "devices" , "tools" , "settings" ] . forEach ( function ( dialog ) {
var style = UI [ dialog ] . style ;
2018-02-01 09:31:03 -05:00
style . display = ( dialog === which && ( force || style . display !== 'flex' ) ? 'flex' : 'none' ) ;
2017-04-18 17:09:33 -04:00
} ) ;
}
function showCatalog ( ) {
showDialog ( "catalog" ) ;
}
2019-07-23 12:54:26 -04:00
function editNamedSetting ( e ) {
var mode = getMode ( ) ,
name = e . target . getAttribute ( "name" ) ,
load = settings . sproc [ mode ] [ name ] ,
edit = prompt ( ` settings for " ${ name } " ` , JSON . stringify ( load ) ) ;
if ( edit ) {
try {
settings . sproc [ mode ] [ name ] = JSON . parse ( edit ) ;
2019-07-23 21:12:40 -04:00
if ( name === settings . process . processName ) {
loadNamedSetting ( null , name ) ;
}
2019-07-24 09:56:16 -04:00
saveSettings ( ) ;
2019-07-23 12:54:26 -04:00
} catch ( e ) {
alert ( 'malformed settings object' ) ;
}
}
}
2018-01-31 10:42:55 -05:00
function loadNamedSetting ( e , named ) {
2019-07-23 21:12:40 -04:00
var mode = getMode ( ) ,
name = e ? e . target . getAttribute ( "load" ) : named || settings . cproc [ mode ] ,
load = settings . sproc [ mode ] [ name ] ;
2017-04-18 17:09:33 -04:00
if ( ! load ) return ;
2019-07-23 21:12:40 -04:00
2017-04-18 17:09:33 -04:00
for ( var k in load ) {
if ( ! load . hasOwnProperty ( k ) ) continue ;
2018-02-14 20:47:35 -05:00
// prevent stored process from overwriting device defaults
2020-03-03 20:06:10 -05:00
//if (k === "outputOriginCenter" && mode == "FDM") continue;
2017-04-18 17:09:33 -04:00
settings . process [ k ] = load [ k ] ;
}
2019-07-23 21:12:40 -04:00
2017-04-18 17:09:33 -04:00
settings . process . processName = name ;
2018-02-14 20:47:35 -05:00
settings . cproc [ mode ] = name ;
2019-03-30 17:22:38 -04:00
2018-01-31 10:42:55 -05:00
// associate named process with the current device
settings . devproc [ currentDeviceName ( ) ] = name ;
2019-05-24 09:06:51 -04:00
// update selection display (off for laser)
2019-05-25 17:52:52 -04:00
$ ( 'selected-device' ) . innerHTML = currentDeviceName ( ) ;
2019-03-30 17:22:38 -04:00
$ ( 'selected-process' ) . innerHTML = name ;
2019-05-24 09:06:51 -04:00
$ ( 'selected' ) . style . display = ( mode !== 'LASER' ) ? 'block' : 'none' ;
2019-03-30 17:22:38 -04:00
2020-03-03 20:06:10 -05:00
// FDM process settings overridden by device
if ( mode == "FDM" ) {
settings . process . outputOriginCenter = ( settings . device . originCenter || false ) ;
}
2017-04-18 17:09:33 -04:00
updateFields ( ) ;
2018-01-31 10:42:55 -05:00
if ( ! named ) {
hideDialog ( ) ;
}
2017-04-18 17:09:33 -04:00
updateSettings ( ) ;
if ( e ) triggerSettingsEvent ( ) ;
}
function deleteNamedSetting ( e ) {
var name = e . target . getAttribute ( "del" ) ;
delete settings . sproc [ getMode ( ) ] [ name ] ;
updateSettingsList ( ) ;
saveSettings ( ) ;
triggerSettingsEvent ( ) ;
}
function updateSettingsList ( ) {
var list = [ ] , s = settings , sp = s . sproc [ getMode ( ) ] || { } , table = UI . settingsList ;
table . innerHTML = '' ;
for ( var k in sp ) {
if ( sp . hasOwnProperty ( k ) ) list . push ( k ) ;
}
list . sort ( ) . forEach ( function ( sk ) {
var row = DOC . createElement ( 'div' ) ,
load = DOC . createElement ( 'button' ) ,
2019-07-23 12:54:26 -04:00
edit = DOC . createElement ( 'button' ) ,
2017-04-18 17:09:33 -04:00
del = DOC . createElement ( 'button' ) ,
name = sk ;
load . setAttribute ( 'load' , sk ) ;
load . onclick = loadNamedSetting ;
load . appendChild ( DOC . createTextNode ( sk ) ) ;
2017-12-14 20:41:19 -05:00
if ( sk == settings . process . processName ) {
load . setAttribute ( 'class' , 'selected' )
}
2017-04-18 17:09:33 -04:00
del . setAttribute ( 'del' , sk ) ;
del . setAttribute ( 'title' , "remove '" + sk + "'" ) ;
del . onclick = deleteNamedSetting ;
del . appendChild ( DOC . createTextNode ( 'x' ) ) ;
2019-07-23 12:54:26 -04:00
edit . innerHTML = '↑' ;
edit . setAttribute ( 'name' , sk ) ;
edit . setAttribute ( 'title' , 'edit' ) ;
edit . onclick = editNamedSetting ;
2017-04-18 17:09:33 -04:00
row . setAttribute ( "class" , "flow-row" ) ;
2019-07-23 12:54:26 -04:00
row . appendChild ( edit ) ;
2017-04-18 17:09:33 -04:00
row . appendChild ( load ) ;
row . appendChild ( del ) ;
table . appendChild ( row ) ;
} ) ;
onControlResize ( ) ;
}
function showSettings ( ) {
updateSettingsList ( ) ;
showDialog ( "settings" ) ;
}
function onWindowResize ( ) {
onControlResize ( ) ;
}
function onControlResize ( ) {
var left = UI . ctrlLeft . getBoundingClientRect ( ) ,
right = UI . ctrlRight . getBoundingClientRect ( ) ;
UI . catalog . style . left = ( left . width + 5 ) + 'px' ;
UI . devices . style . left = ( left . width + 5 ) + 'px' ;
UI . tools . style . left = ( left . width + 5 ) + 'px' ;
UI . settings . style . right = ( right . width + 5 ) + 'px' ;
}
function hideModal ( ) {
UI . modal . style . display = 'none' ;
}
function showHelpLocal ( ) {
2020-02-08 16:50:14 -05:00
showHelp ( "/kiri/help.html" ) ;
2017-04-18 17:09:33 -04:00
}
function showHelp ( local ) {
hideDialog ( ) ;
if ( ! local ) {
WIN . open ( "//wiki.grid.space/wiki/Kiri:Moto" , "_help" ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( 'ua_help' ) ;
2017-04-18 17:09:33 -04:00
return ;
}
ajax ( local , function ( html ) {
UI . help . innerHTML = html ;
$ ( 'help-close' ) . onclick = hideModal ;
2019-04-16 07:45:24 -04:00
$ ( 'kiri-version' ) . innerHTML = ` <i> ${ LANG . version } ${ KIRI . version } </i> ` ;
2017-04-18 17:09:33 -04:00
showModal ( 'help' ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( 'ua_help' ) ;
2017-04-18 17:09:33 -04:00
} ) ;
}
2020-02-06 16:22:43 -05:00
function showLocal ( ) {
$ ( 'local-close' ) . onclick = hideModal ;
showModal ( 'local' ) ;
fetch ( "/api/grid_local" )
. then ( r => r . json ( ) )
. then ( j => {
let bind = [ ] ;
let html = [ '<table>' ] ;
html . push ( ` <thead><tr><th>device</th><th>type</th><th>status</th><th></th></tr></thead> ` ) ;
html . push ( ` <tbody> ` ) ;
for ( let k in j ) {
let r = j [ k ] . stat ;
bind . push ( { uuid : r . device . uuid , host : r . device . addr [ 0 ] , post : r . device . port } ) ;
html . push ( ` <tr> ` ) ;
html . push ( ` <td> ${ r . device . name } </td> ` ) ;
html . push ( ` <td> ${ r . device . mode } </td> ` ) ;
html . push ( ` <td> ${ r . state } </td> ` ) ;
html . push ( ` <td><button id=" ${ r . device . uuid } ">admin</button></td> ` ) ;
html . push ( ` </tr> ` ) ;
}
html . push ( ` </tbody> ` ) ;
html . push ( ` </table> ` ) ;
$ ( 'local-dev' ) . innerHTML = html . join ( '' ) ;
bind . forEach ( rec => {
$ ( rec . uuid ) . onclick = ( ) => {
window . open ( ` http:// ${ rec . host } : ${ rec . port || 4080 } / ` ) ;
} ;
} ) ;
} ) ;
}
2017-04-18 17:09:33 -04:00
function takeFocus ( el ) {
DOC . activeElement . blur ( ) ;
2020-02-25 20:42:48 -05:00
el = [ el || DOC . body , UI . ctrlLeft , UI . container , UI . assets , UI . control , UI . modeFDM , UI . reverseZoom , UI . modelOpacity , DOC . body ] ;
2017-04-18 17:09:33 -04:00
for ( var es , i = 0 ; i < el . length ; i ++ ) {
es = el [ i ] ;
es . focus ( ) ;
if ( DOC . activeElement === es ) {
break ;
}
}
UI . ctrlLeft . focus ( ) ;
UI . container . focus ( ) ;
//console.log({focus: DOC.activeElement});
}
function setViewMode ( mode ) {
var oldMode = viewMode ;
viewMode = mode ;
widgetDeselect ( ) ;
meshUpdateInfo ( ) ;
[ UI . modeArrange , UI . modeSlice , UI . modePreview ] . forEach ( function ( b ) {
b . removeAttribute ( "class" ) ;
} ) ;
switch ( mode ) {
case VIEWS . ARRANGE :
updateSliderMax ( ) ;
UI . layerView . style . display = 'none' ;
UI . modeArrange . setAttribute ( "class" , "buton" ) ;
break ;
case VIEWS . SLICE :
2019-01-18 20:41:10 -05:00
UI . layerView . style . display = 'flex' ;
2017-04-18 17:09:33 -04:00
UI . modeSlice . setAttribute ( "class" , "buton" ) ;
updateSliderMax ( ) ;
break ;
case VIEWS . PREVIEW :
2019-01-18 20:41:10 -05:00
UI . layerView . style . display = 'flex' ;
2017-04-18 17:09:33 -04:00
UI . modePreview . setAttribute ( "class" , "buton" ) ;
break ;
default :
DBUG . log ( "invalid view mode: " + mode ) ;
return ;
}
2019-03-30 13:45:57 -04:00
DOC . activeElement . blur ( ) ;
2017-04-18 17:09:33 -04:00
}
function inMode ( mode ) {
return settings . mode === mode ;
}
function getMode ( ) {
return settings . mode ;
}
2020-03-07 13:14:22 -05:00
function getModeLower ( ) {
return getMode ( ) . toLowerCase ( ) ;
}
2020-02-08 21:01:00 -05:00
function switchMode ( mode ) {
setMode ( mode , updatePlatformSize ) ;
}
2017-04-18 17:09:33 -04:00
function setMode ( mode , lock , then ) {
hideModal ( ) ;
hideDialog ( ) ;
if ( ! MODES [ mode ] ) {
DBUG . log ( "invalid mode: " + mode ) ;
mode = 'FDM' ;
}
settings . mode = mode ;
// restore cached device profile for this mode
2020-02-10 17:41:59 -05:00
if ( settings . cdev [ mode ] ) {
settings . device = clone ( settings . cdev [ mode ] ) ;
}
2018-01-07 11:16:16 -05:00
// update device stat for FDM/CAM
2020-03-07 13:14:22 -05:00
STATS . set ( ` ud_ ${ getModeLower ( ) } ` , settings . filter [ mode ] || 'default' ) ;
2017-04-18 17:09:33 -04:00
MODE = MODES [ mode ] ;
UC . setMode ( MODE ) ;
loadNamedSetting ( ) ;
saveSettings ( ) ;
clearWidgetCache ( ) ;
SPACE . update ( ) ;
UI . modeFDM . setAttribute ( 'class' , MODE === MODES . FDM ? 'buton' : '' ) ;
UI . modeLASER . setAttribute ( 'class' , MODE === MODES . LASER ? 'buton' : '' ) ;
UI . modeCAM . setAttribute ( 'class' , MODE === MODES . CAM ? 'buton' : '' ) ;
UI . mode . style . display = lock ? 'none' : '' ;
UI . modeTable . style . display = lock ? 'none' : '' ;
if ( camStock ) camStock . material . visible = settings . mode === 'CAM' ;
restoreWorkspace ( null , true ) ;
2020-03-03 20:06:10 -05:00
// if (MODE !== MODES.FDM) layoutPlatform();
2017-04-18 17:09:33 -04:00
if ( then ) then ( ) ;
triggerSettingsEvent ( ) ;
}
2018-01-31 10:42:55 -05:00
function currentDeviceName ( ) {
return settings . filter [ getMode ( ) ] ;
}
2017-04-18 17:09:33 -04:00
function setControlsVisible ( show ) {
UI . ctrlLeft . style . display = show ? 'block' : 'none' ;
UI . ctrlRight . style . display = show ? 'block' : 'none' ;
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* LETS _GET _THIS _PARTY _STARTED ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function init ( ) {
if ( kiri . init ) return ;
kiri . init = init ;
var assets = $ ( 'assets' ) ,
control = $ ( 'control' ) ,
container = $ ( 'container' ) ,
welcome = $ ( 'welcome' ) ,
selectedTool = null ,
editTools = null ,
ROT = Math . PI / 2 ,
ROT5 = ROT / 9 ,
ALL = [ MODES . FDM , MODES . LASER , MODES . CAM ] ,
CAM = [ MODES . CAM ] ,
FDM = [ MODES . FDM ] ,
FDM _CAM = [ MODES . CAM , MODES . FDM ] ,
FDM _LASER = [ MODES . LASER , MODES . FDM ] ,
CAM _LASER = [ MODES . LASER , MODES . CAM ] ,
LASER = [ MODES . LASER ] ;
WIN . addEventListener ( "resize" , onWindowResize ) ;
SPACE . showSkyGrid ( false ) ;
2019-05-23 16:52:55 -04:00
SPACE . setSkyColor ( 0xffffff ) ;
2017-04-18 17:09:33 -04:00
SPACE . init ( container , function ( delta ) {
if ( showLayerMax === 0 ) return ;
if ( settings . controller . reverseZoom ) delta = - delta ;
if ( delta > 0 ) showLayerValue -- ;
else if ( delta < 0 ) showLayerValue ++ ;
showSlices ( ) ;
} ) ;
SPACE . platform . onMove ( saveSettings ) ;
2020-02-29 20:13:49 -05:00
SPACE . platform . setRound ( true ) ;
2017-04-18 17:09:33 -04:00
set ( UI , {
container : container ,
ctrlLeft : $ ( 'control-left' ) ,
ctrlRight : $ ( 'control-right' ) ,
layerView : $ ( 'layer-view' ) ,
layerSlider : $ ( 'layer-slider' ) ,
2020-02-25 20:42:48 -05:00
modelOpacity : $ ( 'opacity' ) ,
2017-04-18 17:09:33 -04:00
assets : assets ,
control : control ,
modal : $ ( 'modal' ) ,
print : $ ( 'print' ) ,
2020-02-06 16:22:43 -05:00
local : $ ( 'local' ) ,
2017-04-18 17:09:33 -04:00
help : $ ( 'help' ) ,
2019-01-18 16:36:14 -05:00
alert : {
dialog : $ ( 'alert-area' ) ,
text : $ ( 'alert-text' )
} ,
2017-04-18 17:09:33 -04:00
devices : $ ( 'devices' ) ,
deviceAdd : $ ( 'device-add' ) ,
deviceDelete : $ ( 'device-del' ) ,
deviceSave : $ ( 'device-save' ) ,
deviceClose : $ ( 'device-close' ) ,
deviceSelect : $ ( 'device-select' ) ,
2019-04-12 09:45:52 -04:00
deviceFavorites : $ ( 'device-favorites' ) ,
deviceAll : $ ( 'device-all' ) ,
2017-04-18 17:09:33 -04:00
device : UC . newGroup ( "device" , $ ( 'device' ) ) ,
2020-03-03 20:06:10 -05:00
deviceName : UC . newInput ( LANG . dev _name , { size : 20 , text : true } ) ,
2019-04-12 12:47:22 -04:00
setDeviceFilament : UC . newInput ( LANG . dev _fil , { title : LANG . dev _fil _desc , convert : UC . toFloat , modes : FDM } ) ,
setDeviceNozzle : UC . newInput ( LANG . dev _nozl , { title : LANG . dev _nozl _desc , convert : UC . toFloat , modes : FDM } ) ,
setDeviceWidth : UC . newInput ( LANG . dev _bedw , { title : LANG . dev _bedw _desc , convert : UC . toInt } ) ,
setDeviceDepth : UC . newInput ( LANG . dev _bedd , { title : LANG . dev _bedd _desc , convert : UC . toInt } ) ,
setDeviceHeight : UC . newInput ( LANG . dev _bedhm , { title : LANG . dev _bedhm _desc , convert : UC . toInt , modes : FDM } ) ,
setDeviceMaxSpindle : UC . newInput ( LANG . dev _spmax , { title : LANG . dev _spmax _desc , convert : UC . toInt , modes : CAM } ) ,
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 } ) ,
2020-02-29 20:13:49 -05:00
setDeviceRound : UC . newBoolean ( LANG . dev _bedc , onBooleanClick , { title : LANG . dev _bedc _desc , modes : FDM } ) ,
2017-04-18 17:09:33 -04:00
setDevice : UC . newGroup ( "gcode" , $ ( 'device' ) ) ,
2019-04-16 07:45:24 -04:00
setDeviceFan : UC . newInput ( LANG . dev _fanp , { title : LANG . dev _fanp _desc , modes : FDM , size : 15 } ) ,
setDeviceTrack : UC . newInput ( LANG . dev _prog , { title : LANG . dev _prog _desc , modes : FDM , size : 15 } ) ,
setDeviceLayer : UC . newText ( LANG . dev _layer , { title : LANG . dev _layer _desc , modes : FDM , size : 14 , height : 2 } ) ,
setDeviceToken : UC . newBoolean ( LANG . dev _token , null , { title : LANG . dev _token _desc , modes : CAM } ) ,
setDeviceStrip : UC . newBoolean ( LANG . dev _strip , null , { title : LANG . dev _strip _desc , modes : CAM } ) ,
setDeviceFExt : UC . newInput ( LANG . dev _fext , { title : LANG . dev _fext _desc , modes : CAM , size : 5 } ) ,
setDeviceDwell : UC . newText ( LANG . dev _dwell , { title : LANG . dev _dwell _desc , modes : CAM , size : 14 , height : 2 } ) ,
setDeviceChange : UC . newText ( LANG . dev _tool , { title : LANG . dev _tool _desc , modes : CAM , size : 14 , height : 2 } ) ,
setDeviceSpindle : UC . newText ( LANG . dev _speed , { title : LANG . dev _speed _desc , modes : CAM , size : 14 , height : 2 } ) ,
setDevicePause : UC . newText ( LANG . dev _pause , { title : LANG . dev _pause _desc , modes : FDM , size : 14 , height : 3 } ) ,
setDevicePre : UC . newText ( LANG . dev _head , { title : LANG . dev _head _desc , modes : FDM _CAM , size : 14 , height : 3 } ) ,
setDevicePost : UC . newText ( LANG . dev _foot , { title : LANG . dev _foot _desc , modes : FDM _CAM , size : 14 , height : 3 } ) ,
2017-04-18 17:09:33 -04:00
tools : $ ( 'tools' ) ,
toolsSave : $ ( 'tools-save' ) ,
toolsClose : $ ( 'tools-close' ) ,
toolSelect : $ ( 'tool-select' ) ,
toolAdd : $ ( 'tool-add' ) ,
toolDelete : $ ( 'tool-del' ) ,
toolType : $ ( 'tool-type' ) ,
toolName : $ ( 'tool-name' ) ,
toolNum : $ ( 'tool-num' ) ,
toolFluteDiam : $ ( 'tool-fdiam' ) ,
toolFluteLen : $ ( 'tool-flen' ) ,
toolShaftDiam : $ ( 'tool-sdiam' ) ,
toolShaftLen : $ ( 'tool-slen' ) ,
toolMetric : $ ( 'tool-metric' ) ,
catalog : $ ( 'catalog' ) ,
catalogBody : $ ( 'catalogBody' ) ,
catalogList : $ ( 'catalogList' ) ,
settings : $ ( 'settings' ) ,
settingsBody : $ ( 'settingsBody' ) ,
settingsList : $ ( 'settingsList' ) ,
layerID : $ ( 'layer-id' ) ,
layerSpan : $ ( 'layer-span' ) ,
layerRange : $ ( 'layer-range' ) ,
loading : $ ( 'loading' ) . style ,
progress : $ ( 'progress' ) . style ,
prostatus : $ ( 'prostatus' ) ,
selection : $ ( 'selection' ) ,
selWidth : $ ( 'sel_width' ) ,
selHeight : $ ( 'sel_height' ) ,
selDepth : $ ( 'sel_depth' ) ,
scaleX : $ ( 'scale_x' ) ,
scaleY : $ ( 'scale_y' ) ,
scaleZ : $ ( 'scale_z' ) ,
scaleUniform : $ ( 'scale_uni' ) ,
2020-02-25 20:42:48 -05:00
stock : $ ( 'stock' ) ,
stockWidth : $ ( 'stock-width' ) ,
stockDepth : $ ( 'stock-width' ) ,
stockHeight : $ ( 'stock-width' ) ,
2017-04-18 17:09:33 -04:00
mode : UC . newGroup ( 'mode' , assets ) ,
modeTable : UC . newTableRow ( [
[
UI . modeFDM =
UC . newButton ( "FDM Printing" , function ( ) { setMode ( 'FDM' , null , updatePlatformSize ) } ) ,
] , [
UI . modeLASER =
UC . newButton ( "Laser Cutting" , function ( ) { setMode ( 'LASER' , null , updatePlatformSize ) } ) ,
] , [
UI . modeCAM =
UC . newButton ( "CNC Milling" , function ( ) { setMode ( 'CAM' , null , updatePlatformSize ) } , { id : "modeCAM" } ) ,
]
] ) ,
system : UC . newGroup ( 'setup' ) ,
sysTable : UC . newTableRow ( [
[
UI . setupDevices =
UC . newButton ( "Devices" , showDevices , { modes : FDM _CAM } )
] , [
UI . setupTools =
2020-02-06 16:22:43 -05:00
UC . newButton ( "Tools" , showTools , { modes : CAM } )
] , [
UI . localButton =
UC . newButton ( "Local" , showLocal , { modes : FDM _CAM } )
2017-04-18 17:09:33 -04:00
] , [
UI . helpButton =
2020-02-08 21:13:54 -05:00
UC . newButton ( "Help" , showHelpLocal )
2017-04-18 17:09:33 -04:00
]
] ) ,
wsFunc : UC . newGroup ( 'function' ) ,
wsFuncTable : UC . newTableRow ( [
[
UC . newButton ( "Import" , function ( ) { KIRI . api . import ( ) } ) ,
UI . import =
UC . newButton ( "+" )
] , [
UI . modeArrange =
UC . newButton ( "Arrange" , layoutPlatform ) ,
] , [
UI . modeSlice =
UC . newButton ( "Slice" , prepareSlices )
] , [
UI . modePreview =
UC . newButton ( "Preview" , preparePrint ) ,
] , [
UI . modeExport =
UC . newButton ( "Export" , exportPrint )
]
] ) ,
camera : UC . newGroup ( 'view' ) ,
camTable : UC . newTableRow ( [
[
UC . newButton ( "home" , SPACE . view . home ) ,
UC . newButton ( "reset" , SPACE . view . reset )
] , [
UC . newButton ( "top" , SPACE . view . top ) ,
UC . newButton ( "front" , SPACE . view . front ) ,
] , [
UC . newButton ( "left" , SPACE . view . left ) ,
UC . newButton ( "right" , SPACE . view . right )
]
] ) ,
2020-02-25 21:53:48 -05:00
2020-03-08 11:04:07 -04:00
workspace : UC . newGroup ( 'workspace' ) ,
wsTable : UC . newTableRow ( [
[
UI . saveButton =
UC . newButton ( "Save" , saveWorkspace ) ,
] , [
UC . newButton ( "Clear" , clearWorkspace )
]
] ) ,
2020-02-25 20:42:48 -05:00
layout : UC . newGroup ( 'options' ) ,
2020-03-01 19:00:36 -05:00
showOrigin : UC . newBoolean ( "show origin" , booleanSave , { title : "show device or process origin" } ) ,
2020-03-08 11:04:07 -04:00
alignTop : UC . newBoolean ( "align top" , booleanSave , { title : "align parts to the\ntallest part when\nno stock is set" , modes : [ 42 ] } ) ,
2020-02-25 20:42:48 -05:00
autoLayout : UC . newBoolean ( "auto layout" , booleanSave , { title : "automatically layout platform\nwhen new items added\nor when arrange clicked\nmore than once" } ) ,
freeLayout : UC . newBoolean ( "free layout" , booleanSave , { title : "permit dragable layout" } ) ,
reverseZoom : UC . newBoolean ( "invert zoom" , booleanSave , { title : "invert mouse wheel\nscroll zoom" } ) ,
2020-03-08 11:04:07 -04:00
units : UC . newSelectField ( "units" , { modes : CAM } , "units" ) ,
2017-04-18 17:09:33 -04:00
2020-02-25 21:53:48 -05:00
appendLeft : UC . checkpoint ( ) ,
2017-04-18 17:09:33 -04:00
layers : UC . setGroup ( $ ( "layers" ) ) ,
2020-02-25 20:42:48 -05:00
layerOutline : UC . newBoolean ( "outline" , onLayerToggle , { modes : LOCAL ? ALL : FDM _LASER } ) ,
layerTrace : UC . newBoolean ( "trace" , onLayerToggle , { modes : FDM _LASER } ) ,
layerFacing : UC . newBoolean ( "facing" , onLayerToggle , { modes : CAM } ) ,
layerRough : UC . newBoolean ( "roughing" , onLayerToggle , { modes : CAM } ) ,
layerFinish : UC . newBoolean ( "finishing" , onLayerToggle , { modes : CAM } ) ,
layerFinishX : UC . newBoolean ( "finish x" , onLayerToggle , { modes : CAM } ) ,
layerFinishY : UC . newBoolean ( "finish y" , onLayerToggle , { modes : CAM } ) ,
layerDelta : UC . newBoolean ( "delta" , onLayerToggle , { modes : FDM } ) ,
layerSolid : UC . newBoolean ( "solids" , onLayerToggle , { modes : FDM } ) ,
layerFill : UC . newBoolean ( "solid fill" , onLayerToggle , { modes : FDM } ) ,
layerSparse : UC . newBoolean ( "sparse fill" , onLayerToggle , { modes : FDM } ) ,
layerSupport : UC . newBoolean ( "support" , onLayerToggle , { modes : FDM } ) ,
layerPrint : UC . newBoolean ( "print" , onLayerToggle ) ,
2017-04-18 17:09:33 -04:00
settingsGroup : UC . newGroup ( "settings" , control ) ,
settingsTable : UC . newTableRow ( [
[
UI . settingsLoad =
UC . newButton ( "load" , settingsLoad ) ,
UI . settingsSave =
2017-12-15 08:54:39 -05:00
UC . newButton ( "save" , settingsSave )
2020-02-08 17:41:48 -05:00
] , [
UI . settingsExpert =
2020-02-10 11:30:11 -05:00
UC . newButton ( "expert" , ( ) => { UC . setExpert ( true ) ; SDB . setItem ( 'expert' , true ) } , { modes : FDM , expert : false } ) ,
2020-02-08 17:41:48 -05:00
UI . settingsExpert =
2020-02-10 11:30:11 -05:00
UC . newButton ( "basic" , ( ) => { UC . setExpert ( false ) ; SDB . removeItem ( 'expert' ) } , { modes : FDM , expert : true } )
2017-04-18 17:09:33 -04:00
]
] ) ,
platform : UC . newGroup ( "build area" , control , { modes : LASER } ) ,
bedWidth : UC . newInput ( "width" , { title : "millimeters" , convert : UC . toInt , modes : LASER } ) ,
bedDepth : UC . newInput ( "depth" , { title : "millimeters" , convert : UC . toInt , modes : LASER } ) ,
2019-05-02 15:09:54 -04:00
process : UC . newGroup ( "slicing" , control , { modes : FDM _LASER } ) ,
2017-04-18 17:09:33 -04:00
// 3d print
2018-01-20 18:37:00 -05:00
sliceHeight : UC . newInput ( "layer height" , { title : "millimeters" , convert : UC . toFloat , modes : FDM } ) ,
2017-04-18 17:09:33 -04:00
sliceShells : UC . newInput ( "shell count" , { convert : UC . toInt , modes : FDM } ) ,
2019-05-02 21:56:20 -04:00
sliceTopLayers : UC . newInput ( "top layers" , { title : "top solid layer count" , convert : UC . toInt , modes : FDM } ) ,
2017-12-08 14:51:05 -05:00
sliceSolidLayers : UC . newInput ( "solid layers" , { title : "flat area fill projections\nbased on layer deltas" , convert : UC . toInt , modes : FDM } ) ,
sliceBottomLayers : UC . newInput ( "base layers" , { title : "bottom solid layer count" , convert : UC . toInt , modes : FDM } ) ,
2019-05-02 15:09:54 -04:00
process : UC . newGroup ( "fill" , control , { modes : FDM } ) ,
sliceFillType : UC . newSelectField ( "type" , { modes : FDM } , "infill" ) ,
2019-05-02 21:52:54 -04:00
sliceFillSparse : UC . newInput ( "percentage" , { title : "for infill areas\n0.0 - 1.0" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 1.0 ) , modes : FDM } ) ,
2020-02-08 17:41:48 -05:00
sliceFillAngle : UC . newInput ( "solid angle" , { title : "base angle in degrees" , convert : UC . toFloat , modes : FDM , expert : true } ) ,
sliceFillOverlap : UC . newInput ( "overlap" , { title : "overlap with shell and fill\nas % of nozzle width\nhigher bonds better\n0.0 - 1.0" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 2.0 ) , modes : FDM , expert : true } ) ,
firstLayer : UC . newGroup ( "first layer" , null , { modes : FDM } ) ,
firstSliceHeight : UC . newInput ( "layer height" , { title : "in millimeters\nshould be >= slice height" , convert : UC . toFloat , modes : FDM } ) ,
firstLayerRate : UC . newInput ( "shell speed" , { title : "print move max speed\nmillimeters / minute" , convert : UC . toFloat , modes : FDM } ) ,
firstLayerFillRate : UC . newInput ( "fill speed" , { title : "fill move max speed\nmillimeters / minute" , convert : UC . toFloat , modes : FDM } ) ,
firstLayerPrintMult : UC . newInput ( "print factor" , { title : "extrusion multiplier\n0.0 - 2.0" , convert : UC . toFloat , modes : FDM , expert : true } ) ,
outputBrimCount : UC . newInput ( "skirt count" , { title : "number of skirts" , convert : UC . toInt , modes : FDM } ) ,
outputBrimOffset : UC . newInput ( "skirt offset" , { title : "millimeters" , convert : UC . toFloat , modes : FDM } ) ,
firstLayerNozzleTemp : UC . newInput ( "nozzle temp" , { title : "degrees celsius\nused when non-zero" , convert : UC . toInt , modes : FDM , expert : true } ) ,
firstLayerBedTemp : UC . newInput ( "bed temp" , { title : "degrees celsius\nused when non-zero" , convert : UC . toInt , modes : FDM , expert : true } ) ,
2017-04-18 17:09:33 -04:00
2019-05-03 12:56:28 -04:00
support : UC . newGroup ( "support" , null , { modes : FDM } ) ,
sliceSupportDensity : UC . newInput ( "density" , { title : "0.0 - 1.0\nrecommended 0.15\n0 to disable" , convert : UC . toFloat , bound : UC . bound ( 0.05 , 1.0 ) , modes : FDM } ) ,
sliceSupportSize : UC . newInput ( "pillar size" , { title : "width in millimeters" , bound : UC . bound ( 1.0 , 200.0 ) , convert : UC . toFloat , modes : FDM } ) ,
sliceSupportOffset : UC . newInput ( "part offset" , { title : "millimeters\noffset from part" , bound : UC . bound ( 0.0 , 200.0 ) , convert : UC . toFloat , modes : FDM } ) ,
2020-02-08 17:41:48 -05:00
sliceSupportGap : UC . newInput ( "gap layers" , { title : "number of layers\noffset from part" , bound : UC . bound ( 0 , 5 ) , convert : UC . toInt , modes : FDM , expert : true } ) ,
2019-05-03 12:56:28 -04:00
sliceSupportSpan : UC . newInput ( "max bridge" , { title : "span length that\ntriggers support\nin millimeters" , bound : UC . bound ( 0.0 , 200.0 ) , convert : UC . toFloat , modes : FDM } ) ,
sliceSupportArea : UC . newInput ( "min area" , { title : "min area for a\nsupport column\nin millimeters" , bound : UC . bound ( 0.1 , 200.0 ) , convert : UC . toFloat , modes : FDM } ) ,
2020-02-08 17:41:48 -05:00
sliceSupportExtra : UC . newInput ( "expand" , { title : "expand support area\nbeyond part boundary\nin millimeters" , bound : UC . bound ( 0.0 , 200.0 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
2019-05-03 12:56:28 -04:00
sliceSupportEnable : UC . newBoolean ( "enable" , onBooleanClick , { modes : FDM } ) ,
2019-05-25 17:52:52 -04:00
laserOffset : UC . newInput ( "offset" , { title : "nadjust for beam width\nin millimeters" , convert : UC . toFloat , modes : LASER } ) ,
2019-05-23 16:52:55 -04:00
laserSliceHeight : UC . newInput ( "height" , { title : "millimeters\n0 = auto/detect" , convert : UC . toFloat , modes : LASER } ) ,
laserSliceSingle : UC . newBoolean ( "single" , onBooleanClick , { title : "perform one slice\nat specified height" , modes : LASER } ) ,
2017-04-18 17:09:33 -04:00
2020-02-05 16:19:36 -05:00
camCommon : UC . newGroup ( "common" , null , { modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
camFastFeed : UC . newInput ( "rapid feed" , { title : "rapid moves feedrate\nin workspace units / minute" , convert : UC . toInt , modes : CAM } ) ,
2020-02-05 16:19:36 -05:00
2017-04-18 17:09:33 -04:00
roughing : UC . newGroup ( "roughing" , null , { modes : CAM } ) ,
roughingTool : UC . newSelectField ( "tool" , { modes : CAM } ) ,
roughingSpindle : UC . newInput ( "spindle rpm" , { title : "spindle speed rpm" , convert : UC . toInt , modes : CAM } ) ,
roughingOver : UC . newInput ( "step over" , { title : "0.1 - 1.0\npercentage of\ntool diameter" , convert : UC . toFloat , bound : UC . bound ( 0.1 , 1.0 ) , modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
roughingDown : UC . newInput ( "step down" , { title : "step down depth\nfor each pass\nin workspace units\n0 to disable" , convert : UC . toFloat , modes : CAM } ) ,
roughingSpeed : UC . newInput ( "feed rate" , { title : "max speed while cutting\workspace units / minute" , convert : UC . toInt , modes : CAM } ) ,
roughingPlunge : UC . newInput ( "plunge rate" , { title : "max speed on z axis\workspace units / minute" , convert : UC . toInt , modes : CAM } ) ,
roughingStock : UC . newInput ( "leave stock" , { title : "horizontal offset from vertical faces\nstock to leave for finishing pass\nin workspace units" , convert : UC . toFloat , modes : CAM } ) ,
2020-02-15 11:30:02 -05:00
camPocketOnlyRough : UC . newBoolean ( "pocket only" , onBooleanClick , { title : "constrain to\npart boundaries" , modes : CAM } ) ,
2020-02-08 16:50:14 -05:00
camEaseDown : UC . newBoolean ( "ease down" , onBooleanClick , { title : "plunge cuts will\nspiral down or ease\nalong a linear path\nas they cut downward" , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
roughingOn : UC . newBoolean ( "enable" , onBooleanClick , { modes : CAM } ) ,
finishing : UC . newGroup ( "finishing" , null , { modes : CAM } ) ,
finishingTool : UC . newSelectField ( "tool" , { modes : CAM } ) ,
finishingSpindle : UC . newInput ( "spindle rpm" , { title : "spindle speed rpm" , convert : UC . toInt , modes : CAM } ) ,
2020-02-05 13:59:18 -05:00
finishingOver : UC . newInput ( "step over" , { title : "0.05 - 1.0\npercentage of\ntool diameter\nfor linear XY" , convert : UC . toFloat , bound : UC . bound ( 0.05 , 1.0 ) , modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
finishingDown : UC . newInput ( "step down" , { title : "step down depth\nfor each pass\nin workspace units\n0 to disable" , convert : UC . toFloat , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
finishingAngle : UC . newInput ( "max angle" , { title : "angles greater than this\nare considered vertical" , convert : UC . toFloat , bound : UC . bound ( 45 , 90 ) , modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
finishingSpeed : UC . newInput ( "feed rate" , { title : "max speed while cutting\workspace units / minute" , convert : UC . toInt , modes : CAM } ) ,
finishingPlunge : UC . newInput ( "plunge rate" , { title : "max speed on z axis\workspace units / minute" , convert : UC . toInt , modes : CAM } ) ,
2020-02-15 11:30:02 -05:00
camPocketOnlyFinish : UC . newBoolean ( "pocket only" , onBooleanClick , { title : "constrain to\npart boundaries" , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
finishingOn : UC . newBoolean ( "waterline" , onBooleanClick , { title : "contour finishing\ndisabled when pocketing" , modes : CAM } ) ,
finishingXOn : UC . newBoolean ( "linear x" , onBooleanClick , { title : "linear x-axis finishing" , modes : CAM } ) ,
finishingYOn : UC . newBoolean ( "linear y" , onBooleanClick , { title : "linear y-axis finishing" , modes : CAM } ) ,
finishCurvesOnly : UC . newBoolean ( "curves only" , onBooleanClick , { title : "limit linear cleanup\nto curved surfaces\nto reduce time" , modes : CAM } ) ,
drilling : UC . newGroup ( "drilling" , null , { modes : CAM } ) ,
drillTool : UC . newSelectField ( "tool" , { modes : CAM } ) ,
drillSpindle : UC . newInput ( "spindle rpm" , { title : "spindle speed rpm" , convert : UC . toInt , modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
drillDown : UC . newInput ( "plunge per" , { title : "max plunge between\ndwell periods\nin workspace units\n0 to disable" , convert : UC . toFloat , modes : CAM } ) ,
drillDownSpeed : UC . newInput ( "plunge rate" , { title : "plunge rate\nin workspace units / minute\n0 to disable" , convert : UC . toFloat , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
drillDwell : UC . newInput ( "dwell time" , { title : "dwell time\nbetween plunges in\nin milliseconds" , convert : UC . toFloat , modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
drillLift : UC . newInput ( "drill lift" , { title : "lift between plunges\nafter dwell period\nin workspace units\n0 to disable" , convert : UC . toFloat , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
drillingOn : UC . newBoolean ( "enable" , onBooleanClick , { modes : CAM } ) ,
camTabs : UC . newGroup ( "cutout tabs" , null , { modes : CAM } ) ,
2020-03-05 11:53:54 -05:00
camTabsAngle : UC . newInput ( "angle" , { title : "starting angle for tab spacing\nin degrees" , convert : UC . toInt , bound : UC . bound ( 0 , 360 ) , modes : CAM } ) ,
camTabsCount : UC . newInput ( "count" , { title : "number of tabs to use\nwill be spaced evenly\naround the part" , convert : UC . toInt , bound : UC . bound ( 1 , 20 ) , modes : CAM } ) ,
2020-03-08 11:24:28 -04:00
camTabsWidth : UC . newInput ( "width" , { title : "width in workspace units\nperpendicular to part" , convert : UC . toFloat , bound : UC . bound ( 0.1 , 100 ) , modes : CAM } ) ,
camTabsHeight : UC . newInput ( "height" , { title : "height in workspace units\nfrom part bottom" , convert : UC . toFloat , bound : UC . bound ( 0.1 , 100 ) , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
camTabsOn : UC . newBoolean ( "enable" , onBooleanClick , { title : "enable or disable tabs\ntab generation skipped when\npocket only mode enabled" , modes : CAM } ) ,
2019-05-03 12:56:28 -04:00
output : UC . newGroup ( "raft" , null , { modes : FDM } ) ,
outputRaftSpacing : UC . newInput ( "spacing" , { title : "additional layer spacing\nbetween 1st layer and raft\nin millimeters" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 3.0 ) , modes : FDM } ) ,
outputRaft : UC . newBoolean ( "enable" , onBooleanClick , { title : "create a raft under the\nmodel for better adhesion\nuses skirt offset and\ndisables skirt output" , modes : FDM } ) ,
2017-04-18 17:09:33 -04:00
output : UC . newGroup ( "output" ) ,
outputTileSpacing : UC . newInput ( "spacing" , { title : "millimeters\ndistance between layer output" , convert : UC . toInt , modes : LASER } ) ,
outputTileScaling : UC . newInput ( "scaling" , { title : "multiplier (0.1 to 100)" , convert : UC . toInt , bound : UC . bound ( 0.1 , 100 ) , modes : LASER } ) ,
outputLaserPower : UC . newInput ( "power" , { title : "0 - 100 %" , convert : UC . toInt , bound : UC . bound ( 1 , 100 ) , modes : LASER } ) ,
outputLaserSpeed : UC . newInput ( "speed" , { title : "millimeters / minute" , convert : UC . toInt , modes : LASER } ) ,
2019-05-24 09:06:51 -04:00
outputLaserGroup : UC . newBoolean ( "layer group" , onBooleanClick , { title : "retain layer as\nsingle grouped object" , modes : LASER } ) ,
2017-04-18 17:09:33 -04:00
outputTemp : UC . newInput ( "nozzle temp" , { title : "degrees celsius" , convert : UC . toInt , modes : FDM } ) ,
2019-03-30 17:06:16 -04:00
outputBedTemp : UC . newInput ( "bed temp" , { title : "degrees celsius" , convert : UC . toInt , modes : FDM } ) ,
2017-04-18 17:09:33 -04:00
outputFeedrate : UC . newInput ( "print speed" , { title : "print move max speed\nmillimeters / minute" , convert : UC . toInt , modes : FDM } ) ,
2017-12-06 21:15:37 -05:00
outputFinishrate : UC . newInput ( "finish speed" , { title : "outermost shell speed\nmillimeters / minute" , convert : UC . toInt , modes : FDM } ) ,
2018-01-16 20:34:37 -05:00
outputSeekrate : UC . newInput ( "move speed" , { title : "non-print move speed\nmillimeters / minute\n0 = enable G0 moves" , convert : UC . toInt , modes : FDM } ) ,
2017-04-18 17:09:33 -04:00
outputShellMult : UC . newInput ( "shell factor" , { title : "extrusion multiplier\n0.0 - 2.0" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 2.0 ) , modes : FDM } ) ,
2017-11-10 15:02:14 -05:00
outputFillMult : UC . newInput ( "solid factor" , { title : "extrusion multiplier\n0.0 - 2.0" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 2.0 ) , modes : FDM } ) ,
2017-11-10 15:18:25 -05:00
outputSparseMult : UC . newInput ( "infill factor" , { title : "extrusion multiplier\n0.0 - 2.0" , convert : UC . toFloat , bound : UC . bound ( 0.0 , 2.0 ) , modes : FDM } ) ,
2020-02-08 17:41:48 -05:00
outputFanLayer : UC . newInput ( "fan layer" , { title : "layer to enable fan" , convert : UC . toInt , bound : UC . bound ( 0 , 100 ) , modes : FDM , expert : true } ) ,
2018-01-23 18:09:34 -05:00
2020-03-08 11:04:07 -04:00
camTolerance : UC . newInput ( "tolerance" , { title : "surface precision\nin workspace units" , convert : UC . toFloat , bound : UC . bound ( 0.05 , 1.0 ) , modes : CAM } ) ,
camZTopOffset : UC . newInput ( "z top offset" , { title : "offset from stock surface\nto top face of part\nin workspace units" , convert : UC . toFloat , modes : CAM } ) ,
camZBottom : UC . newInput ( "z bottom" , { title : "offset from part bottom\nto limit cutting depth\nin workspace units" , convert : UC . toFloat , modes : CAM } ) ,
2020-03-08 11:24:28 -04:00
camZClearance : UC . newInput ( "z clearance" , { title : "travel offset from z top\nin workspace units" , convert : UC . toFloat , bound : UC . bound ( 0.01 , 100 ) , modes : CAM } ) ,
2020-02-15 11:30:02 -05:00
// camPocketOnly: UC.newBoolean("pocket only", onBooleanClick, {title:"constrain to\npart boundaries", modes:CAM}),
2017-04-18 17:09:33 -04:00
camDepthFirst : UC . newBoolean ( "depth first" , onBooleanClick , { title : "optimize pocket cuts\nwith depth priority" , modes : CAM } ) ,
outputClockwise : UC . newBoolean ( "clockwise" , onBooleanClick , { title : "waterline milling direction" , modes : CAM } ) ,
camStock : UC . newGroup ( "stock" , null , { modes : CAM } ) ,
2020-03-08 11:04:07 -04:00
camStockX : UC . newInput ( "width" , { title : "width (x) in workspace units\n0 defaults to part size" , convert : UC . toFloat , bound : UC . bound ( 0 , 9999 ) , modes : CAM } ) ,
camStockY : UC . newInput ( "depth" , { title : "depth (y) in workspace units\n0 defaults to part size" , convert : UC . toFloat , bound : UC . bound ( 0 , 9999 ) , modes : CAM } ) ,
camStockZ : UC . newInput ( "height" , { title : "height (z) in workspace units\n0 defaults to part size" , convert : UC . toFloat , bound : UC . bound ( 0 , 9999 ) , modes : CAM } ) ,
2020-02-25 20:42:48 -05:00
camStockOffset : UC . newBoolean ( "offset" , onBooleanClick , { title : "use width, depth, height\nas offsets from max\npart size on platform" , modes : CAM } ) ,
2017-04-18 17:09:33 -04:00
outputOriginCenter : UC . newBoolean ( "origin center" , onBooleanClick , { modes : CAM _LASER } ) ,
camOriginTop : UC . newBoolean ( "origin top" , onBooleanClick , { modes : CAM } ) ,
2020-02-08 17:41:48 -05:00
advanced : UC . newGroup ( "advanced" , null , { modes : FDM , expert : true } ) ,
outputRetractDist : UC . newInput ( "retract dist" , { title : "amount to retract filament\nfor long moves. in millimeters" , convert : UC . toFloat , modes : FDM , expert : true } ) ,
outputRetractSpeed : UC . newInput ( "retract rate" , { title : "speed of filament\nretraction in mm/s" , convert : UC . toInt , modes : FDM , expert : true } ) ,
outputRetractDwell : UC . newInput ( "engage dwell" , { title : "time between re-engaging\nfilament and movement\nin milliseconds" , convert : UC . toInt , modes : FDM , expert : true } ) ,
outputCoastDist : UC . newInput ( "shell coast" , { title : "non-printing end\nof perimeter shells\nin millimeters" , bound : UC . bound ( 0.0 , 10 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
// outputWipeDistance: UC.newInput("wipe", {title:"non-printing move at\close of polygon\nin millimeters", bound:UC.bound(0.0,10), convert:UC.toFloat, modes:FDM, expert: true}),
sliceSolidMinArea : UC . newInput ( "min solid" , { title : "minimum area (mm^2)\nrequired to keep solid\nmust be > 0.1" , convert : UC . toFloat , modes : FDM , expert : true } ) ,
sliceMinHeight : UC . newInput ( "min layer" , { title : "enables adaptive slicing with\nthis as the min layer height\nin millimeters\n0 to disable" , bound : UC . bound ( 0 , 3.0 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
outputMinSpeed : UC . newInput ( "min speed" , { title : "minimum speed\nfor short segments" , bound : UC . bound ( 5 , 200 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
outputShortPoly : UC . newInput ( "slow poly" , { title : "polygons shorter than this\nwill have their print speed\nscaled down to min speed\nin millimeters" , bound : UC . bound ( 0 , 200 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
zHopDistance : UC . newInput ( "z hop dist" , { title : "amount to raise z\non retraction moves\nin millimeters\n0 to disable" , bound : UC . bound ( 0 , 3.0 ) , convert : UC . toFloat , modes : FDM , expert : true } ) ,
antiBacklash : UC . newInput ( "anti-backlash" , { title : "use micro-movements to cancel\nbacklash during fills\nin millimeters" , bound : UC . bound ( 0 , 3 ) , convert : UC . toInt , modes : FDM , expert : true } ) ,
2020-03-04 15:07:06 -05:00
// detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM, expert: true})
2020-03-05 22:26:33 -05:00
polishLayers : LOCAL ? UC . newInput ( "polish layers" , { title : "polish up to specified\n# of layers at a time" , bound : UC . bound ( 0 , 10 ) , convert : UC . toFloat , modes : FDM , expert : true } ) : null ,
polishSpeed : LOCAL ? UC . newInput ( "polish speed" , { title : "polishing speed\nin millimeters / minute" , bound : UC . bound ( 10 , 2000 ) , convert : UC . toInt , modes : FDM , expert : true } ) : null ,
2020-02-08 17:41:48 -05:00
outputLayerRetract : UC . newBoolean ( "layer retract" , onBooleanClick , { title : "force filament retraction\nbetween layers" , modes : FDM , expert : true } ) ,
gcodeVars : UC . newGroup ( "gcode" , null , { modes : FDM , expert : true } ) ,
gcodeNozzle : UC . newInput ( "nozzle" , { title : "select output nozzle" , convert : UC . toInt , modes : FDM , expert : true } ) ,
gcodePauseLayers : UC . newInput ( "pause layers" , { title : "comma-separated list of layers\nto inject pause commands before" , modes : FDM , expert : true } )
2017-04-18 17:09:33 -04:00
} ) ;
function toolUpdate ( a , b , c ) {
DBUG . log ( [ 'toolUpdate' , a , b , c ] )
}
2020-02-25 20:42:48 -05:00
function booleanSave ( ) {
2020-03-01 19:00:36 -05:00
settings . controller . showOrigin = UI . showOrigin . checked ;
2020-02-25 20:42:48 -05:00
settings . controller . autoLayout = UI . autoLayout . checked ;
settings . controller . freeLayout = UI . freeLayout . checked ;
2020-03-08 11:04:07 -04:00
settings . controller . alignTop = UI . alignTop . checked ;
2017-04-18 17:09:33 -04:00
settings . controller . reverseZoom = UI . reverseZoom . checked ;
SPACE . view . setZoom ( settings . controller . reverseZoom , settings . controller . zoomSpeed ) ;
2020-03-01 19:00:36 -05:00
updateOrigin ( ) ;
2017-04-18 17:09:33 -04:00
saveSettings ( ) ;
}
2020-02-25 20:42:48 -05:00
function onLayerToggle ( ) {
2017-04-18 17:09:33 -04:00
updateSettings ( ) ;
showSlices ( ) ;
}
2020-02-25 20:42:48 -05:00
function onBooleanClick ( ) {
updateSettings ( ) ;
}
2020-02-06 16:22:43 -05:00
function inputHasFocus ( ) {
var active = DOC . activeElement ;
return active && ( active . nodeName === "INPUT" || active . nodeName === "TEXTAREA" ) ;
}
2020-03-03 20:06:10 -05:00
function inputTextOK ( ) {
return DOC . activeElement === UI . deviceName ;
}
2020-02-06 16:22:43 -05:00
function textAreaHasFocus ( ) {
var active = DOC . activeElement ;
return active && active . nodeName === "TEXTAREA" ;
}
function inputSize ( ) {
return parseInt ( DOC . activeElement . size ) ;
}
function cca ( c ) {
return c . charCodeAt ( 0 ) ;
}
2017-04-18 17:09:33 -04:00
function keyUpHandler ( evt ) {
switch ( evt . keyCode ) {
// escape
case 27 :
2018-03-07 12:39:46 -05:00
// blur text input focus
DOC . activeElement . blur ( ) ;
2017-04-18 17:09:33 -04:00
// dismiss modals
hideModal ( ) ;
// deselect widgets
widgetDeselect ( ) ;
// hide all dialogs
hideDialog ( ) ;
// cancel slicing
2018-03-14 17:47:40 -04:00
if ( KIRI . work . isSlicing ( ) ) KIRI . work . restart ( ) ;
2017-04-18 17:09:33 -04:00
break ;
}
return false ;
}
function keyDownHandler ( evt ) {
2020-03-03 20:06:10 -05:00
if ( modalShowing ( ) ) {
return false ;
}
2017-04-18 22:22:29 -04:00
var move = evt . altKey ? 5 : 0 ,
2017-04-18 17:09:33 -04:00
deg = move ? 0 : - Math . PI / ( evt . shiftKey ? 36 : 2 ) ;
switch ( evt . keyCode ) {
2018-03-19 12:17:30 +05:30
case 8 : // apple: delete/backspace
case 46 : // others: delete
2017-04-18 17:09:33 -04:00
if ( inputHasFocus ( ) ) return false ;
if ( selectedMeshes . length > 0 ) {
platformDelete ( selectedMeshes ) ;
}
evt . preventDefault ( ) ;
break ;
case 37 : // left arrow
if ( inputHasFocus ( ) ) return false ;
// if (selectedMeshes.length === 0) return;
if ( deg ) rotateSelection ( 0 , 0 , - deg ) ;
if ( move > 0 ) moveSelection ( - move , 0 , 0 ) ;
evt . preventDefault ( ) ;
break ;
case 39 : // right arrow
if ( inputHasFocus ( ) ) return false ;
// if (selectedMeshes.length === 0) return;
if ( deg ) rotateSelection ( 0 , 0 , deg ) ;
if ( move > 0 ) moveSelection ( move , 0 , 0 ) ;
evt . preventDefault ( ) ;
break ;
case 38 : // up arrow
if ( inputHasFocus ( ) ) return false ;
if ( evt . metaKey ) return setVisibleLayer ( showLayerValue + 1 ) ;
// if (selectedMeshes.length === 0) return;
if ( deg ) rotateSelection ( deg , 0 , 0 ) ;
if ( move > 0 ) moveSelection ( 0 , move , 0 ) ;
evt . preventDefault ( ) ;
break ;
case 40 : // down arrow
if ( inputHasFocus ( ) ) return false ;
if ( evt . metaKey ) return setVisibleLayer ( showLayerValue - 1 ) ;
// if (selectedMeshes.length === 0) return;
if ( deg ) rotateSelection ( - deg , 0 , 0 ) ;
if ( move > 0 ) moveSelection ( 0 , - move , 0 ) ;
evt . preventDefault ( ) ;
break ;
case 65 : // 'a' for select all
if ( evt . metaKey ) {
if ( inputHasFocus ( ) ) return false ;
evt . preventDefault ( ) ;
widgetDeselect ( ) ;
platformSelectAll ( ) ;
}
break ;
case 83 : // 's' for save workspace
if ( evt . ctrlKey ) {
evt . preventDefault ( ) ;
saveSettings ( ) ;
log ( "settings saved" ) ;
} else
if ( evt . metaKey ) {
evt . preventDefault ( ) ;
saveWorkspace ( ) ;
}
break ;
case 76 : // 'l' for restore workspace
if ( evt . metaKey ) {
evt . preventDefault ( ) ;
restoreWorkspace ( ) ;
}
break ;
}
}
function keyHandler ( evt ) {
var handled = true ,
style , sel , i , m , bb ,
ncc = evt . charCode - 48 ;
2020-03-03 20:06:10 -05:00
if ( modalShowing ( ) || inputHasFocus ( ) ) {
return false ;
}
2017-04-18 17:09:33 -04:00
switch ( evt . charCode ) {
case cca ( '`' ) : showSlices ( 0 ) ; break ;
case cca ( '0' ) : showSlices ( showLayerMax ) ; break ;
case cca ( '1' ) : // toggle control left
if ( evt . ctrlKey ) {
style = UI . ctrlLeft . style ;
style . display = style . display === 'none' ? 'block' : 'none' ;
} else {
showSlices ( showLayerMax / 10 ) ;
}
break ;
case cca ( '2' ) : // toggle control right
if ( evt . ctrlKey ) {
style = UI . ctrlRight . style ;
style . display = style . display === 'none' ? 'block' : 'none' ;
} else {
showSlices ( showLayerMax * 2 / 10 ) ;
}
break ;
case cca ( '3' ) :
if ( evt . ctrlKey ) {
style = ! SPACE . platform . isHidden ( ) ;
SPACE . platform . setHidden ( style ) ;
SPACE . platform . showGrid ( ! style ) ;
SPACE . update ( ) ;
} else {
showSlices ( showLayerMax * 3 / 10 ) ;
}
break ;
case cca ( '4' ) : showSlices ( showLayerMax * 4 / 10 ) ; break ;
case cca ( '5' ) : showSlices ( showLayerMax * 5 / 10 ) ; break ;
case cca ( '6' ) : showSlices ( showLayerMax * 6 / 10 ) ; break ;
case cca ( '7' ) : showSlices ( showLayerMax * 7 / 10 ) ; break ;
case cca ( '8' ) : showSlices ( showLayerMax * 8 / 10 ) ; break ;
case cca ( '9' ) : showSlices ( showLayerMax * 9 / 10 ) ; break ;
case cca ( '?' ) :
showHelpLocal ( ) ;
break ;
case cca ( 'Z' ) : // reset stored state
if ( confirm ( 'clear all settings?' ) ) {
SDB . clear ( ) ;
}
break ;
case cca ( 'C' ) : // refresh catalog
CATALOG . refresh ( ) ;
break ;
2018-09-08 10:51:43 -04:00
case cca ( 'i' ) : // single settings edit
2018-09-08 10:53:59 -04:00
var v = prompt ( 'edit "' + settings . process . processName + '"' , JSON . stringify ( settings . process ) ) ;
2018-09-08 10:51:43 -04:00
if ( v ) {
try {
settings . process = JSON . parse ( v ) ;
updateFields ( ) ;
} catch ( e ) {
console . log ( e ) ;
2019-01-18 16:46:17 -05:00
alert2 ( "invalid settings format" ) ;
2018-09-08 10:51:43 -04:00
}
}
break ;
2018-01-10 20:31:14 -05:00
case cca ( 'U' ) : // full settings url
2018-01-11 08:01:42 -05:00
storeSettingsToServer ( true ) ;
break ;
case cca ( 'u' ) : // full settings url
loadSettingsFromServer ( prompt ( "settings id to load" ) ) ;
2018-01-10 20:04:51 -05:00
break ;
2017-04-18 17:09:33 -04:00
case cca ( 's' ) : // complete slice
prepareSlices ( ) ;
break ;
case cca ( 'p' ) : // prepare print
preparePrint ( ) ;
break ;
case cca ( 'P' ) : // position widget
positionSelection ( ) ;
break ;
2017-06-08 08:49:48 -04:00
case cca ( 'R' ) : // position widget
rotateInputSelection ( ) ;
break ;
2017-04-18 17:09:33 -04:00
case cca ( 'x' ) : // export print
exportPrint ( ) ;
break ;
case cca ( 'e' ) : // devices
showDevices ( ) ;
break ;
case cca ( 'o' ) : // tools
showTools ( ) ;
break ;
2020-02-06 16:22:43 -05:00
case cca ( 'c' ) : // local devices
showLocal ( ) ;
break ;
2017-04-18 17:09:33 -04:00
case cca ( 'v' ) : // toggle single slice view mode
UI . layerRange . checked = ! UI . layerRange . checked ;
showSlices ( ) ;
break ;
case cca ( 'd' ) : // duplicate object
sel = selectedMeshes . slice ( ) ;
widgetDeselect ( ) ;
for ( i = 0 ; i < sel . length ; i ++ ) {
m = sel [ i ] . clone ( ) ;
m . geometry = m . geometry . clone ( ) ;
m . material = m . material . clone ( ) ;
bb = m . getBoundingBox ( ) ;
var nw = newWidget ( ) . loadGeometry ( m . geometry ) ;
nw . move ( bb . max . x - bb . min . x + 1 , 0 , 0 ) ;
platformAdd ( nw , true ) ;
}
break ;
case cca ( 'm' ) : // mirror object
forSelectedWidgets ( function ( widget ) {
widget . mirror ( ) ;
} ) ;
SPACE . update ( ) ;
break ;
case cca ( 'R' ) : // toggle slice render mode
renderMode ++ ;
prepareSlices ( ) ;
break ;
case cca ( 'a' ) : // auto arrange items on platform
layoutPlatform ( ) ;
break ;
case cca ( 'w' ) : // toggle wireframe on widgets
toggleWireframe ( wireframe _color , wireframe _model _opacity ) ;
break ;
default :
sendOnEvent ( 'keypress' , evt ) ;
handled = false ;
break ;
}
if ( handled ) evt . preventDefault ( ) ;
return false ;
}
function keys ( o ) {
var key , list = [ ] ;
for ( key in o ) { if ( o . hasOwnProperty ( key ) ) list . push ( key ) }
return list . sort ( ) ;
}
function clearSelected ( children ) {
for ( var i = 0 ; i < children . length ; i ++ ) {
children [ i ] . setAttribute ( 'class' , '' ) ;
}
}
2017-06-08 08:49:48 -04:00
function rotateInputSelection ( ) {
if ( selectedMeshes . length === 0 ) {
2019-01-18 16:46:17 -05:00
alert2 ( "select object to rotate" ) ;
2017-06-08 08:49:48 -04:00
return ;
}
var coord = prompt ( "Enter X,Y,Z degrees of rotation" ) . split ( ',' ) ,
prod = Math . PI / 360 ,
x = parseFloat ( coord [ 0 ] || 0.0 ) * prod ,
y = parseFloat ( coord [ 1 ] || 0.0 ) * prod ,
z = parseFloat ( coord [ 2 ] || 0.0 ) * prod ;
rotateSelection ( x , y , z ) ;
}
2017-04-18 17:09:33 -04:00
function positionSelection ( ) {
if ( selectedMeshes . length === 0 ) {
2019-01-18 16:46:17 -05:00
alert2 ( "select object to position" ) ;
2017-04-18 17:09:33 -04:00
return ;
}
var center = settings . process . outputOriginCenter ,
bounds = boundsSelection ( ) ,
coord = prompt ( "Enter X,Y coordinates for selection" ) . split ( ',' ) ,
x = parseFloat ( coord [ 0 ] || 0.0 ) ,
y = parseFloat ( coord [ 1 ] || 0.0 ) ,
z = parseFloat ( coord [ 2 ] || 0.0 ) ;
if ( ! center ) {
x = x - settings . device . bedWidth / 2 + ( bounds . max . x - bounds . min . x ) / 2 ;
y = y - settings . device . bedDepth / 2 + ( bounds . max . y - bounds . min . y ) / 2
}
moveSelection ( x , y , z , true ) ;
}
2018-01-11 08:01:42 -05:00
function loadSettingsFromServer ( tok ) {
2018-01-11 13:42:08 -05:00
var hash = ( tok || LOC . hash . substring ( 1 ) ) . split ( "/" ) ;
2018-01-10 20:04:51 -05:00
if ( hash . length === 2 ) {
new moto . Ajax ( function ( reply ) {
if ( reply ) {
var res = JSON . parse ( reply ) ;
if ( res && res . ver && res . rec ) {
var set = JSON . parse ( atob ( res . rec ) ) ;
set . id = res . space ;
set . ver = res . ver ;
putSettings ( set ) ;
2018-01-11 13:38:28 -05:00
triggerSettingsEvent ( ) ;
2018-01-10 20:04:51 -05:00
LOC . hash = '' ;
}
}
} ) . request ( "/data/" + hash [ 0 ] + "/" + hash [ 1 ] ) ;
}
}
2018-01-11 08:01:42 -05:00
function storeSettingsToServer ( display ) {
2018-01-10 20:04:51 -05:00
var set = btoa ( JSON . stringify ( settings ) ) ;
new moto . Ajax ( function ( reply ) {
if ( reply ) {
var res = JSON . parse ( reply ) ;
if ( res && res . ver ) {
LOC . hash = res . space + "/" + res . ver ;
2019-01-22 10:03:43 -05:00
if ( display ) alert ( "unique settings id is: " + res . space + "/" + res . ver ) ;
2018-01-10 20:04:51 -05:00
}
} else {
updateSpaceState ( ) ;
}
} ) . request ( "/data/" + settings . id + "/" + settings . ver , set ) ;
}
2017-04-18 17:09:33 -04:00
function settingsSave ( ) {
hideDialog ( ) ;
var mode = getMode ( ) ,
s = settings ,
def = "default" ,
cp = s . process ,
pl = s . sproc [ mode ] ,
pt = sf [ mode . toLowerCase ( ) ] . p , // process field mask
name = WIN . prompt ( "Save Settings As" , cp ? cp . processName || def : def ) ;
if ( ! name ) return ;
var np = pl [ name ] = { } ;
cp . processName = name ;
for ( var k in cp ) {
if ( ! cp . hasOwnProperty ( k ) ) continue ;
if ( ! pt . hasOwnProperty ( k ) ) continue ; // mask out invalid fields
np [ k ] = cp [ k ] ;
}
s . cproc [ getMode ( ) ] = name ;
saveSettings ( ) ;
triggerSettingsEvent ( ) ;
}
function settingsLoad ( ) {
showSettings ( ) ;
}
function putLocalDevice ( devicename , code ) {
settings . devices [ devicename ] = code ;
saveSettings ( ) ;
}
function removeLocalDevice ( devicename ) {
delete settings . devices [ devicename ] ;
saveSettings ( ) ;
}
function isLocalDevice ( devicename ) {
return settings . devices [ devicename ] ? true : false ;
// return localFilters.contains(devicename);
}
2019-04-12 09:45:52 -04:00
function isFavoriteDevice ( devicename ) {
return settings . favorites [ devicename ] ? true : false ;
}
2017-04-18 17:09:33 -04:00
function getSelectedDevice ( ) {
return UI . deviceSelect . options [ UI . deviceSelect . selectedIndex ] . text ;
}
2017-11-03 19:55:18 -04:00
function selectDevice ( devicename , lock ) {
deviceLock = lock ;
if ( lock ) UI . setupDevices . style . display = 'none' ;
2017-04-18 17:09:33 -04:00
if ( inMode ( 'LASER' ) ) return ;
if ( isLocalDevice ( devicename ) ) {
setDeviceCode ( settings . devices [ devicename ] , devicename ) ;
} else {
ajax ( "/kiri/filter/" + getMode ( ) + "/" + devicename , function ( code ) {
setDeviceCode ( code , devicename ) ;
} ) ;
}
2019-03-30 17:22:38 -04:00
$ ( 'selected-device' ) . innerHTML = devicename ;
2017-04-18 17:09:33 -04:00
}
function valueOf ( val , dv ) {
return typeof ( val ) !== 'undefined' ? val : dv ;
}
// only for local filters
function updateDeviceCode ( override ) {
var oldname = getSelectedDevice ( ) ,
newname = override || UI . deviceName . value ,
code = {
mode : getMode ( ) ,
settings : {
bed _width : parseInt ( UI . setDeviceWidth . value ) || 300 ,
bed _depth : parseInt ( UI . setDeviceDepth . value ) || 175 ,
2020-02-29 20:13:49 -05:00
bed _circle : UI . setDeviceRound . checked ,
2017-04-18 17:09:33 -04:00
build _height : parseInt ( UI . setDeviceHeight . value ) || 150 ,
nozzle _size : parseFloat ( UI . setDeviceNozzle . value ) || 0.4 ,
filament _diameter : parseFloat ( UI . setDeviceFilament . value ) || 1.75 ,
origin _center : UI . setDeviceOrigin . checked ,
origin _top : UI . setDeviceOriginTop . checked ,
2017-10-10 15:38:47 -04:00
extrude _abs : UI . setDeviceExtrusion . checked ,
2017-04-18 17:09:33 -04:00
spindle _max : parseInt ( UI . setDeviceMaxSpindle . value ) || 0
} ,
cmd : {
fan _power : UI . setDeviceFan . value ,
2018-01-02 12:36:03 -05:00
progress : UI . setDeviceTrack . value ,
2018-04-21 18:06:39 -04:00
spindle : UI . setDeviceSpindle . value . split ( '\n' ) ,
2018-01-02 12:36:03 -05:00
layer : UI . setDeviceLayer . value . split ( '\n' )
2017-04-18 17:09:33 -04:00
} ,
pre : UI . setDevicePre . value . split ( '\n' ) ,
post : UI . setDevicePost . value . split ( '\n' ) ,
2018-02-01 09:31:03 -05:00
pause : UI . setDevicePause . value . split ( '\n' ) ,
dwell : UI . setDeviceDwell . value . split ( '\n' ) ,
2017-04-18 17:09:33 -04:00
'tool-change' : UI . setDeviceChange . value . split ( '\n' ) ,
'file-ext' : UI . setDeviceFExt . value ,
'token-space' : UI . setDeviceToken . checked ? ' ' : '' ,
'strip-comments' : UI . setDeviceStrip . checked
} ;
if ( oldname !== newname && isLocalDevice ( oldname ) ) removeLocalDevice ( oldname ) ;
putLocalDevice ( newname , code ) ;
setDeviceCode ( code , newname ) ;
}
function setDeviceCode ( code , devicename ) {
try {
2020-03-07 13:14:22 -05:00
STATS . set ( ` ud_ ${ getModeLower ( ) } ` , devicename ) ;
2018-01-07 11:16:16 -05:00
2017-04-18 17:09:33 -04:00
if ( typeof ( code ) === 'string' ) code = js2o ( code ) || { } ;
var cmd = code . cmd || { } ,
set = code . settings || { } ,
2018-01-31 10:42:55 -05:00
local = isLocalDevice ( devicename ) ,
2020-02-18 19:45:00 -05:00
dproc = settings . devproc [ devicename ] ,
mode = getMode ( ) ;
2020-03-06 09:33:24 -05:00
2017-04-18 17:09:33 -04:00
settings . device = {
bedHeight : 2.5 ,
bedWidth : valueOf ( set . bed _width , 300 ) ,
bedDepth : valueOf ( set . bed _depth , 175 ) ,
2020-02-29 20:13:49 -05:00
bedRound : valueOf ( set . bed _circle , false ) ,
2017-04-18 17:09:33 -04:00
maxHeight : valueOf ( set . build _height , 150 ) ,
nozzleSize : valueOf ( set . nozzle _size , 0.4 ) ,
filamentSize : valueOf ( set . filament _diameter , 1.75 ) ,
2020-03-03 20:06:10 -05:00
originCenter : valueOf ( set . origin _center , false ) ,
2017-10-10 15:38:47 -04:00
extrudeAbs : valueOf ( set . extrude _abs , false ) ,
2017-04-18 17:09:33 -04:00
spindleMax : valueOf ( set . spindle _max , 0 ) ,
gcodeFan : valueOf ( cmd . fan _power , '' ) ,
gcodeTrack : valueOf ( cmd . progress , '' ) ,
2018-01-02 12:36:03 -05:00
gcodeLayer : valueOf ( cmd . layer , [ ] ) ,
2017-04-18 17:09:33 -04:00
gcodePre : valueOf ( code . pre , [ ] ) ,
gcodePost : valueOf ( code . post , [ ] ) ,
2018-01-06 10:55:48 -05:00
gcodeProc : valueOf ( code . proc , '' ) ,
2018-02-01 09:31:03 -05:00
gcodePause : valueOf ( code . pause , [ ] ) ,
2017-04-18 17:09:33 -04:00
gcodeDwell : valueOf ( code . dwell , [ ] ) ,
2018-04-21 18:06:39 -04:00
gcodeSpindle : valueOf ( cmd . spindle , [ ] ) ,
2017-04-18 17:09:33 -04:00
gcodeChange : valueOf ( code [ 'tool-change' ] , [ ] ) ,
gcodeFExt : valueOf ( code [ 'file-ext' ] , 'gcode' ) ,
gcodeSpace : valueOf ( code [ 'token-space' ] , '' ) ,
gcodeStrip : valueOf ( code [ 'strip-comments' ] , false )
} ;
var dev = settings . device ,
proc = settings . process ;
proc . outputOriginCenter = valueOf ( set . origin _center , true ) ;
proc . camOriginTop = valueOf ( set . origin _top , true ) ;
UI . deviceName . value = devicename ;
// common
UI . setDevicePre . value = dev . gcodePre . join ( '\n' ) ;
UI . setDevicePost . value = dev . gcodePost . join ( '\n' ) ;
2018-02-01 09:31:03 -05:00
UI . setDevicePause . value = dev . gcodePause . join ( '\n' ) ;
2017-04-18 17:09:33 -04:00
UI . setDeviceWidth . value = dev . bedWidth ;
UI . setDeviceDepth . value = dev . bedDepth ;
UI . setDeviceHeight . value = dev . maxHeight ;
2020-02-29 20:13:49 -05:00
UI . setDeviceRound . checked = dev . bedRound ;
2020-03-01 19:00:36 -05:00
UI . setDeviceOrigin . checked = proc . outputOriginCenter ;
2017-04-18 17:09:33 -04:00
// FDM
UI . setDeviceFan . value = dev . gcodeFan ;
UI . setDeviceTrack . value = dev . gcodeTrack ;
2018-01-02 12:36:03 -05:00
UI . setDeviceLayer . value = dev . gcodeLayer . join ( '\n' ) ;
2017-04-18 17:09:33 -04:00
UI . setDeviceFilament . value = dev . filamentSize ;
UI . setDeviceNozzle . value = dev . nozzleSize ;
2020-03-01 19:00:36 -05:00
UI . setDeviceExtrusion . checked = dev . extrudeAbs ;
2017-04-18 17:09:33 -04:00
// CAM
UI . setDeviceMaxSpindle . value = dev . spindleMax ;
2018-04-21 18:06:39 -04:00
UI . setDeviceSpindle . value = dev . gcodeSpindle . join ( '\n' ) ;
2017-04-18 17:09:33 -04:00
UI . setDeviceDwell . value = dev . gcodeDwell . join ( '\n' ) ;
UI . setDeviceChange . value = dev . gcodeChange . join ( '\n' ) ;
UI . setDeviceFExt . value = dev . gcodeFExt ;
UI . setDeviceToken . checked = dev . gcodeSpace ? true : false ;
UI . setDeviceStrip . checked = dev . gcodeStrip ;
// disable editing for non-local devices
[
UI . deviceName ,
UI . setDevicePre ,
UI . setDevicePost ,
2018-02-01 09:31:03 -05:00
UI . setDevicePause ,
2017-04-18 17:09:33 -04:00
UI . setDeviceDepth ,
UI . setDeviceWidth ,
UI . setDeviceHeight ,
2017-10-10 15:38:47 -04:00
UI . setDeviceExtrusion ,
2017-04-18 17:09:33 -04:00
UI . setDeviceOrigin ,
UI . setDeviceOriginTop ,
2020-02-29 20:13:49 -05:00
UI . setDeviceRound ,
2017-04-18 17:09:33 -04:00
UI . setDeviceFan ,
UI . setDeviceTrack ,
2018-01-02 12:36:03 -05:00
UI . setDeviceLayer ,
2017-04-18 17:09:33 -04:00
UI . setDeviceFilament ,
UI . setDeviceNozzle ,
2018-04-21 18:06:39 -04:00
UI . setDeviceMaxSpindle ,
UI . setDeviceSpindle ,
2017-04-18 17:09:33 -04:00
UI . setDeviceDwell ,
UI . setDeviceChange ,
UI . setDeviceFExt ,
UI . setDeviceToken ,
UI . setDeviceStrip
2020-03-06 09:33:24 -05:00
] . forEach ( function ( e ) {
2017-04-18 17:09:33 -04:00
e . disabled = ! local ;
2020-03-06 09:33:24 -05:00
} ) ;
2017-04-18 17:09:33 -04:00
// hide spindle fields when device doens't support it
2020-02-18 19:45:00 -05:00
if ( mode === 'CAM' )
2017-04-18 17:09:33 -04:00
[
2020-02-05 13:59:18 -05:00
UI . setDeviceExtrusion ,
2017-04-18 17:09:33 -04:00
UI . roughingSpindle ,
UI . finishingSpindle ,
UI . drillSpindle
] . forEach ( function ( e ) {
2020-03-01 19:00:36 -05:00
e . parentNode . style . display = dev . spindleMax >= 0 ? 'none' : 'block' ;
2017-04-18 17:09:33 -04:00
} ) ;
UI . deviceSave . disabled =
UI . deviceDelete . disabled = ! local ;
updateFields ( ) ;
updatePlatformSize ( ) ;
2020-02-18 19:45:00 -05:00
settings . filter [ mode ] = devicename ;
settings . cdev [ mode ] = dev ;
2017-04-18 17:09:33 -04:00
2018-01-31 10:42:55 -05:00
// restore last process associated with this device
if ( dproc ) loadNamedSetting ( null , dproc ) ;
2017-04-18 17:09:33 -04:00
saveSettings ( ) ;
} catch ( e ) {
console . log ( { error : e , device : code } ) ;
2019-01-18 16:46:17 -05:00
// alert2("invalid or deprecated device. please select a new device.");
2017-04-18 17:09:33 -04:00
showDevices ( ) ;
}
clearWidgetCache ( ) ;
triggerSettingsEvent ( ) ;
}
function renderDevices ( devices ) {
2018-02-01 09:31:03 -05:00
UI . devices . onclick = UC . hidePop ;
UC . hidePop ( ) ;
2017-04-18 17:09:33 -04:00
var selectedIndex = - 1 ,
selected = currentDeviceName ( ) ,
devs = settings . devices ;
for ( var local in devs ) {
2020-03-06 09:33:24 -05:00
if ( ! ( devs . hasOwnProperty ( local ) && devs [ local ] ) ) {
continue ;
}
2017-04-18 17:09:33 -04:00
var dev = devs [ local ] ,
fdmCode = dev . cmd ,
fdmMode = ( getMode ( ) === 'FDM' ) ;
if ( dev . mode ? ( dev . mode === getMode ( ) ) : ( fdmCode ? fdmMode : ! fdmMode ) ) {
devices . push ( local ) ;
}
} ;
devices = devices . sort ( ) ;
UI . deviceClose . onclick = hideDialog ;
UI . deviceSave . onclick = function ( ) {
clearWidgetCache ( ) ;
updateDeviceCode ( ) ;
saveSettings ( ) ;
showDevices ( ) ;
} ;
UI . deviceAdd . onclick = function ( ) {
clearWidgetCache ( ) ;
updateDeviceCode ( getSelectedDevice ( ) + ".copy" ) ;
showDevices ( ) ;
} ;
UI . deviceDelete . onclick = function ( ) {
clearWidgetCache ( ) ;
removeLocalDevice ( getSelectedDevice ( ) ) ;
showDevices ( ) ;
} ;
2019-04-12 09:45:52 -04:00
UI . deviceAll . onclick = function ( ) {
showFavorites = SDB [ 'dev-favorites' ] = false ;
showDevices ( ) ;
} ;
UI . deviceFavorites . onclick = function ( ) {
showFavorites = SDB [ 'dev-favorites' ] = true ;
showDevices ( ) ;
} ;
2017-04-18 17:09:33 -04:00
UI . deviceSelect . innerHTML = '' ;
2019-04-12 22:06:53 -04:00
let incr = 0 ;
let found = false ;
let first = devices [ 0 ] ;
2017-04-18 17:09:33 -04:00
devices . forEach ( function ( device , index ) {
2019-04-12 09:45:52 -04:00
var opt = DOC . createElement ( 'option' ) ,
fav = isFavoriteDevice ( device ) ,
loc = isLocalDevice ( device ) ;
if ( showFavorites && ! ( fav || loc ) ) {
return ;
}
2019-04-12 22:06:53 -04:00
if ( incr === 0 ) {
first = device ;
}
2017-04-18 17:09:33 -04:00
opt . appendChild ( DOC . createTextNode ( device ) ) ;
2020-03-06 09:33:24 -05:00
opt . onclick = function ( ) {
selectDevice ( device ) ;
} ;
2019-04-12 09:45:52 -04:00
opt . ondblclick = function ( ) {
if ( settings . favorites [ device ] ) {
2020-03-06 09:33:24 -05:00
delete settings . favorites [ device ] ;
alert2 ( ` removed " ${ device } " from favorites ` , 3 ) ;
2019-04-12 09:45:52 -04:00
} else {
2020-03-06 09:33:24 -05:00
settings . favorites [ device ] = true ;
alert2 ( ` added " ${ device } " to favorites ` , 3 ) ;
2019-04-12 09:45:52 -04:00
}
showDevices ( ) ;
} ;
if ( ! showFavorites ) {
if ( fav ) opt . setAttribute ( "favorite" , 1 ) ;
if ( loc ) opt . setAttribute ( "local" , 1 ) ;
}
2017-04-18 17:09:33 -04:00
UI . deviceSelect . appendChild ( opt ) ;
2019-04-12 22:06:53 -04:00
if ( device === selected ) {
selectedIndex = incr ;
found = true ;
}
incr ++ ;
2017-04-18 17:09:33 -04:00
} ) ;
if ( selectedIndex >= 0 ) {
UI . deviceSelect . selectedIndex = selectedIndex ;
selectDevice ( selected ) ;
} else {
UI . deviceSelect . selectedIndex = 0 ;
2019-04-12 22:06:53 -04:00
selectDevice ( first ) ;
2017-04-18 17:09:33 -04:00
}
showDialog ( 'devices' , true ) ;
onWindowResize ( ) ;
UI . deviceSelect . focus ( ) ;
}
function renderTools ( ) {
UI . toolSelect . innerHTML = '' ;
editTools . forEach ( function ( tool , index ) {
tool . order = index ;
var opt = DOC . createElement ( 'option' ) ;
opt . appendChild ( DOC . createTextNode ( tool . name ) ) ;
opt . onclick = function ( ) { selectTool ( tool ) } ;
UI . toolSelect . appendChild ( opt ) ;
} ) ;
}
function selectTool ( tool ) {
selectedTool = tool ;
UI . toolName . value = tool . name ;
UI . toolNum . value = tool . number ;
UI . toolFluteDiam . value = tool . flute _diam ;
UI . toolFluteLen . value = tool . flute _len ;
UI . toolShaftDiam . value = tool . shaft _diam ;
UI . toolShaftLen . value = tool . shaft _len ;
UI . toolMetric . checked = tool . metric ;
UI . toolType . selectedIndex = (
tool . type === 'endmill' ? 0 :
tool . type === 'ballmill' ? 1 :
- 1
) ;
}
function updateTool ( ) {
selectedTool . name = UI . toolName . value ;
selectedTool . number = parseInt ( UI . toolNum . value ) ;
selectedTool . flute _diam = parseFloat ( UI . toolFluteDiam . value ) ;
selectedTool . flute _len = parseFloat ( UI . toolFluteLen . value ) ;
selectedTool . shaft _diam = parseFloat ( UI . toolShaftDiam . value ) ;
selectedTool . shaft _len = parseFloat ( UI . toolShaftLen . value ) ;
selectedTool . metric = UI . toolMetric . checked ;
selectedTool . type = [ 'endmill' , 'ballmill' ] [ UI . toolType . selectedIndex ] ;
renderTools ( ) ;
UI . toolSelect . selectedIndex = selectedTool . order ;
2020-03-06 09:33:24 -05:00
setToolChanged ( true ) ;
}
function setToolChanged ( changed ) {
editTools . changed = changed ;
UI . toolsSave . disabled = ! changed ;
2017-04-18 17:09:33 -04:00
}
function showTools ( ) {
if ( MODE !== MODES . CAM ) return ;
var selectedIndex = null ;
2020-03-06 09:33:24 -05:00
editTools = settings . tools . slice ( ) . sort ( ( a , b ) => {
return a . name > b . name ? 1 : - 1 ;
} ) ;
setToolChanged ( false ) ;
2017-04-18 17:09:33 -04:00
UI . toolsClose . onclick = function ( ) {
if ( editTools . changed && ! confirm ( "abandon changes?" ) ) return ;
hideDialog ( ) ;
} ;
UI . toolAdd . onclick = function ( ) {
editTools . push ( {
id : UTIL . time ( ) ,
number : editTools . length ,
name : "new" ,
type : "endmill" ,
flute _diam : 0.25 ,
flute _len : 1 ,
shaft _diam : 0.25 ,
shaft _len : 3 ,
metric : false
} ) ;
2020-03-06 09:33:24 -05:00
setToolChanged ( true ) ;
2017-04-18 17:09:33 -04:00
renderTools ( ) ;
UI . toolSelect . selectedIndex = editTools . length - 1 ;
selectTool ( editTools [ editTools . length - 1 ] ) ;
} ;
UI . toolDelete . onclick = function ( ) {
editTools . remove ( selectedTool ) ;
2020-03-06 09:33:24 -05:00
setToolChanged ( true ) ;
2017-04-18 17:09:33 -04:00
renderTools ( ) ;
} ;
UI . toolsSave . onclick = function ( ) {
if ( selectedTool ) updateTool ( ) ;
settings . tools = editTools ;
2020-03-06 09:33:24 -05:00
setToolChanged ( false ) ;
2017-04-18 17:09:33 -04:00
saveSettings ( ) ;
updateFields ( ) ;
triggerSettingsEvent ( ) ;
} ;
renderTools ( ) ;
if ( editTools . length > 0 ) {
selectTool ( editTools [ 0 ] ) ;
UI . toolSelect . selectedIndex = 0 ;
} else {
UI . toolAdd . onclick ( ) ;
}
showDialog ( 'tools' ) ;
UI . toolSelect . focus ( ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( 'ua_get_tools' ) ;
2017-04-18 17:09:33 -04:00
}
function showDevices ( ) {
2017-11-03 19:55:18 -04:00
if ( MODE === MODES . LASER || deviceLock ) return ;
2017-04-18 17:09:33 -04:00
setViewMode ( VIEWS . ARRANGE ) ;
ajax ( "/api/filters-" + getMode ( ) . toLowerCase ( ) , function ( flvalue ) {
if ( ! flvalue ) return ;
renderDevices ( js2o ( flvalue ) ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( 'ua_get_devs' ) ;
2017-04-18 17:09:33 -04:00
} ) ;
}
function dragOverHandler ( evt ) {
evt . stopPropagation ( ) ;
evt . preventDefault ( ) ;
evt . dataTransfer . dropEffect = 'copy' ;
SPACE . platform . setColor ( 0x00ff00 ) ;
}
function dragLeave ( ) {
SPACE . platform . setColor ( 0x555555 ) ;
}
function dropHandler ( evt ) {
evt . stopPropagation ( ) ;
evt . preventDefault ( ) ;
SPACE . platform . setColor ( 0x555555 ) ;
var files = evt . dataTransfer . files ,
2020-03-06 09:33:24 -05:00
plate = files . length < 5 || confirm ( ` add ${ files . length } objects to workspace? ` ) ;
2017-04-18 17:09:33 -04:00
if ( plate ) loadFiles ( files ) ;
}
function loadCatalogFile ( e ) {
Widget . loadFromCatalog ( e . target . getAttribute ( 'load' ) , function ( widget ) {
platformAdd ( widget ) ;
hideDialog ( ) ;
} ) ;
}
function deleteCatalogFile ( e ) {
CATALOG . deleteFile ( e . target . getAttribute ( 'del' ) ) ;
}
function updateCatalog ( files ) {
var table = UI . catalogList ,
list = [ ] ;
table . innerHTML = '' ;
for ( var name in files ) {
list . push ( { n : name , ln : name . toLowerCase ( ) , v : files [ name ] . vertices , t : files [ name ] . updated } ) ;
}
list . sort ( function ( a , b ) {
return a . ln < b . ln ? - 1 : 1 ;
} ) ;
for ( var i = 0 ; i < list . length ; i ++ ) {
var row = DOC . createElement ( 'div' ) ,
load = DOC . createElement ( 'button' ) ,
del = DOC . createElement ( 'button' ) ,
file = list [ i ] ,
name = file . n ;
load . setAttribute ( 'load' , name ) ;
load . setAttribute ( 'title' , 'file: ' + name + '\nvertices: ' + file . v ) ;
load . onclick = loadCatalogFile ;
load . appendChild ( DOC . createTextNode ( name . split ( '.' ) [ 0 ] ) ) ;
del . setAttribute ( 'del' , name ) ;
del . setAttribute ( 'title' , "remove '" + name + "'" ) ;
del . onclick = deleteCatalogFile ;
del . appendChild ( DOC . createTextNode ( 'x' ) ) ;
row . setAttribute ( "class" , "flow-row" ) ;
row . appendChild ( load ) ;
row . appendChild ( del ) ;
table . appendChild ( row ) ;
}
catalogSize = list . length ;
// fix layer scroll size
onControlResize ( ) ;
}
SPACE . addEventHandlers ( SELF , [
'keyup' , keyUpHandler ,
'keydown' , keyDownHandler ,
'keypress' , keyHandler ,
'dragover' , dragOverHandler ,
'dragleave' , dragLeave ,
'drop' , dropHandler
] ) ;
SPACE . onEnterKey ( [
UI . layerSpan , function ( ) { showSlices ( ) } ,
UI . layerID , function ( ) { setVisibleLayer ( UI . layerID . value ) } ,
UI . scaleX , scaleSelection ,
UI . scaleY , scaleSelection ,
UI . scaleZ , scaleSelection ,
UI . toolName , updateTool ,
UI . toolNum , updateTool ,
UI . toolFluteDiam , updateTool ,
UI . toolFluteLen , updateTool ,
UI . toolShaftDiam , updateTool ,
UI . toolShaftLen , updateTool ,
UI . bedWidth , updatePlatformSize ,
UI . bedDepth , updatePlatformSize
] ) ;
UI . setupDevices . innerHTML = "D<u>e</u>vices" ;
UI . setupTools . innerHTML = "T<u>o</u>ols" ;
UI . modeArrange . innerHTML = "<u>A</u>rrange" ;
UI . modeSlice . innerHTML = "<u>S</u>lice" ;
UI . modePreview . innerHTML = "<u>P</u>review" ;
UI . modeExport . innerHTML = "E<u>x</u>port" ;
UI . layerID . convert = UC . toFloat . bind ( UI . layerID ) ;
UI . layerSpan . convert = UC . toFloat . bind ( UI . layerSpan ) ;
UI . layerRange . onclick = function ( ) {
UI . layerRange . checked = ! ( UI . layerRange . checked || false ) ;
showSlices ( ) ;
} ;
$ ( 'layer-toggle' ) . onclick = function ( ev ) {
var ls = UI . layers . style ;
ls . display = ls . display !== 'block' ? 'block' : 'none' ;
UI . layers . style . left = ev . target . getBoundingClientRect ( ) . left + 'px' ;
} ;
$ ( 'x-' ) . onclick = function ( ev ) { rotateSelection ( ev . shiftKey ? - ROT5 : - ROT , 0 , 0 ) } ;
$ ( 'x+' ) . onclick = function ( ev ) { rotateSelection ( ev . shiftKey ? ROT5 : ROT , 0 , 0 ) } ;
$ ( 'y-' ) . onclick = function ( ev ) { rotateSelection ( 0 , ev . shiftKey ? - ROT5 : - ROT , 0 ) } ;
$ ( 'y+' ) . onclick = function ( ev ) { rotateSelection ( 0 , ev . shiftKey ? ROT5 : ROT , 0 ) } ;
$ ( 'z-' ) . onclick = function ( ev ) { rotateSelection ( 0 , 0 , ev . shiftKey ? ROT5 : ROT ) } ;
$ ( 'z+' ) . onclick = function ( ev ) { rotateSelection ( 0 , 0 , ev . shiftKey ? - ROT5 : - ROT ) } ;
2020-02-25 20:42:48 -05:00
UI . modelOpacity . onchange = UI . modelOpacity . onclick = function ( ev ) {
setOpacity ( parseInt ( UI . modelOpacity . value ) / 100 ) ;
2017-04-18 17:09:33 -04:00
} ;
UI . layerSlider . ondblclick = function ( ) {
UI . layerRange . checked = ! UI . layerRange . checked ;
showSlices ( ) ;
} ;
UI . layerSlider . onmousedown = function ( ev ) {
if ( ev . shiftKey ) UI . layerRange . checked = ! UI . layerRange . checked ;
} ;
UI . layerSlider . onclick = function ( ) {
setVisibleLayer ( UI . layerSlider . value ) ;
} ;
UI . layerSlider . onmousemove = UI . layerSlider . onchange = function ( ) {
setVisibleLayer ( UI . layerSlider . value ) ;
} ;
UI . layerSlider . onmouseup = function ( ) { takeFocus ( ) } ;
UI . import . setAttribute ( "import" , "1" ) ;
UI . import . onclick = function ( ) {
showDialog ( "catalog" ) ;
} ;
UI . toolMetric . onclick = updateTool ;
UI . toolType . onchange = updateTool ;
$ ( 'kiri' ) . onclick = showHelpLocal ;
SPACE . platform . setSize (
settings . device . bedWidth ,
settings . device . bedDepth ,
settings . device . bedHeight
) ;
SPACE . platform . setGrid ( 25 , 5 ) ;
SPACE . platform . opacity ( 0.2 ) ;
SPACE . mouse . downSelect ( function ( ) {
if ( viewMode !== VIEWS . ARRANGE ) return null ;
return selectedMeshes ;
} ) ;
SPACE . mouse . upSelect ( function ( selection , event ) {
if ( event && event . target . nodeName === "CANVAS" ) {
if ( selection ) {
widgetSelect ( selection . object . widget , event . shiftKey ) ;
} else {
widgetDeselect ( ) ;
}
} else {
return meshArray ( ) ;
}
} ) ;
SPACE . mouse . onDrag ( function ( delta ) {
2020-02-25 20:42:48 -05:00
if ( delta && UI . freeLayout . checked ) {
2017-04-18 17:09:33 -04:00
forSelectedWidgets ( function ( widget ) {
widget . move ( delta . x , delta . y , 0 ) ;
} ) ;
2020-02-25 20:42:48 -05:00
updateCamStock ( ) ;
2017-04-18 17:09:33 -04:00
} else {
return selectedMeshes . length > 0 ;
}
} ) ;
function checkSeed ( ondone ) {
// skip sample object load in onshape (or any script postload)
2020-02-26 20:23:32 -05:00
if ( ! SDB [ SEED ] ) {
SDB [ SEED ] = new Date ( ) . getTime ( ) ;
if ( ! SETUP . s ) {
loadSTL ( "/obj/cube.stl" , function ( vert ) {
CATALOG . putFile ( "sample cube.stl" , vert ) ;
platformComputeMaxZ ( ) ;
SPACE . view . home ( ) ;
setTimeout ( saveWorkspace , 500 ) ;
ondone ( ) ;
showHelpLocal ( ) ;
} ) ;
return true ;
}
2017-04-18 17:09:33 -04:00
}
return false ;
}
function ondone ( ) {
widgetDeselect ( ) ;
CATALOG . addFileListener ( updateCatalog ) ;
SPACE . view . setZoom ( settings . controller . reverseZoom , settings . controller . zoomSpeed ) ;
SPACE . platform . setZOff ( 0.2 ) ;
2020-03-01 19:00:36 -05:00
UI . showOrigin . checked = settings . controller . showOrigin ;
2020-02-25 20:42:48 -05:00
UI . freeLayout . checked = settings . controller . freeLayout ;
UI . autoLayout . checked = settings . controller . autoLayout ;
2020-03-08 11:04:07 -04:00
UI . alignTop . checked = settings . controller . alignTop ;
2020-02-25 20:42:48 -05:00
2017-04-18 17:09:33 -04:00
if ( SETUP . s ) SETUP . s . forEach ( function ( lib ) {
var scr = DOC . createElement ( 'script' ) ;
scr . setAttribute ( 'async' , true ) ;
scr . setAttribute ( 'src' , '/code/' + lib + '.js' ) ;
DOC . body . appendChild ( scr ) ;
2020-03-07 13:14:22 -05:00
STATS . add ( 'load_' + lib ) ;
2017-04-18 17:09:33 -04:00
} ) ;
if ( SETUP . ss ) SETUP . ss . forEach ( function ( style ) {
var ss = DOC . createElement ( 'link' ) ;
ss . setAttribute ( "type" , "text/css" ) ;
ss . setAttribute ( "rel" , "stylesheet" ) ;
ss . setAttribute ( "href" , "/kiri/style-" + style + ".css" ) ;
DOC . body . appendChild ( ss ) ;
} ) ;
if ( SETUP . v ) SETUP . v . forEach ( function ( kv ) {
kv = kv . split ( '=' ) ;
SDB . setItem ( kv [ 0 ] , kv [ 1 ] ) ;
} ) ;
// import octoprint settings from url
if ( SETUP . ophost ) {
OCTOPRINT = {
host : SETUP . ophost [ 0 ] ,
apik : SETUP . opkey ? SETUP . opkey [ 0 ] : ''
} ;
SDB [ 'octo-host' ] = OCTOPRINT . host ;
SDB [ 'octo-apik' ] = OCTOPRINT . apik ;
console . log ( { octoprint : OCTOPRINT } ) ;
}
2017-11-03 19:55:18 -04:00
// mode passed on url
2017-04-18 17:09:33 -04:00
var SETMODE = SETUP . mode ? SETUP . mode [ 0 ] : null ;
2017-11-03 19:55:18 -04:00
// device name pass on url
var DEVNAME = SETUP . dev ? SETUP . dev [ 0 ] : null ;
2017-04-18 17:09:33 -04:00
setMode ( SETMODE || STARTMODE || settings . mode , SETMODE ) ;
setControlsVisible ( true ) ;
updatePlatformSize ( ) ;
takeFocus ( ) ;
if ( STATS . get ( 'upgrade' ) ) DBUG . log ( "kiri | version upgrade" ) ;
STATS . del ( 'upgrade' ) ;
2019-04-16 07:45:24 -04:00
if ( ! SETUP . s ) console . log ( ` kiri | init main | ${ KIRI . version } ` ) ;
2017-04-18 17:09:33 -04:00
// place version number a couple of places to help users
2019-04-16 07:45:24 -04:00
UI . helpButton . title = ` ${ LANG . version } ` + KIRI . version ;
2017-04-18 17:09:33 -04:00
2020-02-10 11:30:11 -05:00
// restore expert setting preference
UC . setExpert ( SDB . getItem ( 'expert' ) ? true : false ) ;
2017-04-18 17:09:33 -04:00
// setup tab visibility watcher
// DOC.addEventListener('visibilitychange', function() { document.title = document.hidden });
// ensure settings has gcode
2017-11-03 19:55:18 -04:00
selectDevice ( DEVNAME || currentDeviceName ( ) , DEVNAME ) ;
2017-04-18 17:09:33 -04:00
// ensure field data propagation
updateSettings ( ) ;
// set initial layer slider size
onControlResize ( ) ;
// send init-done event
sendOnEvent ( 'init-done' , STATS ) ;
2018-01-10 20:04:51 -05:00
// load settings provided in url hash
loadSettingsFromServer ( ) ;
2019-01-18 16:36:14 -05:00
// clear alerts as they build up
setInterval ( updateAlerts , 1000 ) ;
UI . alert . dialog . onclick = function ( ) {
updateAlerts ( true ) ;
} ;
2017-04-18 17:09:33 -04:00
}
restoreWorkspace ( ondone ) || checkSeed ( ondone ) || ondone ( ) ;
} // end init()
SPACE . addEventListener ( DOC , 'DOMContentLoaded' , function ( ) { init ( ) } , false ) ;
SPACE . addEventListener ( WIN , 'mousemove' , function ( ) { mouseMoved = true } ) ;
// prevent safari from exiting full screen mode
DOC . onkeydown = function ( evt ) {
if ( evt . keyCode == 27 ) evt . preventDefault ( ) ;
}
// run optional module functions
if ( Array . isArray ( self . kirimod ) ) {
kirimod . forEach ( function ( mod ) { mod ( kiri . api ) } ) ;
}
} ) ( ) ;