From 4424e59ff91709786abd7a5f026fd13fea0e048a Mon Sep 17 00:00:00 2001 From: Amira Abdel-Rahman <amiraa@mit.edu> Date: Mon, 17 Jun 2019 14:43:01 -0400 Subject: [PATCH] Update smiley --- programs/frep/smiley | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/frep/smiley b/programs/frep/smiley index cda65ee..18df67a 100644 --- a/programs/frep/smiley +++ b/programs/frep/smiley @@ -1 +1 @@ -{"modules":{"0.3625970106871924":{"definition":"//\n// frep circle\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep circle'\n//\n// initialization\n//\nvar init = function() {\n mod.x.value = '0'\n mod.y.value = '0'\n mod.radius.value = '1'\n }\n//\n// inputs\n//\nvar inputs = {\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.variables.event()\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var fn = `((${radius})*(${radius})-((X-(${x}))*(X-(${x}))+(Y-(${y}))*(Y-(${y}))))`\n var variables = ['X','Y']\n var limits = [[x-radius,x+radius],[y-radius,y+radius]]\n var type = 'Magnitude'\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n },\n variables:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var vars = {x:x,y:y,radius:radius}\n mods.output(mod,'variables',vars)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createElement('br'))\n //\n // r\n //\n div.appendChild(document.createTextNode('radius: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.radius = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.variables.event()\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"172","left":"279","inputs":{},"outputs":{}},"0.8373334092218472":{"definition":"//\n// frep view slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep view slice'\n//\n// initialization\n//\nvar init = function() {\n mod.width.value = '1000'\n mod.z.value = '0'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'frep',\n event:function(evt){\n mod.fn.value = evt.detail.function\n view_slice(evt.detail)\n }}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.y.value = ''\n mod.z.value = ''\n })\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.x.value = ''\n mod.z.value = ''\n })\n div.appendChild(input)\n mod.y = input\n //\n // z\n //\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.x.value = ''\n mod.y.value = ''\n })\n div.appendChild(input)\n mod.z = input\n div.appendChild(document.createElement('br'))\n //\n // width\n //\n div.appendChild(document.createTextNode('width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.height.value = ''\n })\n div.appendChild(input)\n mod.width = input\n //\n // height\n //\n div.appendChild(document.createTextNode(' height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.width.value = ''\n })\n div.appendChild(input)\n mod.height = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // view button\n //\n div.appendChild(document.createTextNode(' '))\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n mod.win = window.open('')\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n mod.win.addEventListener('unload',function() {\n mod.win = null\n })\n var canvas = document.createElement('canvas')\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// view_slice\n//\nfunction view_slice(shape) { \n var fn = shape.function\n var vars = shape.variables\n var limits = shape.limits\n var type = shape.type\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var z = parseFloat(mod.z.value)\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n if (vars.length == 2) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[1]\n var ylimits = limits[1]\n var zvar = ''\n var zval = 0\n }\n else if (!isNaN(x)) {\n var xvar = vars[1]\n var xlimits = limits[1]\n var yvar = vars[2]\n var ylimits = limits[2]\n var zvar = vars[0]\n var zval = x\n }\n else if (!isNaN(y)) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[2]\n var ylimits = limits[2]\n var zvar = vars[1]\n var zval = y\n }\n else if (!isNaN(z)) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[1]\n var ylimits = limits[1]\n var zvar = vars[2]\n var zval = z\n }\n if (!isNaN(w))\n h = Math.floor(w*(ylimits[1]-ylimits[0])/(xlimits[1]-xlimits[0]))\n else\n w = Math.floor(h*(xlimits[1]-xlimits[0])/(ylimits[1]-ylimits[0]))\n mod.img.height = h\n mod.img.width = w\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n var h = mod.img.height\n var w = mod.img.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var imgdata = new ImageData(buf,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(imgdata,0,0)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n if (mod.win != null) {\n var canvas = mod.win.document.getElementById(mod.div.id+'canvas')\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n }\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n var ctx = mod.img.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.img.width,mod.img.height)\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:img.height,width:img.width,\n xvar:xvar,yvar:yvar,zvar:zvar,zval:zval,\n xlimits:xlimits,ylimits:ylimits,\n function:fn,\n buffer:img.data.buffer},\n [img.data.buffer])\n }\n//\n// worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var xvar = evt.data.xvar\n var yvar = evt.data.yvar\n var zvar = evt.data.zvar\n var zval = evt.data.zval\n var xlimits = evt.data.xlimits\n var ylimits = evt.data.ylimits\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var f = new Function(xvar,yvar,zvar,'return ('+evt.data.function+')')\n var x,y,v\n for (var row = 0; row < h; ++row) {\n y = ylimits[0]+(ylimits[1]-ylimits[0])*row/(h-1)\n for (var col = 0; col < w; ++col) {\n x = xlimits[0]+(xlimits[1]-xlimits[0])*col/(w-1)\n v = (f(x,y,zval) >= 0) ? 255 : 0\n buf[(h-1-row)*w*4+col*4+0] = v\n buf[(h-1-row)*w*4+col*4+1] = v\n buf[(h-1-row)*w*4+col*4+2] = v\n buf[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n self.postMessage({buffer:buf.buffer},[buf.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"133","left":"2676","inputs":{},"outputs":{}},"0.7152788275346978":{"definition":"//\n// frep circle\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep circle'\n//\n// initialization\n//\nvar init = function() {\n mod.x.value = '0.4'\n mod.y.value = '0.4'\n mod.radius.value = '0.16666666666666666'\n }\n//\n// inputs\n//\nvar inputs = {\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.variables.event()\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var fn = `((${radius})*(${radius})-((X-(${x}))*(X-(${x}))+(Y-(${y}))*(Y-(${y}))))`\n var variables = ['X','Y']\n var limits = [[x-radius,x+radius],[y-radius,y+radius]]\n var type = 'Magnitude'\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n },\n variables:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var vars = {x:x,y:y,radius:radius}\n mods.output(mod,'variables',vars)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createElement('br'))\n //\n // r\n //\n div.appendChild(document.createTextNode('radius: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.radius = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.variables.event()\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"502","left":"666","inputs":{},"outputs":{}},"0.04772797317232935":{"definition":"//\n// construct object\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'construct object'\n//\n// initialization\n//\nvar init = function() {\n mod.in0.value = '{\"x\":0,\"y\":0,\"radius\":1}'\n mod.in1.value = '{}'\n mod.out0.value = '{x:.4*in0.radius,y:.4*in0.radius,radius:in0.radius/6}'\n mod.out1.value = '{}'\n }\n//\n// inputs\n//\nvar inputs = {\n in0:{type:'',label:'input 0',\n event:function(evt) {\n mod.in0.value = JSON.stringify(evt.detail)\n construct_output()\n }},\n in1:{type:'',label:'input 1',\n event:function(evt) {\n mod.in1.value = JSON.stringify(evt.detail)\n construct_output()\n }}}\n//\n// outputs\n//\nvar outputs = {\n out0:{type:'',label:'output 0',\n event:function(arg){\n mods.output(mod,'out0',arg)\n }},\n out1:{type:'',label:'output 1',\n event:function(arg){\n mods.output(mod,'out1',arg)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // inputs\n //\n div.appendChild(document.createTextNode('input 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('input 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in1 = text\n div.appendChild(document.createElement('br'))\n //\n // outputs\n //\n div.appendChild(document.createTextNode('output 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('output 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out1 = text\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n construct_output()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\nfunction construct_output() {\n var in0 = JSON.parse(mod.in0.value)\n var in1 = JSON.parse(mod.in1.value)\n eval('out0 ='+mod.out0.value)\n eval('out1 ='+mod.out1.value)\n outputs.out0.event(out0)\n outputs.out1.event(out1)\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"454","left":"212","inputs":{},"outputs":{}},"0.9645985086194264":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"186","left":"673","inputs":{},"outputs":{}},"0.9458395548196141":{"definition":"//\n// frep reflect\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep reflect'\n//\n// initialization\n//\nvar init = function() {\n mod.origin0.value = '0'\n mod.origin1.value = '0'\n mod.x.checked = true\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var origin0 = parseFloat(mod.origin0.value)\n var origin1 = parseFloat(mod.origin1.value)\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.x.checked) {\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${xvar}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dl = mod.shape.limits[0][0]-origin0\n limits[0][0] = origin0-(dl+dx)\n limits[0][1] = origin0-dl\n }\n else if (mod.y.checked) {\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${yvar}))`)\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dl = mod.shape.limits[1][0]-origin0\n limits[1][0] = origin0-(dl+dy)\n limits[1][1] = origin0-dl\n }\n else if (mod.z.checked) {\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${zvar}))`)\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dl = mod.shape.limits[2][0]-origin0\n limits[2][0] = origin0-(dl+dz)\n limits[2][1] = origin0-dl\n }\n else if (mod.xy.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,'TEMP')\n fn = fn.replace(yre,`((${origin1})+(${xvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${yvar})-(${origin1}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dxl = mod.shape.limits[0][0]-origin0\n var dyl = mod.shape.limits[1][0]-origin1\n limits[0][0] = origin0+dyl\n limits[0][1] = origin0+dyl+dy\n limits[1][0] = origin1+dxl\n limits[1][1] = origin1+dxl+dx\n }\n else if (mod.xz.checked) {\n var xvar = variables[0]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(xre,'TEMP')\n fn = fn.replace(zre,`((${origin1})+(${xvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${zvar})-(${origin1}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dxl = mod.shape.limits[0][0]-origin0\n var dzl = mod.shape.limits[2][0]-origin1\n limits[0][0] = origin0+dzl\n limits[0][1] = origin0+dzl+dz\n limits[2][0] = origin1+dxl\n limits[2][1] = origin1+dxl+dx\n }\n else if (mod.yz.checked) {\n var yvar = variables[1]\n var zvar = variables[2]\n var yre = new RegExp(yvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(yre,'TEMP')\n fn = fn.replace(zre,`((${origin1})+(${yvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${zvar})-(${origin1}))`)\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dyl = mod.shape.limits[1][0]-origin0\n var dzl = mod.shape.limits[2][0]-origin1\n limits[1][0] = origin0+dzl\n limits[1][1] = origin0+dzl+dz\n limits[2][0] = origin1+dyl\n limits[2][1] = origin1+dyl+dy\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // axis\n //\n div.appendChild(document.createTextNode('axis: '))\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('x'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'x'\n div.appendChild(input)\n mod.x = input\n div.appendChild(document.createTextNode(' y'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'y'\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createTextNode(' z'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'z'\n div.appendChild(input)\n mod.z = input\n div.appendChild(document.createElement('br'))\n //\n // origin 0\n //\n div.appendChild(document.createTextNode('origin 0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.origin0 = input\n div.appendChild(document.createElement('br'))\n //\n // axis\n //\n div.appendChild(document.createTextNode('xy'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'xy'\n div.appendChild(input)\n mod.xy = input\n div.appendChild(document.createTextNode(' xz'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'xz'\n div.appendChild(input)\n mod.xz = input\n div.appendChild(document.createTextNode(' yz'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'yz'\n div.appendChild(input)\n mod.yz = input\n div.appendChild(document.createElement('br'))\n //\n // origin 1\n //\n div.appendChild(document.createTextNode('origin 1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.origin1 = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"501","left":"1033","inputs":{},"outputs":{}},"0.04930175848785401":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = 'Math.min(((1)*(1)-((X-(0))*(X-(0))+(Y-(0))*(Y-(0)))),-(((0.16666666666666666)*(0.16666666666666666)-((X-(0.4))*(X-(0.4))+(Y-(0.4))*(Y-(0.4))))))'\n mod.fn1.value = '((0.16666666666666666)*(0.16666666666666666)-(((0-(X))-(0.4))*((0-(X))-(0.4))+(Y-(0.4))*(Y-(0.4))))'\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"183","left":"1033","inputs":{},"outputs":{}},"0.5608762029437723":{"definition":"//\n// frep scale\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep scale'\n//\n// initialization\n//\nvar init = function() {\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = ''\n mod.sx.value = '.7'\n mod.sy.value = '.7'\n mod.sz.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.ox.value != '') {\n var ox = parseFloat(mod.ox.value)\n var sx = parseFloat(mod.sx.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/(${sx}))`)\n limits[0][0] = ox+(limits[0][0]-ox)*sx\n limits[0][1] = ox+(limits[0][1]-ox)*sx\n }\n if (mod.oy.value != '') {\n var oy = parseFloat(mod.oy.value)\n var sy = parseFloat(mod.sy.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/(${sy}))`)\n limits[1][0] = oy+(limits[1][0]-oy)*sy\n limits[1][1] = oy+(limits[1][1]-oy)*sy\n }\n if (mod.oz.value != '') {\n var oz = parseFloat(mod.oz.value)\n var sz = parseFloat(mod.sz.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`((${oz})+(${zvar}-(${oz}))/(${sz}))`)\n limits[2][0] = oz+(limits[2][0]-oz)*sz\n limits[2][1] = oz+(limits[2][1]-oz)*sz\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sx = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"528","left":"1444","inputs":{},"outputs":{}},"0.40238136387777756":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = 'Math.min(Math.min(((1)*(1)-((X-(0))*(X-(0))+(Y-(0))*(Y-(0)))),-(((0.16666666666666666)*(0.16666666666666666)-((X-(0.4))*(X-(0.4))+(Y-(0.4))*(Y-(0.4)))))),-(((0.16666666666666666)*(0.16666666666666666)-(((0-(X))-(0.4))*((0-(X))-(0.4))+(Y-(0.4))*(Y-(0.4))))))'\n mod.fn1.value = 'Math.min(((0)-Y),(Math.min(((1)*(1)-((((0)+(X-(0))/(0.7))-(0))*(((0)+(X-(0))/(0.7))-(0))+(((0)+(Y-(0))/(0.7))-(0))*(((0)+(Y-(0))/(0.7))-(0)))),-(((1)*(1)-((((0)+(((0)+(X-(0))/(0.75))-(0))/(0.7))-(0))*(((0)+(((0)+(X-(0))/(0.75))-(0))/(0.7))-(0))+(((0)+(((0)+(Y-(0))/(0.75))-(0))/(0.7))-(0))*(((0)+(((0)+(Y-(0))/(0.75))-(0))/(0.7))-(0))))))))'\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"173","left":"1392","inputs":{},"outputs":{}},"0.5939459494005885":{"definition":"//\n// frep scale\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep scale'\n//\n// initialization\n//\nvar init = function() {\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = ''\n mod.sx.value = '.75'\n mod.sy.value = '.75'\n mod.sz.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.ox.value != '') {\n var ox = parseFloat(mod.ox.value)\n var sx = parseFloat(mod.sx.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/(${sx}))`)\n limits[0][0] = ox+(limits[0][0]-ox)*sx\n limits[0][1] = ox+(limits[0][1]-ox)*sx\n }\n if (mod.oy.value != '') {\n var oy = parseFloat(mod.oy.value)\n var sy = parseFloat(mod.sy.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/(${sy}))`)\n limits[1][0] = oy+(limits[1][0]-oy)*sy\n limits[1][1] = oy+(limits[1][1]-oy)*sy\n }\n if (mod.oz.value != '') {\n var oz = parseFloat(mod.oz.value)\n var sz = parseFloat(mod.sz.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`((${oz})+(${zvar}-(${oz}))/(${sz}))`)\n limits[2][0] = oz+(limits[2][0]-oz)*sz\n limits[2][1] = oz+(limits[2][1]-oz)*sz\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sx = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"585","left":"1849","inputs":{},"outputs":{}},"0.690161531242695":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"606","left":"2209","inputs":{},"outputs":{}},"0.19288167008415902":{"definition":"//\n// frep slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep slice'\n//\n// initialization\n//\nvar init = function() {\n mod.x0.value = ''\n mod.x1.value = ''\n mod.y0.value = ''\n mod.y1.value = '0'\n mod.z0.value = ''\n mod.z1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n var variables = mod.shape.variables\n var fn = mod.shape.function\n if (mod.x0.value != '') {\n var x0 = parseFloat(mod.x0.value)\n var xvar = variables[0]\n fn = `Math.min((${xvar}-(${x0})),(${fn}))`\n limits[0][0] = Math.max(limits[0][0],x0)\n }\n if (mod.x1.value != '') {\n var x1 = parseFloat(mod.x1.value)\n var xvar = variables[0]\n fn = `Math.min(((${x1})-${xvar}),(${fn}))`\n limits[0][1] = Math.min(limits[0][1],x1)\n }\n if (mod.y0.value != '') {\n var y0 = parseFloat(mod.y0.value)\n var yvar = variables[1]\n fn = `Math.min((${yvar}-(${y0})),(${fn}))`\n limits[1][0] = Math.max(limits[1][0],y0)\n }\n if (mod.y1.value != '') {\n var y1 = parseFloat(mod.y1.value)\n var yvar = variables[1]\n fn = `Math.min(((${y1})-${yvar}),(${fn}))`\n limits[1][1] = Math.min(limits[1][1],y1)\n }\n if (mod.z0.value != '') {\n var z0 = parseFloat(mod.z0.value)\n var zvar = variables[2]\n fn = `Math.min((${zvar}-(${z0})),(${fn}))`\n limits[2][0] = Math.max(limits[2][0],z0)\n }\n if (mod.z1.value != '') {\n var z1 = parseFloat(mod.z1.value)\n var zvar = variables[2]\n fn = `Math.min(((${z1})-${zvar}),(${fn}))`\n limits[2][1] = Math.min(limits[2][1],z1)\n }\n var shape = {function:fn,variables:mod.shape.variables,limits:limits,type:mod.shape.type}\n mod.fn.value = fn\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x0\n //\n div.appendChild(document.createTextNode('x0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x0 = input\n //\n // x1\n //\n div.appendChild(document.createTextNode(' x1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x1 = input\n div.appendChild(document.createElement('br'))\n //\n // y0\n //\n div.appendChild(document.createTextNode('y0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y0 = input\n //\n // y1\n //\n div.appendChild(document.createTextNode(' y1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y1 = input\n div.appendChild(document.createElement('br'))\n //\n // z0\n //\n div.appendChild(document.createTextNode('z0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.z0 = input\n //\n // z1\n //\n div.appendChild(document.createTextNode(' z1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.z1 = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"267","left":"1783","inputs":{},"outputs":{}},"0.8080126368305371":{"definition":"//\n// frep taper \n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep taper'\n//\n// initialization\n//\nvar init = function() {\n mod.variable0.value = '-1'\n mod.variable1.value = '1'\n mod.scale0.value = '.5'\n mod.scale1.value = '2'\n mod.originx.value = '0'\n mod.originy.value = '0'\n mod.xy.checked = true\n mod.xz.checked = false\n mod.yz.checked = false\n mod.xyz.checked = false\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var var0 = parseFloat(mod.variable0.value)\n var var1 = parseFloat(mod.variable1.value)\n var dvar = var1-var0\n var s0 = parseFloat(mod.scale0.value)\n var s1 = parseFloat(mod.scale1.value)\n var ds = s1-s0\n var ox = parseFloat(mod.originx.value)\n var oy = parseFloat(mod.originy.value)\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.xy.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${yvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(ymin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(ymax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(ymin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(ymax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n }\n else if (mod.xz.checked) {\n var xvar = variables[0]\n var zvar = variables[2]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(zmin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(zmin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n }\n else if (mod.yz.checked) {\n var yvar = variables[1]\n var zvar = variables[2]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var y00 = oy+(ymin-oy)*(s0+ds*(zmin-var0)/dvar)\n var y01 = oy+(ymin-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][0] = Math.min(y00,y01)\n var y10 = oy+(ymax-oy)*(s0+ds*(zmin-var0)/dvar)\n var y11 = oy+(ymax-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][1] = Math.max(y10,y11)\n }\n else if (mod.xyz.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n fn = fn.replace(yre,`((${oy})+(${yvar}-(${oy}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(zmin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(zmin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var y00 = oy+(ymin-oy)*(s0+ds*(zmin-var0)/dvar)\n var y01 = oy+(ymin-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][0] = Math.min(y00,y01)\n var y10 = oy+(ymax-oy)*(s0+ds*(zmin-var0)/dvar)\n var y11 = oy+(ymax-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][1] = Math.max(y10,y11)\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // direction \n //\n div.appendChild(document.createTextNode('direction: '))\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('x(y)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xy = input\n div.appendChild(document.createTextNode(' x(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xz = input\n div.appendChild(document.createTextNode(' y(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.yz = input\n div.appendChild(document.createTextNode(' xy(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xyz = input\n div.appendChild(document.createElement('br'))\n //\n // variable 0\n //\n div.appendChild(document.createTextNode('at: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.variable0 = input\n //\n // scale 0\n //\n div.appendChild(document.createTextNode(' scale by: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale0 = input\n div.appendChild(document.createElement('br'))\n //\n // variable 1\n //\n div.appendChild(document.createTextNode('at: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.variable1 = input\n //\n // scale 1\n //\n div.appendChild(document.createTextNode(' scale by: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale1 = input\n div.appendChild(document.createElement('br'))\n //\n // x origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.originx = input\n //\n // y origin\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.originy = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"147","left":"2148","inputs":{},"outputs":{}},"0.01016844222037161":{"definition":"//\n// frep inflate\n// todo: better Z limit\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep inflate'\n//\n// initialization\n//\nvar init = function() {\n mod.scale.value = '1'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'2D',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'3D',\n event:function(){\n var variables = []\n variables[0] = mod.shape.variables[0]\n variables[1] = mod.shape.variables[1]\n variables[2] = 'Z'\n var scale = parseFloat(mod.scale.value)\n var limits = []\n limits[0] = [mod.shape.limits[0][0],mod.shape.limits[0][1]]\n limits[1] = [mod.shape.limits[1][0],mod.shape.limits[1][1]]\n limits[2] = [0,limits[0][1]-limits[0][0]]\n fn = `((${scale})*(${mod.shape.function})-Z)`\n fn = `Math.min(${mod.shape.function},${fn})`\n fn = `Math.min(Z,${fn})`\n var shape = {function:fn,variables:variables,limits:limits,type:mod.shape.type}\n mod.fn.value = fn\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"909","left":"2234","inputs":{},"outputs":{}},"0.43117078925934216":{"definition":"//\n// frep GPU volume renderer\n//\n// Neil Gershenfeld and Amira Abdel-Rahman\n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {};\n//\n// name\n//\nvar name = 'render GPU';\n//\n// initialization\n//\nvar init = function() {\n mod.steps.value=256.0;\n mod.alphaCorrection=10.0;\n mod.rendType=\"0\";\n mod.windowOpen=false;\n mod.xLimit1 =-1.0 ;\n mod.xLimit2 =1.0 ; \n mod.yLimit1 =-1.0 ; \n mod.yLimit2 =1.0 ; \n mod.zLimit1 =-1.0 ; \n mod.zLimit2 =1.0 ;\n mod.height=10.0;\n mod.width=10.0;\n mod.rendPerformance=0;\n };\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'frep',\n event:function(evt){\n\n mod.shape=evt.detail;\n\n // outputs.messageLog.event(mod.shape.limits);\n\n //get largerst range and rescale other ones to adjust limit mapping\n var tempIndex=0;\n var tempMax=-1.0;\n\n for(i=0;i<mod.shape.limits.length;i++)\n {\n if((mod.shape.limits[i][1]-mod.shape.limits[i][0]) >= tempMax )\n {\n tempIndex=i;\n tempMax=mod.shape.limits[i][1]-mod.shape.limits[i][0];\n }\n }\n for(i=0;i < mod.shape.limits.length;i++)\n {\n if(i!=tempIndex)\n {\n var tempDif = (mod.shape.limits[tempIndex][1]-mod.shape.limits[tempIndex][0])-(mod.shape.limits[i][1]-mod.shape.limits[i][0]);\n mod.shape.limits[i][0]-=tempDif/2.0;\n mod.shape.limits[i][1]+=tempDif/2.0;\n \n }\n }\n\n mod.xLimit1=mod.shape.limits[0][0] ;\n mod.xLimit2=mod.shape.limits[0][1] ; \n mod.yLimit1=mod.shape.limits[1][0] ; \n mod.yLimit2=mod.shape.limits[1][1] ; \n mod.zLimit1=mod.shape.limits[2][0] ; \n mod.zLimit2=mod.shape.limits[2][1] ;\n \n //\n //turn function string to glsl\n\t //\n\t \n\t //remove all Math.\n var str1 = mod.shape.function;\n\t str1=str1.replace(/Math./g, '');\n\t \n\t //change atan2 functions to atan\n\t str1=str1.replace(/atan2/g, \"atan\");\n \n //change all % to mod(,)\n while(str1.indexOf(\"%\")>-1) //While '%' is there\n {\n //get location\n var modLocation=str1.indexOf(\"%\");\n //replace with ','\n str1=str1.replace(/%/, \",\");\n outputs.messageLog.event(\"1:\"+str1);\n\n //parse before\n var counterBefore=modLocation;\n var count=0;\n if(str1[--counterBefore]==')')\n {\n count++;\n while(count>0)\n {\n counterBefore--;\n if(str1[counterBefore]==')')\n {\n count++;\n\n }else if (str1[counterBefore]=='(')\n {\n count--;\n }\n }\n }else{\n while(!isNaN(str1[counterBefore]) ||(str1[counterBefore]=='.')||(str1[counterBefore]=='X') ||(str1[counterBefore]=='Y')||(str1[counterBefore]=='Z'))\n {\n counterBefore--;\n }\n\n }\n \n \n //parse after\n var counterAfter=modLocation;\n count=0;\n if(str1[++counterAfter]=='(')\n {\n count++;\n while(count>0)\n {\n counterAfter++;\n if(str1[counterAfter]=='(')\n {\n count++;\n\n }else if (str1[counterAfter]==')')\n {\n count--;\n }\n }\n }else\n {\n while(!isNaN(str1[counterAfter]) ||(str1[counterAfter]=='.')||(str1[counterAfter]=='X') ||(str1[counterAfter]=='Y')||(str1[counterAfter]=='Z'))\n {\n counterAfter++;\n }\n }\n \n str1 = str1.substr(0, counterAfter) + \")\" + str1.substr(counterAfter);\n str1 = str1.substr(0, counterBefore) + \"mod(\" + str1.substr(counterBefore);\n }\n\n //turn all ints to floatS\n var str='';\n for(var i=0;i<str1.length;i++)\n {\n //if number\n if(!isNaN(str1[i]))\n {\n str+=str1[i];\n //check next value\n for(var j=i+1;j<str1.length;j++)\n {\n //if number add and continue\n if(!isNaN(str1[j])) \n {\n str+=str1[j];\n i=j;\n }\n //else if dot add and add numbers till NaN\n else if(str1[j]=='.')\n {\n str+=str1[j];\n i=j;\n //add till not num\n for(var k=j+1;k<str1.length;k++)\n {\n if( ( !isNaN(str1[k]) )||str1[k]=='e')\n {\n //fix for scientific notation\n if(str1[k]=='e' && str1[k+1]=='-')\n {\n str+=str1[k];\n i=k;\n\n k++;\n\n str+=str1[k];\n i=k;\n\n }else\n {\n str+=str1[k];\n i=k;\n\n }\n \n }\n else\n {\n k=str1.length;\n }\n }\n j=str1.length;\n }\n //else add .0 and go to next number\n else\n {\n str+='.';\n str+='0';\n j=str1.length;\n }\n }\n\n }\n else\n {\n str+=str1[i];\n }\n }\n \n mod.str=str;\n outputs.messageLog.event(str);\n\n //if window open update shader function\n if(mod.windowOpen)\n {\n mod.updateShaderFunction();\n }\n\n }}};\n//\n// outputs\n//\nvar outputs = {\n messageLog:{type:'string',\n event:function(mess){\n //show processed function\n mods.output(mod,'messageLog',mess);\n }\n }\n}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas');\n canvas.width = mods.ui.canvas;\n canvas.height = mods.ui.canvas;\n canvas.style.backgroundColor = 'rgb(0,0,0)';\n div.appendChild(canvas);\n mod.canvas = canvas;\n div.appendChild(document.createElement('br'));\n //\n // resolution\n //\n div.appendChild(document.createTextNode('resolution: '));\n var input = document.createElement('input');\n input.type = 'text';\n input.size = 3;\n input.addEventListener('input',function(){\n if(mod.windowOpen)\n {\n mod.redraw(true);\n }\n });\n div.appendChild(input);\n mod.steps = input;\n div.appendChild(document.createElement('br'));\n //\n // adaptive rendering\n //\n div.appendChild(document.createTextNode('rendering performance: '))\n var input = document.createElement('SELECT');\n \n input.setAttribute(\"id\", \"rend-adpselect\");\n \n //select menu for functions\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"0\");\n var t = document.createTextNode('constant');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"1\");\n var t = document.createTextNode('adaptive');\n z.appendChild(t);\n input.appendChild(z);\n input.addEventListener('change',function(evt){\n var temp= document.getElementById(\"rend-adpselect\");\n mod.rendPerformance=parseInt(temp.value);\n mod.updateShaderFunction();\n });\n\n div.appendChild(input);\n \n div.appendChild(document.createElement('br'));\n //\n // rendering style\n //\n div.appendChild(document.createTextNode('rendering style: '))\n var input = document.createElement('SELECT');\n \n input.setAttribute(\"id\", \"rend-select\");\n \n //select menu for functions\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"0\");\n var t = document.createTextNode('default');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"1\");\n var t = document.createTextNode('xray');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"2\");\n var t = document.createTextNode('height map (fixed)');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"3\");\n var t = document.createTextNode('height map (variable)');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"4\");\n var t = document.createTextNode('normals');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"5\");\n var t = document.createTextNode('light');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"6\");\n var t = document.createTextNode('specular');\n z.appendChild(t);\n input.appendChild(z);\n \n input.addEventListener('change',function(evt){\n var temp= document.getElementById(\"rend-select\");\n mod.rendType=String(parseInt(temp.value));\n mod.updateShaderFunction();\n });\n\n div.appendChild(input);\n div.appendChild(document.createElement('br'));\n \n //\n // view\n // \n div.appendChild(document.createElement('br')) ; \n var btn = document.createElement('button');\n btn.style.padding = mods.ui.padding;\n btn.style.margin = 1;\n var span = document.createElement('span');\n var text = document.createTextNode('view');\n span.appendChild(text);\n btn.appendChild(span);\n btn.addEventListener('click',function(){\n mod.windowOpen=true; \n open_view_window();\n });\n div.appendChild(btn);\n}\n\n//\n// local functions\n//\n \n//\n// open_view_window\n//\nfunction open_view_window() {\n //\n // globals\n //\n var container;\n var camera, sceneFirstPass, sceneSecondPass, renderer;\n var containerAxes, cameraAxes , sceneAxes, rendererAxes,axes,sphereO;\n var rtTexture;\n var materialSecondPass;\n var center;\n var meshSecondPass;\n var boxGeometry;\n var gridHelper;\n var gridHelpersSize=5;\n var clock;\n var delta=0;\n var interval=10;\n var frameID;\n\n //\n // functions\n //\n \n addShaderScripts();\n open_window();\n \n //\n // open_window\n //\n function open_window() \n {\n //\n // open window\n //\n win = window.open('');\n mod.win = win;\n\n //\n // load three.js\n //\n var script = document.createElement('script');\n script.type = 'text/javascript';\n script.onload = init_window;\n script.src = 'js/three.js/three.min.js';\n mod.div.appendChild(script);\n }\n\n //\n // add shader scripts to html\n //\n function addShaderScripts() \n {\n\n /////////////////////////fragmentShaderFirstPass////////////////////////////////////\n\n var div = document.createElement('script');\n\n div.id = 'fragmentShaderFirstPass';\n div.type = 'x-shader/x-fragment';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n\n void main()\n {\n //The fragment's world space coordinates as fragment output.\n gl_FragColor = vec4( worldSpaceCoords.x , worldSpaceCoords.y, worldSpaceCoords.z, 1 );\n }\n `;\n \n //\n mod.div.appendChild(div);\n \n /////////////////////////vertexShaderFirstPass////////////////////////////////////\n var div = document.createElement('script');\n\n div.id = 'vertexShaderFirstPass';\n div.type = 'x-shader/x-vertex';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n\n void main()\n {\n //Set the world space coordinates of the back faces vertices as output.\n worldSpaceCoords = position + vec3(0.5, 0.5, 0.5); //move it from [-0.5;0.5] to [0,1]\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n `;\n \n //\n mod.div.appendChild(div);\n /////////////////////////fragmentShaderSecondPass////////////////////////////////////\n var div = document.createElement('script');\n\n div.id = 'fragmentShaderSecondPass';\n div.type = 'x-shader/x-fragment';\n\n \n div.innerHTML=fragmentShaderSecondPass();\n mod.div.appendChild(div);\n\n /////////////////////vertexShaderSecondPass///////////////////\n var div = document.createElement('script');\n\n div.id = 'vertexShaderSecondPass';\n div.type = 'x-shader/x-vertex';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n varying vec4 projectedCoords;\n\n\n void main()\n {\n \n worldSpaceCoords = (modelMatrix * vec4(position + vec3(0.5, 0.5,0.5), 1.0 )).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n projectedCoords = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n }\n `;\n //\n mod.div.appendChild(div);\n }\n \n //\n // fragment shader (the one that does all the work)\n //\n function fragmentShaderSecondPass()\n {\n var txt =\n `\n const float PI = 3.1415926535897932384626433832795;\n #define rendType `+mod.rendType+`\n varying vec3 worldSpaceCoords;\n varying vec4 projectedCoords;\n uniform sampler2D tex;\n uniform float steps;\n uniform float alphaCorrection;\n // uniform float rendType;\n uniform vec3 cameraPos;\n // The maximum distance through our rendering volume is sqrt(3).\n // The maximum number of steps we take to travel a distance of 1 is 512.\n // ceil( sqrt(3) * 512 ) = 887\n // This prevents the back of the image from getting cut off when steps=512 & viewing diagonally.\n const int MAX_STEPS = 887;\n uniform float xLimit1;\n uniform float xLimit2;\n uniform float yLimit1;\n uniform float yLimit2;\n uniform float zLimit1;\n uniform float zLimit2;\n float orgMin=0.0;\n float orgMax=1.0;\n vec3 viewDirection;\n \n\n float map(vec3 p)\n {\n float X= p.x;\n float Y= p.y;\n float Z= p.z;\n\n return `+mod.str+`;\n }\n vec3 simpleLambert (vec3 normal) {\n vec3 lightDir = vec3(0.2,-0.6,-0.4); // Light direction\n vec3 lightDir1 = vec3(0.4, 0.6,-0.4); // Light direction\n vec3 lightCol = vec3(0.5,0.5,0.5); // Light color\n vec3 _Color=vec3(0.2,0.5,0.8);\n float lightIntensity = 3.0;\n float ambient = 0.2;\n \n float NdotL = max(dot(normalize(normal), normalize(lightDir)),0.0) * lightIntensity;\n float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0) *lightIntensity;\n\n vec3 c=vec3(0.0,0.0,0.0);\n\n c.rgb = _Color * lightCol * (NdotL + NdotL1)+ ambient ;\n\n return c;\n }\n vec3 specular (vec3 normal) {\n vec3 lightDir = vec3(0.2,-0.6,-0.4); // Light direction\n vec3 lightDir1 = vec3(0.4, 0.6,-0.4); // Light direction\n vec3 lightCol = vec3(0.5,0.5,0.5); // Light color\n vec3 _Color=vec3(0.2,0.5,0.8);\n float lightIntensity=3.0;\n float ambient = 0.2;\n\n float _SpecularPower=0.7;\n float _Gloss=0.7;\n \n float NdotL = max(dot(normalize(normal ), normalize(lightDir)),0.0)*lightIntensity;\n float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0)*lightIntensity;\n vec3 c;\n vec3 camera= cameraPos-0.5;\n\n float t= dot(normalize(lightDir), normalize( -camera));\n float tt=(dot(normalize(normal), normalize(-camera)));\n float s= ( t*_Gloss + tt*_SpecularPower)/lightIntensity;\n\n float t1= dot(normalize(lightDir1), normalize( -camera));\n float tt1=(dot(normalize(normal), normalize(-camera)));\n float s1= ( t1*_Gloss * tt1*_SpecularPower)/2.0;\n\n // float s = pow( dot(normalize(normal),h), _SpecularPower) * _Gloss;\n // h.x= (h.x - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // h.y= (h.y - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // h.z= (h.z - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // vec3 h1 = (lightDir1 + camera)/2.0;\n // float s1 = pow( dot(normalize(normal)/2.0,h1), _SpecularPower) * _Gloss;\n\n c.rgb = _Color * lightCol * (NdotL+NdotL1)+s + s1+ ambient;\n return c;\n }\n vec3 frontLight (vec3 normal) {\n \n vec3 camera= cameraPos-0.5;\n float t=dot(normalize(normal), normalize(-camera));\n vec3 c;\n c = vec3(t,t,t);\n return c;\n }\n\n vec3 ClosestPointOnLine(vec3 start ,vec3 direction ,vec3 vPoint )\n {\n vec3 vVector1 = vPoint - start;\n vec3 vVector2 = normalize(direction);\n \n float t = dot(vVector2, vVector1);\n if (t <= 0.0)\n {\n return start;\n }\n \n vec3 vVector3 = vVector2 * t;\n \n vec3 vClosestPoint = start + vVector3;\n return vClosestPoint;\n }\n vec3 GetClosetPoint( vec3 A, vec3 B, vec3 P, bool segmentClamp)\n {\n vec3 AP = P - A;\n vec3 AB = B - A; \n float ab2 = AB.x*AB.x + AB.y*AB.y;\n float apab = AP.x*AB.x + AP.y*AB.y;\n float t = apab / ab2;\n if (segmentClamp)\n {\n if (t < 0.0) t = 0.0;\n else if (t > 1.0) t = 1.0;\n }\n vec3 Closest = A + AB * t;\n return Closest;\n }\n vec3 calcNormal( in vec3 pos )\n {\n // vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;\n // return normalize( e.xyy*map( pos + e.xyy ) + \n // e.yyx*map( pos + e.yyx ) + \n // e.yxy*map( pos + e.yxy ) + \n // e.xxx*map( pos + e.xxx ) );\n \n // vec3 eps = vec3( 0.0005, 0.0, 0.0 );\n // vec3 nor = vec3(\n // map(pos+eps.xyy) - map(pos-eps.xyy),\n // map(pos+eps.yxy) - map(pos-eps.yxy),\n // map(pos+eps.yyx) - map(pos-eps.yyx) );\n // return normalize(nor);\n\n const float eps = 0.01;\n vec3 n;\n n.x=map(pos + vec3(eps, 0, 0) ) - map(pos - vec3(eps, 0, 0));\n n.y=map(pos + vec3(0, eps, 0) ) - map(pos - vec3(0, eps, 0));\n n.z=map(pos + vec3(0, 0, eps) ) - map(pos - vec3(0, 0, eps));\n //problem with \n // n.x=result - map(pos - vec3(eps, 0, 0));\n // n.y=result - map(pos - vec3(0, eps, 0));\n // n.z=result - map(pos - vec3(0, 0, eps));\n return normalize(n);\n \n }\n\n //Acts like a texture3D using Z slices and trilinear filtering.\n vec4 sampleAs3DTextureCustom( vec3 texCoord )\n { \n float X= (texCoord.x - orgMin) * (xLimit2 - xLimit1) / (orgMax - orgMin) + xLimit1;\n float Y= (texCoord.y - orgMin) * (yLimit2 - yLimit1) / (orgMax - orgMin) + yLimit1;\n float Z= (texCoord.z - orgMin) * (zLimit2 - zLimit1) / (orgMax - orgMin) + zLimit1;\n\n //slice color red\n vec4 m;\n m=vec4(0.0,0.0,0.0,0.0);\n\n float result=`+mod.str+`;\n if(result>0.0)\n {\n m.a=1.0;\n vec3 p=vec3(X,Y,Z);\n vec3 n=calcNormal( p );\n\n #if rendType==0\n //default\n {\n float tempConst=0.001;\n m.rgb=frontLight(n)+tempConst;\n }\n #elif rendType==1\n //xray\n {\n m=vec4(1.0,1.0,1.0,0.01);\n }\n #elif rendType==2\n //height map\n {\n m.r=texCoord.z;\n m.g=texCoord.z;\n m.b=texCoord.z;\n }\n #elif rendType==3\n //depth/height map variable\n {\n vec3 cp=ClosestPointOnLine(-cameraPos,cameraPos,texCoord);\n float d= (distance(cp, normalize(cameraPos)*2.0));\n m.r=d;\n m.g=d;\n m.b=d;\n }\n #elif rendType==4\n //normals\n {\n m.r= (n.r - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n m.g= (n.g - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n m.b= (n.b - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n }\n #elif rendType==5\n //fixed lights\n {\n float tempConst=0.05;\n m.rgb=simpleLambert (n)+tempConst;\n }\n #elif rendType==6\n //fixed lights specular\n {\n float tempConst=0.00;\n m.rgb=specular (n)+tempConst;\n }\n #endif\n \n }\n return m ;\n }\n \n void main( void ) {\n\n //Transform the coordinates it from [-1;1] to [0;1]\n vec2 texc = vec2(((projectedCoords.x / projectedCoords.w) + 1.0 ) / 2.0,\n ((projectedCoords.y / projectedCoords.w) + 1.0 ) / 2.0 );\n\n //The back position is the world space position stored in the texture.\n vec3 backPos = texture2D(tex, texc).xyz;\n\n //The front position is the world space position of the second render pass.\n vec3 frontPos = worldSpaceCoords;\n\n //The direction from the front position to back position.\n vec3 dir = backPos - frontPos;\n \n float rayLength = length(dir);\n\n //Calculate how long to increment in each step.\n float delta = 1.0 / steps;\n\n //The increment in each direction for each step.\n vec3 deltaDirection = normalize(dir) * delta;\n\n viewDirection=normalize(dir);//amira added\n\n float deltaDirectionLength = length(deltaDirection);\n\n //Start the ray casting from the front position.\n vec3 currentPosition = frontPos;\n\n //The color accumulator.\n vec4 accumulatedColor = vec4(0.0);\n\n //The alpha value accumulated so far.\n float accumulatedAlpha = 0.0;\n\n //How long has the ray travelled so far.\n float accumulatedLength = 0.0;\n\n //If we have twice as many samples, we only need ~1/2 the alpha per sample.\n //Scaling by 256/10 just happens to give a good value for the alphaCorrection slider.\n float alphaScaleFactor = 25.6 * delta;\n\n vec4 colorSample;\n float alphaSample;\n\n //Perform the ray marching iterations\n for(int i = 0; i < MAX_STEPS; i++)\n {\n //Get the voxel intensity value from the 3D texture.\n colorSample = sampleAs3DTextureCustom( currentPosition );\n\n //Allow the alpha correction customization.\n alphaSample = colorSample.a * alphaCorrection;\n\n //Applying this effect to both the color and alpha accumulation results in more realistic transparency.\n alphaSample *= (1.0 - accumulatedAlpha);\n\n //Scaling alpha by the number of steps makes the final color invariant to the step size.\n alphaSample *= alphaScaleFactor;\n\n //Perform the composition.\n accumulatedColor += colorSample * alphaSample;\n\n //Store the alpha accumulated so far.\n accumulatedAlpha += alphaSample;\n\n //Advance the ray.\n currentPosition += deltaDirection;\n accumulatedLength += deltaDirectionLength;\n\n //If the length traversed is more than the ray length, or if the alpha accumulated reaches 1.0 then exit.\n if(accumulatedLength >= rayLength || accumulatedAlpha >= 1.0 )\n break;\n }\n\n gl_FragColor = accumulatedColor;\n\n }\n `;\n return txt;\n }\n\n //\n // init_window\n //\n function init_window() {\n //\n // close button\n //\n var btn = document.createElement('button');\n btn.appendChild(document.createTextNode('close'));\n btn.style.padding = mods.ui.padding;\n btn.style.margin = 1;\n btn.addEventListener('click',function(){\n win.close();\n mod.win = undefined;\n });\n win.document.body.appendChild(btn);\n //\n // label text\n //\n var text = win.document.createTextNode(' left: pan, right: rotate, scroll: zoom');\n win.document.body.appendChild(text);\n //\n // GL container\n //\n win.document.body.appendChild(document.createElement('br')) ; \n container = win.document.createElement('div');\n container.style.overflow = 'hidden';\n win.document.body.appendChild(container);\n\n ///////////////////////////////////////////axes////////////////////////////\n //GL Axes Container\n // win.document.body.appendChild(document.createElement('br')) ; \n containerAxes = win.document.createElement('div');\n containerAxes.style.overflow = 'hidden';\n containerAxes.style.position = 'absolute';\n containerAxes.style.zIndex = 100;\n containerAxes.style.left = 0;\n containerAxes.style.bottom = 0;\n containerAxes.style.margin = 20;\n win.document.body.appendChild(containerAxes);\n //\n //cameraAxes\n //\n cameraAxes = new THREE.PerspectiveCamera( 50, 100 / 100, 1, 1000 );\n cameraAxes.up = new THREE.Vector3(0, 0, 1);\n //\n //rendererAxes\n //\n rendererAxes = new THREE.WebGLRenderer({ alpha: true } );\n rendererAxes.setClearColor( 0x000000, 0 );\n rendererAxes.setSize( 100, 100 );\n containerAxes.appendChild( rendererAxes.domElement );\n //\n //sceneAxes\n //\n sceneAxes=new THREE.Scene();\n axes = new THREE.AxisHelper( 100 );\n sceneAxes.add( axes ); \n\n ///////////////////////////////////////////////////////////////////////////////////\n \n //\n //camera\n //\n camera = new THREE.PerspectiveCamera( 40, win.innerWidth / win.innerHeight, 0.01, 3000.0 );\n camera.position.z = 2.0;\n camera.aspect = win.innerWidth / win.innerHeight;\n camera.up = new THREE.Vector3(0, 0, 1);\n camera.position.x = 5;\n camera.lookAt(new THREE.Vector3(0,0,0));\n camera.updateProjectionMatrix();\n center= new THREE.Vector3(0,0,0);\n\n \n \n //\n //setup textures and scenes\n //\n var screenSize = new THREE.Vector2( win.innerWidth, win.innerHeight );\n rtTexture = new THREE.WebGLRenderTarget( screenSize.x, screenSize.y,\n { minFilter: THREE.LinearFilter,\n magFilter: THREE.LinearFilter,\n wrapS: THREE.ClampToEdgeWrapping,\n wrapT: THREE.ClampToEdgeWrapping,\n format: THREE.RGBAFormat,\n type: THREE.FloatType,\n generateMipmaps: false} );\n\n\n var materialFirstPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderFirstPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderFirstPass' ).textContent,\n side: THREE.BackSide\n } );\n\n var lookAtVector = new THREE.Vector3(0,0, -1);\n lookAtVector.applyQuaternion(camera.quaternion);\n\n sceneFirstPass = new THREE.Scene();\n sceneSecondPass = new THREE.Scene();\n\n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n materialSecondPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n side: THREE.FrontSide,\n uniforms: { tex: { type: \"t\", value: rtTexture },\n steps : {type: \"1f\" , value: mod.steps.value }, \n xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n cameraPos :{value: tempCam.normalize()} \n }\n });\n\n //HELPER GRID\n gridHelper = new THREE.GridHelper( gridHelpersSize, 20 );//SIZE DIVISION\n var geometry = new THREE.SphereGeometry( 0.1,32,32);\n var material = new THREE.MeshNormalMaterial();\n sphereO = new THREE.Mesh( geometry, material );\n\n var materialX = new THREE.LineBasicMaterial({\n color: 0xFF0000\n });\n var materialY = new THREE.LineBasicMaterial({\n color: 0x00FF00\n });\n \n var geometryX = new THREE.Geometry();\n geometryX.vertices.push(\n new THREE.Vector3( -5, 0, 0 ),\n new THREE.Vector3( 5, 0, 0 )\n );\n var geometryY = new THREE.Geometry();\n geometryY.vertices.push(\n new THREE.Vector3( 0, -5, 0 ),\n new THREE.Vector3( 0, 5, 0 )\n );\n \n var lineX = new THREE.Line( geometryX, materialX );\n var lineY = new THREE.Line( geometryY, materialY );\n\n gridHelper.add(lineX);\n gridHelper.add(lineY);\n sceneSecondPass.add( gridHelper );\n // sceneSecondPass.add( sphereO );\n gridHelper.geometry.rotateX( Math.PI / 2 );\n \n updateGridHelper();\n \n \n //\n //cube renderer\n //\n boxGeometry = new THREE.BoxGeometry(1.0, 1.0, 1.0);\n boxGeometry.doubleSided = true;\n\n materialSecondPass.transparent =true;\n var meshFirstPass = new THREE.Mesh( boxGeometry, materialFirstPass );\n meshSecondPass = new THREE.Mesh( boxGeometry, materialSecondPass );\n\n sceneFirstPass.add( meshFirstPass );\n sceneSecondPass.add( meshSecondPass );\n\n renderer = new THREE.WebGLRenderer();\n container.appendChild( renderer.domElement );\n renderer.setSize( win.innerWidth, win.innerHeight );\n\n\n //\n // mod viewer\n //\n\n //grab the context from your destination canvas\n var destCtx = mod.canvas.getContext('2d');\n destCtx.clearRect(0,0,mod.canvas.width,mod.canvas.height);\n //call its drawImage() function passing it the source canvas directly\n destCtx.drawImage(container.childNodes[0], 0, 0);\n\n\n clock=new THREE.Clock();\n //\n //controls\n //\n var Controls = (function(Controls) {\n // \"use strict\";\n \n // Check for double inclusion\n if (Controls.addMouseHandler)\n return Controls;\n \n Controls.addMouseHandler = function (domObject, drag, zoomIn, zoomOut) {\n var startDragX = null,\n startDragY = null;\n \n function mouseWheelHandler(e) {\n e = window.event || e;\n var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));\n \n if (delta < 0 && zoomOut) {\n zoomOut(delta);\n } else if (zoomIn) {\n zoomIn(delta);\n }\n \n e.preventDefault();\n }\n \n function mouseDownHandler(e) {\n startDragX = e.clientX;\n startDragY = e.clientY;\n \n e.preventDefault();\n }\n \n function mouseMoveHandler(e) {\n if (startDragX === null || startDragY === null)\n return;\n \n if (drag)\n drag(e.clientX - startDragX, e.clientY - startDragY);\n \n startDragX = e.clientX;\n startDragY = e.clientY;\n \n e.preventDefault();\n }\n \n function mouseUpHandler(e) {\n mouseMoveHandler.call(this, e);\n startDragX = null;\n startDragY = null;\n \n e.preventDefault();\n }\n \n domObject.addEventListener(\"mousewheel\", mouseWheelHandler);\n domObject.addEventListener(\"DOMMouseScroll\", mouseWheelHandler);\n domObject.addEventListener(\"mousedown\", mouseDownHandler);\n domObject.addEventListener(\"mousemove\", mouseMoveHandler);\n domObject.addEventListener(\"mouseup\", mouseUpHandler);\n };\n return Controls;\n }(Controls || {}));\n Controls.addMouseHandler(renderer.domElement, drag, zoomIn, zoomOut);\n \n\n //\n // event handlers\n //\n win.addEventListener( 'resize', onWindowResize, false );\n win.addEventListener('contextmenu',context_menu);\n \n render();\n }\n \n //\n //window resize\n //\n function onWindowResize( event ) {\n\n //TODO: Fix box white edge when window resize\n renderer.setSize( win.innerWidth, win.innerHeight );\n\n camera.aspect = win.innerWidth / win.innerHeight;\n camera.updateProjectionMatrix();\n\n redraw(false);\n }\n\n //\n //context menu\n //\n function context_menu(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n return (false);\n }\n\n //\n // mouse_down\n //\n function mouse_down(evt) \n { \n evt.preventDefault();\n evt.stopPropagation();\n mod.button = evt.button;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n }\n\n //\n // mouse_up\n //\n function mouse_up(evt) {\n mod.button = undefined;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n }\n\n //\n // mouse_move\n //\n function mouse_move(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n var dx = evt.clientX-mod.x;\n var dy = evt.clientY-mod.y;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n if (mod.button == 0) {\n mod.x0 += \n Math.sin(mod.thetaz)*mod.height*dy/win.innerHeight\n -Math.cos(mod.thetaz)*mod.width*dx/win.innerWidth;\n mod.y0 += \n Math.cos(mod.thetaz)*mod.height*dy/win.innerHeight\n +Math.sin(mod.thetaz)*mod.width*dx/win.innerWidth;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n redraw(false);\n }\n else if (mod.button == 2) {\n mod.thetaxy += dy/win.innerHeight;\n mod.thetaz += dx/win.innerWidth;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n renderer.render(scene,camera);\n }\n }\n\n //\n // mouse_wheel\n //\n function mouse_wheel(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n var dy = evt.deltaY/win.innerHeight;\n mod.r += mod.height*dy;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n redraw(false);\n }\n\n //\n //redraw\n //\n \n\n function frame() \n {\n if (delta == 5) {\n delta=0;\n clearInterval(frameID);\n } else {\n delta++; \n render(true,mod.steps.value*delta/5);\n }\n } \n\n function redraw(updateUniforms)\n {\n if(mod.rendPerformance==1)\n {\n if(frameID!=null)\n {\n clearInterval(frameID);\n }\n frameID=setInterval(frame, interval); \n }else\n {\n if(frameID!=null)\n {\n clearInterval(frameID);\n }\n render(updateUniforms,mod.steps.value);\n }\n }\n mod.redraw=redraw;\n\n function updateGridHelper()\n {\n //TODO: later move/rotate camera based on changes\n //update grid helper based on limits\n gridHelper.geometry.rotateX( - Math.PI / 2 );\n gridHelper.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2 - mod.xLimit1)*gridHelpersSize/2.0);\n gridHelper.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2 - mod.yLimit1)*gridHelpersSize/2.0);\n gridHelper.position.x=( (0.0 - (mod.xLimit1)) * (0.5 - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n gridHelper.position.y=( (0.0 - (mod.yLimit1)) * (0.5 - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n gridHelper.position.z=( (0.0 - (mod.zLimit1)) * (0.5 - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n gridHelper.geometry.rotateX( Math.PI / 2 );\n \n sphereO.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2 - mod.xLimit1)*gridHelpersSize/0.5);\n sphereO.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2 - mod.yLimit1)*gridHelpersSize/0.5);\n sphereO.scale.z=gridHelpersSize/(Math.abs(mod.zLimit2 - mod.zLimit1)*gridHelpersSize/0.5);\n \n sphereO.position.x=( (0.0 - (mod.xLimit1)) * (0.5 - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n sphereO.position.y=( (0.0 - (mod.yLimit1)) * (0.5 - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n sphereO.position.z=( (0.0 - (mod.zLimit1)) * (0.5 - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n }\n\n //\n //render\n //\n function render(updateUniforms ,resolutionStep) {\n if(updateUniforms)\n {\n \n materialSecondPass.uniforms.steps.value = resolutionStep;\n materialSecondPass.uniforms.alphaCorrection.value = mod.alphaCorrection;\n materialSecondPass.uniforms.xLimit1.value =mod.xLimit1 ;\n materialSecondPass.uniforms.xLimit2.value =mod.xLimit2 ; \n materialSecondPass.uniforms.yLimit1.value =mod.yLimit1 ; \n materialSecondPass.uniforms.yLimit2.value =mod.yLimit2 ; \n materialSecondPass.uniforms.zLimit1.value =mod.zLimit1 ; \n materialSecondPass.uniforms.zLimit2.value =mod.zLimit2 ;\n\n\n //TODO: Find the error with xray and fix it\n if(mod.rendType=='1')//xray\n {\n materialSecondPass.transparent =false;\n }else\n {\n materialSecondPass.transparent =true;\n }\n\n updateGridHelper();\n }\n\n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n\n materialSecondPass.uniforms.cameraPos.value=tempCam.normalize();\n tempCam.normalize();\n tempCam.addScalar(0.5);\n\n //Render first pass and store the world space coords of the back face fragments into the texture.\n renderer.render( sceneFirstPass, camera, rtTexture, true );\n\n //Render the second pass and perform the volume rendering.\n renderer.render( sceneSecondPass, camera );\n\n //render axes camera\n cameraAxes.position.x=camera.position.x;\n cameraAxes.position.y=camera.position.y;\n cameraAxes.position.z=camera.position.z;\n\tcameraAxes.position.sub( center ); \n\tcameraAxes.position.setLength( 300 );\n cameraAxes.lookAt( sceneAxes.position.clone() ); \n\n rendererAxes.render( sceneAxes, cameraAxes );\n\n updateModViewer();\n \n }\n\n //\n //render to small mod viewer\n //\n function updateModViewer()\n {\n var w=win.innerWidth;\n var h=win.innerHeight;\n if (w > h) {\n var x0 = 0;\n var y0 = mod.canvas.height*.5*(1-h/w);\n var wd = mod.canvas.width;\n var hd = mod.canvas.width*h/w;\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h);\n var y0 = 0;\n var wd = mod.canvas.height*w/h;\n var hd = mod.canvas.height;\n }\n var destCtx = mod.canvas.getContext('2d');\n destCtx.drawImage(container.childNodes[0],x0,y0,wd,hd);\n\n }\n\n //\n //when fuction changes\n //\n function updateShaderFunction()\n {\n // outputs.messageLog.event('update shader');\n \n // outputs.messageLog.event(mod.xLimit1);\n\n var div = document.getElementById('fragmentShaderSecondPass');\n\n div.innerHTML=\"\";\n div.innerHTML =fragmentShaderSecondPass();\n \n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n // outputs.messageLog.event('update shader1');\n materialSecondPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n side: THREE.FrontSide,\n uniforms: { tex: { type: \"t\", value: rtTexture },\n steps : {type: \"1f\" , value: mod.steps.value }, \n xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n cameraPos :{value: tempCam.normalize()}\n }\n });\n\n //new THREE.Vector3(20.0,-60.0,-40.0)\n meshSecondPass.material=materialSecondPass;\n meshSecondPass.material.needsUpdate = true;\n meshSecondPass.material.transparent =true;\n\n redraw(true);\n\n //test performance\n // mod.tend = Date.now();\n // var dt = mod.tend-mod.tstart;\n // outputs.messageLog.event(dt/1000);\n\n }\n mod.updateShaderFunction=updateShaderFunction;\n \n //\n //controls\n //\n function drag(deltaX, deltaY) \n {\n var radPerPixel = (Math.PI / 450),\n deltaPhi = radPerPixel * deltaX,\n deltaTheta = radPerPixel * deltaY,\n pos = camera.position.sub(center),\n radius = pos.length(),\n theta = Math.acos(pos.z / radius),\n phi = Math.atan2(pos.y, pos.x);\n\n // Subtract deltaTheta and deltaPhi\n theta = Math.min(Math.max(theta - deltaTheta, 0), Math.PI);\n phi -= deltaPhi;\n\n // Turn back into Cartesian coordinates\n pos.x = radius * Math.sin(theta) * Math.cos(phi);\n pos.y = radius * Math.sin(theta) * Math.sin(phi);\n pos.z = radius * Math.cos(theta);\n\n camera.position.add(center);\n camera.lookAt(center);\n redraw(false);\n }\n\n ///\n function zoomIn() \n {\n camera.position.sub(center).multiplyScalar(0.9).add(center);\n redraw(false);\n }\n\n ///\n function zoomOut() \n {\n camera.position.sub(center).multiplyScalar(1.1).add(center);\n redraw(false);\n }\n}\n\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n });\n}());\n\n\n","top":"709.8880770918156","left":"2738.279844505063","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"variables\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04772797317232935\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"in0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.04772797317232935\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"clear\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9458395548196141\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9458395548196141\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5939459494005885\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5939459494005885\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"clear\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.19288167008415902\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.19288167008415902\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8373334092218472\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.01016844222037161\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.01016844222037161\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.43117078925934216\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}"]} \ No newline at end of file +{"modules":{"0.3625970106871924":{"definition":"//\n// frep circle\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep circle'\n//\n// initialization\n//\nvar init = function() {\n mod.x.value = '0'\n mod.y.value = '0'\n mod.radius.value = '1'\n }\n//\n// inputs\n//\nvar inputs = {\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.variables.event()\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var fn = `((${radius})*(${radius})-((X-(${x}))*(X-(${x}))+(Y-(${y}))*(Y-(${y}))))`\n var variables = ['X','Y']\n var limits = [[x-radius,x+radius],[y-radius,y+radius]]\n var type = 'Magnitude'\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n },\n variables:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var vars = {x:x,y:y,radius:radius}\n mods.output(mod,'variables',vars)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createElement('br'))\n //\n // r\n //\n div.appendChild(document.createTextNode('radius: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.radius = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.variables.event()\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"331","left":"406","inputs":{},"outputs":{}},"0.8373334092218472":{"definition":"//\n// frep view slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep view slice'\n//\n// initialization\n//\nvar init = function() {\n mod.width.value = '1000'\n mod.z.value = '0'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'frep',\n event:function(evt){\n mod.fn.value = evt.detail.function\n view_slice(evt.detail)\n }}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.y.value = ''\n mod.z.value = ''\n })\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.x.value = ''\n mod.z.value = ''\n })\n div.appendChild(input)\n mod.y = input\n //\n // z\n //\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.x.value = ''\n mod.y.value = ''\n })\n div.appendChild(input)\n mod.z = input\n div.appendChild(document.createElement('br'))\n //\n // width\n //\n div.appendChild(document.createTextNode('width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.height.value = ''\n })\n div.appendChild(input)\n mod.width = input\n //\n // height\n //\n div.appendChild(document.createTextNode(' height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('input',function(){\n mod.width.value = ''\n })\n div.appendChild(input)\n mod.height = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // view button\n //\n div.appendChild(document.createTextNode(' '))\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n mod.win = window.open('')\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n mod.win.addEventListener('unload',function() {\n mod.win = null\n })\n var canvas = document.createElement('canvas')\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// view_slice\n//\nfunction view_slice(shape) { \n var fn = shape.function\n var vars = shape.variables\n var limits = shape.limits\n var type = shape.type\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var z = parseFloat(mod.z.value)\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n if (vars.length == 2) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[1]\n var ylimits = limits[1]\n var zvar = ''\n var zval = 0\n }\n else if (!isNaN(x)) {\n var xvar = vars[1]\n var xlimits = limits[1]\n var yvar = vars[2]\n var ylimits = limits[2]\n var zvar = vars[0]\n var zval = x\n }\n else if (!isNaN(y)) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[2]\n var ylimits = limits[2]\n var zvar = vars[1]\n var zval = y\n }\n else if (!isNaN(z)) {\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[1]\n var ylimits = limits[1]\n var zvar = vars[2]\n var zval = z\n }\n if (!isNaN(w))\n h = Math.floor(w*(ylimits[1]-ylimits[0])/(xlimits[1]-xlimits[0]))\n else\n w = Math.floor(h*(xlimits[1]-xlimits[0])/(ylimits[1]-ylimits[0]))\n mod.img.height = h\n mod.img.width = w\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n var h = mod.img.height\n var w = mod.img.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var imgdata = new ImageData(buf,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(imgdata,0,0)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n if (mod.win != null) {\n var canvas = mod.win.document.getElementById(mod.div.id+'canvas')\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n }\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n var ctx = mod.img.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.img.width,mod.img.height)\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:img.height,width:img.width,\n xvar:xvar,yvar:yvar,zvar:zvar,zval:zval,\n xlimits:xlimits,ylimits:ylimits,\n function:fn,\n buffer:img.data.buffer},\n [img.data.buffer])\n }\n//\n// worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var xvar = evt.data.xvar\n var yvar = evt.data.yvar\n var zvar = evt.data.zvar\n var zval = evt.data.zval\n var xlimits = evt.data.xlimits\n var ylimits = evt.data.ylimits\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var f = new Function(xvar,yvar,zvar,'return ('+evt.data.function+')')\n var x,y,v\n for (var row = 0; row < h; ++row) {\n y = ylimits[0]+(ylimits[1]-ylimits[0])*row/(h-1)\n for (var col = 0; col < w; ++col) {\n x = xlimits[0]+(xlimits[1]-xlimits[0])*col/(w-1)\n v = (f(x,y,zval) >= 0) ? 255 : 0\n buf[(h-1-row)*w*4+col*4+0] = v\n buf[(h-1-row)*w*4+col*4+1] = v\n buf[(h-1-row)*w*4+col*4+2] = v\n buf[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n self.postMessage({buffer:buf.buffer},[buf.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"292","left":"2803","inputs":{},"outputs":{}},"0.7152788275346978":{"definition":"//\n// frep circle\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep circle'\n//\n// initialization\n//\nvar init = function() {\n mod.x.value = '0.4'\n mod.y.value = '0.4'\n mod.radius.value = '0.16666666666666666'\n }\n//\n// inputs\n//\nvar inputs = {\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.variables.event()\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var fn = `((${radius})*(${radius})-((X-(${x}))*(X-(${x}))+(Y-(${y}))*(Y-(${y}))))`\n var variables = ['X','Y']\n var limits = [[x-radius,x+radius],[y-radius,y+radius]]\n var type = 'Magnitude'\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n },\n variables:{type:'',\n event:function(){\n var x = parseFloat(mod.x.value)\n var y = parseFloat(mod.y.value)\n var radius = parseFloat(mod.radius.value)\n var vars = {x:x,y:y,radius:radius}\n mods.output(mod,'variables',vars)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x\n //\n div.appendChild(document.createTextNode('x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x = input\n //\n // y\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createElement('br'))\n //\n // r\n //\n div.appendChild(document.createTextNode('radius: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.radius = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.variables.event()\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"661","left":"793","inputs":{},"outputs":{}},"0.04772797317232935":{"definition":"//\n// construct object\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'construct object'\n//\n// initialization\n//\nvar init = function() {\n mod.in0.value = '{\"x\":0,\"y\":0,\"radius\":1}'\n mod.in1.value = '{}'\n mod.out0.value = '{x:.4*in0.radius,y:.4*in0.radius,radius:in0.radius/6}'\n mod.out1.value = '{}'\n }\n//\n// inputs\n//\nvar inputs = {\n in0:{type:'',label:'input 0',\n event:function(evt) {\n mod.in0.value = JSON.stringify(evt.detail)\n construct_output()\n }},\n in1:{type:'',label:'input 1',\n event:function(evt) {\n mod.in1.value = JSON.stringify(evt.detail)\n construct_output()\n }}}\n//\n// outputs\n//\nvar outputs = {\n out0:{type:'',label:'output 0',\n event:function(arg){\n mods.output(mod,'out0',arg)\n }},\n out1:{type:'',label:'output 1',\n event:function(arg){\n mods.output(mod,'out1',arg)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // inputs\n //\n div.appendChild(document.createTextNode('input 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('input 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in1 = text\n div.appendChild(document.createElement('br'))\n //\n // outputs\n //\n div.appendChild(document.createTextNode('output 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('output 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out1 = text\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n construct_output()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\nfunction construct_output() {\n var in0 = JSON.parse(mod.in0.value)\n var in1 = JSON.parse(mod.in1.value)\n eval('out0 ='+mod.out0.value)\n eval('out1 ='+mod.out1.value)\n outputs.out0.event(out0)\n outputs.out1.event(out1)\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"613","left":"339","inputs":{},"outputs":{}},"0.9645985086194264":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"345","left":"800","inputs":{},"outputs":{}},"0.9458395548196141":{"definition":"//\n// frep reflect\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep reflect'\n//\n// initialization\n//\nvar init = function() {\n mod.origin0.value = '0'\n mod.origin1.value = '0'\n mod.x.checked = true\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var origin0 = parseFloat(mod.origin0.value)\n var origin1 = parseFloat(mod.origin1.value)\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.x.checked) {\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${xvar}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dl = mod.shape.limits[0][0]-origin0\n limits[0][0] = origin0-(dl+dx)\n limits[0][1] = origin0-dl\n }\n else if (mod.y.checked) {\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${yvar}))`)\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dl = mod.shape.limits[1][0]-origin0\n limits[1][0] = origin0-(dl+dy)\n limits[1][1] = origin0-dl\n }\n else if (mod.z.checked) {\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`(${2*origin0}-(${zvar}))`)\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dl = mod.shape.limits[2][0]-origin0\n limits[2][0] = origin0-(dl+dz)\n limits[2][1] = origin0-dl\n }\n else if (mod.xy.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,'TEMP')\n fn = fn.replace(yre,`((${origin1})+(${xvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${yvar})-(${origin1}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dxl = mod.shape.limits[0][0]-origin0\n var dyl = mod.shape.limits[1][0]-origin1\n limits[0][0] = origin0+dyl\n limits[0][1] = origin0+dyl+dy\n limits[1][0] = origin1+dxl\n limits[1][1] = origin1+dxl+dx\n }\n else if (mod.xz.checked) {\n var xvar = variables[0]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(xre,'TEMP')\n fn = fn.replace(zre,`((${origin1})+(${xvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${zvar})-(${origin1}))`)\n var dx = mod.shape.limits[0][1]-mod.shape.limits[0][0]\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dxl = mod.shape.limits[0][0]-origin0\n var dzl = mod.shape.limits[2][0]-origin1\n limits[0][0] = origin0+dzl\n limits[0][1] = origin0+dzl+dz\n limits[2][0] = origin1+dxl\n limits[2][1] = origin1+dxl+dx\n }\n else if (mod.yz.checked) {\n var yvar = variables[1]\n var zvar = variables[2]\n var yre = new RegExp(yvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(yre,'TEMP')\n fn = fn.replace(zre,`((${origin1})+(${yvar})-(${origin0}))`)\n fn = fn.replace(/TEMP/g,`((${origin0})+(${zvar})-(${origin1}))`)\n var dy = mod.shape.limits[1][1]-mod.shape.limits[1][0]\n var dz = mod.shape.limits[2][1]-mod.shape.limits[2][0]\n var dyl = mod.shape.limits[1][0]-origin0\n var dzl = mod.shape.limits[2][0]-origin1\n limits[1][0] = origin0+dzl\n limits[1][1] = origin0+dzl+dz\n limits[2][0] = origin1+dyl\n limits[2][1] = origin1+dyl+dy\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // axis\n //\n div.appendChild(document.createTextNode('axis: '))\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('x'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'x'\n div.appendChild(input)\n mod.x = input\n div.appendChild(document.createTextNode(' y'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'y'\n div.appendChild(input)\n mod.y = input\n div.appendChild(document.createTextNode(' z'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'z'\n div.appendChild(input)\n mod.z = input\n div.appendChild(document.createElement('br'))\n //\n // origin 0\n //\n div.appendChild(document.createTextNode('origin 0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.origin0 = input\n div.appendChild(document.createElement('br'))\n //\n // axis\n //\n div.appendChild(document.createTextNode('xy'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'xy'\n div.appendChild(input)\n mod.xy = input\n div.appendChild(document.createTextNode(' xz'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'xz'\n div.appendChild(input)\n mod.xz = input\n div.appendChild(document.createTextNode(' yz'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n input.id = mod.div.id+'yz'\n div.appendChild(input)\n mod.yz = input\n div.appendChild(document.createElement('br'))\n //\n // origin 1\n //\n div.appendChild(document.createTextNode('origin 1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.origin1 = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"660","left":"1160","inputs":{},"outputs":{}},"0.04930175848785401":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = 'Math.min(((1)*(1)-((X-(0))*(X-(0))+(Y-(0))*(Y-(0)))),-(((0.16666666666666666)*(0.16666666666666666)-((X-(0.4))*(X-(0.4))+(Y-(0.4))*(Y-(0.4))))))'\n mod.fn1.value = '((0.16666666666666666)*(0.16666666666666666)-(((0-(X))-(0.4))*((0-(X))-(0.4))+(Y-(0.4))*(Y-(0.4))))'\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"342","left":"1160","inputs":{},"outputs":{}},"0.5608762029437723":{"definition":"//\n// frep scale\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep scale'\n//\n// initialization\n//\nvar init = function() {\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = ''\n mod.sx.value = '.7'\n mod.sy.value = '.7'\n mod.sz.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.ox.value != '') {\n var ox = parseFloat(mod.ox.value)\n var sx = parseFloat(mod.sx.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/(${sx}))`)\n limits[0][0] = ox+(limits[0][0]-ox)*sx\n limits[0][1] = ox+(limits[0][1]-ox)*sx\n }\n if (mod.oy.value != '') {\n var oy = parseFloat(mod.oy.value)\n var sy = parseFloat(mod.sy.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/(${sy}))`)\n limits[1][0] = oy+(limits[1][0]-oy)*sy\n limits[1][1] = oy+(limits[1][1]-oy)*sy\n }\n if (mod.oz.value != '') {\n var oz = parseFloat(mod.oz.value)\n var sz = parseFloat(mod.sz.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`((${oz})+(${zvar}-(${oz}))/(${sz}))`)\n limits[2][0] = oz+(limits[2][0]-oz)*sz\n limits[2][1] = oz+(limits[2][1]-oz)*sz\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sx = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"687","left":"1571","inputs":{},"outputs":{}},"0.40238136387777756":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = 'Math.min(Math.min(((1)*(1)-((X-(0))*(X-(0))+(Y-(0))*(Y-(0)))),-(((0.16666666666666666)*(0.16666666666666666)-((X-(0.4))*(X-(0.4))+(Y-(0.4))*(Y-(0.4)))))),-(((0.16666666666666666)*(0.16666666666666666)-(((0-(X))-(0.4))*((0-(X))-(0.4))+(Y-(0.4))*(Y-(0.4))))))'\n mod.fn1.value = 'Math.min(((0)-Y),(Math.min(((1)*(1)-((((0)+(X-(0))/(0.7))-(0))*(((0)+(X-(0))/(0.7))-(0))+(((0)+(Y-(0))/(0.7))-(0))*(((0)+(Y-(0))/(0.7))-(0)))),-(((1)*(1)-((((0)+(((0)+(X-(0))/(0.75))-(0))/(0.7))-(0))*(((0)+(((0)+(X-(0))/(0.75))-(0))/(0.7))-(0))+(((0)+(((0)+(Y-(0))/(0.75))-(0))/(0.7))-(0))*(((0)+(((0)+(Y-(0))/(0.75))-(0))/(0.7))-(0))))))))'\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"332","left":"1519","inputs":{},"outputs":{}},"0.5939459494005885":{"definition":"//\n// frep scale\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep scale'\n//\n// initialization\n//\nvar init = function() {\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = ''\n mod.sx.value = '.75'\n mod.sy.value = '.75'\n mod.sz.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.ox.value != '') {\n var ox = parseFloat(mod.ox.value)\n var sx = parseFloat(mod.sx.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/(${sx}))`)\n limits[0][0] = ox+(limits[0][0]-ox)*sx\n limits[0][1] = ox+(limits[0][1]-ox)*sx\n }\n if (mod.oy.value != '') {\n var oy = parseFloat(mod.oy.value)\n var sy = parseFloat(mod.sy.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/(${sy}))`)\n limits[1][0] = oy+(limits[1][0]-oy)*sy\n limits[1][1] = oy+(limits[1][1]-oy)*sy\n }\n if (mod.oz.value != '') {\n var oz = parseFloat(mod.oz.value)\n var sz = parseFloat(mod.sz.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`((${oz})+(${zvar}-(${oz}))/(${sz}))`)\n limits[2][0] = oz+(limits[2][0]-oz)*sz\n limits[2][1] = oz+(limits[2][1]-oz)*sz\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sx = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sy = input\n div.appendChild(document.createTextNode(' z: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.sz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"744","left":"1976","inputs":{},"outputs":{}},"0.690161531242695":{"definition":"//\n// frep subtract\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep subtract'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.min(${mod.shape0.function},-(${mod.shape1.function}))`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v)\n limits[v] = [mod.shape0.limits[v][0],mod.shape0.limits[v][1]]\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"765","left":"2336","inputs":{},"outputs":{}},"0.19288167008415902":{"definition":"//\n// frep slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep slice'\n//\n// initialization\n//\nvar init = function() {\n mod.x0.value = ''\n mod.x1.value = ''\n mod.y0.value = ''\n mod.y1.value = '0'\n mod.z0.value = ''\n mod.z1.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n var variables = mod.shape.variables\n var fn = mod.shape.function\n if (mod.x0.value != '') {\n var x0 = parseFloat(mod.x0.value)\n var xvar = variables[0]\n fn = `Math.min((${xvar}-(${x0})),(${fn}))`\n limits[0][0] = Math.max(limits[0][0],x0)\n }\n if (mod.x1.value != '') {\n var x1 = parseFloat(mod.x1.value)\n var xvar = variables[0]\n fn = `Math.min(((${x1})-${xvar}),(${fn}))`\n limits[0][1] = Math.min(limits[0][1],x1)\n }\n if (mod.y0.value != '') {\n var y0 = parseFloat(mod.y0.value)\n var yvar = variables[1]\n fn = `Math.min((${yvar}-(${y0})),(${fn}))`\n limits[1][0] = Math.max(limits[1][0],y0)\n }\n if (mod.y1.value != '') {\n var y1 = parseFloat(mod.y1.value)\n var yvar = variables[1]\n fn = `Math.min(((${y1})-${yvar}),(${fn}))`\n limits[1][1] = Math.min(limits[1][1],y1)\n }\n if (mod.z0.value != '') {\n var z0 = parseFloat(mod.z0.value)\n var zvar = variables[2]\n fn = `Math.min((${zvar}-(${z0})),(${fn}))`\n limits[2][0] = Math.max(limits[2][0],z0)\n }\n if (mod.z1.value != '') {\n var z1 = parseFloat(mod.z1.value)\n var zvar = variables[2]\n fn = `Math.min(((${z1})-${zvar}),(${fn}))`\n limits[2][1] = Math.min(limits[2][1],z1)\n }\n var shape = {function:fn,variables:mod.shape.variables,limits:limits,type:mod.shape.type}\n mod.fn.value = fn\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x0\n //\n div.appendChild(document.createTextNode('x0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x0 = input\n //\n // x1\n //\n div.appendChild(document.createTextNode(' x1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.x1 = input\n div.appendChild(document.createElement('br'))\n //\n // y0\n //\n div.appendChild(document.createTextNode('y0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y0 = input\n //\n // y1\n //\n div.appendChild(document.createTextNode(' y1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.y1 = input\n div.appendChild(document.createElement('br'))\n //\n // z0\n //\n div.appendChild(document.createTextNode('z0: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.z0 = input\n //\n // z1\n //\n div.appendChild(document.createTextNode(' z1: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.z1 = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"426","left":"1910","inputs":{},"outputs":{}},"0.8080126368305371":{"definition":"//\n// frep taper \n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep taper'\n//\n// initialization\n//\nvar init = function() {\n mod.variable0.value = '-1'\n mod.variable1.value = '1'\n mod.scale0.value = '.5'\n mod.scale1.value = '2'\n mod.originx.value = '0'\n mod.originy.value = '0'\n mod.xy.checked = true\n mod.xz.checked = false\n mod.yz.checked = false\n mod.xyz.checked = false\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var var0 = parseFloat(mod.variable0.value)\n var var1 = parseFloat(mod.variable1.value)\n var dvar = var1-var0\n var s0 = parseFloat(mod.scale0.value)\n var s1 = parseFloat(mod.scale1.value)\n var ds = s1-s0\n var ox = parseFloat(mod.originx.value)\n var oy = parseFloat(mod.originy.value)\n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.xy.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${yvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(ymin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(ymax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(ymin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(ymax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n }\n else if (mod.xz.checked) {\n var xvar = variables[0]\n var zvar = variables[2]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(zmin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(zmin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n }\n else if (mod.yz.checked) {\n var yvar = variables[1]\n var zvar = variables[2]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${oy})+(${yvar}-(${oy}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var y00 = oy+(ymin-oy)*(s0+ds*(zmin-var0)/dvar)\n var y01 = oy+(ymin-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][0] = Math.min(y00,y01)\n var y10 = oy+(ymax-oy)*(s0+ds*(zmin-var0)/dvar)\n var y11 = oy+(ymax-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][1] = Math.max(y10,y11)\n }\n else if (mod.xyz.checked) {\n var xvar = variables[0]\n var yvar = variables[1]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,`((${ox})+(${xvar}-(${ox}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n fn = fn.replace(yre,`((${oy})+(${yvar}-(${oy}))/((${s0})+(${ds})*(${zvar}-(${var0}))/(${dvar})))`)\n var xmin = limits[0][0]\n var xmax = limits[0][1]\n var zmin = limits[2][0]\n var zmax = limits[2][1]\n var x00 = ox+(xmin-ox)*(s0+ds*(zmin-var0)/dvar)\n var x01 = ox+(xmin-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][0] = Math.min(x00,x01)\n var x10 = ox+(xmax-ox)*(s0+ds*(zmin-var0)/dvar)\n var x11 = ox+(xmax-ox)*(s0+ds*(zmax-var0)/dvar)\n limits[0][1] = Math.max(x10,x11)\n var ymin = limits[1][0]\n var ymax = limits[1][1]\n var y00 = oy+(ymin-oy)*(s0+ds*(zmin-var0)/dvar)\n var y01 = oy+(ymin-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][0] = Math.min(y00,y01)\n var y10 = oy+(ymax-oy)*(s0+ds*(zmin-var0)/dvar)\n var y11 = oy+(ymax-oy)*(s0+ds*(zmax-var0)/dvar)\n limits[1][1] = Math.max(y10,y11)\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // direction \n //\n div.appendChild(document.createTextNode('direction: '))\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('x(y)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xy = input\n div.appendChild(document.createTextNode(' x(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xz = input\n div.appendChild(document.createTextNode(' y(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.yz = input\n div.appendChild(document.createTextNode(' xy(z)'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'axis'\n div.appendChild(input)\n mod.xyz = input\n div.appendChild(document.createElement('br'))\n //\n // variable 0\n //\n div.appendChild(document.createTextNode('at: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.variable0 = input\n //\n // scale 0\n //\n div.appendChild(document.createTextNode(' scale by: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale0 = input\n div.appendChild(document.createElement('br'))\n //\n // variable 1\n //\n div.appendChild(document.createTextNode('at: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.variable1 = input\n //\n // scale 1\n //\n div.appendChild(document.createTextNode(' scale by: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale1 = input\n div.appendChild(document.createElement('br'))\n //\n // x origin\n //\n div.appendChild(document.createTextNode('origin x: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.originx = input\n //\n // y origin\n //\n div.appendChild(document.createTextNode(' y: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.originy = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"306","left":"2275","inputs":{},"outputs":{}},"0.01016844222037161":{"definition":"//\n// frep inflate\n// todo: better Z limit\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep inflate'\n//\n// initialization\n//\nvar init = function() {\n mod.scale.value = '1'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'2D',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'3D',\n event:function(){\n var variables = []\n variables[0] = mod.shape.variables[0]\n variables[1] = mod.shape.variables[1]\n variables[2] = 'Z'\n var scale = parseFloat(mod.scale.value)\n var limits = []\n limits[0] = [mod.shape.limits[0][0],mod.shape.limits[0][1]]\n limits[1] = [mod.shape.limits[1][0],mod.shape.limits[1][1]]\n limits[2] = [0,limits[0][1]-limits[0][0]]\n fn = `((${scale})*(${mod.shape.function})-Z)`\n fn = `Math.min(${mod.shape.function},${fn})`\n fn = `Math.min(Z,${fn})`\n var shape = {function:fn,variables:variables,limits:limits,type:mod.shape.type}\n mod.fn.value = fn\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // scale\n //\n div.appendChild(document.createTextNode('scale: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.scale = input\n div.appendChild(document.createElement('br'))\n //\n // function\n //\n div.appendChild(document.createTextNode('function: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1068","left":"2361","inputs":{},"outputs":{}},"0.400055301726435":{"definition":"//\n// frep GPU volume renderer\n//\n// Neil Gershenfeld and Amira Abdel-Rahman\n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {};\n//\n// name\n//\nvar name = 'render GPU';\n//\n// initialization\n//\nvar init = function() {\n mod.steps.value=256.0;\n mod.alphaCorrection=10.0;\n mod.rendType=\"0\";\n mod.windowOpen=false;\n mod.xLimit1 =-1.0 ;\n mod.xLimit2 =1.0 ; \n mod.yLimit1 =-1.0 ; \n mod.yLimit2 =1.0 ; \n mod.zLimit1 =-1.0 ; \n mod.zLimit2 =1.0 ;\n mod.height=10.0;\n mod.width=10.0;\n mod.rendPerformance=0;\n };\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'frep',\n event:function(evt){\n\n mod.shape=evt.detail;\n\n // outputs.messageLog.event(mod.shape.limits);\n\n //get largerst range and rescale other ones to adjust limit mapping\n var tempIndex=0;\n var tempMax=-1.0;\n\n for(i=0;i<mod.shape.limits.length;i++)\n {\n if((mod.shape.limits[i][1]-mod.shape.limits[i][0]) >= tempMax )\n {\n tempIndex=i;\n tempMax=mod.shape.limits[i][1]-mod.shape.limits[i][0];\n }\n }\n for(i=0;i < mod.shape.limits.length;i++)\n {\n if(i!=tempIndex)\n {\n var tempDif = (mod.shape.limits[tempIndex][1]-mod.shape.limits[tempIndex][0])-(mod.shape.limits[i][1]-mod.shape.limits[i][0]);\n mod.shape.limits[i][0]-=tempDif/2.0;\n mod.shape.limits[i][1]+=tempDif/2.0;\n \n }\n }\n\n mod.xLimit1=mod.shape.limits[0][0] ;\n mod.xLimit2=mod.shape.limits[0][1] ; \n mod.yLimit1=mod.shape.limits[1][0] ; \n mod.yLimit2=mod.shape.limits[1][1] ; \n mod.zLimit1=mod.shape.limits[2][0] ; \n mod.zLimit2=mod.shape.limits[2][1] ;\n \n //\n //turn function string to glsl\n\t //\n\t \n\t //remove all Math.\n var str1 = mod.shape.function;\n\t str1=str1.replace(/Math./g, '');\n\t \n\t //change atan2 functions to atan\n\t str1=str1.replace(/atan2/g, \"atan\");\n \n //change all % to mod(,)\n while(str1.indexOf(\"%\")>-1) //While '%' is there\n {\n //get location\n var modLocation=str1.indexOf(\"%\");\n //replace with ','\n str1=str1.replace(/%/, \",\");\n outputs.messageLog.event(\"1:\"+str1);\n\n //parse before\n var counterBefore=modLocation;\n var count=0;\n if(str1[--counterBefore]==')')\n {\n count++;\n while(count>0)\n {\n counterBefore--;\n if(str1[counterBefore]==')')\n {\n count++;\n\n }else if (str1[counterBefore]=='(')\n {\n count--;\n }\n }\n }else{\n while(!isNaN(str1[counterBefore]) ||(str1[counterBefore]=='.')||(str1[counterBefore]=='X') ||(str1[counterBefore]=='Y')||(str1[counterBefore]=='Z'))\n {\n counterBefore--;\n }\n\n }\n \n \n //parse after\n var counterAfter=modLocation;\n count=0;\n if(str1[++counterAfter]=='(')\n {\n count++;\n while(count>0)\n {\n counterAfter++;\n if(str1[counterAfter]=='(')\n {\n count++;\n\n }else if (str1[counterAfter]==')')\n {\n count--;\n }\n }\n }else\n {\n while(!isNaN(str1[counterAfter]) ||(str1[counterAfter]=='.')||(str1[counterAfter]=='X') ||(str1[counterAfter]=='Y')||(str1[counterAfter]=='Z'))\n {\n counterAfter++;\n }\n }\n \n str1 = str1.substr(0, counterAfter) + \")\" + str1.substr(counterAfter);\n str1 = str1.substr(0, counterBefore) + \"mod(\" + str1.substr(counterBefore);\n }\n\n //turn all ints to floatS\n var str='';\n for(var i=0;i<str1.length;i++)\n {\n //if number\n if(!isNaN(str1[i]))\n {\n str+=str1[i];\n //check next value\n for(var j=i+1;j<str1.length;j++)\n {\n //if number add and continue\n if(!isNaN(str1[j])) \n {\n str+=str1[j];\n i=j;\n }\n //else if dot add and add numbers till NaN\n else if(str1[j]=='.')\n {\n str+=str1[j];\n i=j;\n //add till not num\n for(var k=j+1;k<str1.length;k++)\n {\n if( ( !isNaN(str1[k]) )||str1[k]=='e')\n {\n //fix for scientific notation\n if(str1[k]=='e' && str1[k+1]=='-')\n {\n str+=str1[k];\n i=k;\n\n k++;\n\n str+=str1[k];\n i=k;\n\n }else\n {\n str+=str1[k];\n i=k;\n\n }\n \n }\n else\n {\n k=str1.length;\n }\n }\n j=str1.length;\n }\n //else add .0 and go to next number\n else\n {\n str+='.';\n str+='0';\n j=str1.length;\n }\n }\n\n }\n else\n {\n str+=str1[i];\n }\n }\n \n mod.str=str;\n outputs.messageLog.event(str);\n\n //if window open update shader function\n if(mod.windowOpen)\n {\n mod.updateShaderFunction();\n }\n\n }}};\n//\n// outputs\n//\nvar outputs = {\n messageLog:{type:'string',\n event:function(mess){\n //show processed function\n mods.output(mod,'messageLog',mess);\n }\n }\n}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas');\n canvas.width = mods.ui.canvas;\n canvas.height = mods.ui.canvas;\n canvas.style.backgroundColor = 'rgb(0,0,0)';\n div.appendChild(canvas);\n mod.canvas = canvas;\n div.appendChild(document.createElement('br'));\n //\n // resolution\n //\n div.appendChild(document.createTextNode('resolution: '));\n var input = document.createElement('input');\n input.type = 'text';\n input.size = 3;\n input.addEventListener('input',function(){\n if(mod.windowOpen)\n {\n mod.redraw(true);\n }\n });\n div.appendChild(input);\n mod.steps = input;\n div.appendChild(document.createElement('br'));\n //\n // adaptive rendering\n //\n div.appendChild(document.createTextNode('rendering performance: '))\n var input = document.createElement('SELECT');\n \n input.setAttribute(\"id\", \"rend-adpselect\");\n \n //select menu for functions\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"0\");\n var t = document.createTextNode('constant');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"1\");\n var t = document.createTextNode('adaptive');\n z.appendChild(t);\n input.appendChild(z);\n input.addEventListener('change',function(evt){\n var temp= document.getElementById(\"rend-adpselect\");\n mod.rendPerformance=parseInt(temp.value);\n mod.updateShaderFunction();\n });\n\n div.appendChild(input);\n \n div.appendChild(document.createElement('br'));\n //\n // rendering style\n //\n div.appendChild(document.createTextNode('rendering style: '))\n var input = document.createElement('SELECT');\n \n input.setAttribute(\"id\", \"rend-select\");\n \n //select menu for functions\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"0\");\n var t = document.createTextNode('default');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"1\");\n var t = document.createTextNode('xray');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"2\");\n var t = document.createTextNode('height map (fixed)');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"3\");\n var t = document.createTextNode('height map (variable)');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"4\");\n var t = document.createTextNode('normals');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"5\");\n var t = document.createTextNode('light');\n z.appendChild(t);\n input.appendChild(z);\n\n var z = document.createElement(\"option\");\n z.setAttribute(\"value\", \"6\");\n var t = document.createTextNode('specular');\n z.appendChild(t);\n input.appendChild(z);\n \n input.addEventListener('change',function(evt){\n var temp= document.getElementById(\"rend-select\");\n mod.rendType=String(parseInt(temp.value));\n mod.updateShaderFunction();\n });\n\n div.appendChild(input);\n div.appendChild(document.createElement('br'));\n \n //\n // view\n // \n div.appendChild(document.createElement('br')) ; \n var btn = document.createElement('button');\n btn.style.padding = mods.ui.padding;\n btn.style.margin = 1;\n var span = document.createElement('span');\n var text = document.createTextNode('view');\n span.appendChild(text);\n btn.appendChild(span);\n btn.addEventListener('click',function(){\n mod.windowOpen=true; \n open_view_window();\n });\n div.appendChild(btn);\n}\n\n//\n// local functions\n//\n \n//\n// open_view_window\n//\nfunction open_view_window() {\n //\n // globals\n //\n var container;\n var camera, sceneFirstPass, sceneSecondPass, renderer;\n var containerAxes, cameraAxes , sceneAxes, rendererAxes,axes,sphereO;\n var rtTexture;\n var materialSecondPass;\n var center;\n var meshSecondPass;\n var boxGeometry;\n var gridHelper;\n var gridHelpersSize=5;\n var clock;\n var delta=0;\n var interval=10;\n var frameID;\n\n //\n // functions\n //\n \n addShaderScripts();\n open_window();\n \n //\n // open_window\n //\n function open_window() \n {\n //\n // open window\n //\n win = window.open('');\n mod.win = win;\n\n //\n // load three.js\n //\n var script = document.createElement('script');\n script.type = 'text/javascript';\n script.onload = init_window;\n script.src = 'js/three.js/three.min.js';\n mod.div.appendChild(script);\n }\n\n //\n // add shader scripts to html\n //\n function addShaderScripts() \n {\n\n /////////////////////////fragmentShaderFirstPass////////////////////////////////////\n\n var div = document.createElement('script');\n\n div.id = 'fragmentShaderFirstPass';\n div.type = 'x-shader/x-fragment';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n\n void main()\n {\n //The fragment's world space coordinates as fragment output.\n gl_FragColor = vec4( worldSpaceCoords.x , worldSpaceCoords.y, worldSpaceCoords.z, 1 );\n }\n `;\n \n //\n mod.div.appendChild(div);\n \n /////////////////////////vertexShaderFirstPass////////////////////////////////////\n var div = document.createElement('script');\n\n div.id = 'vertexShaderFirstPass';\n div.type = 'x-shader/x-vertex';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n\n void main()\n {\n //Set the world space coordinates of the back faces vertices as output.\n worldSpaceCoords = position + vec3(0.5, 0.5, 0.5); //move it from [-0.5;0.5] to [0,1]\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n `;\n \n //\n mod.div.appendChild(div);\n /////////////////////////fragmentShaderSecondPass////////////////////////////////////\n var div = document.createElement('script');\n\n div.id = 'fragmentShaderSecondPass';\n div.type = 'x-shader/x-fragment';\n\n \n div.innerHTML=fragmentShaderSecondPass();\n mod.div.appendChild(div);\n\n /////////////////////vertexShaderSecondPass///////////////////\n var div = document.createElement('script');\n\n div.id = 'vertexShaderSecondPass';\n div.type = 'x-shader/x-vertex';\n\n div.innerHTML =\n `\n varying vec3 worldSpaceCoords;\n varying vec4 projectedCoords;\n\n\n void main()\n {\n \n worldSpaceCoords = (modelMatrix * vec4(position + vec3(0.5, 0.5,0.5), 1.0 )).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n projectedCoords = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n }\n `;\n //\n mod.div.appendChild(div);\n }\n \n //\n // fragment shader (the one that does all the work)\n //\n function fragmentShaderSecondPass()\n {\n var txt =\n `\n const float PI = 3.1415926535897932384626433832795;\n #define rendType `+mod.rendType+`\n varying vec3 worldSpaceCoords;\n varying vec4 projectedCoords;\n uniform sampler2D tex;\n uniform float steps;\n uniform float alphaCorrection;\n // uniform float rendType;\n uniform vec3 cameraPos;\n // The maximum distance through our rendering volume is sqrt(3).\n // The maximum number of steps we take to travel a distance of 1 is 512.\n // ceil( sqrt(3) * 512 ) = 887\n // This prevents the back of the image from getting cut off when steps=512 & viewing diagonally.\n const int MAX_STEPS = 887;\n uniform float xLimit1;\n uniform float xLimit2;\n uniform float yLimit1;\n uniform float yLimit2;\n uniform float zLimit1;\n uniform float zLimit2;\n float orgMin=0.0;\n float orgMax=1.0;\n vec3 viewDirection;\n \n\n float map(vec3 p)\n {\n float X= p.x;\n float Y= p.y;\n float Z= p.z;\n\n return `+mod.str+`;\n }\n vec3 simpleLambert (vec3 normal) {\n vec3 lightDir = vec3(0.2,-0.6,-0.4); // Light direction\n vec3 lightDir1 = vec3(0.4, 0.6,-0.4); // Light direction\n vec3 lightCol = vec3(0.5,0.5,0.5); // Light color\n vec3 _Color=vec3(0.2,0.5,0.8);\n float lightIntensity = 3.0;\n float ambient = 0.2;\n \n float NdotL = max(dot(normalize(normal), normalize(lightDir)),0.0) * lightIntensity;\n float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0) *lightIntensity;\n\n vec3 c=vec3(0.0,0.0,0.0);\n\n c.rgb = _Color * lightCol * (NdotL + NdotL1)+ ambient ;\n\n return c;\n }\n vec3 specular (vec3 normal) {\n vec3 lightDir = vec3(0.2,-0.6,-0.4); // Light direction\n vec3 lightDir1 = vec3(0.4, 0.6,-0.4); // Light direction\n vec3 lightCol = vec3(0.5,0.5,0.5); // Light color\n vec3 _Color=vec3(0.2,0.5,0.8);\n float lightIntensity=3.0;\n float ambient = 0.2;\n\n float _SpecularPower=0.7;\n float _Gloss=0.7;\n \n float NdotL = max(dot(normalize(normal ), normalize(lightDir)),0.0)*lightIntensity;\n float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0)*lightIntensity;\n vec3 c;\n vec3 camera= cameraPos-0.5;\n\n float t= dot(normalize(lightDir), normalize( -camera));\n float tt=(dot(normalize(normal), normalize(-camera)));\n float s= ( t*_Gloss + tt*_SpecularPower)/lightIntensity;\n\n float t1= dot(normalize(lightDir1), normalize( -camera));\n float tt1=(dot(normalize(normal), normalize(-camera)));\n float s1= ( t1*_Gloss * tt1*_SpecularPower)/2.0;\n\n // float s = pow( dot(normalize(normal),h), _SpecularPower) * _Gloss;\n // h.x= (h.x - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // h.y= (h.y - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // h.z= (h.z - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n // vec3 h1 = (lightDir1 + camera)/2.0;\n // float s1 = pow( dot(normalize(normal)/2.0,h1), _SpecularPower) * _Gloss;\n\n c.rgb = _Color * lightCol * (NdotL+NdotL1)+s + s1+ ambient;\n return c;\n }\n vec3 frontLight (vec3 normal) {\n \n vec3 camera= cameraPos-0.5;\n float t=dot(normalize(normal), normalize(-camera));\n vec3 c;\n c = vec3(t,t,t);\n return c;\n }\n\n vec3 ClosestPointOnLine(vec3 start ,vec3 direction ,vec3 vPoint )\n {\n vec3 vVector1 = vPoint - start;\n vec3 vVector2 = normalize(direction);\n \n float t = dot(vVector2, vVector1);\n if (t <= 0.0)\n {\n return start;\n }\n \n vec3 vVector3 = vVector2 * t;\n \n vec3 vClosestPoint = start + vVector3;\n return vClosestPoint;\n }\n vec3 GetClosetPoint( vec3 A, vec3 B, vec3 P, bool segmentClamp)\n {\n vec3 AP = P - A;\n vec3 AB = B - A; \n float ab2 = AB.x*AB.x + AB.y*AB.y;\n float apab = AP.x*AB.x + AP.y*AB.y;\n float t = apab / ab2;\n if (segmentClamp)\n {\n if (t < 0.0) t = 0.0;\n else if (t > 1.0) t = 1.0;\n }\n vec3 Closest = A + AB * t;\n return Closest;\n }\n vec3 calcNormal( in vec3 pos )\n {\n // vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;\n // return normalize( e.xyy*map( pos + e.xyy ) + \n // e.yyx*map( pos + e.yyx ) + \n // e.yxy*map( pos + e.yxy ) + \n // e.xxx*map( pos + e.xxx ) );\n \n // vec3 eps = vec3( 0.0005, 0.0, 0.0 );\n // vec3 nor = vec3(\n // map(pos+eps.xyy) - map(pos-eps.xyy),\n // map(pos+eps.yxy) - map(pos-eps.yxy),\n // map(pos+eps.yyx) - map(pos-eps.yyx) );\n // return normalize(nor);\n\n const float eps = 0.01;\n vec3 n;\n n.x=map(pos + vec3(eps, 0, 0) ) - map(pos - vec3(eps, 0, 0));\n n.y=map(pos + vec3(0, eps, 0) ) - map(pos - vec3(0, eps, 0));\n n.z=map(pos + vec3(0, 0, eps) ) - map(pos - vec3(0, 0, eps));\n //problem with \n // n.x=result - map(pos - vec3(eps, 0, 0));\n // n.y=result - map(pos - vec3(0, eps, 0));\n // n.z=result - map(pos - vec3(0, 0, eps));\n return normalize(n);\n \n }\n\n //Acts like a texture3D using Z slices and trilinear filtering.\n vec4 sampleAs3DTextureCustom( vec3 texCoord )\n { \n float X= (texCoord.x - orgMin) * (xLimit2 - xLimit1) / (orgMax - orgMin) + xLimit1;\n float Y= (texCoord.y - orgMin) * (yLimit2 - yLimit1) / (orgMax - orgMin) + yLimit1;\n float Z= (texCoord.z - orgMin) * (zLimit2 - zLimit1) / (orgMax - orgMin) + zLimit1;\n\n //slice color red\n vec4 m;\n m=vec4(0.0,0.0,0.0,0.0);\n\n float result=`+mod.str+`;\n if(result>0.0)\n {\n m.a=1.0;\n vec3 p=vec3(X,Y,Z);\n vec3 n=calcNormal( p );\n\n #if rendType==0\n //default\n {\n float tempConst=0.001;\n m.rgb=frontLight(n)+tempConst;\n }\n #elif rendType==1\n //xray\n {\n m=vec4(1.0,1.0,1.0,0.01);\n }\n #elif rendType==2\n //height map\n {\n m.r=texCoord.z;\n m.g=texCoord.z;\n m.b=texCoord.z;\n }\n #elif rendType==3\n //depth/height map variable\n {\n vec3 cp=ClosestPointOnLine(-cameraPos,cameraPos,texCoord);\n float d= (distance(cp, normalize(cameraPos)*2.0));\n m.r=d;\n m.g=d;\n m.b=d;\n }\n #elif rendType==4\n //normals\n {\n m.r= (n.r - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n m.g= (n.g - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n m.b= (n.b - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n }\n #elif rendType==5\n //fixed lights\n {\n float tempConst=0.05;\n m.rgb=simpleLambert (n)+tempConst;\n }\n #elif rendType==6\n //fixed lights specular\n {\n float tempConst=0.00;\n m.rgb=specular (n)+tempConst;\n }\n #endif\n \n }\n return m ;\n }\n \n void main( void ) {\n\n //Transform the coordinates it from [-1;1] to [0;1]\n vec2 texc = vec2(((projectedCoords.x / projectedCoords.w) + 1.0 ) / 2.0,\n ((projectedCoords.y / projectedCoords.w) + 1.0 ) / 2.0 );\n\n //The back position is the world space position stored in the texture.\n vec3 backPos = texture2D(tex, texc).xyz;\n\n //The front position is the world space position of the second render pass.\n vec3 frontPos = worldSpaceCoords;\n\n //The direction from the front position to back position.\n vec3 dir = backPos - frontPos;\n \n float rayLength = length(dir);\n\n //Calculate how long to increment in each step.\n float delta = 1.0 / steps;\n\n //The increment in each direction for each step.\n vec3 deltaDirection = normalize(dir) * delta;\n\n viewDirection=normalize(dir);//amira added\n\n float deltaDirectionLength = length(deltaDirection);\n\n //Start the ray casting from the front position.\n vec3 currentPosition = frontPos;\n\n //The color accumulator.\n vec4 accumulatedColor = vec4(0.0);\n\n //The alpha value accumulated so far.\n float accumulatedAlpha = 0.0;\n\n //How long has the ray travelled so far.\n float accumulatedLength = 0.0;\n\n //If we have twice as many samples, we only need ~1/2 the alpha per sample.\n //Scaling by 256/10 just happens to give a good value for the alphaCorrection slider.\n float alphaScaleFactor = 25.6 * delta;\n\n vec4 colorSample;\n float alphaSample;\n\n //Perform the ray marching iterations\n for(int i = 0; i < MAX_STEPS; i++)\n {\n //Get the voxel intensity value from the 3D texture.\n colorSample = sampleAs3DTextureCustom( currentPosition );\n\n //Allow the alpha correction customization.\n alphaSample = colorSample.a * alphaCorrection;\n\n //Applying this effect to both the color and alpha accumulation results in more realistic transparency.\n alphaSample *= (1.0 - accumulatedAlpha);\n\n //Scaling alpha by the number of steps makes the final color invariant to the step size.\n alphaSample *= alphaScaleFactor;\n\n //Perform the composition.\n accumulatedColor += colorSample * alphaSample;\n\n //Store the alpha accumulated so far.\n accumulatedAlpha += alphaSample;\n\n //Advance the ray.\n currentPosition += deltaDirection;\n accumulatedLength += deltaDirectionLength;\n\n //If the length traversed is more than the ray length, or if the alpha accumulated reaches 1.0 then exit.\n if(accumulatedLength >= rayLength || accumulatedAlpha >= 1.0 )\n break;\n }\n\n gl_FragColor = accumulatedColor;\n\n }\n `;\n return txt;\n }\n\n //\n // init_window\n //\n function init_window() {\n //\n // close button\n //\n var btn = document.createElement('button');\n btn.appendChild(document.createTextNode('close'));\n btn.style.padding = mods.ui.padding;\n btn.style.margin = 1;\n btn.addEventListener('click',function(){\n win.close();\n mod.win = undefined;\n });\n win.document.body.appendChild(btn);\n //\n // label text\n //\n var text = win.document.createTextNode(' left: pan, right: rotate, scroll: zoom');\n win.document.body.appendChild(text);\n //\n // GL container\n //\n win.document.body.appendChild(document.createElement('br')) ; \n container = win.document.createElement('div');\n container.style.overflow = 'hidden';\n win.document.body.appendChild(container);\n\n ///////////////////////////////////////////axes////////////////////////////\n //GL Axes Container\n // win.document.body.appendChild(document.createElement('br')) ; \n containerAxes = win.document.createElement('div');\n containerAxes.style.overflow = 'hidden';\n containerAxes.style.position = 'absolute';\n containerAxes.style.zIndex = 100;\n containerAxes.style.left = 0;\n containerAxes.style.bottom = 0;\n containerAxes.style.margin = 20;\n win.document.body.appendChild(containerAxes);\n //\n //cameraAxes\n //\n cameraAxes = new THREE.PerspectiveCamera( 50, 100 / 100, 1, 1000 );\n cameraAxes.up = new THREE.Vector3(0, 0, 1);\n //\n //rendererAxes\n //\n rendererAxes = new THREE.WebGLRenderer({ alpha: true } );\n rendererAxes.setClearColor( 0x000000, 0 );\n rendererAxes.setSize( 100, 100 );\n containerAxes.appendChild( rendererAxes.domElement );\n //\n //sceneAxes\n //\n sceneAxes=new THREE.Scene();\n axes = new THREE.AxesHelper( 100 );\n sceneAxes.add( axes ); \n\n ///////////////////////////////////////////////////////////////////////////////////\n \n //\n //camera\n //\n camera = new THREE.PerspectiveCamera( 40, win.innerWidth / win.innerHeight, 0.01, 3000.0 );\n camera.position.z = 2.0;\n camera.aspect = win.innerWidth / win.innerHeight;\n camera.up = new THREE.Vector3(0, 0, 1);\n camera.position.x = 5;\n camera.lookAt(new THREE.Vector3(0,0,0));\n camera.updateProjectionMatrix();\n center= new THREE.Vector3(0,0,0);\n\n \n \n //\n //setup textures and scenes\n //\n var screenSize = new THREE.Vector2( win.innerWidth, win.innerHeight );\n rtTexture = new THREE.WebGLRenderTarget( screenSize.x, screenSize.y,\n { minFilter: THREE.LinearFilter,\n magFilter: THREE.LinearFilter,\n wrapS: THREE.ClampToEdgeWrapping,\n wrapT: THREE.ClampToEdgeWrapping,\n format: THREE.RGBAFormat,\n type: THREE.FloatType,\n generateMipmaps: false} );\n\n\n var materialFirstPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderFirstPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderFirstPass' ).textContent,\n side: THREE.BackSide\n } );\n\n var lookAtVector = new THREE.Vector3(0,0, -1);\n lookAtVector.applyQuaternion(camera.quaternion);\n\n sceneFirstPass = new THREE.Scene();\n sceneSecondPass = new THREE.Scene();\n\n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n materialSecondPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n side: THREE.FrontSide,\n uniforms: { tex: { type: \"t\", value: rtTexture },\n steps : {type: \"1f\" , value: mod.steps.value }, \n xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n cameraPos :{value: tempCam.normalize()} \n }\n });\n\n //HELPER GRID\n gridHelper = new THREE.GridHelper( gridHelpersSize, 20 );//SIZE DIVISION\n var geometry = new THREE.SphereGeometry( 0.1,32,32);\n var material = new THREE.MeshNormalMaterial();\n sphereO = new THREE.Mesh( geometry, material );\n\n var materialX = new THREE.LineBasicMaterial({\n color: 0xFF0000\n });\n var materialY = new THREE.LineBasicMaterial({\n color: 0x00FF00\n });\n \n var geometryX = new THREE.Geometry();\n geometryX.vertices.push(\n new THREE.Vector3( -5, 0, 0 ),\n new THREE.Vector3( 5, 0, 0 )\n );\n var geometryY = new THREE.Geometry();\n geometryY.vertices.push(\n new THREE.Vector3( 0, -5, 0 ),\n new THREE.Vector3( 0, 5, 0 )\n );\n \n var lineX = new THREE.Line( geometryX, materialX );\n var lineY = new THREE.Line( geometryY, materialY );\n\n gridHelper.add(lineX);\n gridHelper.add(lineY);\n sceneSecondPass.add( gridHelper );\n // sceneSecondPass.add( sphereO );\n gridHelper.geometry.rotateX( Math.PI / 2 );\n \n updateGridHelper();\n \n \n //\n //cube renderer\n //\n boxGeometry = new THREE.BoxGeometry(1.0, 1.0, 1.0);\n boxGeometry.doubleSided = true;\n\n materialSecondPass.transparent =true;\n var meshFirstPass = new THREE.Mesh( boxGeometry, materialFirstPass );\n meshSecondPass = new THREE.Mesh( boxGeometry, materialSecondPass );\n\n sceneFirstPass.add( meshFirstPass );\n sceneSecondPass.add( meshSecondPass );\n\n renderer = new THREE.WebGLRenderer();\n container.appendChild( renderer.domElement );\n renderer.setSize( win.innerWidth, win.innerHeight );\n\n\n //\n // mod viewer\n //\n\n //grab the context from your destination canvas\n var destCtx = mod.canvas.getContext('2d');\n destCtx.clearRect(0,0,mod.canvas.width,mod.canvas.height);\n //call its drawImage() function passing it the source canvas directly\n destCtx.drawImage(container.childNodes[0], 0, 0);\n\n\n clock=new THREE.Clock();\n //\n //controls\n //\n var Controls = (function(Controls) {\n // \"use strict\";\n \n // Check for double inclusion\n if (Controls.addMouseHandler)\n return Controls;\n \n Controls.addMouseHandler = function (domObject, drag, zoomIn, zoomOut) {\n var startDragX = null,\n startDragY = null;\n \n function mouseWheelHandler(e) {\n e = window.event || e;\n var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));\n \n if (delta < 0 && zoomOut) {\n zoomOut(delta);\n } else if (zoomIn) {\n zoomIn(delta);\n }\n \n e.preventDefault();\n }\n \n function mouseDownHandler(e) {\n startDragX = e.clientX;\n startDragY = e.clientY;\n \n e.preventDefault();\n }\n \n function mouseMoveHandler(e) {\n if (startDragX === null || startDragY === null)\n return;\n \n if (drag)\n drag(e.clientX - startDragX, e.clientY - startDragY);\n \n startDragX = e.clientX;\n startDragY = e.clientY;\n \n e.preventDefault();\n }\n \n function mouseUpHandler(e) {\n mouseMoveHandler.call(this, e);\n startDragX = null;\n startDragY = null;\n \n e.preventDefault();\n }\n \n domObject.addEventListener(\"mousewheel\", mouseWheelHandler);\n domObject.addEventListener(\"DOMMouseScroll\", mouseWheelHandler);\n domObject.addEventListener(\"mousedown\", mouseDownHandler);\n domObject.addEventListener(\"mousemove\", mouseMoveHandler);\n domObject.addEventListener(\"mouseup\", mouseUpHandler);\n };\n return Controls;\n }(Controls || {}));\n Controls.addMouseHandler(renderer.domElement, drag, zoomIn, zoomOut);\n \n\n //\n // event handlers\n //\n win.addEventListener( 'resize', onWindowResize, false );\n win.addEventListener('contextmenu',context_menu);\n \n render();\n }\n \n //\n //window resize\n //\n function onWindowResize( event ) {\n\n //TODO: Fix box white edge when window resize\n renderer.setSize( win.innerWidth, win.innerHeight );\n\n camera.aspect = win.innerWidth / win.innerHeight;\n camera.updateProjectionMatrix();\n\n redraw(false);\n }\n\n //\n //context menu\n //\n function context_menu(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n return (false);\n }\n\n //\n // mouse_down\n //\n function mouse_down(evt) \n { \n evt.preventDefault();\n evt.stopPropagation();\n mod.button = evt.button;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n }\n\n //\n // mouse_up\n //\n function mouse_up(evt) {\n mod.button = undefined;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n }\n\n //\n // mouse_move\n //\n function mouse_move(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n var dx = evt.clientX-mod.x;\n var dy = evt.clientY-mod.y;\n mod.x = evt.clientX;\n mod.y = evt.clientY;\n if (mod.button == 0) {\n mod.x0 += \n Math.sin(mod.thetaz)*mod.height*dy/win.innerHeight\n -Math.cos(mod.thetaz)*mod.width*dx/win.innerWidth;\n mod.y0 += \n Math.cos(mod.thetaz)*mod.height*dy/win.innerHeight\n +Math.sin(mod.thetaz)*mod.width*dx/win.innerWidth;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n redraw(false);\n }\n else if (mod.button == 2) {\n mod.thetaxy += dy/win.innerHeight;\n mod.thetaz += dx/win.innerWidth;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n renderer.render(scene,camera);\n }\n }\n\n //\n // mouse_wheel\n //\n function mouse_wheel(evt) \n {\n evt.preventDefault();\n evt.stopPropagation();\n var dy = evt.deltaY/win.innerHeight;\n mod.r += mod.height*dy;\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n camera.position.z = mod.r*Math.cos(mod.thetaxy);\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n camera.updateProjectionMatrix();\n redraw(false);\n }\n\n //\n //redraw\n //\n \n\n function frame() \n {\n if (delta == 5) {\n delta=0;\n clearInterval(frameID);\n } else {\n delta++; \n render(true,mod.steps.value*delta/5);\n }\n } \n\n function redraw(updateUniforms)\n {\n if(mod.rendPerformance==1)\n {\n if(frameID!=null)\n {\n clearInterval(frameID);\n }\n frameID=setInterval(frame, interval); \n }else\n {\n if(frameID!=null)\n {\n clearInterval(frameID);\n }\n render(updateUniforms,mod.steps.value);\n }\n }\n mod.redraw=redraw;\n\n function updateGridHelper()\n {\n //TODO: later move/rotate camera based on changes\n //update grid helper based on limits\n gridHelper.geometry.rotateX( - Math.PI / 2 );\n gridHelper.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2 - mod.xLimit1)*gridHelpersSize/2.0);\n gridHelper.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2 - mod.yLimit1)*gridHelpersSize/2.0);\n gridHelper.position.x=( (0.0 - (mod.xLimit1)) * (0.5 - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n gridHelper.position.y=( (0.0 - (mod.yLimit1)) * (0.5 - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n gridHelper.position.z=( (0.0 - (mod.zLimit1)) * (0.5 - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n gridHelper.geometry.rotateX( Math.PI / 2 );\n \n sphereO.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2 - mod.xLimit1)*gridHelpersSize/0.5);\n sphereO.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2 - mod.yLimit1)*gridHelpersSize/0.5);\n sphereO.scale.z=gridHelpersSize/(Math.abs(mod.zLimit2 - mod.zLimit1)*gridHelpersSize/0.5);\n \n sphereO.position.x=( (0.0 - (mod.xLimit1)) * (0.5 - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n sphereO.position.y=( (0.0 - (mod.yLimit1)) * (0.5 - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n sphereO.position.z=( (0.0 - (mod.zLimit1)) * (0.5 - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n }\n\n //\n //render\n //\n function render(updateUniforms ,resolutionStep) {\n if(updateUniforms)\n {\n \n materialSecondPass.uniforms.steps.value = resolutionStep;\n materialSecondPass.uniforms.alphaCorrection.value = mod.alphaCorrection;\n materialSecondPass.uniforms.xLimit1.value =mod.xLimit1 ;\n materialSecondPass.uniforms.xLimit2.value =mod.xLimit2 ; \n materialSecondPass.uniforms.yLimit1.value =mod.yLimit1 ; \n materialSecondPass.uniforms.yLimit2.value =mod.yLimit2 ; \n materialSecondPass.uniforms.zLimit1.value =mod.zLimit1 ; \n materialSecondPass.uniforms.zLimit2.value =mod.zLimit2 ;\n\n\n //TODO: Find the error with xray and fix it\n if(mod.rendType=='1')//xray\n {\n materialSecondPass.transparent =false;\n }else\n {\n materialSecondPass.transparent =true;\n }\n\n updateGridHelper();\n }\n\n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n\n materialSecondPass.uniforms.cameraPos.value=tempCam.normalize();\n tempCam.normalize();\n tempCam.addScalar(0.5);\n\n //Render first pass and store the world space coords of the back face fragments into the texture.\n //renderer.render( sceneFirstPass, camera, rtTexture, true );\n\n //Render the second pass and perform the volume rendering.\n //renderer.render( sceneSecondPass, camera );\n\n var previousRenderTarget = renderer.getRenderTarget();\n\t renderer.setRenderTarget(rtTexture);\n\t renderer.render( sceneFirstPass, camera );\n\t renderer.setRenderTarget( previousRenderTarget );\n\t renderer.render( sceneSecondPass, camera );\n\n //render axes camera\n cameraAxes.position.x=camera.position.x;\n cameraAxes.position.y=camera.position.y;\n cameraAxes.position.z=camera.position.z;\n\tcameraAxes.position.sub( center ); \n\tcameraAxes.position.setLength( 300 );\n cameraAxes.lookAt( sceneAxes.position.clone() ); \n\n rendererAxes.render( sceneAxes, cameraAxes );\n\n updateModViewer();\n \n }\n\n //\n //render to small mod viewer\n //\n function updateModViewer()\n {\n var w=win.innerWidth;\n var h=win.innerHeight;\n if (w > h) {\n var x0 = 0;\n var y0 = mod.canvas.height*.5*(1-h/w);\n var wd = mod.canvas.width;\n var hd = mod.canvas.width*h/w;\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h);\n var y0 = 0;\n var wd = mod.canvas.height*w/h;\n var hd = mod.canvas.height;\n }\n var destCtx = mod.canvas.getContext('2d');\n destCtx.drawImage(container.childNodes[0],x0,y0,wd,hd);\n\n }\n\n //\n //when fuction changes\n //\n function updateShaderFunction()\n {\n // outputs.messageLog.event('update shader');\n \n // outputs.messageLog.event(mod.xLimit1);\n\n var div = document.getElementById('fragmentShaderSecondPass');\n\n div.innerHTML=\"\";\n div.innerHTML =fragmentShaderSecondPass();\n \n var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n // outputs.messageLog.event('update shader1');\n materialSecondPass = new THREE.ShaderMaterial( {\n vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n side: THREE.FrontSide,\n uniforms: { tex: { type: \"t\", value: rtTexture },\n steps : {type: \"1f\" , value: mod.steps.value }, \n xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n cameraPos :{value: tempCam.normalize()}\n }\n });\n\n //new THREE.Vector3(20.0,-60.0,-40.0)\n meshSecondPass.material=materialSecondPass;\n meshSecondPass.material.needsUpdate = true;\n meshSecondPass.material.transparent =true;\n\n redraw(true);\n\n //test performance\n // mod.tend = Date.now();\n // var dt = mod.tend-mod.tstart;\n // outputs.messageLog.event(dt/1000);\n\n }\n mod.updateShaderFunction=updateShaderFunction;\n \n //\n //controls\n //\n function drag(deltaX, deltaY) \n {\n var radPerPixel = (Math.PI / 450),\n deltaPhi = radPerPixel * deltaX,\n deltaTheta = radPerPixel * deltaY,\n pos = camera.position.sub(center),\n radius = pos.length(),\n theta = Math.acos(pos.z / radius),\n phi = Math.atan2(pos.y, pos.x);\n\n // Subtract deltaTheta and deltaPhi\n theta = Math.min(Math.max(theta - deltaTheta, 0), Math.PI);\n phi -= deltaPhi;\n\n // Turn back into Cartesian coordinates\n pos.x = radius * Math.sin(theta) * Math.cos(phi);\n pos.y = radius * Math.sin(theta) * Math.sin(phi);\n pos.z = radius * Math.cos(theta);\n\n camera.position.add(center);\n camera.lookAt(center);\n redraw(false);\n }\n\n ///\n function zoomIn() \n {\n camera.position.sub(center).multiplyScalar(0.9).add(center);\n redraw(false);\n }\n\n ///\n function zoomOut() \n {\n camera.position.sub(center).multiplyScalar(1.1).add(center);\n redraw(false);\n }\n}\n\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n });\n}());\n\n\n","top":"1023.4653952925182","left":"2843.396641500616","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"variables\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04772797317232935\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"in0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.04772797317232935\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"clear\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7152788275346978\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9458395548196141\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9645985086194264\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9458395548196141\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3625970106871924\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.04930175848785401\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5939459494005885\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5608762029437723\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5939459494005885\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"clear\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.690161531242695\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.19288167008415902\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.19288167008415902\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.40238136387777756\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8373334092218472\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8080126368305371\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.01016844222037161\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.01016844222037161\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.400055301726435\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}"]} \ No newline at end of file -- GitLab