fabmodules/src/guis/fab.html

6540 wiersze
233 KiB
HTML

<html>
<body style="margin:0 0 0 0;overflow:hidden;">
<!--
fab.html
Neil Gershenfeld
(c) Massachusetts Institute of Technology 2012
Permission granted for experimental and personal use;
license for commercial sale available from MIT.
todo
.math save
file, directory delete, rename, copy, move, scroll bars, mkdir
file exports
cube edges
rounded cube
arrow keys on menus
constrained moves
align node groups
uniform scale
draw grid
unlink bugs
chamfer
paths
side text pane
panel rotations
toggle render
triangulation
linear attract/repel
.fab save/read format
file directories
help
.math view rotation
xmlhttp name fields
.path view
hierarchichal graph view toggle
-->
<svg xmlns="http://www.w3.org/2000/svg"
id="svg" style="position:absolute;left:10;top:10;height:100%;width:100%">
<defs>
<marker id="Triangle"
viewBox="0 0 10 10" refX="13" refY="5"
markerUnits="strokeWidth"
markerWidth="5" markerHeight="5"
stroke="rgb(0,200,0)" fill="rgb(0,200,0)"
stroke-opacity="0.5" fill-opacity="0.5"
orient="auto">
<path d="M 0 0 L 10 5 L 0 10 L 5 5 z" />
</marker>
</defs>
<image id="image_xy" style="position:absolute"
opacity="1"
display="none" xlink:href="">
<image id="image_xz" style="position:absolute"
opacity="1"
display="none" xlink:href="">
<image id="image_zy" style="position:absolute"
opacity="1"
display="none" xlink:href="">
<image id="image_xyz" style="position:absolute"
opacity="1"
display="none" xlink:href="">
</svg>
<div id="edit_panel">
</div>
<script type="text/javascript">
date = "alpha 1/26/14"
svgNS = "http://www.w3.org/2000/svg"
xlinkNS="http://www.w3.org/1999/xlink"
window_width = window.innerWidth
window_height = window.innerHeight
menu_font_size = window_height/70
menu_width = 7.5*menu_font_size
menu_height = 1.82*menu_font_size
node_font_size = 1.1*menu_font_size
text_font_size = 1.25*menu_font_size
text_height = 1.8*text_font_size
button_color = "rgb(200,200,200)"
frame_border = 10 // border from browser frame
panel_height = (window_height-2*menu_height-frame_border)/2.0
panel_size = panel_height
panel_scale = 1
panel_color = "rgb(0,0,0)"
panel_border = 2
panel_border_color = "rgb(200,200,200)"
panel_xmin = - panel_size / 2.0
panel_ymin = - panel_size / 2.0
panel_zmin = - panel_size / 2.0
panel_xwidth = panel_size
panel_ywidth = panel_size
panel_zwidth = panel_size
world_x = ' ' // mouse world position
world_y = ' ' // mouse world position
world_z = ' ' // mouse world position
world_x_offset = 0 // offset for node label
world_y_offset = 0 // offset for node label
world_z_offset = 0 // offset for node label
view_xmin = -1
view_ymin = -1
view_zmin = -1
view_dx = 2
view_dy = 2
view_dz = 2
view_xrot = -80
view_yrot = 0
view_zrot = 100
zoom_scale = .25 // zoom scale factor
axis_size = 2
node_size = 5
node_offset = 0.25
nodes = new Array()
node_color = "rgb(0,200,0)"
node_highlight_color = "rgb(255,0,0)"
text_color = "rgb(150,0,0)"
text_highlight_color = "rgb(255,0,0)"
selected_nodes = []
selected_node = -1
highlighted_node = -1
last_selected_node = -1
link_size = 3
links = new Array()
link_color = "rgb(0,200,0)"
link_opacity = "0.5"
max_id = Math.pow(2,32)-1
menu_names = ""
scale = 1 // view scale
sscale = 0.02 // view scale mouse scale
rscale = 1 // view rotation mouse scale
rad_deg = 3.14159265/180.0 // radians per degree
x_start = 0 // mouse move start
y_start = 0 // mouse move start
message = "" // status message
btn = "" // last mouse button pressed
pending_nodes = [] // nodes list for walking graph
string_digits = 8
display_digits = 3
resolution = 250
file_name = ""
edit_panel = document.getElementById("edit_panel")
xpos = 2*frame_border+2*panel_size
ypos = 2*frame_border+2*menu_height
edit_panel.setAttribute("style","position:absolute;left:"+xpos+"px;top:"+ypos+"px;")
edit_panel_div = document.createElement("div")
edit_panel.appendChild(edit_panel_div)
function graph_class() {
//
// graph class variables
//
this.units = 1
this.grid = 0
this.mode = "Real"
this.expression = ""
this.nodes = []
this.current_undo_string = ""
this.last_undo_string = ""
this.last_last_undo_string = ""
//
// functions
//
this.to_string = function() {
//
// write graph to string
//
str = "graph start:\n"
str += "units: "+this.units+"\n"
str += "xmin: "+view_xmin+"\n"
str += "ymin: "+view_ymin+"\n"
str += "zmin: "+view_zmin+"\n"
str += "dx: "+view_dx+"\n"
str += "dy: "+view_dy+"\n"
str += "dz: "+view_dz+"\n"
str += "xrot: "+view_xrot+"\n"
str += "yrot: "+view_yrot+"\n"
str += "zrot: "+view_zrot+"\n"
str += "grid: "+this.grid+"\n"
str += "mode: "+this.mode+"\n"
for (var i in this.nodes) {
node = this.nodes[i]
str += "\nnode start:\n"
str += "index: "+node.index+"\n"
str += "name: "+node.name+"\n"
str += "offset: "+node.offset+"\n"
str += "x: "+node.x+"\n"
str += "y: "+node.y+"\n"
str += "z: "+node.z+"\n"
str += "code start:\n"
str += node.code
str += "\ncode end:\n"
str += "from: "+JSON.stringify(node.from)+"\n"
str += "to: "+JSON.stringify(node.to)+"\n"
str += "node end:\n"
}
str += "\ngraph end:\n"
return str
}
this.fromstring = function(str) {
//
// read graph from string
//
lines = str.split("\n")
for (i in graph.nodes) {
node = graph.nodes[i]
node.xy.parentNode.removeChild(node.xy)
node.xz.parentNode.removeChild(node.xz)
node.zy.parentNode.removeChild(node.zy)
node.xyz.parentNode.removeChild(node.xyz)
for (i in node.from) {
from_node = graph.nodes[node.from[i]]
to_index = from_node.to.indexOf(node.index)
from_node.to.splice(to_index,1)
node.links_xy[i].parentNode.removeChild(node.links_xy[i])
node.links_xz[i].parentNode.removeChild(node.links_xz[i])
node.links_zy[i].parentNode.removeChild(node.links_zy[i])
node.links_xyz[i].parentNode.removeChild(node.links_xyz[i])
}
}
graph.nodes = []
graph.grid = 0
in_graph = 0
in_node = 0
in_code = 0
for (var i in lines) {
if (lines[i].indexOf("graph start:") == 0) {
in_graph = 1
in_node = 0
}
else if (lines[i].indexOf("graph end:") == 0) {
for (var i in graph.nodes) {
node = graph.nodes[i]
graph.add_node_graphics(node)
for (var j in node.from)
graph.add_link_graphics(graph.nodes[node.from[j]],node)
}
for (var i in graph.nodes)
if (graph.nodes[i].from.length == 0)
graph.update(graph.nodes[i].index)
redraw_axes()
graph.evaluate()
graph.render()
}
else if (lines[i].indexOf("node start:") == 0) {
in_node = 1
in_graph = 0
node = new Object()
node.graph = this
node.last= {}
node.in = function(index) {return node.graph.nodes[node.from[index]]}
node.out = function(index) {return node.graph.nodes[node.to[index]]}
node.input = {}
node.output = {}
node.offset = 1
}
else if (lines[i].indexOf("node end:") == 0) {
in_node = 0
node.last.x = node.x
node.last.y = node.y
node.last.z = node.z
}
else if (lines[i].indexOf("index: ") == 0) {
index = parseInt(lines[i].substr(7))
graph.nodes[index] = node
node.index = index
}
else if ((lines[i].indexOf("units: ") == 0) && (in_graph == 1))
graph.units = parseFloat(lines[i].substr(7))
else if ((lines[i].indexOf("xmin: ") == 0) && (in_graph == 1))
view_xmin = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("ymin: ") == 0) && (in_graph == 1))
view_ymin = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("zmin: ") == 0) && (in_graph == 1))
view_zmin = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("dx: ") == 0) && (in_graph == 1))
view_dx = parseFloat(lines[i].substr(4))
else if ((lines[i].indexOf("dy: ") == 0) && (in_graph == 1))
view_dy = parseFloat(lines[i].substr(4))
else if ((lines[i].indexOf("dz: ") == 0) && (in_graph == 1))
view_dz = parseFloat(lines[i].substr(4))
else if ((lines[i].indexOf("xrot: ") == 0) && (in_graph == 1))
view_xrot = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("yrot: ") == 0) && (in_graph == 1))
view_yrot = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("zrot: ") == 0) && (in_graph == 1))
view_zrot = parseFloat(lines[i].substr(6))
else if ((lines[i].indexOf("grid: ") == 0) && (in_graph == 1))
graph.grid = lines[i].substr(6)
else if ((lines[i].indexOf("mode: ") == 0) && (in_graph == 1))
graph.mode = lines[i].substr(6)
else if ((lines[i].indexOf("name: ") == 0) && (in_node == 1))
node.name = lines[i].substr(6)
else if ((lines[i].indexOf("offset: ") == 0) && (in_node == 1))
node.offset = lines[i].substr(8)
else if ((lines[i].indexOf("x: ") == 0) && (in_node == 1))
node.x = parseFloat(lines[i].substr(3))
else if ((lines[i].indexOf("y: ") == 0) && (in_node == 1))
node.y = parseFloat(lines[i].substr(3))
else if ((lines[i].indexOf("z: ") == 0) && (in_node == 1))
node.z = parseFloat(lines[i].substr(3))
else if ((lines[i].indexOf("code start:") == 0) && (in_node == 1)) {
in_code = 1
node.code = ""
}
else if ((lines[i].indexOf("code end:") == 0) && (in_node == 1)) {
node.code = node.code.substr(0,(node.code.length-1))
in_code = 0
}
else if ((in_code == 1) && (in_node = 1))
node.code += lines[i]+"\n"
else if ((lines[i].indexOf("from: ") == 0) && (in_node == 1))
node.from = JSON.parse(lines[i].substr(6))
else if ((lines[i].indexOf("to: ") == 0) && (in_node == 1))
node.to = JSON.parse(lines[i].substr(4))
}
}
this.render = function() {
//
// render graph
//
this.evaluate()
graph.last_last_undo_string = graph.last_undo_string
graph.last_undo_string = graph.current_undo_string
graph.current_undo_string = graph.to_string()
pixels_per_mm = resolution / (view_dx * graph.units)
if (this.expression.indexOf("undefined") == -1) {
if (view_dz == 0)
slices = 1
else
slices = 255
render_msg = "{"+this.mode+"}{"+this.units+"}{"+view_dx+"}{"+view_dy+"}{"+view_dz+"}{"+view_xmin+"}{"+view_ymin+"}{"+view_zmin+"}{"+view_xrot*rad_deg+"}{"+view_yrot*rad_deg+"}{"+view_zrot*rad_deg+"}{"+pixels_per_mm+"}{"+slices+"}{"+this.expression+"}"
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {render_response(xmlhttp); };
xmlhttp.open('POST','/render',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(render_msg);
}
else
msg("part undefined")
}
this.fabricate = function() {
//
// fabricate graph
//
this.evaluate()
if (this.expression.indexOf("undefined") == -1) {
if (view_dz == 0)
slices = 1
else
slices = 255
render_msg = "{"+this.mode+"}{"+this.units+"}{"+view_dx+"}{"+view_dy+"}{"+view_dz+"}{"+view_xmin+"}{"+view_ymin+"}{"+view_zmin+"}{"+view_xrot*rad_deg+"}{"+view_yrot*rad_deg+"}{"+view_zrot*rad_deg+"}{"+resolution+"}{"+slices+"}{"+this.expression+"}"
xmlhttp=new XMLHttpRequest();
xmlhttp.open('POST','/fabricate',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(render_msg);
}
else
msg("part undefined")
}
//
// node routines
//
this.add_node = function(name,x,y,z,offset,code) {
//
// add node
//
max_index = -1
for (n in this.nodes)
if ((this.nodes[n]).index > max_index)
max_index = (this.nodes[n]).index
max_index += 1
node = new Object()
node.index = max_index
this.nodes[node.index] = node
node.graph = this
node.name = name
node.x = x
node.y = y
node.z = z
node.offset = offset
node.last= {}
node.last.x = x
node.last.y = y
node.last.z = z
node.from = []
node.to = []
node.in = function(index) {return node.graph.nodes[node.from[index]]}
node.out = function(index) {return node.graph.nodes[node.to[index]]}
node.input = {}
node.output = {}
node.code = code
node.graph.add_node_graphics(node)
world_x_offset = 0
world_y_offset = 0
world_z_offset = 0
return node
}
this.add_node_graphics = function(node) {
//
// add node graphics
//
node.links_xy = []
node.links_xz = []
node.links_zy = []
node.links_xyz = []
node.xy = document.createElementNS(svgNS,"g");
node.xy_node = document.createElementNS(svgNS,"circle")
node.xy_node.setAttribute("cx",xpanel_xy(node.x))
node.xy_node.setAttribute("cy",ypanel_xy(node.y))
node.xy_node.setAttribute("r",node_size)
node.xy_node.setAttribute("fill",node_color)
node.xy_node.setAttribute("onmouseover","node_over(evt)")
node.xy_node.setAttribute("onmouseout","node_out(evt)")
node.xy_node.setAttribute("onmousedown","node_down_xy(evt)")
node.xy_node.setAttribute("onmouseup","node_up(evt)")
node.xy_node.setAttribute("index",node.index)
node.xy.appendChild(node.xy_node)
node.xy_text = document.createElementNS(svgNS,"text")
node.xy_text.setAttribute("onmouseover","node_over(evt)")
node.xy_text.setAttribute("onmouseout","node_out(evt)")
node.xy_text.setAttribute("onmousedown","node_down_xy(evt)")
node.xy_text.setAttribute("onmouseup","node_up(evt)")
node.xy_text.setAttribute("index",node.index)
node.xy_text.setAttribute("font-size",node_font_size);
node.xy_text.setAttribute("font-family","sans-serif");
node.xy_text.setAttribute("font-weight","bold");
node.xy_text.setAttribute("fill",text_color)
node.xy_text.setAttribute("text-anchor","middle");
node.xy_text.setAttribute("dominant-baseline","middle")
node.xy_text.setAttribute("x",xpanel_xy(node.x))
node.xy_text.setAttribute("y",ypanel_xy(node.y)+node.offset*node_font_size)
text_node = document.createTextNode(node.name)
node.xy_text.appendChild(text_node)
node.xy.appendChild(node.xy_text)
document.getElementById("panel_xy").appendChild(node.xy)
node.xz = document.createElementNS(svgNS,"g");
node.xz_node = document.createElementNS(svgNS,"circle")
node.xz_node.setAttribute("cx",xpanel_xz(node.x))
node.xz_node.setAttribute("cy",ypanel_xz(node.z))
node.xz_node.setAttribute("r",node_size)
node.xz_node.setAttribute("fill",node_color)
node.xz_node.setAttribute("onmouseover","node_over(evt)")
node.xz_node.setAttribute("onmouseout","node_out(evt)")
node.xz_node.setAttribute("onmousedown","node_down_xz(evt)")
node.xz_node.setAttribute("onmouseup","node_up(evt)")
node.xz_node.setAttribute("index",node.index)
node.xz.appendChild(node.xz_node)
node.xz_text = document.createElementNS(svgNS,"text")
node.xz_text.setAttribute("onmouseover","node_over(evt)")
node.xz_text.setAttribute("onmouseout","node_out(evt)")
node.xz_text.setAttribute("onmousedown","node_down_xz(evt)")
node.xz_text.setAttribute("onmouseup","node_up(evt)")
node.xz_text.setAttribute("index",node.index)
node.xz_text.setAttribute("font-size",node_font_size);
node.xz_text.setAttribute("font-family","sans-serif");
node.xz_text.setAttribute("font-weight","bold");
node.xz_text.setAttribute("fill","rgb(200,0,0)")
node.xz_text.setAttribute("text-anchor","middle");
node.xz_text.setAttribute("dominant-baseline","middle")
node.xz_text.setAttribute("x",xpanel_xz(node.x))
node.xz_text.setAttribute("y",ypanel_xz(node.z)+node.offset*node_font_size)
text_node = document.createTextNode(node.name)
node.xz_text.appendChild(text_node)
node.xz.appendChild(node.xz_text)
document.getElementById("panel_xz").appendChild(node.xz)
node.zy = document.createElementNS(svgNS,"g");
node.zy_node = document.createElementNS(svgNS,"circle")
node.zy_node.setAttribute("cx",xpanel_zy(node.z))
node.zy_node.setAttribute("cy",ypanel_zy(node.y))
node.zy_node.setAttribute("r",node_size)
node.zy_node.setAttribute("fill",node_color)
node.zy_node.setAttribute("onmouseover","node_over(evt)")
node.zy_node.setAttribute("onmouseout","node_out(evt)")
node.zy_node.setAttribute("onmousedown","node_down_xy(evt)")
node.zy_node.setAttribute("onmouseup","node_up(evt)")
node.zy_node.setAttribute("index",node.index)
node.zy.appendChild(node.zy_node)
node.zy_text = document.createElementNS(svgNS,"text")
node.zy_text.setAttribute("onmouseover","node_over(evt)")
node.zy_text.setAttribute("onmouseout","node_out(evt)")
node.zy_text.setAttribute("onmousedown","node_down_zy(evt)")
node.zy_text.setAttribute("onmouseup","node_up(evt)")
node.zy_text.setAttribute("index",node.index)
node.zy_text.setAttribute("font-size",node_font_size);
node.zy_text.setAttribute("font-family","sans-serif");
node.zy_text.setAttribute("font-weight","bold");
node.zy_text.setAttribute("fill","rgb(200,0,0)")
node.zy_text.setAttribute("text-anchor","middle");
node.zy_text.setAttribute("dominant-baseline","middle")
node.zy_text.setAttribute("x",xpanel_zy(node.z))
node.zy_text.setAttribute("y",ypanel_zy(node.y)+node.offset*node_font_size)
text_node = document.createTextNode(node.name)
node.zy_text.appendChild(text_node)
node.zy.appendChild(node.zy_text)
document.getElementById("panel_zy").appendChild(node.zy)
node.xyz = document.createElementNS(svgNS,"g");
pt = xypanel_xyz(node.x,node.y,node.z)
node.xyz_node = document.createElementNS(svgNS,"circle")
node.xyz_node.setAttribute("cx",pt[0])
node.xyz_node.setAttribute("cy",pt[1])
node.xyz_node.setAttribute("r",node_size)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_node.setAttribute("onmouseover","node_over(evt)")
node.xyz_node.setAttribute("onmouseout","node_out(evt)")
node.xyz_node.setAttribute("onmousedown", "node_down_xyz(evt)")
node.xyz_node.setAttribute("onmouseup","node_up(evt)")
node.xyz_node.setAttribute("index",node.index)
node.xyz.appendChild(node.xyz_node)
node.xyz_text = document.createElementNS(svgNS,"text")
node.xyz_text.setAttribute("onmouseover","node_over(evt)")
node.xyz_text.setAttribute("onmouseout","node_out(evt)")
node.xyz_text.setAttribute("onmousedown", "node_down_xyz(evt)")
node.xyz_text.setAttribute("onmouseup","node_up(evt)")
node.xyz_text.setAttribute("index",node.index)
node.xyz_text.setAttribute("font-size",node_font_size);
node.xyz_text.setAttribute("font-family","sans-serif");
node.xyz_text.setAttribute("font-weight","bold");
node.xyz_text.setAttribute("fill","rgb(200,0,0)")
node.xyz_text.setAttribute("text-anchor","middle");
node.xyz_text.setAttribute("dominant-baseline","middle")
node.xyz_text.setAttribute("x",pt[0])
node.xyz_text.setAttribute("y",pt[1]+node.offset*node_font_size)
text_node = document.createTextNode(node.name)
node.xyz_text.appendChild(text_node)
node.xyz.appendChild(node.xyz_text)
document.getElementById("panel_xyz").appendChild(node.xyz)
}
this.link = function(from_node_index,to_node_index,from_code,to_code) {
//
// link nodes
//
from_node = this.nodes[from_node_index]
to_node = this.nodes[to_node_index]
from_node.to.push(to_node_index)
to_node.from.push(from_node_index)
//
// node code
//
if (from_code != "") {
index = from_node.to.length - 1
from_node.code = from_code.replace(RegExp('#','g'),index) + from_node.code
}
if (to_code != "") {
to_node.code = to_code + to_node.code
}
//
// draw link
//
this.add_link_graphics(from_node,to_node)
//
// update
//
this.update(to_node_index)
}
this.add_link_graphics = function(from_node,to_node) {
//
// add link graphics
//
link = document.createElementNS(svgNS,"line")
x1 = xpanel_xy(from_node.x)
x2 = xpanel_xy(to_node.x)
y1 = ypanel_xy(from_node.y)
y2 = ypanel_xy(to_node.y)
link.setAttribute("x1",x1)
link.setAttribute("y1",y1)
link.setAttribute("x2",x2)
link.setAttribute("y2",y2)
link.setAttribute("stroke-width",link_size)
link.setAttribute("stroke",link_color)
link.setAttribute("stroke-opacity",link_opacity)
link.setAttribute("marker-end","url(#Triangle)")
document.getElementById("panel_xy").insertBefore(link,
document.getElementById("panel_xy").firstChild.nextSibling.nextSibling)
to_node.links_xy.push(link)
link = document.createElementNS(svgNS,"line")
x1 = xpanel_xz(from_node.x)
x2 = xpanel_xz(to_node.x)
y1 = ypanel_xz(from_node.z)
y2 = ypanel_xz(to_node.z)
link.setAttribute("x1",x1)
link.setAttribute("y1",y1)
link.setAttribute("x2",x2)
link.setAttribute("y2",y2)
link.setAttribute("stroke-width",link_size)
link.setAttribute("stroke",link_color)
link.setAttribute("stroke-opacity",link_opacity)
link.setAttribute("marker-end","url(#Triangle)")
document.getElementById("panel_xz").insertBefore(link,
document.getElementById("panel_xz").firstChild.nextSibling.nextSibling)
to_node.links_xz.push(link)
link = document.createElementNS(svgNS,"line")
x1 = xpanel_zy(from_node.z)
x2 = xpanel_zy(to_node.z)
y1 = ypanel_zy(from_node.y)
y2 = ypanel_zy(to_node.y)
link.setAttribute("x1",x1)
link.setAttribute("y1",y1)
link.setAttribute("x2",x2)
link.setAttribute("y2",y2)
link.setAttribute("stroke-width",link_size)
link.setAttribute("stroke",link_color)
link.setAttribute("stroke-opacity",link_opacity)
link.setAttribute("marker-end","url(#Triangle)")
document.getElementById("panel_zy").insertBefore(link,
document.getElementById("panel_zy").firstChild.nextSibling.nextSibling)
to_node.links_zy.push(link)
link = document.createElementNS(svgNS,"line")
pt1 = xypanel_xyz(from_node.x,from_node.y,from_node.z)
pt2 = xypanel_xyz(to_node.x,to_node.y,to_node.z)
x1 = pt1[0]
y1 = pt1[1]
z1 = pt1[2]
x2 = pt2[0]
y2 = pt2[1]
z2 = pt2[2]
link.setAttribute("x1",x1)
link.setAttribute("y1",y1)
link.setAttribute("x2",x2)
link.setAttribute("y2",y2)
link.setAttribute("stroke-width",link_size)
link.setAttribute("stroke",link_color)
link.setAttribute("stroke-opacity",link_opacity)
link.setAttribute("marker-end","url(#Triangle)")
document.getElementById("panel_xyz").insertBefore(link,document.getElementById("panel_xyz").firstChild.nextSibling.nextSibling)
to_node.links_xyz.push(link)
}
this.delete_node = function(index) {
//
// delete node
//
node = this.nodes[index]
node.xy.parentNode.removeChild(node.xy)
node.xz.parentNode.removeChild(node.xz)
node.zy.parentNode.removeChild(node.zy)
node.xyz.parentNode.removeChild(node.xyz)
for (i in node.from) {
from_node = graph.nodes[node.from[i]]
to_index = from_node.to.indexOf(node.index)
from_node.to.splice(to_index,1)
node.links_xy[i].parentNode.removeChild(node.links_xy[i])
node.links_xy.splice(i,1)
node.links_xz[i].parentNode.removeChild(node.links_xz[i])
node.links_xz.splice(i,1)
node.links_zy[i].parentNode.removeChild(node.links_zy[i])
node.links_zy.splice(i,1)
node.links_xyz[i].parentNode.removeChild(node.links_xyz[i])
node.links_xyz.splice(i,1)
}
for (i in node.to) {
to_node = graph.nodes[node.to[i]]
from_index = to_node.from.indexOf(node.index)
to_node.from.splice(from_index,1)
to_node.links_xy[from_index].parentNode.removeChild(to_node.links_xy[from_index])
to_node.links_xy.splice(from_index,1)
to_node.links_xz[from_index].parentNode.removeChild(to_node.links_xz[from_index])
to_node.links_xz.splice(from_index,1)
to_node.links_zy[from_index].parentNode.removeChild(to_node.links_zy[from_index])
to_node.links_zy.splice(from_index,1)
to_node.links_xyz[from_index].parentNode.removeChild(to_node.links_xyz[from_index])
to_node.links_xyz.splice(from_index,1)
}
delete graph.nodes[node.index]
}
this.delete_nodes = function(node) {
//
// delete nodes
//
selected_nodes = []
children = []
parents = []
for (var n in node.to)
parents.push(node.to[n])
selected_nodes[node.index] = node.index
for (var n in node.from)
children.push(node.from[n])
while (children.length > 0) {
child = children.pop()
node = graph.nodes[child]
selected_nodes[node.index] = node.index
for (n in node.from)
children.push(node.from[n])
}
for (var n in selected_nodes)
graph.delete_node(selected_nodes[n])
for (var n in parents)
graph.update(parents[n])
selected_node = -1
selected_nodes = []
}
this.update_node = function(index) {
//
// update node
//
node = this.nodes[index]
node.input = {}
node.output = {}
for (var f in node.from)
for (var o in node.graph.nodes[node.from[f]].output)
node.input[o.replace('#',f)] = node.graph.nodes[node.from[f]].output[o]
//
// helper functions
//
function replace(str,from,to) {
return str.replace(RegExp(from,'g'),to)
}
function angle(dx,dy) {
if (dx == 0)
if (dy > 0)
return (rad_deg * 90)
else
return (rad_deg * -90)
else
if (dx > 0)
return (Math.atan(dy/dx))
else
return ((180.0*rad_deg)+Math.atan(dy/dx))
}
function number(n) {
return '('+n.toFixed(string_digits)+')'
}
//
// eval
//
eval(node.code)
node.last.x = node.x
node.last.y = node.y
node.last.z = node.z
//
// draw
//
this.draw(node)
}
this.update = function(index) {
//
// update node and its parents
//
this.update_node(index)
for (var n in node.to)
pending_nodes.push(node.to[n])
while (pending_nodes.length > 0) {
parent_node = pending_nodes.pop()
this.update(parent_node)
}
}
this.draw = function(node) {
//
// redraw node
//
x = node.x
y = node.y
z = node.z
offset = node.offset
node.xy_node.setAttribute("cx",xpanel_xy(x))
node.xy_node.setAttribute("cy",ypanel_xy(y))
node.xz_node.setAttribute("cx",xpanel_xz(x))
node.xz_node.setAttribute("cy",ypanel_xz(z))
node.zy_node.setAttribute("cx",xpanel_zy(z))
node.zy_node.setAttribute("cy",ypanel_zy(y))
pt = xypanel_xyz(x,y,z)
node.xyz_node.setAttribute("cx",pt[0])
node.xyz_node.setAttribute("cy",pt[1])
node.xy_text.setAttribute("x",xpanel_xy(x))
node.xy_text.setAttribute("y",ypanel_xy(y)+offset*node_font_size)
node.xz_text.setAttribute("x",xpanel_xz(x))
node.xz_text.setAttribute("y",ypanel_xz(z)+offset*node_font_size)
node.zy_text.setAttribute("x",xpanel_zy(z))
node.zy_text.setAttribute("y",ypanel_zy(y)+offset*node_font_size)
node.xyz_text.setAttribute("x",pt[0])
node.xyz_text.setAttribute("y",pt[1]+offset*node_font_size)
//
// redraw its links
//
for (var i in node.from) {
x1 = xpanel_xy(this.nodes[node.from[i]].x)
y1 = ypanel_xy(this.nodes[node.from[i]].y)
x2 = xpanel_xy(node.x)
y2 = ypanel_xy(node.y)
node.links_xy[i].setAttribute("x1",x1)
node.links_xy[i].setAttribute("y1",y1)
node.links_xy[i].setAttribute("x2",x2)
node.links_xy[i].setAttribute("y2",y2)
x1 = xpanel_xz(this.nodes[node.from[i]].x)
y1 = ypanel_xz(this.nodes[node.from[i]].z)
x2 = xpanel_xz(node.x)
y2 = ypanel_xz(node.z)
node.links_xz[i].setAttribute("x1",x1)
node.links_xz[i].setAttribute("y1",y1)
node.links_xz[i].setAttribute("x2",x2)
node.links_xz[i].setAttribute("y2",y2)
z1 = xpanel_zy(this.nodes[node.from[i]].z)
y1 = ypanel_zy(this.nodes[node.from[i]].y)
z2 = xpanel_zy(node.z)
y2 = ypanel_zy(node.y)
node.links_zy[i].setAttribute("x1",z1)
node.links_zy[i].setAttribute("y1",y1)
node.links_zy[i].setAttribute("x2",z2)
node.links_zy[i].setAttribute("y2",y2)
pt1 = xypanel_xyz(this.nodes[node.from[i]].x,this.nodes[node.from[i]].y,this.nodes[node.from[i]].z)
pt2 = xypanel_xyz(node.x,node.y,node.z)
x1 = pt1[0]
y1 = pt1[1]
z1 = pt1[2]
x2 = pt2[0]
y2 = pt2[1]
z2 = pt2[2]
node.links_xyz[i].setAttribute("x1",x1)
node.links_xyz[i].setAttribute("y1",y1)
node.links_xyz[i].setAttribute("x2",x2)
node.links_xyz[i].setAttribute("y2",y2)
}
//
// redraw text
//
update_text(node)
}
this.redraw = function() {
//
// redraw graph
//
for (var n in graph.nodes)
graph.draw(graph.nodes[n])
}
this.evaluate = function() {
//
// evaluate expression
//
expr = '1' // math_png bug, fails for 1 < 0
for (var n in graph.nodes)
if ((graph.nodes[n].output['part#'] != undefined) &
(graph.nodes[n].to.length == 0))
expr = 'min('+expr+','+graph.nodes[n].output['part#']+')'
expr = '('+expr+')'
this.expression = expr
return expr
}
}
var graph = new graph_class()
function xworld_xy(xscreen) {
//
// return world x coordinate in xy view
//
x = view_xmin + view_dx*(xscreen-frame_border)/(panel_size*panel_scale)
if (graph.grid == 0)
return x
else {
nx = Math.round(x/graph.grid)
return (nx * graph.grid)
}
}
function yworld_xy(yscreen) {
//
// return world y coordinate in xy view
//
y = view_ymin + view_dy - view_dy*(yscreen-2*menu_height-frame_border)/(panel_size*panel_scale)
if (graph.grid == 0)
return y
else {
ny = Math.round(y/graph.grid)
return (ny * graph.grid)
}
}
function xworld_xz(xscreen) {
//
// return world x coordinate in xz view
//
x = view_xmin + view_dx*(xscreen-frame_border)/panel_size
if (graph.grid == 0)
return x
else {
nx = Math.round(x/graph.grid)
return (nx * graph.grid)
}
}
function zworld_xz(zscreen) {
//
// return world z coordinate in xz view
//
z = view_zmin + view_dz - view_dz*(zscreen-2*menu_height-frame_border-panel_size)/panel_size
if (graph.grid == 0)
return z
else {
nz = Math.round(z/graph.grid)
return (nz * graph.grid)
}
}
function zworld_zy(zscreen) {
//
// return world z coordinate in zy view
//
z = view_zmin + view_dz - view_dz*(zscreen-frame_border-panel_size)/panel_size
if (graph.grid == 0)
return z
else {
nz = Math.round(z/graph.grid)
return (nz * graph.grid)
}
}
function yworld_zy(yscreen) {
//
// return world y coordinate in zy view
//
y = view_ymin + view_dy - view_dy*(yscreen-2*menu_height-frame_border)/panel_size
if (graph.grid == 0)
return y
else {
ny = Math.round(y/graph.grid)
return (ny * graph.grid)
}
}
function xpanel_xy(xworld) {
//
// return panel x coordinate in xy view
//
return (panel_xmin + panel_xwidth*(xworld-view_xmin)/view_dx)
}
function ypanel_xy(yworld) {
//
// return panel y coordinate in xy view
//
return (panel_ymin + panel_ywidth*(1-(yworld-view_ymin)/view_dy))
}
function xpanel_xz(xworld) {
//
// return panel x coordinate in xz view
//
return (panel_xmin + panel_xwidth*(xworld-view_xmin)/view_dx)
}
function ypanel_xz(zworld) {
//
// return panel y coordinate in xz view
//
return (panel_zmin + panel_zwidth*(1-(zworld-view_zmin)/view_dz))
}
function xpanel_zy(zworld) {
//
// return panel x coordinate in zy view
//
return (panel_zmin + panel_zwidth*(1-(zworld-view_zmin)/view_dz))
}
function ypanel_zy(yworld) {
//
// return panel y coordinate in zy view
//
return (panel_ymin + panel_ywidth*(1-(yworld-view_ymin)/view_dy))
}
function xypanel_xyz(x,y,z) {
//
// return panel coordinate in xyz view
//
theta_x = view_xrot*rad_deg
theta_y = view_yrot*rad_deg
theta_z = view_zrot*rad_deg
//
// view scaling
//
xs = -1+2*(x-view_xmin)/view_dx
ys = -1+2*(y-view_ymin)/view_dy
zs = -1+2*(z-view_zmin)/view_dz
//
// z rotation
//
xt = xs
yt = ys
xs = Math.cos(theta_z)*xt + Math.sin(theta_z)*yt
ys = - Math.sin(theta_z)*xt + Math.cos(theta_z)*yt
//
// y rotation
//
xt = xs
zt = zs
xs = Math.cos(theta_y)*xt + Math.sin(theta_y)*zt
zs = - Math.sin(theta_y)*xt + Math.cos(theta_y)*zt
//
// x rotation
//
yt = ys
zt = zs
ys = Math.cos(theta_x)*yt - Math.sin(theta_x)*zt
zs = Math.sin(theta_x)*yt + Math.cos(theta_x)*zt
//
// screen scaling
//
xpanel = panel_size/2.0 + xs*panel_size/2.0
ypanel = panel_size/2.0 - ys*panel_size/2.0
return Array(xpanel,ypanel)
}
function move_xy(evt) {
//
// xy view mouse move routine
//
world_x = xworld_xy(evt.clientX)
world_y = yworld_xy(evt.clientY)
world_z = ' '
if (selected_nodes.length != 0) {
//
// moving nodes
//
parent_x = selected_nodes[selected_node][0]
parent_y = selected_nodes[selected_node][1]
for (child in selected_nodes) {
child_x = selected_nodes[child][0]
child_y = selected_nodes[child][1]
dx = - parent_x + child_x
dy = - parent_y + child_y
node = graph.nodes[selected_nodes[child][2]]
node.x = world_x + world_x_offset + dx
node.y = world_y + world_y_offset + dy
graph.update_node(node.index)
}
graph.update(selected_node)
msg(message+" x: "+strprt(world_x+world_x_offset)+" y: "+strprt(world_y+world_y_offset))
}
else if (selected_node != -1) {
//
// moving node
//
graph.nodes[selected_node].x = world_x + world_x_offset
if (graph.grid != 0) {
nx = Math.round(graph.nodes[selected_node].x/graph.grid)
graph.nodes[selected_node].x = parseFloat((nx*graph.grid).toFixed(string_digits))
}
graph.nodes[selected_node].y = world_y + world_y_offset
if (graph.grid != 0) {
ny = Math.round(graph.nodes[selected_node].y/graph.grid)
graph.nodes[selected_node].y = parseFloat((ny*graph.grid).toFixed(string_digits))
}
graph.update(selected_node)
msg(message+" x: "+strprt(world_x+world_x_offset)+" y: "+strprt(world_y+world_y_offset))
}
else if (evt.ctrlKey == 1) {
//
// control move
//
}
else if (btn == "left") {
//
// panning view
//
view_xmin = view_xmin_start + xworld_xy(x_start) - world_x
view_ymin = view_ymin_start + yworld_xy(y_start) - world_y
graph.redraw()
redraw_axes()
}
else {
//
// show position
//
msg(message+" x: "+strprt(world_x)+" y: "+strprt(world_y))
}
}
function move_xz(evt) {
//
// xz view mouse move routine
//
world_x = xworld_xz(evt.clientX)
world_y = ' '
world_z = zworld_xz(evt.clientY)
if (selected_nodes.length != 0) {
//
// moving nodes
//
parent_x = selected_nodes[selected_node][0]
parent_z = selected_nodes[selected_node][1]
for (child in selected_nodes) {
child_x = selected_nodes[child][0]
child_z = selected_nodes[child][1]
dx = - parent_x + child_x
dz = - parent_z + child_z
node = graph.nodes[selected_nodes[child][2]]
node.x = world_x + world_x_offset + dx
node.z = world_z + world_z_offset + dz
graph.update_node(node.index)
}
graph.update(selected_node)
msg(message+" x: "+strprt(world_x+world_x_offset)+" z: "+strprt(world_z+world_z_offset))
}
else if (selected_node != -1) {
//
// moving node
//
graph.nodes[selected_node].x = world_x + world_x_offset
if (graph.grid != 0) {
nx = Math.round(graph.nodes[selected_node].x/graph.grid)
graph.nodes[selected_node].x = parseFloat((nx*graph.grid).toFixed(string_digits))
}
graph.nodes[selected_node].z = world_z + world_z_offset
if (graph.grid != 0) {
nz = Math.round(graph.nodes[selected_node].z/graph.grid)
graph.nodes[selected_node].z = parseFloat((nz*graph.grid).toFixed(string_digits))
}
graph.update(selected_node)
msg(message+" x: "+strprt(world_x+world_x_offset)+" z: "+strprt(world_z+world_z_offset))
}
else if (evt.ctrlKey == 1) {
//
//
}
else if (btn == "left") {
//
// panning view
//
view_xmin = view_xmin_start + xworld_xz(x_start) - world_x
view_zmin = view_zmin_start + zworld_xz(y_start) - world_z
graph.redraw()
redraw_axes()
}
else {
//
// show position
//
msg(message+" x: "+strprt(world_x)+" z: "+strprt(world_z))
}
}
function move_zy(evt) {
//
// zy view mouse move routine
//
world_x = ' '
world_y = yworld_zy(evt.clientY)
world_z = zworld_zy(evt.clientX)
if (selected_nodes.length != 0) {
//
// moving nodes
//
parent_y = selected_nodes[selected_node][0]
parent_z = selected_nodes[selected_node][1]
for (child in selected_nodes) {
child_y = selected_nodes[child][0]
child_z = selected_nodes[child][1]
dy = - parent_y + child_y
dz = - parent_z + child_z
node = graph.nodes[selected_nodes[child][2]]
node.y = world_y + world_y_offset + dy
node.z = world_z + world_z_offset + dz
graph.update_node(node.index)
}
graph.update(selected_node)
msg(message+" y: "+strprt(world_y+world_y_offset)+" z: "+strprt(world_z+world_z_offset))
}
else if (selected_node != -1) {
//
// moving node
//
graph.nodes[selected_node].z = world_z + world_z_offset
if (graph.grid != 0) {
nz = Math.round(graph.nodes[selected_node].z/graph.grid)
graph.nodes[selected_node].z = parseFloat((nz*graph.grid).toFixed(string_digits))
}
graph.nodes[selected_node].y = world_y + world_y_offset
if (graph.grid != 0) {
ny = Math.round(graph.nodes[selected_node].y/graph.grid)
graph.nodes[selected_node].y = parseFloat((ny*graph.grid).toFixed(string_digits))
}
graph.update(selected_node)
msg(message+" z: "+strprt(world_z+world_z_offset)+" y: "+strprt(world_y+world_y_offset))
}
else if (evt.ctrlKey == 1) {
//
//
}
else if (btn == "left") {
//
// panning view
//
view_zmin = view_zmin_start + zworld_zy(x_start) - world_z
view_ymin = view_ymin_start + yworld_zy(y_start) - world_y
graph.redraw()
redraw_axes()
}
else {
//
// show position
//
msg(message+" z: "+strprt(world_z)+" y: "+strprt(world_y))
}
}
function move_xyz(evt) {
//
// xyz view mouse move routine
//
if (btn == "left") {
//
// rotating view
//
x = evt.clientX
y = evt.clientY
dx = x - x_start
dy = y - y_start
x_start = x
y_start = y
view_zrot -= rscale*dx
view_xrot += rscale*dy
msg("x rotation: "+view_xrot+" z rotation: "+view_zrot)
rotate3d()
}
}
function node_over(evt) {
//
// node mouse over
//
node = graph.nodes[Number(evt.target.getAttribute("index"))]
node.xy_node.setAttribute("fill",node_highlight_color)
node.xy_text.setAttribute("fill",text_highlight_color)
node.xz_node.setAttribute("fill",node_highlight_color)
node.xz_text.setAttribute("fill",text_highlight_color)
node.zy_node.setAttribute("fill",node_highlight_color)
node.zy_text.setAttribute("fill",text_highlight_color)
node.xyz_node.setAttribute("fill",node_highlight_color)
node.xyz_text.setAttribute("fill",text_highlight_color)
highlighted_node = node.index
}
function node_out(evt) {
//
// node mouse out
//
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
highlighted_node = -1
}
function node_down_xy(evt) {
//
// xy mouse node down routine
//
selected_node = Number(evt.target.getAttribute("index"))
node = graph.nodes[selected_node]
world_x_offset = node.x - world_x
world_y_offset = node.y - world_y
world_z_offset = 0
if ((message == "parent node to cut? (can also shift-del)")) {
//
// cutting nodes
//
message = ""
graph.delete_nodes(node)
graph.evaluate()
graph.render()
}
else if ((message == "parent node to move? (can also shift-drag)") || (evt.shiftKey == 1)) {
//
// moving nodes, walk graph to find children
//
message = ""
selected_nodes = []
children = []
selected_nodes[node.index] = [node.x,node.y,node.index]
for (n in node.from)
children.push(node.from[n])
while (children.length > 0) {
child = children.pop()
node = graph.nodes[child]
selected_nodes[node.index] = [node.x,node.y,node.index]
for (n in node.from)
children.push(node.from[n])
}
}
}
function node_down_xz(evt) {
//
// xz mouse node down routine
//
selected_node = Number(evt.target.getAttribute("index"))
node = graph.nodes[selected_node]
world_x_offset = node.x - world_x
world_y_offset = 0
world_z_offset = node.z - world_z
if ((message == "parent node to cut? (can also shift-del)")) {
//
// cutting nodes
//
message = ""
graph.delete_nodes(node)
graph.evaluate()
graph.render()
}
else if ((message == "parent node to move? (can also shift-drag)") || (evt.shiftKey == 1)) {
//
// moving nodes, walk graph to find children
//
message = ""
selected_nodes = []
children = []
selected_nodes[node.index] = [node.x,node.z,node.index]
for (n in node.from)
children.push(node.from[n])
while (children.length > 0) {
child = children.pop()
node = graph.nodes[child]
selected_nodes[node.index] = [node.x,node.z,node.index]
for (n in node.from)
children.push(node.from[n])
}
}
}
function node_down_zy(evt) {
//
// zy mouse node down routine
//
selected_node = Number(evt.target.getAttribute("index"))
node = graph.nodes[selected_node]
world_x_offset = 0
world_y_offset = node.y - world_y
world_z_offset = node.z - world_z
if ((message == "parent node to cut? (can also shift-del)")) {
//
// cutting nodes
//
message = ""
graph.delete_nodes(node)
graph.evaluate()
graph.render()
}
else if ((message == "parent node to move? (can also shift-drag)") || (evt.shiftKey == 1)) {
//
// moving nodes, walk graph to find children
//
message = ""
selected_nodes = []
children = []
selected_nodes[node.index] = [node.y,node.z,node.index]
for (n in node.from)
children.push(node.from[n])
while (children.length > 0) {
child = children.pop()
node = graph.nodes[child]
selected_nodes[node.index] = [node.y,node.z,node.index]
for (n in node.from)
children.push(node.from[n])
}
}
}
function node_down_xyz(evt) {
//
// xyz mouse node down routine
//
selected_node = Number(evt.target.getAttribute("index"))
}
function panel_down_xy(evt) {
//
// xy mouse panel down routine
//
x_start = evt.clientX
y_start = evt.clientY
view_xmin_start = view_xmin
view_ymin_start = view_ymin
if (evt.button == 0)
btn = "left"
}
function panel_down_xz(evt) {
//
// xz mouse panel down routine
//
x_start = evt.clientX
y_start = evt.clientY
view_xmin_start = view_xmin
view_zmin_start = view_zmin
if (evt.button == 0)
btn = "left"
}
function panel_down_zy(evt) {
//
// zy mouse panel down routine
//
x_start = evt.clientX
y_start = evt.clientY
view_zmin_start = view_zmin
view_ymin_start = view_ymin
if (evt.button == 0)
btn = "left"
}
function panel_down_xyz(evt) {
//
// xyz mouse panel down routine
//
x_start = evt.clientX
y_start = evt.clientY
if (evt.button == 0)
btn = "left"
}
function node_up(evt) {
//
// mouse node up routine
//
index = evt.target.getAttribute("index")
var node = graph.nodes[index]
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
if (message == "node to link from?") {
//
// linking from
//
message = "node to link to?"
msg(message) }
else if (message == "node to link to?") {
//
// linking to
//
message = ""
msg("link from "+last_selected_node+" to "+selected_node)
graph.link(last_selected_node,selected_node,"","")
}
else if (message == "node to fix link from?") {
//
// fixed linking from
//
message = "node to fix link to?"
msg(message) }
else if (message == "node to fix link to?") {
//
// fixed linking to
//
message = ""
msg("fixed link from "+last_selected_node+" to "+selected_node)
graph.link(last_selected_node,selected_node,
"node.out(#).x = node.x + node.out(#).x - node.last.x;\n\
node.out(#).y = node.y + node.out(#).y - node.last.y;\n\
node.out(#).z = node.z + node.out(#).z - node.last.z;\n",
"")
}
else if (message == "node to unlink input?") {
//
// unlinking node input
//
if (node.from.length == 0) {
message = ""
msg("node has no inputs")
}
else if (node.from.length > 1) {
message = "input node to unlink?"
msg(message)
}
else {
message = ""
from_node = graph.nodes[node.from[0]]
to_index = from_node.to.indexOf(node.index)
from_node.to.splice(to_index,1)
node.from = []
node.input = {}
node.output = {}
node.links_xy[0].parentNode.removeChild(node.links_xy[0])
node.links_xy.splice(0,1)
node.links_xz[0].parentNode.removeChild(node.links_xz[0])
node.links_xz.splice(0,1)
node.links_zy[0].parentNode.removeChild(node.links_zy[0])
node.links_zy.splice(0,1)
node.links_xyz[0].parentNode.removeChild(node.links_xyz[0])
node.links_xyz.splice(0,1)
node.links_xy = []
node.links_xz = []
node.links_zy = []
node.links_xyz = []
graph.update(node.index)
}
}
else if (message == "input node to unlink?") {
//
// selecting input to unlink
//
message = ""
last_node = graph.nodes[last_selected_node]
to_index = node.to.indexOf(last_node.index)
node.to.splice(to_index,1)
from_index = last_node.from.indexOf(node.index)
last_node.from.splice(from_index,1)
last_node.input = {}
last_node.output = {}
last_node.links_xy[from_index].parentNode.removeChild(last_node.links_xy[from_index])
last_node.links_xy.splice(from_index,1)
last_node.links_xz[from_index].parentNode.removeChild(last_node.links_xz[from_index])
last_node.links_xz.splice(from_index,1)
last_node.links_zy.splice(from_index,1)
last_node.links_zy[from_index].parentNode.removeChild(last_node.links_zy[from_index])
last_node.links_xyz[from_index].parentNode.removeChild(last_node.links_xyz[from_index])
last_node.links_xyz.splice(from_index,1)
graph.update(last_selected_node)
}
else if (message == "node to delete? (can also del highlighted node)") {
//
// delete node
//
message = ""
graph.delete_node(selected_node)
}
else if (message == "node to align x?") {
//
// align x
//
message = "node to align x to?"
msg(message)
}
else if (message == "node to align x to?") {
//
// align x to
//
message = ""
msg(message)
from_node = graph.nodes[last_selected_node]
to_node = graph.nodes[selected_node]
from_node.x = to_node.x
graph.update(last_selected_node)
}
else if (message == "node to align y?") {
//
// align y
//
message = "node to align y to?"
msg(message)
}
else if (message == "node to align y to?") {
//
// align y to
//
message = ""
msg(message)
from_node = graph.nodes[last_selected_node]
to_node = graph.nodes[selected_node]
from_node.y = to_node.y
graph.update(last_selected_node)
}
else if (message == "node to align z?") {
//
// align z
//
message = "node to align z to?"
msg(message)
}
else if (message == "node to align z to?") {
//
// align z to
//
message = ""
msg(message)
from_node = graph.nodes[last_selected_node]
to_node = graph.nodes[selected_node]
from_node.z = to_node.z
graph.update(last_selected_node)
}
else if (message == "node to align xy?") {
//
// align xy
//
message = "node to align xy to?"
msg(message)
}
else if (message == "node to align xy to?") {
//
// align xy to
//
message = ""
msg(message)
from_node = graph.nodes[last_selected_node]
to_node = graph.nodes[selected_node]
from_node.x = to_node.x
from_node.y = to_node.y
graph.update(last_selected_node)
}
else if (message == "node to align xyz?") {
//
// align xyz
//
message = "node to align xyz to?"
msg(message)
}
else if (message == "node to align xyz to?") {
//
// align xyz to
//
message = ""
msg(message)
from_node = graph.nodes[last_selected_node]
to_node = graph.nodes[selected_node]
from_node.x = to_node.x
from_node.y = to_node.y
from_node.z = to_node.z
graph.update(last_selected_node)
}
else if (message == "node location?") {
//
// placing new node
//
message = ""
}
else if ((evt.clientX == x_start) && (evt.clientY == y_start)) {
//
// editing node
//
edit_node(node)
}
last_selected_node = selected_node
selected_node = -1
selected_nodes = []
btn = ""
}
function panel_up_xy(evt) {
//
// xy mouse panel up routine
//
if (selected_node != -1) {
node = graph.nodes[selected_node]
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
selected_node = -1
selected_nodes = []
graph.evaluate()
graph.render()
}
else if (message == "")
graph.render()
btn = ""
}
function panel_up_xz(evt) {
//
// xz mouse panel up routine
//
if (selected_node != -1) {
node = graph.nodes[selected_node]
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
selected_node = -1
graph.evaluate()
graph.render()
}
else if (message == "")
graph.render()
btn = ""
}
function panel_up_zy(evt) {
//
// zy mouse panel up routine
//
if (selected_node != -1) {
node = graph.nodes[selected_node]
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
selected_node = -1
graph.evaluate()
graph.render()
}
else if (message == "")
graph.render()
btn = ""
}
function panel_up_xyz(evt) {
//
// xyz mouse panel up routine
//
if (message == "")
graph.render()
btn = ""
}
function edit_node(node) {
//
// click to edit node
//
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","submit")
element.setAttribute("onClick","node_form(node_index_input.value,node_name_input.value,node_x_input.value,node_y_input.value,node_z_input.value,node_offset_input.value,node_code_input.value)")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","update form")
element.setAttribute("onClick","{edit_node(last_node_edited)}")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","close")
element.setAttribute("onClick","edit_panel.removeChild(edit_panel_div)")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("index: ")
last_node_edited = node
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",node.index)
element.setAttribute("id","node_index_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("name: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",node.name)
element.setAttribute("id","node_name_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("label offset: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",node.offset)
element.setAttribute("id","node_offset_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("x: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",parseFloat((node.x).toFixed(string_digits)))
element.setAttribute("id","node_x_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("y: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",parseFloat((node.y).toFixed(string_digits)))
element.setAttribute("id","node_y_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("z: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",parseFloat((node.z).toFixed(string_digits)))
element.setAttribute("id","node_z_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("code: ")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createElement("textarea")
element.setAttribute("rows","15")
element.setAttribute("cols","60")
element.setAttribute("autofocus","autofocus")
element.setAttribute("id","node_code_input")
text_element = document.createTextNode(node.code)
element.appendChild(text_element)
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("from: "+JSON.stringify(node.from))
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("input: "+JSON.stringify(node.input))
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("to: "+JSON.stringify(node.to))
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("output: "+JSON.stringify(node.output))
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
function node_form(index,name,x,y,z,offset,code) {
//
// node form handler
//
var node = graph.nodes[Number(index)]
node.name = name
node.code = code
node.offset = offset
with (Math) {
node.x = Number(eval(x))
node.y = Number(eval(y))
node.z = Number(eval(z))
}
graph.update(index)
graph.render()
node.xy_node.setAttribute("fill",node_color)
node.xy_text.setAttribute("fill",text_color)
node.xz_node.setAttribute("fill",node_color)
node.xz_text.setAttribute("fill",text_color)
node.zy_node.setAttribute("fill",node_color)
node.zy_text.setAttribute("fill",text_color)
node.xyz_node.setAttribute("fill",node_color)
node.xyz_text.setAttribute("fill",text_color)
}
function get_view() {
//
// form to get view limits
//
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","submit")
element.setAttribute("onClick","view_form(view_xmin_input.value,view_ymin_input.value,view_zmin_input.value,view_dxyz_input.value)")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","update form")
element.setAttribute("onClick","{get_view()}")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","close")
element.setAttribute("onClick","edit_panel.removeChild(edit_panel_div)")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("view: ")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("xmin: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",view_xmin)
element.setAttribute("id","view_xmin_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("ymin: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",view_ymin)
element.setAttribute("id","view_ymin_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("zmin: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",view_zmin)
element.setAttribute("id","view_zmin_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("width: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("value",view_dx)
element.setAttribute("id","view_dxyz_input")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
function view_form(xmin,ymin,zmin,dxyz) {
//
// view form handler
//
view_xmin = parseFloat(xmin)
view_ymin = parseFloat(ymin)
view_zmin = parseFloat(zmin)
view_dx = parseFloat(dxyz)
view_dy = parseFloat(dxyz)
if (view_dz != 0)
view_dz = parseFloat(dxyz)
redraw_axes()
graph.redraw()
graph.render()
}
function update_text(node) {
//
// update node text
//
new_text_node = document.createTextNode(node.name)
node.xy_text.replaceChild(new_text_node,
node.xy_text.childNodes[0])
new_text_node = document.createTextNode(node.name)
node.xz_text.replaceChild(new_text_node,
node.xz_text.childNodes[0])
new_text_node = document.createTextNode(node.name)
node.zy_text.replaceChild(new_text_node,
node.zy_text.childNodes[0])
new_text_node = document.createTextNode(node.name)
node.xyz_text.replaceChild(new_text_node,
node.xyz_text.childNodes[0])
}
function get_grid() {
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createTextNode("grid size (world units): ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("size","4")
element.setAttribute("value",graph.grid)
element.setAttribute("id","grid_input")
element.setAttribute("onkeydown","if (event.keyCode == 13) {graph.grid = grid_input.value; msg('grid set to '+graph.grid); edit_panel.removeChild(edit_panel_div)}")
element.setAttribute("autofocus","autofocus")
edit_panel_div.appendChild(element)
element = document.createTextNode(" (enter to submit)")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
function get_units() {
//
// form to get units
//
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createTextNode("mm per world unit: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("size","4")
element.setAttribute("value",graph.units)
element.setAttribute("id","units_input")
element.setAttribute("onkeydown","if (event.keyCode == 13) {graph.units = units_input.value; msg('units set to '+graph.units); edit_panel.removeChild(edit_panel_div)}")
element.setAttribute("autofocus","autofocus")
edit_panel_div.appendChild(element)
element = document.createTextNode(" (enter to submit)")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
function get_resolution() {
//
// form to get resolution
//
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createTextNode("render resolution (pixels): ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("size","4")
element.setAttribute("value",resolution)
element.setAttribute("id","resolution_input")
element.setAttribute("onkeydown","if (event.keyCode == 13) {resolution = resolution_input.value; graph.render(); msg('resolution set to '+resolution); edit_panel.removeChild(edit_panel_div)}")
element.setAttribute("autofocus","autofocus")
edit_panel_div.appendChild(element)
element = document.createTextNode(" (enter to submit)")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
function rotate3d() {
//
// rotate 3D view
//
// draw axes
//
origin = xypanel_xyz(0,0,0)
xaxis = xypanel_xyz(1,0,0)
yaxis = xypanel_xyz(0,1,0)
zaxis = xypanel_xyz(0,0,1)
axis_xyz_x = document.getElementById("axis_xyz_x")
axis_xyz_x.setAttribute("x1",origin[0])
axis_xyz_x.setAttribute("y1",origin[1])
axis_xyz_x.setAttribute("x2",xaxis[0])
axis_xyz_x.setAttribute("y2",xaxis[1])
axis_xyz_y = document.getElementById("axis_xyz_y")
axis_xyz_y.setAttribute("x1",origin[0])
axis_xyz_y.setAttribute("y1",origin[1])
axis_xyz_y.setAttribute("x2",yaxis[0])
axis_xyz_y.setAttribute("y2",yaxis[1])
axis_xyz_z = document.getElementById("axis_xyz_z")
axis_xyz_z.setAttribute("x1",origin[0])
axis_xyz_z.setAttribute("y1",origin[1])
axis_xyz_z.setAttribute("x2",zaxis[0])
axis_xyz_z.setAttribute("y2",zaxis[1])
//
// draw nodes and links
//
for (var i in graph.nodes) {
var node = graph.nodes[i]
x = node.x
y = node.y
z = node.z
pt = xypanel_xyz(x,y,z)
node.xyz_node.setAttribute("cx",pt[0])
node.xyz_node.setAttribute("cy",pt[1])
node.xyz_text.setAttribute("x",pt[0])
node.xyz_text.setAttribute("y",pt[1]+node.offset*node_font_size)
for (var f in node.from) {
pt1 = xypanel_xyz(graph.nodes[node.from[f]].x,graph.nodes[node.from[f]].y,graph.nodes[node.from[f]].z)
pt2 = xypanel_xyz(node.x,node.y,node.z)
x1 = pt1[0]
y1 = pt1[1]
z1 = pt1[2]
x2 = pt2[0]
y2 = pt2[1]
z2 = pt2[2]
node.links_xyz[f].setAttribute("x1",x1)
node.links_xyz[f].setAttribute("y1",y1)
node.links_xyz[f].setAttribute("x2",x2)
node.links_xyz[f].setAttribute("y2",y2)
}
}
}
function strprt(x) {
//
// convert float to string and truncate for printing
//
return (x.toFixed(display_digits))
}
function menu(x,y,width,height,names) {
//
// menu
//
if (menu_names == "") {
//
// build menu if doesn't exist
//
menu_names = new Array
for (i = 0; i < names.length; ++i) {
button(x,y+.985*i*height,width,height,names[i],'action(evt)')
menu_names.push("menu_"+names[i])
}
}
else {
//
// otherwise remove it
//
rm_menu()
}
}
function button(x,y,width,height,label,action) {
//
// add a button
//
var new_button = document.createElementNS(svgNS,"g");
new_button.setAttribute("transform","translate("+x+","+y+")")
new_button.setAttribute("onmouseup",action)
new_button.setAttribute("id","menu_"+label)
new_button.setAttribute("onmouseover","mouse_over(evt)")
new_button.setAttribute("onmouseout","mouse_out(evt)")
new_button.setAttribute("fill-opacity",".8")
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",width)
new_rect.setAttribute("height",height)
new_rect.setAttribute("fill",button_color)
new_button.appendChild(new_rect);
var new_txt = document.createElementNS(svgNS,"text");
new_txt.setAttribute("x",width/2)
new_txt.setAttribute("y",height/2+5)
new_txt.setAttribute("font-size",menu_font_size);
new_txt.setAttribute("font-family","sans-serif");
new_txt.setAttribute("text-anchor","middle");
//new_txt.setAttribute("fill","rgb(200,0,0)")
new_txt.setAttribute("fill","rgb(0,0,0)")
var new_txt_node = document.createTextNode(label);
new_txt.appendChild(new_txt_node);
new_button.appendChild(new_txt);
document.getElementById("svg").appendChild(new_button);
}
function msg(string) {
document.getElementById("message").firstChild.nodeValue = string
}
function mouse_over(evt) {
//
// highlight for mouseover
//
message = ""
element = evt.target.parentNode
element.setAttribute("fill-opacity","1")
}
function mouse_out(evt) {
//
// remove highlight for mouseout
//
element = evt.target.parentNode
element.setAttribute("fill-opacity",".8")
}
function shapes_menu(evt) {
//
// shapes menu
//
names = ["node","true","(t)riangle","right trian(g)le","(r)ect. edge","r(e)ct. center","rect. cor(n)ers","rounded rect.","po(l)ygon","(c)irc. edge","c(i)rc. center","circ. diam.","(a)rc","elli(p)se","c(u)be edge","cu(b)e center","cube corners","pyrami(d)","(s)phere edge","sp(h)ere center","sphere diam.","cylinder (x)","cylinder (y)","cylinder (z)","c(o)ne","torus","function"]
menu(0*menu_width,2*menu_height,menu_width,menu_height,names)
}
function operators_menu(evt) {
//
// operators menu
//
names = ["(a)dd","(s)ubtract","(i)ntersect","in(v)ert","(c)learance"]
menu(1*menu_width,2*menu_height,menu_width,menu_height,names)
}
function transform_menu(evt) {
//
// transforms menu
//
names = ["(d)uplicate","(t)ranslate","(o)rigin","(color)","rotate (x)","rotate (y)","rotate (z)","mirror x","mirror y","mirror z","reflect xy","reflect xz","reflect yz","(e)xtrude","(s)cale xy", "s(c)ale xyz","taper x y","taper xy z","shear x y","shear xy z","twist xy z","revolve y","bend z","(w)arp z","loft z","morph","thicken","thin","amplitude","shell","fillet","(chamfer)","(r)epel","(a)ttract","(l)inear array","ra(d)ial array"]
menu(2*menu_width,2*menu_height,menu_width,menu_height,names)
}
function edit_menu(evt) {
//
// edit menu
//
names = ["(n)ode","(l)ink","(f)ixed link","(insert node)","unlink node","(d)elete node","(c)ut nodes","(copy nodes)","(paste nodes)","(m)ove nodes","(u)ndo","(redo)","align (x)","align (y)","align (z)","align xy (2)","align xyz (3)","(g)rid size"]
,
menu(3*menu_width,2*menu_height,menu_width,menu_height,names)
}
function view_menu(evt) {
//
// view menu
//
names = ["(2)D","(3)D","(up) zoom in","(down) zoom out","pan","(l)imits","(r)esolution","(toggle graph)","(toggle render)","(fit)","(e)xpression"]
menu(4*menu_width,2*menu_height,menu_width,menu_height,names)
}
function file_menu(evt) {
//
// file menu
//
names = ["(o)pen .fab","(s)ave .fab","export .(m)ath","(export .s(v)g)","(export .s(t)l)","(export .(p)ng)","(quit)"]
menu(5*menu_width,2*menu_height,menu_width,menu_height,names)
}
function library_menu(evt) {
//
// library menu
//
;
}
function solve_menu(evt) {
//
// solve menu
//
;
}
function CAM_menu(evt) {
//
// CAM menu
//
names = ["(f)abricate","(u)nits"]
menu(8*menu_width,2*menu_height,menu_width,menu_height,names)
}
function help_menu(evt) {
//
// help_menu
//
;
}
function render_response(xmlhttp) {
//
// render response handler
//
if (xmlhttp.readyState == 4) {
image_xy = document.getElementById("image_xy")
image_xy.setAttributeNS(xlinkNS,"href","/fab_render_xy.png")
image_xy.setAttribute("display","")
if (view_dz != 0) {
image_xz = document.getElementById("image_xz")
image_xz.setAttributeNS(xlinkNS,"href","/fab_render_xz.png")
image_xz.setAttribute("display","")
image_zy = document.getElementById("image_zy")
image_zy.setAttributeNS(xlinkNS,"href","/fab_render_zy.png")
image_zy.setAttribute("display","")
image_xyz = document.getElementById("image_xyz")
image_xyz.setAttributeNS(xlinkNS,"href","/fab_render_xyz.png")
image_xyz.setAttribute("display","")
}
}
}
function fab_file_open_handler(xmlhttp) {
//
// .fab file open response handler
//
if (xmlhttp.readyState == 4) {
graph.fromstring(xmlhttp.responseText)
msg("opened "+file_name)
}
}
function fab_file_list_handler(filename) {
//
// fab file list form handler
//
edit_panel.removeChild(edit_panel_div)
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {fab_file_open_handler(xmlhttp); };
xmlhttp.open('POST','/open',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("{"+filename+"}");
file_name = filename
}
function fab_file_delete_handler(filename) {
//
// fab file delete form handler
//
edit_panel.removeChild(edit_panel_div)
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {fab_list_response(xmlhttp); };
xmlhttp.open('POST','/delete',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("{"+filename+"}");
file_name = filename
}
function fab_dir_list_handler(dirname) {
//
// fab dir list form handler
//
edit_panel.removeChild(edit_panel_div)
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {fab_list_response(xmlhttp); };
xmlhttp.open('POST','/cd',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("{"+dirname+"}");
}
function fab_list_response(xmlhttp) {
//
// .fab list response form
//
if (xmlhttp.readyState == 4) {
text = xmlhttp.responseText.split(';')
files = text[0].split(',')
cwd = text[1]
dirs = text[2].split(',')
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","close")
element.setAttribute("onClick",'{edit_panel.removeChild(edit_panel_div)}')
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
if (files.length > 0) {
files[0] = files[0].substr(1)
element = document.createTextNode(".fab files: ")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
for (var f in files) {
file_name = files[f]
if (file_name.indexOf(".fab") != -1) {
element = document.createTextNode(file_name+" ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","open")
element.setAttribute("onClick",'{fab_file_list_handler("'+file_name+'")}')
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","delete")
element.setAttribute("onClick",'{fab_file_delete_handler("'+file_name+'")}')
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
}
}
}
if (dirs.length > 0) {
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode("directories: ")
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode(cwd)
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
element = document.createTextNode(".. ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","cd")
element.setAttribute("onClick",'{fab_dir_list_handler("..")}')
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
for (var d in dirs) {
dir_name = dirs[d]
if ((dir_name[0] != '.') && (dir_name != 0)){
element = document.createTextNode(dir_name+" ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","button")
element.setAttribute("value","cd")
element.setAttribute("onClick",'{fab_dir_list_handler("'+dir_name+'")}')
edit_panel_div.appendChild(element)
element = document.createElement("br")
edit_panel_div.appendChild(element)
}
}
}
edit_panel.appendChild(edit_panel_div)
}
}
function post_response(xmlhttp) {
//
// post response handler
//
if (xmlhttp.readyState == 4) {
msg(xmlhttp.responseText)
}
}
function action(evt) {
//
// menu actions
//
if (message != "") {
label = "menu_"+message
message = ""
}
else
label = evt.target.parentNode.getAttribute("id")
//
// shapes
//
if (label == 'menu_node') {
name = "node"
x = 0
y = 0
z = 0
code = ""
node = graph.add_node(name,x,y,z,1,code)
graph.update(node.index)
selected_node = node.index
message = "node location?"
}
else if (label == 'menu_true') {
name = "true"
x = 0
y = 0
z = 0
code = "\
node.output['part#'] = '(-1)';"
node = graph.add_node(name,x,y,z,1,code)
graph.update(node.index)
selected_node = node.index
message = "node location?"
}
else if (label == 'menu_(r)ect. edge') {
//
// corner
//
name = "corner"
x = -node_offset
y = -node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
corner = graph.add_node(name,x,y,z,1,code)
//
// origin
//
name = "rectangle"
x = 0
y = 0
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
xorg = node.x;\n\
yorg = node.y;\n\
part = '(('+number(xorg)+'-'+number(Math.abs(dx))+')-X)';\n\
part1 = '(X-('+number(xorg)+'+'+number(Math.abs(dx))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(yorg)+'-'+number(Math.abs(dy))+')-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(yorg)+'+'+number(Math.abs(dy))+'))';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;"
rect = graph.add_node(name,x,y,z,1,code)
graph.link(corner.index,rect.index,"","")
graph.update(corner.index)
selected_node = corner.index
message = "node location?"
}
else if (label == 'menu_r(e)ct. center') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// corner
//
name = "rectangle"
x = node_offset
y = node_offset
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
part = '(('+number(xorg)+'-'+number(Math.abs(dx))+')-X)';\n\
part1 = '(X-('+number(xorg)+'+'+number(Math.abs(dx))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(yorg)+'-'+number(Math.abs(dy))+')-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(yorg)+'+'+number(Math.abs(dy))+'))';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;"
corner = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,corner.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_rect. cor(n)ers') {
//
// point 1
//
name = "point 1"
x = -node_offset
y = -node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x1 = node.x;\n\
node.output.y1 = node.y;"
point1_node = graph.add_node(name,x,y,z,1,code)
//
// point 2
//
name = "point 2"
x = 0
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x1 = node.input.x1;\n\
node.output.y1 = node.input.y1;\n\
node.output.x2 = node.x;\n\
node.output.y2 = node.y;"
point2_node = graph.add_node(name,x,y,z,1,code)
//
// rectangle
//
name = "rectangle"
x = node_offset
y = 0
z = 0
code = "\
x1 = node.input.x1;\n\
y1 = node.input.y1;\n\
x2 = node.input.x2;\n\
y2 = node.input.y2;\n\
x3 = node.x;\n\
y3 = node.y;\n\
if (x1 != undefined) {\n\
dx12 = x2 - x1;\n\
dy12 = y2 - y1;\n\
r12 = Math.sqrt(dx12*dx12+dy12*dy12);\n\
nx12 = -dy12/r12;\n\
ny12 = dx12/r12;\n\
dx23 = x3 - x2;\n\
dy23 = y3 - y2;\n\
r = nx12*dx23 + ny12*dy23;\n\
dx23 = r*nx12;\n\
dy23 = r*ny12;\n\
node.x = x2 + dx23;\n\
node.y = y2 + dy23;\n\
r23 = Math.sqrt(dx23*dx23+dy23*dy23);\n\
nx23 = -dy23/r23;\n\
ny23 = dx23/r23;\n\
part = '((X-'+number(x1)+')*'+number(nx12)+'+(Y-'+number(y1)+')*'+number(ny12)+')';\n\
part1 = '(('+number(x3)+'-X)*'+number(nx12)+'+('+number(y3)+'-Y)*'+number(ny12)+')';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '((X-'+number(x2)+')*'+number(nx23)+'+(Y-'+number(y2)+')*'+number(ny23)+')';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(x1)+'-X)*'+number(nx23)+'+('+number(y1)+'-Y)*'+number(ny23)+')';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;\n\
}"
rectangle_node = graph.add_node(name,x,y,z,1,code)
graph.link(point2_node.index,rectangle_node.index,"","")
graph.link(point1_node.index,point2_node.index,"","")
graph.update(point1_node.index)
selected_node = point1_node.index
message = "node location?"
}
else if (label == 'menu_rounded rect.') {
//
// corner
//
name = "corner"
x = -1.5*node_offset
y = -1.5*node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
corner_node = graph.add_node(name,x,y,z,1,code)
//
// radius
//
name = "radius"
x = -node_offset
y = -node_offset
z = 0
code = "\
node.y = node.in(0).y + node.x - node.in(0).x;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x1 = node.in(0).x;\n\
node.output.y1 = node.in(0).y;"
radius_node = graph.add_node(name,x,y,z,1,code)
//
// corner
//
name = "rectangle"
x = 0
y = 0
z = 0
code = "\
x1 = node.input.x1;\n\
y1 = node.input.y1;\n\
x2 = node.in(0).x\n\
y2 = node.in(0).y\n\
x3 = node.x\n\
y3 = node.y\n\
if (x1 != undefined) {\n\
part = '(('+number(x1)+')-X)';\n\
part1 = '(X-('+number(x3)+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(y2)+')-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(y3-(y2-y1))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(x2)+')-X)';\n\
part2 = '(X-('+number(x3-(x2-x1))+'))';\n\
part1 = 'max('+part1+','+part2+')';\n\
part2 = '(('+number(y1)+')-Y)';\n\
part1 = 'max('+part1+','+part2+')';\n\
part2 = '(Y-('+number(y3)+'))';\n\
part1 = 'max('+part1+','+part2+')';\n\
part = 'min('+part+','+part1+')';\n\
r = x2-x1;\n\
part1 = '(((X-'+number(x2)+')*(X-'+number(x2)+')+(Y-'+number(y2)+')*(Y-'+number(y2)+')) - '+number(r)+'*'+number(r)+')';\n\
part = 'min('+part+','+part1+')';\n\
part1 = '(((X-'+number(x2)+')*(X-'+number(x2)+')+(Y-'+number(y3-(y2-y1))+')*(Y-'+number(y3-(y2-y1))+')) - '+number(r)+'*'+number(r)+')';\n\
part = 'min('+part+','+part1+')';\n\
part1 = '(((X-'+number(x3-(x2-x1))+')*(X-'+number(x3-(x2-x1))+')+(Y-'+number(y2)+')*(Y-'+number(y2)+')) - '+number(r)+'*'+number(r)+')';\n\
part = 'min('+part+','+part1+')';\n\
part1 = '(((X-'+number(x3-(x2-x1))+')*(X-'+number(x3-(x2-x1))+')+(Y-'+number(y3-(y2-y1))+')*(Y-'+number(y3-(y2-y1))+')) - '+number(r)+'*'+number(r)+')';\n\
part = 'min('+part+','+part1+')';\n\
node.output['part#'] = part;\n\
}"
rectangle_node = graph.add_node(name,x,y,z,1,code)
graph.link(radius_node.index,rectangle_node.index,"","")
graph.link(corner_node.index,radius_node.index,"","")
graph.update(corner_node.index)
selected_node = corner_node.index
message = "node location?"
}
else if (label == 'menu_(c)irc. edge') {
//
// origin
//
name = "radius"
x = -node_offset
y = -node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
radius = graph.add_node(name,x,y,z,1,code)
//
// radius
//
name = "circle"
x = 0
y = 0
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
xorg = node.x;\n\
yorg = node.y;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - '+number(r)+'*'+number(r)+')';"
circle = graph.add_node(name,x,y,z,1,code)
graph.link(radius.index,circle.index,"","")
graph.update(radius.index)
selected_node = radius.index
message = "node location?"
}
else if (label == 'menu_c(i)rc. center') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// radius
//
name = "circle"
x = node_offset
y = node_offset
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - '+number(r)+'*'+number(r)+')';"
radius = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,radius.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_circ. diam.') {
//
// origin
//
name = "diameter"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
diameter_node = graph.add_node(name,x,y,z,1,code)
//
// circle
//
name = "circle"
x = node_offset
y = node_offset
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r = Math.sqrt(dx*dx+dy*dy)/2.0;\n\
xorg = node.in(0).x+dx/2.0;\n\
yorg = node.in(0).y+dy/2.0;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - '+number(r)+'*'+number(r)+')';"
circle_node = graph.add_node(name,x,y,z,1,code)
graph.link(diameter_node.index,circle_node.index,"","")
graph.update(diameter_node.index)
selected_node = diameter_node.index
message = "node location?"
}
else if (label == 'menu_(a)rc') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
"
origin_node = graph.add_node(name,x,y,z,1,code)
//
// inner radius
//
name = "inner"
x = node_offset
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.z = node.in(0).z;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r0 = Math.sqrt(dx*dx+dy*dy);\n\
//\n\
//r0 = 1; // uncomment to fix inner radius\n\
//\n\
theta0 = angle(dx,dy);\n\
//\n\
//theta0 = rad_deg * 45; // uncomment to fix angle\n\
//\n\
node.x = node.in(0).x + r0*Math.cos(theta0);\n\
node.y = node.in(0).y + r0*Math.sin(theta0);\n\
node.output.theta0 = theta0;\n\
node.output.x0 = node.in(0).x;\n\
node.output.y0 = node.in(0).y;\n\
node.output.r0 = r0;\n\
"
inner_node = graph.add_node(name,x,y,z,1,code)
//
// outer radius
//
name = "outer"
x = 2*node_offset
y = 2*node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.z = node.in(0).z;\n\
if (node.input.theta0 != undefined) {\n\
theta0 = node.input.theta0;\n\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
r0 = node.input.r0;\n\
z0 = node.z;\n\
x1 = node.in(0).x;\n\
y1 = node.in(0).y;\n\
dx = node.x - x0;\n\
dy = node.y - y0;\n\
r1 = Math.sqrt(dx*dx+dy*dy);\n\
//\n\
//r1 = 1; // uncomment to fix outer radius\n\
//\n\
node.x = x0 + r1*Math.cos(theta0);\n\
node.y = y0 + r1*Math.sin(theta0);\n\
part0 = '(((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')) - '+number(r0)+'*'+number(r0)+')';\n\
part1 = '(((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')) - '+number(r1)+'*'+number(r1)+')';\n\
node.output.part = '(max(-('+part0+'),'+part1+'))';\n\
node.output.x0 = x0;\n\
node.output.y0 = y0;\n\
node.output.theta0 = theta0;\n\
node.output.r1 = r1;\n\
}\n\
"
outer_node = graph.add_node(name,x,y,z,1,code)
//
// arc
//
name = "arc"
x = -2*node_offset
y = 2*node_offset
z = 0
code = "\
node.z = node.in(0).z;\n\
if (node.input.part != undefined) {\n\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
theta0 = node.input.theta0;\n\
r1 = node.input.r1;\n\
dx = node.x - x0;\n\
dy = node.y - y0;\n\
theta1 = angle(dx,dy);\n\
//\n\
//theta1 = rad_deg * 45; // uncomment to fix angle\n\
//\n\
node.x = x0 + r1*Math.cos(theta1);\n\
node.y = y0 + r1*Math.sin(theta1);\n\
dx = node.x - x0;\n\
dy = node.y - y0;\n\
nx = -dy;\n\
ny = dx;\n\
part1 = '((X-'+number(x0)+')*'+number(nx)+'+(Y-'+number(y0)+')*'+number(ny)+')';\n\
dx = node.in(0).x - x0;\n\
dy = node.in(0).y - y0;\n\
nx = dy;\n\
ny = -dx;\n\
part0 = '((X-'+number(x0)+')*'+number(nx)+'+(Y-'+number(y0)+')*'+number(ny)+')';\n\
part = node.input.part;\n\
if (theta1 > theta0)\n\
node.output['part#'] = 'max('+part1+',max('+part+','+part0+'))';\n\
else\n\
node.output['part#'] = 'max(-('+part1+'),max('+part+',-('+part0+')))';\n\
}\n\
"
arc_node = graph.add_node(name,x,y,z,1,code)
graph.link(outer_node.index,arc_node.index,"","")
graph.link(inner_node.index,outer_node.index,"","")
graph.link(origin_node.index,inner_node.index,"","")
graph.update(origin_node.index)
selected_node = origin_node.index
message = "node location?"
}
else if (label == 'menu_elli(p)se') {
name = "radius 1"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
"
radius_1_node = graph.add_node(name,x,y,z,1,code)
name = "origin 1"
x = .3*node_offset
y = .3*node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.z = node.in(0).z;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r1 = Math.sqrt(dx*dx+dy*dy);\n\
node.output.r1 = r1;\n\
"
origin_1_node = graph.add_node(name,x,y,z,-1,code)
name = "origin 2"
x = 1.9*node_offset
y = 1.9*node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.z = node.in(0).z;\n\
node.output.r1 = node.input.r1;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
d = Math.sqrt(dx*dx+dy*dy);\n\
node.output.d = d;\n\
node.output.x = node.in(0).x;\n\
node.output.y1 = node.in(0).y;\n\
"
origin_2_node = graph.add_node(name,x,y,z,1,code)
name = "ellipse"
x = 2*node_offset
y = 2*node_offset
z = 0
code = "\
node.z = node.in(0).z;\n\
d = node.input['d'];\n\
if (d != undefined){\n\
r1 = node.input['r1'];\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r2 = Math.sqrt(dx*dx+dy*dy);\n\
x1 = node.input['x1'];\n\
y1 = node.input['y1'];\n\
x2 = node.in(0).x;\n\
y2 = node.in(0).y;\n\
alpha = (r1 - d - r2)/(r2 - d - r1);\n\
r = r1 + (d+r1)*alpha;\n\
node.output['part#'] = '(sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(Y-'+number(y1)+')*(Y-'+number(y1)+'))+'+number(alpha)+'*sqrt((X-'+number(x2)+')*(X-'+number(x2)+')+(Y-'+number(y2)+')*(Y-'+number(y2)+'))-'+number(r)+')';\n\
}"
ellipse_node = graph.add_node(name,x,y,z,-1,code)
graph.link(origin_2_node.index,ellipse_node.index,"","")
graph.link(origin_1_node.index,origin_2_node.index,"","")
graph.link(radius_1_node.index,origin_1_node.index,"","")
graph.update(radius_1_node.index)
selected_node = radius_1_node.index
message = "node location?"
}
else if (label == 'menu_(t)riangle') {
//
// point 1
//
name = "point 1"
x = -node_offset
y = -node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x1 = node.x;\n\
node.output.y1 = node.y;"
point1 = graph.add_node(name,x,y,z,1,code)
//
// point 2
//
name = "point 2"
x = 0
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x1 = node.input.x1;\n\
node.output.y1 = node.input.y1;\n\
node.output.x2 = node.x;\n\
node.output.y2 = node.y;"
point2 = graph.add_node(name,x,y,z,1,code)
//
// triangle
//
name = "triangle"
x = node_offset
y = 0
z = 0
code = "\
x1 = node.input.x1;\n\
y1 = node.input.y1;\n\
x2 = node.input.x2;\n\
y2 = node.input.y2;\n\
x3 = node.x;\n\
y3 = node.y;\n\
if (x1 != undefined) {\n\
dx12 = x2 - x1;\n\
dy12 = y2 - y1;\n\
r12 = Math.sqrt(dx12*dx12+dy12*dy12);\n\
nx12 = -dy12/r12;\n\
ny12 = dx12/r12;\n\
part = '((X-'+number(x1)+')*'+number(nx12)+'+(Y-'+number(y1)+')*'+number(ny12)+')';\n\
dx23 = x3 - x2;\n\
dy23 = y3 - y2;\n\
r23 = Math.sqrt(dx23*dx23+dy23*dy23);\n\
nx23 = -dy23/r23;\n\
ny23 = dx23/r23;\n\
part1 = '((X-'+number(x2)+')*'+number(nx23)+'+(Y-'+number(y2)+')*'+number(ny23)+')';\n\
part = 'max('+part+','+part1+')';\n\
dx31 = x1 - x3;\n\
dy31 = y1 - y3;\n\
r31 = Math.sqrt(dx31*dx31+dy31*dy31);\n\
nx31 = -dy31/r31;\n\
ny31 = dx31/r31;\n\
part1 = '((X-'+number(x3)+')*'+number(nx31)+'+(Y-'+number(y3)+')*'+number(ny31)+')';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;\n\
}"
triangle = graph.add_node(name,x,y,z,1,code)
graph.link(point2.index,triangle.index,"","")
graph.link(point1.index,point2.index,"","")
graph.update(point1.index)
selected_node = point1.index
message = "node location?"
}
else if (label == 'menu_right trian(g)le') {
//
// corner
//
name = "corner"
x = 0
y = 0
z = 0
code = "\
node.z = 0;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
corner = graph.add_node(name,x,y,z,1,code)
//
// right triangle
//
name = "triangle"
x = node_offset
y = 0
z = 0
code = "\
node.y = node.in(0).y;\n\
x1 = node.in(0).x;\n\
y1 = node.in(0).y;\n\
d = node.x-x1;\n\
x2 = x1;\n\
y2 = y1+d;\n\
x3 = node.x;\n\
y3 = node.y;\n\
if (x1 != undefined) {\n\
dx12 = x2 - x1;\n\
dy12 = y2 - y1;\n\
r12 = Math.sqrt(dx12*dx12+dy12*dy12);\n\
nx12 = -dy12/r12;\n\
ny12 = dx12/r12;\n\
part = '('+number(x1)+'-X)';\n\
dx23 = x3 - x2;\n\
dy23 = y3 - y2;\n\
r23 = Math.sqrt(dx23*dx23+dy23*dy23);\n\
nx23 = -dy23/r23;\n\
ny23 = dx23/r23;\n\
part1 = '((X-'+number(x2)+')*'+number(nx23)+'+(Y-'+number(y2)+')*'+number(ny23)+')';\n\
part = 'max('+part+','+part1+')';\n\
dx31 = x1 - x3;\n\
dy31 = y1 - y3;\n\
r31 = Math.sqrt(dx31*dx31+dy31*dy31);\n\
nx31 = -dy31/r31;\n\
ny31 = dx31/r31;\n\
part1 = '('+number(y1)+'-Y)';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;\n\
}"
triangle = graph.add_node(name,x,y,z,1,code)
graph.link(corner.index,triangle.index,"","")
graph.update(corner.index)
selected_node = corner.index
message = "node location?"
}
else if (label == 'menu_po(l)ygon') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// polygon
//
name = "polygon"
x = node_offset
y = 0
z = 0
code = "\
//\n\
n = 5; // number of sides\n\
//\n\
dtheta = 2*Math.PI/n;\n\
node.z = node.in(0).z;\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
theta = angle(dx,dy);\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
nx = Math.cos(theta);\n\
ny = Math.sin(theta);\n\
part = '((X-'+number(x0)+')*'+number(nx)+'+(Y-'+number(y0)+')*'+number(ny)+'-'+number(r)+')';\n\
for (i = 1; i < n; ++i) {\n\
nx = Math.cos(dtheta*i+theta);\n\
ny = Math.sin(dtheta*i+theta);\n\
new_part = '((X-'+number(x0)+')*'+number(nx)+'+(Y-'+number(y0)+')*'+number(ny)+'-'+number(r)+')';\n\
part = 'max('+part+','+new_part+')';\n\
}\n\
node.output['part#'] = part;\n\
"
//node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';
polygon = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,polygon.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_c(u)be edge') {
//
// origin
//
name = "corner"
x = -node_offset
y = -node_offset
z = -node_offset
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
corner = graph.add_node(name,x,y,z,1,code)
//
// cube
//
name = "cube"
x = 0
y = 0
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
xorg = node.x;\n\
yorg = node.y;\n\
zorg = node.z;\n\
part = '(('+number(xorg)+'-'+number(Math.abs(dx))+')-X)';\n\
part1 = '(X-('+number(xorg)+'+'+number(Math.abs(dx))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(yorg)+'-'+number(Math.abs(dy))+')-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(yorg)+'+'+number(Math.abs(dy))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(zorg)+'-'+number(Math.abs(dz))+')-Z)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Z-('+number(zorg)+'+'+number(Math.abs(dz))+'))';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;"
cube = graph.add_node(name,x,y,z,1,code)
graph.link(corner.index,cube.index,"","")
graph.update(corner.index)
selected_node = corner.index
message = "node location?"
}
else if (label == 'menu_cu(b)e center') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// corner
//
name = "cube"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zorg = node.in(0).z;\n\
part = '(('+number(xorg)+'-'+number(Math.abs(dx))+')-X)';\n\
part1 = '(X-('+number(xorg)+'+'+number(Math.abs(dx))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(yorg)+'-'+number(Math.abs(dy))+')-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(yorg)+'+'+number(Math.abs(dy))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(('+number(zorg)+'-'+number(Math.abs(dz))+')-Z)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Z-('+number(zorg)+'+'+number(Math.abs(dz))+'))';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;"
corner = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,corner.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_cube corners') {
//
// corner
//
name = "corner"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
corner_node = graph.add_node(name,x,y,z,1,code)
//
// cube
//
name = "cube"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zorg = node.in(0).z;\n\
part = '('+number(xorg)+'-X)';\n\
part1 = '(X-('+number(xorg)+'+'+number(Math.abs(dx))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '('+number(yorg)+'-Y)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Y-('+number(yorg)+'+'+number(Math.abs(dy))+'))';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '('+number(zorg)+'-Z)';\n\
part = 'max('+part+','+part1+')';\n\
part1 = '(Z-('+number(zorg)+'+'+number(Math.abs(dz))+'))';\n\
part = 'max('+part+','+part1+')';\n\
node.output['part#'] = part;"
cube_node = graph.add_node(name,x,y,z,1,code)
graph.link(corner_node.index,cube_node.index,"","")
graph.update(corner_node.index)
selected_node = corner_node.index
message = "node location?"
}
else if (label == 'menu_pyrami(d)') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = node_offset
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// pyramid
//
name = "pyramid"
x = node_offset
y = node_offset
z = -node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zbot = node.z;\n\
ztop = node.in(0).z;\n\
if (ztop > zbot) {\n\
part = '(('+number(xorg)+'-('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dx))+')-X)'\n\
part1 = '(X-('+number(xorg)+'+('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dx))+'))'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(('+number(yorg)+'-('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dy))+')-Y)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Y-('+number(yorg)+'+('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dy))+'))'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '('+number(zbot)+'-Z)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Z-'+number(ztop)+')'\n\
part = 'max('+part+','+part1+')'\n\
}\n\
else {\n\
part = '(('+number(xorg)+'-('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dx))+')-X)'\n\
part1 = '(X-('+number(xorg)+'+('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dx))+'))'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(('+number(yorg)+'-('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dy))+')-Y)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Y-('+number(yorg)+'+('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*'+number(Math.abs(dy))+'))'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '('+number(ztop)+'-Z)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Z-'+number(zbot)+'))'\n\
part = 'max('+part+','+part1+')'\n\
}\n\
node.output['part#'] = part;"
pyramid = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,pyramid.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_(s)phere edge') {
//
// radius
//
name = "radius"
x = -node_offset
y = -node_offset
z = -node_offset
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
radius = graph.add_node(name,x,y,z,1,code)
//
// sphere
//
name = "sphere"
x = 0
y = 0
z = 0
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
xorg = node.x;\n\
yorg = node.y;\n\
zorg = node.z;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';"
sphere = graph.add_node(name,x,y,z,1,code)
graph.link(radius.index,sphere.index,"","")
graph.update(radius.index)
selected_node = radius.index
message = "node location?"
}
else if (label == 'menu_sp(h)ere center') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// radius
//
name = "sphere"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zorg = node.in(0).z;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';"
radius = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,radius.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_sphere diam.') {
//
// diameter
//
name = "diameter"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
diameter_node = graph.add_node(name,x,y,z,1,code)
//
// sphere
//
name = "sphere"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz)/2.0;\n\
xorg = node.in(0).x + dx/2.0;\n\
yorg = node.in(0).y + dy/2.0;\n\
zorg = node.in(0).z + dz/2.0;\n\
node.output['part#'] = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';"
sphere_node = graph.add_node(name,x,y,z,1,code)
graph.link(diameter_node.index,sphere_node.index,"","")
graph.update(diameter_node.index)
selected_node = diameter_node.index
message = "node location?"
}
else if (label == 'menu_cylinder (x)') {
//
// origin
//
name = "origin"
x = node_offset
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// cylinder
//
name = "cylinder x"
x = -node_offset
y = .5*node_offset
z = .5*node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dy*dy+dz*dz);\n\
yorg = node.in(0).y;\n\
zorg = node.in(0).z;\n\
xbot = node.x;\n\
xtop = node.in(0).x;\n\
if (xtop < xbot) {\n\
xbot = xtop;\n\
xtop = node.x;\n\
}\n\
part = '(((Y-'+number(yorg)+')*(Y-'+number(yorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';\n\
part1 = '('+number(xbot)+'-X)';\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(X-'+number(xtop)+')';\n\
part = 'max('+part+','+part1+')'\n\
node.output['part#'] = part;"
cylinder = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,cylinder.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_cylinder (y)') {
//
// origin
//
name = "origin"
x = 0
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// cylinder
//
name = "cylinder y"
x = .5*node_offset
y = -node_offset
z = .5*node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dz*dz);\n\
xorg = node.in(0).x;\n\
zorg = node.in(0).z;\n\
ybot = node.y;\n\
ytop = node.in(0).y;\n\
if (ytop < ybot) {\n\
ybot = ytop;\n\
ytop = node.y;\n\
}\n\
part = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Z-'+number(zorg)+')*(Z-'+number(zorg)+')) - '+number(r)+'*'+number(r)+')';\n\
part1 = '('+number(ybot)+'-Y)';\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Y-'+number(ytop)+')';\n\
part = 'max('+part+','+part1+')'\n\
node.output['part#'] = part;"
cylinder = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,cylinder.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_cylinder (z)') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = node_offset
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// cylinder
//
name = "cylinder z"
x = .5*node_offset
y = .5*node_offset
z = -node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zbot = node.z;\n\
ztop = node.in(0).z;\n\
if (ztop < zbot) {\n\
zbot = ztop;\n\
ztop = node.z;\n\
}\n\
part = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - '+number(r)+'*'+number(r)+')';\n\
part1 = '('+number(zbot)+'-Z)';\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Z-'+number(ztop)+')';\n\
part = 'max('+part+','+part1+')'\n\
node.output['part#'] = part;"
cylinder = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,cylinder.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_c(o)ne') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = node_offset
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// cone
//
name = "cone"
x = node_offset
y = node_offset
z = -node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
xorg = node.in(0).x;\n\
yorg = node.in(0).y;\n\
zbot = node.z;\n\
ztop = node.in(0).z;\n\
if (ztop > zbot) {\n\
part = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - ((('+number(ztop)+'-Z)/('+number(ztop-zbot)+')*(('+number(ztop)+'-Z)/('+number(ztop-zbot)+')))*'+number(r)+'*'+number(r)+'))'\n\
part1 = '(('+zbot+')-Z)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Z-('+ztop+'))'\n\
part = 'max('+part+','+part1+')'\n\
}\n\
else {\n\
part = '(((X-'+number(xorg)+')*(X-'+number(xorg)+')+(Y-'+number(yorg)+')*(Y-'+number(yorg)+')) - ((('+number(-ztop)+'+Z)/('+number(zbot-ztop)+')*(('+number(-ztop)+'+Z)/('+number(zbot-ztop)+')))*'+number(r)+'*'+number(r)+'))'\n\
part1 = '(('+ztop+')-Z)'\n\
part = 'max('+part+','+part1+')'\n\
part1 = '(Z-('+zbot+'))'\n\
part = 'max('+part+','+part1+')'\n\
}\n\
node.output['part#'] = part;"
cone = graph.add_node(name,x,y,z,1,code)
graph.link(origin.index,cone.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_torus') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// radius
//
name = "radius"
x = node_offset
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.z = node.in(0).z;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
theta = angle(dx,dy);\n\
r0 = Math.sqrt(dx*dx+dy*dy);\n\
node.output.theta = theta;\n\
node.output.x0 = node.in(0).x;\n\
node.output.y0 = node.in(0).y;\n\
node.output.r0 = r0;\n\
"
radius = graph.add_node(name,x,y,z,1,code)
//
// torus
//
name = "torus"
x = 1.5*node_offset
y = 1.5*node_offset
z = 0
code = "\
node.z = node.in(0).z;\n\
if (node.input['theta'] != undefined) {\n\
theta = node.input['theta'];\n\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
r0 = node.input.r0;\n\
z0 = node.z;\n\
x1 = node.in(0).x;\n\
y1 = node.in(0).y;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
r1 = Math.sqrt(dx*dx+dy*dy);\n\
node.x = x1 + r1*Math.cos(theta);\n\
node.y = y1 + r1*Math.sin(theta);\n\
node.output['part#'] = '(pow('+number(r0)+'-sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')),2)+(Z-'+number(z0)+')*(Z-'+number(z0)+')-'+number(r1*r1)+')';\n\
}\n\
"
torus = graph.add_node(name,x,y,z,1,code)
graph.link(radius.index,torus.index,"","")
graph.link(origin.index,radius.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_function') {
//
// origin
//
name = "function"
x = 0
y = 0
z = 0
code = "\
fn = 'sin(sqrt(X*X+Y*Y))/(0.001+sqrt(X*X+Y*Y))'; // function\n\
xyscale = 15.0; // function xy scale\n\
zscale = .5; // function z scale\n\
xmin = -10; // min x value\n\
xmax = 10; // max x value\n\
ymin = -10; // min y value\n\
ymax = 10; // max y value\n\
thickness = 0.1; // function thickness\n\
x0 = node.x;\n\
y0 = node.y;\n\
z0 = node.z;\n\
fn = replace(fn,'X','((X-'+number(x0)+')*'+number(xyscale)+')');\n\
fn = replace(fn ,'Y','((Y-'+number(y0)+')*'+number(xyscale)+')');\n\
part = '(Z-('+number(zscale)+'*('+fn+')+'+number(z0)+'))';\n\
part1 = '(('+number(zscale)+'*('+fn+')+'+number(z0-thickness)+')-Z)';\n\
part = 'max('+part+','+part1+')';\n\
part = 'max('+part+',('+number(xmin/xyscale+x0)+'-X))';\n\
part = 'max('+part+',('+number(ymin/xyscale+y0)+'-Y))';\n\
part = 'max('+part+',(X-'+number(xmax/xyscale+x0)+'))';\n\
part = 'max('+part+',(Y-'+number(ymax/xyscale+y0)+'))';\n\
node.output['part#'] = part;"
fnode = graph.add_node(name,x,y,z,1,code)
graph.update(fnode.index)
selected_node = fnode.index
message = "node location?"
}
//
// operators
//
else if (label == 'menu_(a)dd') {
//
// add
//
name = "add"
x = 0
y = 0
z = 0
code = "\
if (node.input['part0'] != undefined) {\n\
part = node.input['part0'];\n\
for (var n in Object.keys(node.input)) {\n\
key = Object.keys(node.input)[n];\n\
if ((key.indexOf('part') != -1) && (key != 'part0'))\n\
part = 'min('+part+','+node.input[key]+')';\n\
}\n\
node.output['part#'] = part;\n\
}"
add = graph.add_node(name,x,y,z,1,code)
graph.update(add.index)
selected_node = add.index
message = "node location?"
}
else if (label == 'menu_(s)ubtract') {
//
// subtract
//
name = "subtract"
x = 0
y = 0
z = 0
code = "\
if (node.input['part0'] != undefined) {\n\
part = node.input['part0'];\n\
for (var n in Object.keys(node.input)) {\n\
key = Object.keys(node.input)[n];\n\
if ((key.indexOf('part') != -1) && (key != 'part0'))\n\
part = 'max('+part+',-('+node.input[key]+'))';\n\
}\n\
node.output['part#'] = part;\n\
}"
subtract = graph.add_node(name,x,y,z,1,code)
graph.update(subtract.index)
selected_node = subtract.index
message = "node location?"
}
else if (label == 'menu_(i)ntersect') {
name = "intersect"
x = 0
y = 0
z = 0
code = "\
if (node.input['part0'] != undefined) {\n\
part = node.input['part0'];\n\
for (var n in Object.keys(node.input)) {\n\
key = Object.keys(node.input)[n];\n\
if ((key.indexOf('part') != -1) && (key != 'part0'))\n\
part = 'max('+part+','+node.input[key]+')'\n\
}\n\
node.output['part#'] = part;\n\
}"
intersect = graph.add_node(name,x,y,z,1,code)
graph.update(intersect.index)
selected_node = intersect.index
message = "node location?"
}
else if (label == 'menu_in(v)ert') {
name = "invert"
x = 0
y = 0
z = 0
code = "\
node.output['part#'] = '(-('+node.input['part0']+'))';"
invert = graph.add_node(name,x,y,z,1,code)
graph.update(invert.index)
selected_node = invert.index
message = "node location?"
}
else if (label == 'menu_(c)learance') {
//
// clearance
//
name = "clearance"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
if (node.input['part0'] != undefined) {\n\
node.output = node.input;\n\
}"
clearance = graph.add_node(name,x,y,z,1,code)
//
// amount
//
name = "amount"
x = node_offset
y = node_offset
z = 0
code = "\
if (node.input['part0'] != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
part = node.input['part0'];\n\
for (var n in Object.keys(node.input)) {\n\
key = Object.keys(node.input)[n];\n\
if ((key.indexOf('part') != -1) && (key != 'part0'))\n\
part = 'max('+part+',-('+node.input[key]+')+'+number(r)+'/10.0)';\n\
}\n\
for (var n in Object.keys(node.input)) {\n\
key = Object.keys(node.input)[n];\n\
if ((key.indexOf('part') != -1) && (key != 'part0'))\n\
part = 'min('+part+','+node.input[key]+')';\n\
}\n\
node.output['part#'] = part;\n\
}"
amount = graph.add_node(name,x,y,z,-1,code)
graph.link(clearance.index,amount.index,"","")
graph.update(clearance.index)
selected_node = clearance.index
message = "node location?"
}
//
// transforms
//
else if (label == 'menu_(d)uplicate') {
name = "duplicate"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
part = replace(part,'X','(X-('+dx+'))');\n\
part = replace(part,'Y','(Y-('+dy+'))');\n\
part = replace(part,'Z','(Z-('+dz+'))');\n\
}\n\
node.output['part#'] = 'min('+part+','+node.input['part0']+')';"
duplicate = graph.add_node(name,x,y,z,1,code)
graph.update(duplicate.index)
selected_node = duplicate.index
message = "node location?"
}
else if (label == 'menu_(t)ranslate') {
name = "translate"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
part = replace(part,'X','(X-'+number(dx)+')');\n\
part = replace(part,'Y','(Y-'+number(dy)+')');\n\
part = replace(part,'Z','(Z-'+number(dz)+')');\n\
}\n\
node.output['part#'] = part;"
translate = graph.add_node(name,x,y,z,1,code)
graph.update(translate.index)
selected_node = translate.index
message = "node location?"
}
else if (label == 'menu_(o)rigin') {
name = "origin"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = part;\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_mirror x') {
name = "mirror x"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'X','('+number(node.in(0).x+node.x)+'-X)');\n\
part = replace(part,'Y','(Y-'+number(node.y-node.in(0).y)+')');\n\
part = replace(part,'Z','(Z-'+number(node.z-node.in(0).z)+')');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_mirror y') {
name = "mirror y"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'X','(X-'+number(node.x-node.in(0).x)+')');\n\
part = replace(part,'Y','('+number(node.in(0).y+node.y)+'-Y)');\n\
part = replace(part,'Z','(Z-'+number(node.z-node.in(0).z)+')');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_mirror z') {
name = "mirror z"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'X','(X-'+number(node.x-node.in(0).x)+')');\n\
part = replace(part,'Y','(Y-'+number(node.y-node.in(0).y)+')');\n\
part = replace(part,'Z','('+number(node.in(0).z+node.z)+'-Z)');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_reflect xy') {
name = "reflect xy"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'X','(ytemp-'+number(node.y-node.in(0).x)+')');\n\
part = replace(part,'Y','(X-'+number(node.x-node.in(0).y)+')');\n\
part = replace(part,'Z','(Z-'+number(node.z-node.in(0).z)+')');\n\
part = replace(part,'ytemp','Y');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_reflect xz') {
name = "reflect xz"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'X','(ztemp-'+number(node.z-node.in(0).x)+')');\n\
part = replace(part,'Z','(X-'+number(node.x-node.in(0).z)+')');\n\
part = replace(part,'Y','(Y-'+number(node.y-node.in(0).y)+')');\n\
part = replace(part,'ztemp','Z');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_reflect yz') {
name = "reflect yz"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part = replace(part,'Z','(ytemp-'+number(node.y-node.in(0).z)+')');\n\
part = replace(part,'Y','(Z-'+number(node.z-node.in(0).y)+')');\n\
part = replace(part,'X','(X-'+number(node.x-node.in(0).x)+')');\n\
part = replace(part,'ytemp','Y');\n\
}\n\
node.output['part#'] = part;"
mirror = graph.add_node(name,x,y,z,1,code)
graph.update(mirror.index)
selected_node = mirror.index
message = "node location?"
}
else if (label == 'menu_rotate (x)') {
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.in(0).x;\n\
node.output.yorg = node.in(0).y;\n\
node.output.zorg = node.in(0).z;\n\
}\n\
"
origin_node = graph.add_node(name,x,y,z,1,code)
name = "rotate x"
x = 0
y = node_offset
z = node_offset
code = "\
part = node.input['part'];\n\
if (part != undefined) {\n\
xorg = node.input.xorg;\n\
yorg = node.input.yorg;\n\
zorg = node.input.zorg;\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
dy = node.y - y0;\n\
dz = node.z - z0;\n\
theta = angle(dy,dz);\n\
//\n\
//theta = rad_deg * 45; // uncomment to fix angle\n\
//\n\
Ysub = '('+number(yorg)+'+'+number(Math.cos(theta))+'*(Y-'+number(y0)+')+'+number(Math.sin(theta))+'*(ztemp-'+number(z0)+'))';\n\
Zsub = '('+number(zorg)+'-'+number(Math.sin(theta))+'*(Y-'+number(y0)+')+'+number(Math.cos(theta))+'*(Z-'+number(z0)+'))';\n\
Xsub = '('+number(xorg)+'+X-'+number(x0)+')';\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'Z',Zsub);\n\
part = replace(part,'ztemp','Z');\n\
part = replace(part,'X',Xsub);\n\
}\n\
node.output['part#'] = part;"
rotate_node = graph.add_node(name,x,y,z,1,code)
graph.link(origin_node.index,rotate_node.index,"","")
graph.update(origin_node.index)
selected_node = origin_node.index
message = "node location?"
}
else if (label == 'menu_rotate (y)') {
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.in(0).x;\n\
node.output.yorg = node.in(0).y;\n\
node.output.zorg = node.in(0).z;\n\
}\n\
"
origin_node = graph.add_node(name,x,y,z,1,code)
name = "rotate y"
x = node_offset
y = 0
z = node_offset
code = "\
part = node.input['part'];\n\
if (part != undefined) {\n\
xorg = node.input['xorg'];\n\
yorg = node.input['yorg'];\n\
zorg = node.input['zorg'];\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
dx = node.x - x0;\n\
dz = node.z - z0;\n\
theta = angle(dx,dz);\n\
//\n\
//theta = rad_deg * 45; // uncomment to fix angle\n\
//\n\
Xsub = '('+number(xorg)+'+'+number(Math.cos(theta))+'*(X-'+number(x0)+')+'+number(Math.sin(theta))+'*(ztemp-'+number(z0)+'))';\n\
Zsub = '('+number(zorg)+'-'+number(Math.sin(theta))+'*(X-'+number(x0)+')+'+number(Math.cos(theta))+'*(Z-'+number(z0)+'))';\n\
Ysub = '('+number(yorg)+'+Y-'+number(y0)+')';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Z',Zsub);\n\
part = replace(part,'ztemp','Z');\n\
part = replace(part,'Y',Ysub);\n\
}\n\
node.output['part#'] = part;"
rotate_node = graph.add_node(name,x,y,z,1,code)
graph.link(origin_node.index,rotate_node.index,"","")
graph.update(origin_node.index)
selected_node = origin_node.index
message = "node location?"
}
else if (label == 'menu_rotate (z)') {
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.in(0).x;\n\
node.output.yorg = node.in(0).y;\n\
node.output.zorg = node.in(0).z;\n\
}\n\
"
origin_node = graph.add_node(name,x,y,z,1,code)
name = "rotate z"
x = node_offset
y = node_offset
z = 0
code = "\
part = node.input['part'];\n\
if (part != undefined) {\n\
xorg = node.input.xorg;\n\
yorg = node.input.yorg;\n\
zorg = node.input.zorg;\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
dx = node.x - x0;\n\
dy = node.y - y0;\n\
theta = angle(dx,dy);\n\
//\n\
//theta = rad_deg * 45; // uncomment to fix angle\n\
//\n\
Xsub = '('+number(xorg)+'+'+number(Math.cos(theta))+'*(X-'+number(x0)+')+'+number(Math.sin(theta))+'*(ytemp-'+number(y0)+'))';\n\
Ysub = '('+number(yorg)+'-'+number(Math.sin(theta))+'*(X-'+number(x0)+')+'+number(Math.cos(theta))+'*(Y-'+number(y0)+'))';\n\
Zsub = '('+number(zorg)+'+Z-'+number(z0)+')';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'ytemp','Y');\n\
part = replace(part,'Z',Zsub);\n\
}\n\
node.output['part#'] = part;"
rotate_node = graph.add_node(name,x,y,z,1,code)
graph.link(origin_node.index,rotate_node.index,"","")
graph.update(origin_node.index)
selected_node = origin_node.index
message = "node location?"
}
else if (label == 'menu_(e)xtrude') {
name = "extrude"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.x = node.in(0).x;\n\
node.y = node.in(0).y;\n\
zbot = node.in(0).z;\n\
ztop = node.z;\n\
if (zbot > ztop) {\n\
ztemp = ztop;\n\
ztop = zbot;\n\
zbot = ztemp;\n\
}\n\
node.output['part#'] = 'max(max('+part+','+number(zbot)+'-Z),Z-'+number(ztop)+')';\n\
}"
extrude = graph.add_node(name,x,y,z,1,code)
graph.update(extrude.index)
selected_node = extrude.index
message = "node location?"
}
else if (label == 'menu_(s)cale xy') {
name = "xy scale"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.out(1).x = node.x + node.out(1).x - node.last.x;\n\
node.out(1).y = node.y + node.out(1).y - node.last.y;\n\
node.out(1).z = node.z + node.out(1).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.in(0).x;\n\
node.output.yorg = node.in(0).y;\n\
}\n\
"
xy_node = graph.add_node(name,x,y,z,1,code)
name = "x scale"
x = node_offset
y = 0
z = 0
code = "\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
x1 = node.x;\n\
node.y = y0;\n\
node.z = z0;\n\
node.output.x0 = x0;\n\
node.output.y0 = y0;\n\
node.output.z0 = z0;\n\
node.output.x1 = x1;\n\
part = node.input['part'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.input.xorg;\n\
node.output.yorg = node.input.yorg;\n\
}\n\
"
x_node = graph.add_node(name,x,y,z,-1,code)
name = "y scale"
x = 0
y = node_offset
z = 0
code = "\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
y1 = node.y;\n\
node.x = x0;\n\
node.z = z0;\n\
node.output.y1 = y1;\n\
"
y_node = graph.add_node(name,x,y,z,-1,code)
name = "scale"
x = node_offset
y = node_offset
z = node_offset
code = "\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
z0 = node.input.z0;\n\
x1 = node.input.x1;\n\
y1 = node.input.y1;\n\
node.x = x1;\n\
node.y = y1;\n\
part = node.input.part;\n\
if (part != undefined) {\n\
xorg = node.input.xorg;\n\
yorg = node.input.yorg;\n\
dx0 = x0 - xorg;\n\
dy0 = y0 - yorg;\n\
r0 = Math.sqrt(dx0*dx0+dy0*dy0);\n\
dx1 = Math.abs(x1 - x0);\n\
dy1 = Math.abs(y1 - y0);\n\
xscale = dx1 / r0;\n\
yscale = dy1 / r0;\n\
//\n\
//xscale = 1.0; // uncomment to fix x scale\n\
//yscale = 1.0; // uncomment to fix y scale\n\
//\n\
part = replace(part,'X','('+number(xorg)+'+'+number(1.0/xscale)+'*(X-'+number(xorg)+'))');\n\
part = replace(part,'Y','('+number(yorg)+'+'+number(1.0/yscale)+'*(Y-'+number(yorg)+'))');\n\
node.output['part#'] = part;\n\
}\n\
"
scale_node = graph.add_node(name,x,y,z,-1,code)
graph.link(x_node.index,scale_node.index,"","")
graph.link(y_node.index,scale_node.index,"","")
graph.link(xy_node.index,x_node.index,"","")
graph.link(xy_node.index,y_node.index,"","")
graph.update(xy_node.index)
selected_node = xy_node.index
message = "node location?"
}
else if (label == 'menu_s(c)ale xyz') {
name = "xyz scale"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.out(1).x = node.x + node.out(1).x - node.last.x;\n\
node.out(1).y = node.y + node.out(1).y - node.last.y;\n\
node.out(1).z = node.z + node.out(1).z - node.last.z;\n\
node.out(2).x = node.x + node.out(2).x - node.last.x;\n\
node.out(2).y = node.y + node.out(2).y - node.last.y;\n\
node.out(2).z = node.z + node.out(2).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.in(0).x;\n\
node.output.yorg = node.in(0).y;\n\
node.output.zorg = node.in(0).z;\n\
}\n\
"
xyz_node = graph.add_node(name,x,y,z,1,code)
name = "x scale"
x = node_offset
y = 0
z = 0
code = "\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
x1 = node.x;\n\
node.y = y0;\n\
node.z = z0;\n\
node.output.x0 = x0;\n\
node.output.y0 = y0;\n\
node.output.z0 = z0;\n\
node.output.x1 = x1;\n\
part = node.input.part;\n\
if (part != undefined) {\n\
node.output.part = part;\n\
node.output.xorg = node.input.xorg;\n\
node.output.yorg = node.input.yorg;\n\
node.output.zorg = node.input.zorg;\n\
}\n\
"
x_node = graph.add_node(name,x,y,z,-1,code)
name = "y scale"
x = 0
y = node_offset
z = 0
code = "\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
y1 = node.y;\n\
node.x = x0;\n\
node.z = z0;\n\
node.output.y1 = y1;\n\
"
y_node = graph.add_node(name,x,y,z,-1,code)
name = "z scale"
x = 0
y = 0
z = node_offset
code = "\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
z1 = node.z;\n\
node.x = x0;\n\
node.y = y0;\n\
node.output.z1 = z1;\n\
"
z_node = graph.add_node(name,x,y,z,-1,code)
name = "scale"
x = node_offset
y = node_offset
z = node_offset
code = "\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
z0 = node.input.z0;\n\
x1 = node.input.x1;\n\
y1 = node.input.y1;\n\
z1 = node.input.z1;\n\
node.x = x1;\n\
node.y = y1;\n\
node.z = z1;\n\
part = node.input.part;\n\
if (part != undefined) {\n\
xorg = node.input.xorg;\n\
yorg = node.input.yorg;\n\
zorg = node.input.zorg;\n\
dx0 = x0 - xorg;\n\
dy0 = y0 - yorg;\n\
dz0 = z0 - zorg;\n\
r0 = Math.sqrt(dx0*dx0+dy0*dy0+dz0*dz0);\n\
dx1 = Math.abs(x1 - x0);\n\
dy1 = Math.abs(y1 - y0);\n\
dz1 = Math.abs(z1 - z0);\n\
xscale = dx1 / r0;\n\
yscale = dy1 / r0;\n\
zscale = dz1 / r0;\n\
//\n\
//xscale = 1.0; // uncomment to fix x scale\n\
//yscale = 1.0; // uncomment to fix y scale\n\
//zscale = 1.0; // uncomment to fix z scale\n\
//\n\
part = replace(part,'X','('+number(xorg)+'+'+number(1.0/xscale)+'*(X-'+number(xorg)+'))');\n\
part = replace(part,'Y','('+number(yorg)+'+'+number(1.0/yscale)+'*(Y-'+number(yorg)+'))');\n\
part = replace(part,'Z','('+number(zorg)+'+'+number(1.0/zscale)+'*(Z-'+number(zorg)+'))');\n\
node.output['part#'] = part;\n\
}\n\
"
scale_node = graph.add_node(name,x,y,z,-1,code)
graph.link(x_node.index,scale_node.index,"","")
graph.link(y_node.index,scale_node.index,"","")
graph.link(z_node.index,scale_node.index,"","")
graph.link(xyz_node.index,x_node.index,"","")
graph.link(xyz_node.index,y_node.index,"","")
graph.link(xyz_node.index,z_node.index,"","")
graph.update(xyz_node.index)
selected_node = xyz_node.index
message = "node location?"
}
else if (label == 'menu_taper\ x y') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output['part#'] = node.input['part0'];\n\
node.output.x0 = node.x;\n\
node.output.y0 = node.y;"
origin = graph.add_node(name,x,y,z,1,code)
//
// start
//
name = "start"
x = 1.5*node_offset
y = 0
z = 0
code = "\
node.y = node.in(0).y;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.s0 = node.x - node.in(0).x;\n\
node.output['part#'] = node.input['part0'];"
start = graph.add_node(name,x,y,z,1,code)
//
// finish
//
name = "finish"
x = node_offset
y = node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.s0 = node.input.s0;\n\
node.output['part#'] = node.input['part0'];"
finish = graph.add_node(name,x,y,z,-1,code)
//
// taper
//
name = "taper x y"
x = 0
y = node_offset
z = 0
code = "\
node.x = Number(node.input['x0']);\n\
node.y = node.in(0).y;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
x0 = Number(node.input['x0']);\n\
y0 = Number(node.input['y0']);\n\
x1 = node.x;\n\
y1 = node.y;\n\
s0 = Number(node.input['s0'])/(y1-y0);\n\
s1 = (node.in(0).x-node.x)/(y1-y0);\n\
//\n\
//s0 = 0.5; // uncomment to set starting scale\n\
//s1 = 2.0; // uncomment to set ending scale\n\
//\n\
part = replace(part,'X','('+number(x0)+' + (X-'+number(x0)+')*('+number(y1)+'-'+number(y0)+')/('+number(s1)+'*(Y-'+number(y0)+') + '+number(s0)+'*('+number(y1)+'-Y)))');\n\
node.output['part#'] = part;\n\
}"
taper = graph.add_node(name,x,y,z,-1,code)
graph.link(finish.index,taper.index,"","")
graph.link(start.index,finish.index,"","")
graph.link(origin.index,start.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_taper\ xy z') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output['part#'] = node.input['part0'];\n\
node.output.x0 = node.x;\n\
node.output.y0 = node.y;\n\
node.output.z0 = node.z;"
origin = graph.add_node(name,x,y,z,1,code)
//
// start
//
name = "start"
x = 1.5*node_offset
y = 0
z = 0
code = "\
node.y = node.in(0).y;\n\
node.z = node.in(0).z;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.s0 = node.x - node.in(0).x;\n\
node.output['part#'] = node.input['part0'];"
start = graph.add_node(name,x,y,z,1,code)
//
// finish
//
name = "finish"
x = node_offset
y = 0
z = node_offset
code = "\
node.y = node.in(0).y;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.s0 = node.input.s0;\n\
node.output['part#'] = node.input['part0'];"
finish = graph.add_node(name,x,y,z,-1,code)
//
// taper
//
name = "taper xy z"
x = 0
y = 0
z = node_offset
code = "\
node.x = Number(node.input['x0']);\n\
node.y = Number(node.input['y0']);\n\
node.z = node.in(0).z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
x0 = Number(node.input['x0']);\n\
y0 = Number(node.input['y0']);\n\
z0 = Number(node.input['z0']);\n\
x1 = node.x;\n\
y1 = node.y;\n\
z1 = node.z;\n\
s0 = Number(node.input['s0'])/(z1-z0);\n\
s1 = (node.in(0).x-node.x)/(z1-z0);\n\
//\n\
//s0 = 0.5; // uncomment to set starting scale\n\
//s1 = 2.0; // uncomment to set ending scale\n\
//\n\
part = replace(part,'X','('+number(x0)+' + (X-'+number(x0)+')*('+number(z1)+'-'+number(z0)+')/('+number(s1)+'*(Z-'+number(z0)+') + '+number(s0)+'*('+number(z1)+'-Z)))');\n\
part = replace(part,'Y','('+number(y0)+' + (Y-'+number(y0)+')*('+number(z1)+'-'+number(z0)+')/('+number(s1)+'*(Z-'+number(z0)+') + '+number(s0)+'*('+number(z1)+'-Z)))');\n\
node.output['part#'] = part;\n\
}"
taper = graph.add_node(name,x,y,z,-1,code)
graph.link(finish.index,taper.index,"","")
graph.link(start.index,finish.index,"","")
graph.link(origin.index,start.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_shear x y') {
//
// shear x y
//
name = "shear x y"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
y0 = node.in(0).y;\n\
y1 = node.y;\n\
part = replace(part,'X','(X-'+number(dx)+'*(Y-'+number(y0)+')/'+number(y1-y0)+')');\n\
node.output['part#'] = part;\n\
}"
shear = graph.add_node(name,x,y,z,1,code)
graph.update(shear.index)
selected_node = shear.index
message = "node location?"
}
else if (label == 'menu_shear xy z') {
//
// shear xy z
//
name = "shear xy z"
x = 0
y = 0
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
z0 = node.in(0).z;\n\
z1 = node.z;\n\
part = replace(part,'X','(X-'+number(dx)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')');\n\
part = replace(part,'Y','(Y-'+number(dy)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')');\n\
node.output['part#'] = part;\n\
}"
shear = graph.add_node(name,x,y,z,1,code)
graph.update(shear.index)
selected_node = shear.index
message = "node location?"
}
else if (label == 'menu_twist\ xy z') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.x;\n\
node.output.y0 = node.y;\n\
node.output.z0 = node.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.in(0).x;\n\
node.output.yin = node.in(0).y;\n\
node.output.zin = node.in(0).z;\n\
node.output['part#'] = node.input['part0'];\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
//
// start
//
name = "start"
x = 1.5*node_offset
y = 0
z = 0
code = "\
node.y = node.in(0).y;\n\
node.z = node.in(0).z;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.r = Math.abs(node.x - node.in(0).x);\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.input.xin;\n\
node.output.yin = node.input.yin;\n\
node.output.zin = node.input.zin;\n\
node.output['part#'] = node.input['part0'];\n\
}"
start = graph.add_node(name,x,y,z,1,code)
//
// finish
//
name = "finish"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.input['x0'];\n\
dy = node.y - node.input['y0'];\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
if (r > 0) {\n\
node.x = node.input['x0'] + dx*node.input['r']/r;\n\
node.y = node.input['y0'] + dy*node.input['r']/r;\n\
}\n\
//\n\
// uncomment to fix angle\n\
//\n\
//theta = 45*rad_deg;\n\
//node.x = node.input['x0'] + node.input['r']*Math.cos(theta);\n\
//node.y = node.input['y0'] + node.input['r']*Math.sin(theta);\n\
//\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.dx = dx;\n\
node.output.dy = dy;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.input.xin;\n\
node.output.yin = node.input.yin;\n\
node.output.zin = node.input.zin;\n\
node.output['part#'] = node.input['part0'];\n\
}"
finish = graph.add_node(name,x,y,z,-1,code)
//
// twist
//
name = "twist xy z"
x = 0
y = 0
z = node_offset
code = "\
node.x = Number(node.input['x0']);\n\
node.y = Number(node.input['y0']);\n\
node.z = node.in(0).z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
xin = Number(node.input['xin']);\n\
yin = Number(node.input['yin']);\n\
zin = Number(node.input['zin']);\n\
x0 = Number(node.input['x0']);\n\
y0 = Number(node.input['y0']);\n\
z0 = Number(node.input['z0']);\n\
dx = Number(node.input['dx']);\n\
dy = Number(node.input['dy']);\n\
z1 = node.z;\n\
theta = angle(dx,dy);\n\
Zsub = '('+number(zin)+'+Z-'+number(z0)+')';\n\
part = replace(part,'Z',Zsub);\n\
Xsub = '('+number(xin)+'+cos('+number(theta)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')*(X-'+number(x0)+')+sin('+number(theta)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')*(ytemp-'+number(y0)+'))';\n\
Ysub = '('+number(yin)+'-sin('+number(theta)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')*(X-'+number(x0)+')+cos('+number(theta)+'*(Z-'+number(z0)+')/'+number(z1-z0)+')*(Y-'+number(y0)+'))';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'ytemp','Y');\n\
node.output['part#'] = part;\n\
}"
twist = graph.add_node(name,x,y,z,-1,code)
graph.link(finish.index,twist.index,"","")
graph.link(start.index,finish.index,"","")
graph.link(origin.index,start.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_revolve y') {
//
// origin
//
name = "revolve y"
x = 0
y = 0
z = 0
code = "\
if (node.input['part0'] != undefined) { \n\
node.z = node.in(0).z;\n\
x0 = node.x;\n\
y0 = node.y;\n\
z0 = node.z;\n\
part = node.input['part0'];\n\
Xsub = '('+number(x0)+'+sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ztemp-'+number(z0)+')*(ztemp-'+number(z0)+')))';\n\
Zsub = number(z0);\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Z',Zsub);\n\
part = replace(part,'ztemp','Z');\n\
node.output['part#'] = part;\n\
} \n\
"
revolve = graph.add_node(name,x,y,z,1,code)
graph.update(revolve.index)
selected_node = revolve.index
message = "node location?"
}
else if (label == 'menu_bend z') {
//
// radius
//
name = "radius"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = part;\n\
}"
radius_node = graph.add_node(name,x,y,z,-1,code)
//
// bend z
//
name = "bend z"
x = 0
y = -node_offset
z = 0
code = "\
dx = node.in(0).x - node.x;\n\
dy = node.in(0).y - node.y;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
nx = dx/r;\n\
ny = dy/r;\n\
px = -ny;\n\
py = nx;\n\
x0 = node.x;\n\
y0 = node.y;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
Xsub = '('+number(x0)+'+sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+'))*'+number(nx)+'+'+number(r*px)+'*acos(((X-'+number(x0)+')*'+number(nx)+'+(ytemp-'+number(y0)+')*'+number(ny)+')/sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')))*sgn(asin(((X-'+number(x0)+')*'+number(px)+'+(ytemp-'+number(y0)+')*'+number(py)+')/sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')))))';\n\
Ysub = '('+number(y0)+'+sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+'))*'+number(ny)+'+'+number(r*py)+'*acos(((X-'+number(x0)+')*'+number(nx)+'+(ytemp-'+number(y0)+')*'+number(ny)+')/sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')))*sgn(asin(((X-'+number(x0)+')*'+number(px)+'+(ytemp-'+number(y0)+')*'+number(py)+')/sqrt((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')))))';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'ytemp','Y');\n\
node.output['part#'] = part;\n\
}"
bend_node = graph.add_node(name,x,y,z,1,code)
graph.link(radius_node.index,bend_node.index,"","")
graph.update(radius_node.index)
selected_node = radius_node.index
message = "node location?"
}
else if (label == 'menu_(w)arp z') {
//
// radius
//
name = "radius"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.x;\n\
node.output.y0 = node.y;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = part;\n\
}"
radius_node = graph.add_node(name,x,y,z,1,code)
//
// origin
//
name = "origin"
x = 0
y = -node_offset
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
dx = node.in(0).x - node.x;\n\
dy = node.in(0).y - node.y;\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
if (r > 0) {\n\
nx = dx/r;\n\
ny = dy/r;\n\
node.output.nx0 = nx;\n\
node.output.ny0 = ny;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.r0 = r;\n\
}\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = part;\n\
}"
origin_node = graph.add_node(name,x,y,z,1,code)
//
// warp z
//
name = "warp z"
x = node_offset
y = -node_offset
z = 0
code = "\
x0 = node.input.x0;\n\
y0 = node.input.y0;\n\
r0 = node.input.r0;\n\
nx0 = node.input.nx0;\n\
ny0 = node.input.ny0;\n\
px0 = -ny0;\n\
py0 = nx0;\n\
x1 = node.in(0).x;\n\
y1 = node.in(0).y;\n\
if (r0 > 0) {\n\
x2 = node.x;\n\
y2 = node.y;\n\
dx2 = x2-x1;\n\
dy2 = y2-y1;\n\
r2 = Math.sqrt(dx2*dx2+dy2*dy2);\n\
nx2 = dx2/r2;\n\
ny2 = dy2/r2;\n\
node.x = x1 + r0*nx2;\n\
node.y = y1 + r0*ny2;\n\
x2 = node.x;\n\
y2 = node.y;\n\
dx2 = x2-x1;\n\
dy2 = y2-y1;\n\
r2 = Math.sqrt(dx2*dx2+dy2*dy2);\n\
nx2 = dx2/r2;\n\
ny2 = dy2/r2;\n\
px2 = -ny2;\n\
py2 = nx2;\n\
dx0 = x0-x1;\n\
dy0 = y0-y1;\n\
theta0 = angle(dx0,dy0);\n\
theta2 = angle(dx2,dy2);\n\
theta = theta2 - theta0;\n\
if (theta > 0) {\n\
px0 = -px0;\n\
py0 = -py0;\n\
px2 = -px2;\n\
py2 = -py2;\n\
theta = -theta;\n\
}\n\
x3 = x0 + px0*r0*theta;\n\
y3 = y0 + py0*r0*theta;\n\
}\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
part0 = 'max((X-'+number(x0)+')*'+number(-px0)+'+(Y-'+number(y0)+')*'+number(-py0)+','+part+')';\n\
part1 = 'max((X-'+number(x0)+')*'+number(px0)+'+(Y-'+number(y0)+')*'+number(py0)+','+part+')';\n\
part1 = 'max(-(X-'+number(x3)+')*'+number(px0)+'-(Y-'+number(y3)+')*'+number(py0)+','+part1+')';\n\
Xsub = '('+number(x1)+'+sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+'))*'+number(nx0)+'+'+number(r0*px0)+'*acos(((X-'+number(x1)+')*'+number(nx0)+'+(ytemp-'+number(y1)+')*'+number(ny0)+')/sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+')))*sgn(asin(((X-'+number(x1)+')*'+number(px0)+'+(ytemp-'+number(y1)+')*'+number(py0)+')/sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+')))))';\n\
Ysub = '('+number(y1)+'+sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+'))*'+number(ny0)+'+'+number(r0*py0)+'*acos(((X-'+number(x1)+')*'+number(nx0)+'+(ytemp-'+number(y1)+')*'+number(ny0)+')/sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+')))*sgn(asin(((X-'+number(x1)+')*'+number(px0)+'+(ytemp-'+number(y1)+')*'+number(py0)+')/sqrt((X-'+number(x1)+')*(X-'+number(x1)+')+(ytemp-'+number(y1)+')*(ytemp-'+number(y1)+')))))';\n\
part1 = replace(part1,'X',Xsub);\n\
part1 = replace(part1,'Y',Ysub);\n\
part1 = replace(part1,'ytemp','Y');\n\
part2 = 'max((X-'+number(x3)+')*'+number(px0)+'+(Y-'+number(y3)+')*'+number(py0)+','+part+')';\n\
Xsub = '('+number(x3)+'+((X-'+number(x2)+')*'+number(px2)+'+(ytemp-'+number(y2)+')*'+number(py2)+')*'+number(px0)+'+((X-'+number(x2)+')*'+number(nx2)+'+(ytemp-'+number(y2)+')*'+number(ny2)+')*'+number(nx0)+')';\n\
Ysub = '('+number(y3)+'+((X-'+number(x2)+')*'+number(px2)+'+(Y-'+number(y2)+')*'+number(py2)+')*'+number(py0)+'+((X-'+number(x2)+')*'+number(nx2)+'+(Y-'+number(y2)+')*'+number(ny2)+')*'+number(ny0)+')';\n\
part2 = replace(part2,'X',Xsub);\n\
part2 = replace(part2,'Y',Ysub);\n\
part2 = replace(part2,'ytemp','Y');\n\
node.output['part#'] = 'min('+part2+',min('+part1+','+part0+'))';\n\
}"
warp_node = graph.add_node(name,x,y,z,-1,code)
graph.link(origin_node.index,warp_node.index,"","")
graph.link(radius_node.index,origin_node.index,"","")
graph.update(radius_node.index)
selected_node = radius_node.index
message = "node location?"
}
else if (label == 'menu_thicken') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
part = replace(part,'X','(X-'+number(dx)+')');\n\
part = replace(part,'Y','(Y-'+number(dy)+')');\n\
part = replace(part,'Z','(Z-'+number(dz)+')');\n\
node.output['part#'] = '('+part+')';\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
//
// thicken
//
name = "thicken"
x = node_offset
y = node_offset
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
node.output['part#'] = '(('+part+')-'+number(r)+'/10.0)';\n\
}"
thicken = graph.add_node(name,x,y,z,-1,code)
graph.link(origin.index,thicken.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_thin') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
part = replace(part,'X','(X-'+number(dx)+')');\n\
part = replace(part,'Y','(Y-'+number(dy)+')');\n\
part = replace(part,'Z','(Z-'+number(dz)+')');\n\
node.output['part#'] = '('+part+')';\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
//
// thin
//
name = "thin"
x = node_offset
y = node_offset
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
node.output['part#'] = '(('+part+')+'+number(r)+'/10.0)';\n\
}"
thin = graph.add_node(name,x,y,z,-1,code)
graph.link(origin.index,thin.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_amplitude') {
//
// amplitude
//
name = "amplitude"
x = 0
y = 0
z = 0
code = "\
scale = 10; // set amplitude scale factor\n\
//\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = '('+scale+'*('+part+'))';\n\
}"
amplitude = graph.add_node(name,x,y,z,-1,code)
graph.update(amplitude.index)
selected_node = amplitude.index
message = "node location?"
}
else if (label == 'menu_shell') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
part = replace(part,'X','(X-'+number(dx)+')');\n\
part = replace(part,'Y','(Y-'+number(dy)+')');\n\
part = replace(part,'Z','(Z-'+number(dz)+')');\n\
node.output['part#'] = '('+part+')';\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
//
// shell
//
name = "shell"
x = node_offset
y = node_offset
z = 0
code = "\
part = node.input['part0'];\n\
if (part != undefined) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
node.output['part#'] = 'max('+part+',-('+part+')-('+number(r)+'/10.0))';\n\
}"
shell = graph.add_node(name,x,y,z,-1,code)
graph.link(origin.index,shell.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
else if (label == 'menu_loft z') {
name = "loft z"
x = 0
y = 0
z = 0
code = "\
part0 = node.input['part0'];\n\
part1 = node.input['part1'];\n\
if ((part0 != undefined) && (part1 != undefined)) {\n\
z0 = node.in(0).z;\n\
z1 = node.z;\n\
z2 = node.in(1).z;\n\
if (z0 < z2) {\n\
zbot = z0;\n\
ztop = z2;\n\
}\n\
else {\n\
zbot = z2;\n\
ztop = z0;\n\
}\n\
part0 = replace(part0,'Z',number(z0));\n\
part1 = replace(part1,'Z',number(z2));\n\
alpha = 0.5;\n\
part = '(((Z-'+number(z1)+')*(Z-'+number(z2)+')/'+number((z0-z1)*(z0-z2))+'+0.5*(Z-'+number(z0)+')*(Z-'+number(z2)+')/'+number((z1-z0)*(z1-z2))+')*('+part0+')+(0.5*(Z-'+number(z0)+')*(Z-'+number(z2)+')/'+number((z1-z0)*(z1-z2))+'+(Z-'+number(z0)+')*(Z-'+number(z1)+')/'+number((z2-z0)*(z2-z1))+')*('+part1+'))';\n\
part = 'max('+part+',('+number(zbot)+'-Z))';\n\
part = 'max('+part+',(Z-'+number(ztop)+'))';\n\
node.output['part#'] = part;\n\
}"
loft = graph.add_node(name,x,y,z,-1,code)
graph.update(loft.index)
selected_node = loft.index
message = "node location?"
}
else if (label == 'menu_morph') {
name = "morph"
x = 0
y = 0
z = 0
code = "\
part0 = node.input['part0'];\n\
part1 = node.input['part1'];\n\
if ((part0 != undefined) && (part1 != undefined)) {\n\
dx0 = node.x - node.in(0).x;\n\
dy0 = node.y - node.in(0).y;\n\
dz0 = node.z - node.in(0).z;\n\
r0 = Math.sqrt(dx0*dx0+dy0*dy0+dz0*dz0);\n\
part0 = replace(part0,'X','(X-'+number(dx0)+')');\n\
part0 = replace(part0,'Y','(Y-'+number(dy0)+')');\n\
part0 = replace(part0,'Z','(Z-'+number(dz0)+')');\n\
dx1 = node.x - node.in(1).x;\n\
dy1 = node.y - node.in(1).y;\n\
dz1 = node.z - node.in(1).z;\n\
r1 = Math.sqrt(dx1*dx1+dy1*dy1+dz1*dz1);\n\
part1 = replace(part1,'X','(X-'+number(dx1)+')');\n\
part1 = replace(part1,'Y','(Y-'+number(dy1)+')');\n\
part1 = replace(part1,'Z','(Z-'+number(dz1)+')');\n\
if (r0 < r1)\n\
alpha = 1-0.5*r0/r1;\n\
else\n\
alpha = 0.5*r1/r0;\n\
node.output['part#'] = '('+number(alpha)+'*('+part0+')+('+number(1-alpha)+')*('+part1+'))';\n\
}"
morph = graph.add_node(name,x,y,z,-1,code)
graph.update(morph.index)
selected_node = morph.index
message = "node location?"
}
else if (label == 'menu_fillet') {
//
// fillet
//
name = "fillet"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
for (var n in Object.keys(node.input)) {\n\
node.output['part'+n] = node.input[Object.keys(node.input)[n]];\n\
}"
fillet_node = graph.add_node(name,x,y,z,1,code)
//
// scale
//
name = "scale"
x = node_offset
y = node_offset
z = node_offset
code = "\
part0 = node.input['part0'];\n\
part1 = node.input['part1'];\n\
for (var n in Object.keys(node.input)) {\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
s = r;\n\
//\n\
//s=1 // uncomment to fix scale\n\
//\n\
if (n == 0)\n\
part = node.input[Object.keys(node.input)[n]];\n\
else {\n\
new_part = node.input[Object.keys(node.input)[n]];\n\
joint_part = 'min('+part+','+new_part+')';\n\
fillet_part = '(sqrt(abs('+part+'))+sqrt(abs('+new_part+'))-'+number(s)+')';\n\
part = 'min('+joint_part+','+fillet_part+')';\n\
node.output['part#'] = part;\n\
}\n\
}"
scale = graph.add_node(name,x,y,z,1,code)
graph.link(fillet_node.index,scale.index,"","")
graph.update(fillet_node.index)
selected_node = fillet_node.index
message = "node location?"
}
else if (label == 'menu_(r)epel') {
//
// repel
//
name = "repel"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = '('+part+')';\n\
}"
repel = graph.add_node(name,x,y,z,1,code)
//
// distance
//
name = "distance"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
Xsub = '('+number(x0)+'+(X-'+number(x0)+')*(1-'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')+(ztemp-'+number(z0)+')*(ztemp-'+number(z0)+'))/'+number(r)+')))';\n\
Ysub = '('+number(y0)+'+(Y-'+number(y0)+')*(1-'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')+(ztemp-'+number(z0)+')*(ztemp-'+number(z0)+'))/'+number(r)+')))';\n\
Zsub = '('+number(z0)+'+(Z-'+number(z0)+')*(1-'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')+(Z-'+number(z0)+')*(Z-'+number(z0)+'))/'+number(r)+')))';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'Z',Zsub);\n\
part = replace(part,'ytemp','Y');\n\
part = replace(part,'ztemp','Z');\n\
node.output['part#'] = '('+part+')';\n\
}"
distance = graph.add_node(name,x,y,z,1,code)
graph.link(repel.index,distance.index,"","")
graph.update(repel.index)
selected_node = repel.index
message = "node location?"
}
else if (label == 'menu_(a)ttract') {
//
// attract
//
name = "attract"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output['part#'] = '('+part+')';\n\
}"
attract = graph.add_node(name,x,y,z,1,code)
//
// distance
//
name = "distance"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
r = Math.sqrt(dx*dx+dy*dy+dz*dz);\n\
x0 = node.in(0).x;\n\
y0 = node.in(0).y;\n\
z0 = node.in(0).z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
Xsub = '('+number(x0)+'+(X-'+number(x0)+')*(1+'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(ytemp-'+number(y0)+')*(ytemp-'+number(y0)+')+(ztemp-'+number(z0)+')*(ztemp-'+number(z0)+'))/'+number(r)+')))';\n\
Ysub = '('+number(y0)+'+(Y-'+number(y0)+')*(1+'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')+(ztemp-'+number(z0)+')*(ztemp-'+number(z0)+'))/'+number(r)+')))';\n\
Zsub = '('+number(z0)+'+(Z-'+number(z0)+')*(1+'+number(r)+'*exp(-((X-'+number(x0)+')*(X-'+number(x0)+')+(Y-'+number(y0)+')*(Y-'+number(y0)+')+(Z-'+number(z0)+')*(Z-'+number(z0)+'))/'+number(r)+')))';\n\
part = replace(part,'X',Xsub);\n\
part = replace(part,'Y',Ysub);\n\
part = replace(part,'Z',Zsub);\n\
part = replace(part,'ytemp','Y');\n\
part = replace(part,'ztemp','Z');\n\
node.output['part#'] = '('+part+')';\n\
}"
distance = graph.add_node(name,x,y,z,1,code)
graph.link(attract.index,distance.index,"","")
graph.update(attract.index)
selected_node = attract.index
message = "node location?"
}
else if (label == 'menu_(l)inear array') {
name = "linear array"
x = 0
y = 0
z = 0
code = "\
n = 4; // number of array elements\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
array_part = part;\n\
dx = node.x - node.in(0).x;\n\
dy = node.y - node.in(0).y;\n\
dz = node.z - node.in(0).z;\n\
//\n\
//dx = 0.1; // uncomment to set x step\n\
//dy = 0.1; // uncomment to set y step\n\
//dz = 0.1; // uncomment to set z step\n\
//\n\
for (i=1;i<n;i++) {\n\
new_part = part;\n\
new_part = replace(new_part,'X','(X-'+number(i*dx)+')');\n\
new_part = replace(new_part,'Y','(Y-'+number(i*dy)+')');\n\
new_part = replace(new_part,'Z','(Z-'+number(i*dz)+')');\n\
array_part = 'min('+array_part+','+new_part+')';\n\
}\n\
node.output['part#'] = '('+array_part+')';\n\
}"
array = graph.add_node(name,x,y,z,1,code)
graph.update(array.index)
selected_node = array.index
message = "node location?"
}
else if (label == 'menu_ra(d)ial array') {
//
// origin
//
name = "origin"
x = 0
y = 0
z = 0
code = "\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.x;\n\
node.output.y0 = node.y;\n\
node.output.z0 = node.z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.in(0).x;\n\
node.output.yin = node.in(0).y;\n\
node.output.zin = node.in(0).z;\n\
node.output['part#'] = node.input['part0'];\n\
}"
origin = graph.add_node(name,x,y,z,1,code)
//
// start
//
name = "start"
x = 1.5*node_offset
y = 0
z = 0
code = "\
dx = node.x - node.input.x0;\n\
dy = node.y - node.input.y0;\n\
theta = angle(dx,dy);\n\
//\n\
// uncomment to fix angle\n\
//\n\
//theta = 45*rad_deg;\n\
//\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
if (r > 0) {\n\
node.x = node.input['x0'] + r*Math.cos(theta);\n\
node.y = node.input['y0'] + r*Math.sin(theta);\n\
}\n\
node.z = node.in(0).z;\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.r = r;\n\
node.output.theta1 = theta;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.input.xin;\n\
node.output.yin = node.input.yin;\n\
node.output.zin = node.input.zin;\n\
node.output['part#'] = node.input['part0'];\n\
}"
start = graph.add_node(name,x,y,z,1,code)
//
// finish
//
name = "finish"
x = node_offset
y = node_offset
z = node_offset
code = "\
dx = node.x - node.input.x0;\n\
dy = node.y - node.input.y0;\n\
theta = angle(dx,dy);\n\
//\n\
// uncomment to fix angle\n\
//\n\
//theta = 45*rad_deg;\n\
//\n\
r = Math.sqrt(dx*dx+dy*dy);\n\
if (r > 0) {\n\
node.x = node.input['x0'] + node.input['r']*Math.cos(theta);\n\
node.y = node.input['y0'] + node.input['r']*Math.sin(theta);\n\
}\n\
//\n\
node.out(0).x = node.x + node.out(0).x - node.last.x;\n\
node.out(0).y = node.y + node.out(0).y - node.last.y;\n\
node.out(0).z = node.z + node.out(0).z - node.last.z;\n\
node.output.x0 = node.input.x0;\n\
node.output.y0 = node.input.y0;\n\
node.output.z0 = node.input.z0;\n\
node.output.r = node.input.r;\n\
node.output.theta1 = node.input.theta1;\n\
node.output.theta2 = theta;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
node.output.xin = node.input.xin;\n\
node.output.yin = node.input.yin;\n\
node.output.zin = node.input.zin;\n\
node.output['part#'] = node.input['part0'];\n\
}"
finish = graph.add_node(name,x,y,z,-1,code)
//
// radial array
//
name = "radial array"
x = 0
y = 0
z = node_offset
code = "\
node.x = Number(node.input['x0']);\n\
node.y = Number(node.input['y0']);\n\
node.z = node.in(0).z;\n\
part = node.input['part0'];\n\
if (part != undefined) {\n\
//\n\
n = 4; // number of radial copies\n\
//\n\
xin = Number(node.input['xin']);\n\
yin = Number(node.input['yin']);\n\
zin = Number(node.input['zin']);\n\
x0 = Number(node.input['x0']);\n\
y0 = Number(node.input['y0']);\n\
z0 = Number(node.input['z0']);\n\
r = Number(node.input['r']);\n\
theta1 = Number(node.input['theta1']);\n\
theta2 = Number(node.input['theta2']);\n\
z2 = node.z;\n\
array_part = '1';\n\
for (var i = 0; i < n; ++i) {\n\
new_part = part;\n\
theta = theta1 + i*(theta2-theta1)/(n-1.0);\n\
//theta = theta1 + i*(theta2-theta1)/(n); // uncomment to skip last copy\n\
z = z0 + i*(z2-z0)/(n-1.0);\n\
x = x0 + r*Math.cos(theta);\n\
y = y0 + r*Math.sin(theta);\n\
Zsub = '('+number(zin)+'+Z-'+number(z)+')';\n\
new_part = replace(new_part,'Z',Zsub);\n\
Xsub = '('+number(xin)+'+'+number(Math.cos(theta))+'*(X-'+number(x)+')+'+number(Math.sin(theta))+'*(ytemp-'+number(y)+'))';\n\
Ysub = '('+number(yin)+'-'+number(Math.sin(theta))+'*(X-'+number(x)+')+'+number(Math.cos(theta))+'*(Y-'+number(y)+'))';\n\
new_part = replace(new_part,'X',Xsub);\n\
new_part = replace(new_part,'Y',Ysub);\n\
new_part = replace(new_part,'ytemp','Y');\n\
array_part = 'min('+array_part+','+new_part+')';\n\
}\n\
node.output['part#'] = array_part;\n\
}"
radial = graph.add_node(name,x,y,z,-1,code)
graph.link(finish.index,radial.index,"","")
graph.link(start.index,finish.index,"","")
graph.link(origin.index,start.index,"","")
graph.update(origin.index)
selected_node = origin.index
message = "node location?"
}
//
// edit
//
else if (label == 'menu_(n)ode') {
msg("click node to edit")
}
else if (label == 'menu_(l)ink') {
message = "node to link from?"
msg(message)
}
else if (label == 'menu_(f)ixed link') {
message = "node to fix link from?"
msg(message)
}
else if (label == 'menu_unlink node') {
message = "node to unlink input?"
msg(message)
}
else if (label == 'menu_(d)elete node') {
message = "node to delete? (can also del highlighted node)"
msg(message)
}
else if (label == 'menu_(c)ut nodes') {
message = "parent node to cut? (can also shift-del)"
msg(message)
}
else if (label == 'menu_(m)ove nodes') {
message = "parent node to move? (can also shift-drag)"
msg(message)
}
else if (label == 'menu_(u)ndo') {
last_last_temp = graph.last_last_undo_string
graph.fromstring(graph.last_undo_string)
graph.evaluate()
graph.render()
graph.last_undo_string = last_last_temp
msg('undo')
}
else if (label == 'menu_align (x)') {
message = "node to align x?"
msg(message)
}
else if (label == 'menu_align (y)') {
message = "node to align y?"
msg(message)
}
else if (label == 'menu_align (z)') {
message = "node to align z?"
msg(message)
}
else if (label == 'menu_align xy (2)') {
message = "node to align xy?"
msg(message)
}
else if (label == 'menu_align xyz (3)') {
message = "node to align xyz?"
msg(message)
}
else if (label == 'menu_(g)rid size') {
get_grid()
}
//
// view
//
else if (label == 'menu_fit') {
;
}
else if (label == 'menu_(2)D') {
panel_scale = 2
view_zmin = 0
view_dz = 0
panel_xy.setAttribute("width",panel_scale*panel_size)
panel_xy.setAttribute("height",panel_scale*panel_size)
document.getElementById("xy").setAttribute("display","none")
document.getElementById("xz").setAttribute("display","none")
document.getElementById("zy").setAttribute("display","none")
document.getElementById("xyz").setAttribute("display","none")
document.getElementById("hmid_line").setAttribute("display","none")
document.getElementById("vmid_line").setAttribute("display","none")
graph.render()
}
else if (label == 'menu_(3)D') {
panel_scale = 1
view_zmin = -view_dx/2
view_dz = view_dx
panel_xy.setAttribute("width",panel_scale*panel_size)
panel_xy.setAttribute("height",panel_scale*panel_size)
document.getElementById("xy").setAttribute("display","")
document.getElementById("xz").setAttribute("display","")
document.getElementById("zy").setAttribute("display","")
document.getElementById("xyz").setAttribute("display","")
document.getElementById("hmid_line").setAttribute("display","")
document.getElementById("vmid_line").setAttribute("display","")
graph.render()
}
else if (label == 'menu_(up) zoom in') {
xpos = world_x
ypos = world_y
zpos = world_z
if (world_x != ' ')
view_xmin = view_xmin + zoom_scale*(world_x-view_xmin)
else
view_xmin = view_xmin + zoom_scale*view_dx/2.0
if (world_y != ' ')
view_ymin = view_ymin + zoom_scale*(world_y-view_ymin)
else
view_ymin = view_ymin + zoom_scale*view_dy/2.0
if (world_z != ' ')
view_zmin = view_zmin + zoom_scale*(world_z-view_zmin)
else
view_zmin = view_zmin + zoom_scale*view_dz/2.0
view_dx = view_dx*(1-zoom_scale)
view_dy = view_dy*(1-zoom_scale)
view_dz = view_dz*(1-zoom_scale)
graph.redraw()
redraw_axes()
graph.render()
world_x = xpos
world_y = ypos
world_z = zpos
}
else if (label == 'menu_(down) zoom out') {
xpos = world_x
ypos = world_y
zpos = world_z
if (world_x != ' ')
view_xmin = view_xmin - zoom_scale*(world_x-view_xmin)
else
view_xmin = view_xmin - zoom_scale*view_dx/2.0
if (world_y != ' ')
view_ymin = view_ymin - zoom_scale*(world_y-view_ymin)
else
view_ymin = view_ymin - zoom_scale*view_dy/2.0
if (world_z != ' ')
view_zmin = view_zmin - zoom_scale*(world_z-view_zmin)
else
view_zmin = view_zmin - zoom_scale*view_dz/2.0
view_dx = view_dx*(1+zoom_scale)
view_dy = view_dy*(1+zoom_scale)
view_dz = view_dz*(1+zoom_scale)
graph.redraw()
redraw_axes()
graph.render()
world_x = xpos
world_y = ypos
world_z = zpos
}
else if (label == 'menu_pan') {
msg("click and drag background to pan")
}
else if (label == 'menu_(l)imits') {
get_view()
}
else if (label == 'menu_(r)esolution') {
get_resolution()
graph.render()
}
else if (label == 'menu_(e)xpression') {
alert(graph.evaluate())
}
//
// file
//
else if (label == 'menu_(o)pen .fab') {
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {fab_list_response(xmlhttp); };
xmlhttp.open('POST','/list_files',true)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("");
}
else if (label == 'menu_(s)ave .fab') {
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createTextNode(".fab file name to save?: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("size","4")
element.setAttribute("value",file_name)
element.setAttribute("id","file_name_input")
element.setAttribute("onkeydown","{if (event.keyCode == 13) {if ((file_name_input.value != '') && (file_name_input.value != null)) {file_name = file_name_input.value; if (file_name.indexOf('.fab') != -1) {file_name = file_name.slice(0,file_name.length-4);} str = graph.to_string(); xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange = function() {post_response(xmlhttp);}; xmlhttp.open('POST','/save_graph/'+file_name+'.fab/',true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.send(str);} edit_panel.removeChild(edit_panel_div);}}")
element.setAttribute("autofocus","autofocus")
edit_panel_div.appendChild(element)
element = document.createTextNode(" (enter to submit)")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
else if (label == 'menu_export .(m)ath') {
graph.evaluate()
pixels_per_mm = resolution / (view_dx * graph.units)
if (graph.expression.indexOf("undefined") == -1) {
if (view_dz == 0)
slices = 1
else
slices = 255
render_msg = "{"+graph.mode+"}{"+graph.units+"}{"+view_dx+"}{"+view_dy+"}{"+view_dz+"}{"+view_xmin+"}{"+view_ymin+"}{"+view_zmin+"}{"+view_xrot*rad_deg+"}{"+view_yrot*rad_deg+"}{"+view_zrot*rad_deg+"}{"+pixels_per_mm+"}{"+slices+"}{"+graph.expression+"}"
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
edit_panel.removeChild(edit_panel_div)
edit_panel_div = document.createElement("div")
edit_panel_div.setAttribute("id","edit_panel_div")
element = document.createTextNode(".math file name to save?: ")
edit_panel_div.appendChild(element)
element = document.createElement("input")
element.setAttribute("type","text")
element.setAttribute("size","4")
element.setAttribute("value",file_name)
element.setAttribute("id","file_name_input")
element.setAttribute("onkeydown","{if (event.keyCode == 13) {if ((file_name_input.value != '') && (file_name_input.value != null)) {file_name = file_name_input.value; if (file_name.indexOf('.math') != -1) {file_name = file_name.slice(0,file_name.length-5);} str = graph.to_string(); xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange = function() {post_response(xmlhttp);}; xmlhttp.open('POST','/save_math/'+file_name+'.math/',true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.send(render_msg);} edit_panel.removeChild(edit_panel_div);}}")
element.setAttribute("autofocus","autofocus")
edit_panel_div.appendChild(element)
element = document.createTextNode(" (enter to submit)")
edit_panel_div.appendChild(element)
edit_panel.appendChild(edit_panel_div)
}
else {
msg("expression undefined")
}
}
else if (label == 'menu_export .s(v)g') {
alert('export svg')
}
else if (label == 'menu_export .s(t)l') {
alert('export stl')
}
else if (label == 'menu_export .(p)ng') {
alert('export png')
}
//
// CAM
//
else if (label == 'menu_(f)abricate') {
graph.fabricate()
}
else if (label == 'menu_(u)nits') {
get_units()
}
//
// command not implemented
//
else {
msg(label+' not yet implemented')
}
rm_menu()
}
function rm_menu() {
//
// remove menu
//
for (i = 0; i < menu_names.length; ++i) {
element = document.getElementById(menu_names[i])
document.getElementById("svg").removeChild(element)
}
menu_names = ""
}
function text(x,y,size,fill,id,string) {
//
// add text
//
var new_txt = document.createElementNS(svgNS,"text");
new_txt.setAttribute("id",id)
new_txt.setAttribute("x",x)
new_txt.setAttribute("y",y)
new_txt.setAttribute("font-size",size);
new_txt.setAttribute("font-family","sans-serif");
new_txt.setAttribute("fill",fill)
var new_txt_node = document.createTextNode(string)
new_txt.appendChild(new_txt_node);
document.getElementById("svg").appendChild(new_txt);
return new_txt
}
function CBA(x,y,size) {
//
// add CBA logo
//
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x)
new_rect.setAttribute("y",y)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x+1.4*size)
new_rect.setAttribute("y",y)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x+2.8*size)
new_rect.setAttribute("y",y)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x)
new_rect.setAttribute("y",y-1.4*size)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x+2.8*size)
new_rect.setAttribute("y",y-1.4*size)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x+1.4*size)
new_rect.setAttribute("y",y-2.8*size)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_rect = document.createElementNS(svgNS,"rect");
new_rect.setAttribute("width",size)
new_rect.setAttribute("height",size)
new_rect.setAttribute("x",x+2.8*size)
new_rect.setAttribute("y",y-2.8*size)
new_rect.setAttribute("fill","blue")
document.getElementById("svg").appendChild(new_rect)
var new_circ = document.createElementNS(svgNS,"circle");
new_circ.setAttribute("r",size/2)
new_circ.setAttribute("cx",x+size/2)
new_circ.setAttribute("cy",y+size/2-2.8*size)
new_circ.setAttribute("fill","red")
document.getElementById("svg").appendChild(new_circ)
var new_circ = document.createElementNS(svgNS,"circle");
new_circ.setAttribute("r",size/2)
new_circ.setAttribute("cx",x+size/2+1.4*size)
new_circ.setAttribute("cy",y+size/2-1.4*size)
new_circ.setAttribute("fill","red")
document.getElementById("svg").appendChild(new_circ)
}
function redraw_axes() {
axis_xy_x.setAttribute("x1",xpanel_xy(0))
axis_xy_x.setAttribute("y1",ypanel_xy(0))
axis_xy_x.setAttribute("x2",xpanel_xy(1))
axis_xy_x.setAttribute("y2",ypanel_xy(0))
axis_xy_y.setAttribute("x1",xpanel_xy(0))
axis_xy_y.setAttribute("y1",ypanel_xy(0))
axis_xy_y.setAttribute("x2",xpanel_xy(0))
axis_xy_y.setAttribute("y2",ypanel_xy(1))
axis_xz_x.setAttribute("x1",xpanel_xz(0))
axis_xz_x.setAttribute("y1",ypanel_xz(0))
axis_xz_x.setAttribute("x2",xpanel_xz(1))
axis_xz_x.setAttribute("y2",ypanel_xz(0))
axis_xz_z.setAttribute("x1",xpanel_xz(0))
axis_xz_z.setAttribute("y1",ypanel_xz(0))
axis_xz_z.setAttribute("x2",xpanel_xz(0))
axis_xz_z.setAttribute("y2",ypanel_xz(1))
axis_zy_z.setAttribute("x1",xpanel_zy(0))
axis_zy_z.setAttribute("y1",ypanel_zy(0))
axis_zy_z.setAttribute("x2",xpanel_zy(1))
axis_zy_z.setAttribute("y2",ypanel_zy(0))
axis_zy_y.setAttribute("x1",xpanel_zy(0))
axis_zy_y.setAttribute("y1",ypanel_zy(0))
axis_zy_y.setAttribute("x2",xpanel_zy(0))
axis_zy_y.setAttribute("y2",ypanel_zy(1))
origin = xypanel_xyz(0,0,0)
xaxis = xypanel_xyz(1,0,0)
yaxis = xypanel_xyz(0,1,0)
zaxis = xypanel_xyz(0,0,1)
axis_xyz_x.setAttribute("x1",origin[0])
axis_xyz_x.setAttribute("y1",origin[1])
axis_xyz_x.setAttribute("x2",xaxis[0])
axis_xyz_x.setAttribute("y2",xaxis[1])
axis_xyz_y.setAttribute("x1",origin[0])
axis_xyz_y.setAttribute("y1",origin[1])
axis_xyz_y.setAttribute("x2",yaxis[0])
axis_xyz_y.setAttribute("y2",yaxis[1])
axis_xyz_z.setAttribute("x1",origin[0])
axis_xyz_z.setAttribute("y1",origin[1])
axis_xyz_z.setAttribute("x2",zaxis[0])
axis_xyz_z.setAttribute("y2",zaxis[1])
}
function init() {
//
// init UI
//
var w = menu_width
var h = menu_height
CBA(0,.5*text_height,text_font_size/3.5)
text(.9*text_height,.6*text_height,text_font_size,"black","prompt","fab ("+date+")")
text(6.5*text_height,.6*text_height,text_font_size,"black","message","")
button(0*w,h,w,h,"(s)hapes","shapes_menu(evt)")
button(1*w,h,w,h,"(o)perators","operators_menu(evt)")
button(2*w,h,w,h,"(t)ransforms","transform_menu(evt)")
button(3*w,h,w,h,"(e)dit","edit_menu(evt)")
button(4*w,h,w,h,"(v)iew","view_menu(evt)")
button(5*w,h,w,h,"(f)ile","file_menu(evt)")
button(6*w,h,w,h,"(library)","library_menu(evt)")
button(7*w,h,w,h,"(solve)","solve_menu(evt)")
button(8*w,h,w,h,"(C)AM","CAM_menu(evt)")
button(9*w,h,w,h,"(help)","help_menu(evt)")
//
// add drawing panels
//
svg = document.getElementById("svg")
var panel_xz = document.createElementNS(svgNS,"svg")
panel_xz.setAttribute("onmousedown","panel_down_xz(evt)")
panel_xz.setAttribute("onmouseup","panel_up_xz(evt)")
panel_xz.setAttribute("onmousemove","move_xz(evt)")
panel_xz.setAttribute("onmouseout","msg('')")
panel_xz.setAttribute("id","panel_xz")
panel_xz.setAttribute("x",0)
panel_xz.setAttribute("y",2*menu_height+panel_size)
panel_xz.setAttribute("width",panel_size)
panel_xz.setAttribute("height",panel_size)
panel_xz.setAttribute("preserveAspectRatio","none")
panel_xz.setAttribute("viewBox",panel_xmin+" "+panel_zmin+" "+panel_xwidth+" "+panel_zwidth)
var rect = document.createElementNS(svgNS,"rect");
rect.setAttribute("x",-panel_size)
rect.setAttribute("y",-panel_size)
rect.setAttribute("width",2*panel_size)
rect.setAttribute("height",2*panel_size)
rect.setAttribute("fill",panel_color)
panel_xz.appendChild(rect)
svg.appendChild(panel_xz)
var panel_zy = document.createElementNS(svgNS,"svg")
panel_zy.setAttribute("onmousedown","panel_down_zy(evt)")
panel_zy.setAttribute("onmouseup","panel_up_zy(evt)")
panel_zy.setAttribute("onmousemove","move_zy(evt)")
panel_zy.setAttribute("onmouseout","msg('')")
panel_zy.setAttribute("id","panel_zy")
panel_zy.setAttribute("x",panel_size)
panel_zy.setAttribute("y",2*menu_height)
panel_zy.setAttribute("width",panel_size)
panel_zy.setAttribute("height",panel_size)
panel_zy.setAttribute("preserveAspectRatio","none")
panel_zy.setAttribute("viewBox",panel_zmin+" "+panel_ymin+" "+panel_zwidth+" "+panel_ywidth)
var rect = document.createElementNS(svgNS,"rect");
rect.setAttribute("x",-panel_size)
rect.setAttribute("y",-panel_size)
rect.setAttribute("width",2*panel_size)
rect.setAttribute("height",2*panel_size)
rect.setAttribute("fill",panel_color)
panel_zy.appendChild(rect)
svg.appendChild(panel_zy)
var panel_xyz = document.createElementNS(svgNS,"svg")
panel_xyz.setAttribute("onmousedown","panel_down_xyz(evt)")
panel_xyz.setAttribute("onmousemove","move_xyz(evt)")
panel_xyz.setAttribute("onmouseup","panel_up_xyz(evt)")
panel_xyz.setAttribute("onmouseout","msg('')")
panel_xyz.setAttribute("id","panel_xyz")
panel_xyz.setAttribute("x",panel_size)
panel_xyz.setAttribute("y",2*menu_height+panel_size)
panel_xyz.setAttribute("width",panel_size)
panel_xyz.setAttribute("height",panel_size)
panel_xyz.setAttribute("preserveAspectRatio","none")
panel_xyz.setAttribute("viewBox",panel_xmin+" "+panel_ymin+" "+panel_xwidth+" "+panel_ywidth)
panel_xyz.setAttribute("viewBox","0 0 "+panel_size+" "+panel_size)
var rect = document.createElementNS(svgNS,"rect");
rect.setAttribute("x",-panel_size)
rect.setAttribute("y",-panel_size)
rect.setAttribute("width",2*panel_size)
rect.setAttribute("height",2*panel_size)
rect.setAttribute("fill",panel_color)
panel_xyz.appendChild(rect)
svg.appendChild(panel_xyz)
var panel_xy = document.createElementNS(svgNS,"svg")
panel_xy.setAttribute("onmousedown","panel_down_xy(evt)")
panel_xy.setAttribute("onmouseup","panel_up_xy(evt)")
panel_xy.setAttribute("onmousemove","move_xy(evt)")
panel_xy.setAttribute("onmouseout","msg('')")
panel_xy.setAttribute("id","panel_xy")
panel_xy.setAttribute("x",0)
panel_xy.setAttribute("y",2*menu_height)
panel_xy.setAttribute("width",panel_size)
panel_xy.setAttribute("height",panel_size)
panel_xy.setAttribute("preserveAspectRatio","none")
panel_xy.setAttribute("viewBox",panel_xmin+" "+panel_ymin+" "+panel_xwidth+" "+panel_ywidth)
var rect = document.createElementNS(svgNS,"rect");
rect.setAttribute("x",-panel_size)
rect.setAttribute("y",-panel_size)
rect.setAttribute("width",2*panel_size)
rect.setAttribute("height",2*panel_size)
rect.setAttribute("fill",panel_color)
panel_xy.appendChild(rect)
//document.addEventListener('DOMMouseScroll', msg(' '), false)
svg.appendChild(panel_xy)
//
// add render images
//
image_xy = document.getElementById("image_xy")
image_xy.setAttribute("x",-panel_size/2.0)
image_xy.setAttribute("y",-panel_size/2.0)
image_xy.setAttribute("width",panel_size)
image_xy.setAttribute("height",panel_size)
panel_xy.insertBefore(image_xy,panel_xy.childNodes[1])
image_xz = document.getElementById("image_xz")
image_xz.setAttribute("x",-panel_size/2.0)
image_xz.setAttribute("y",-panel_size/2.0)
image_xz.setAttribute("width",panel_size)
image_xz.setAttribute("height",panel_size)
panel_xz.insertBefore(image_xz,panel_xz.childNodes[1])
image_zy = document.getElementById("image_zy")
image_zy.setAttribute("x",-panel_size/2.0)
image_zy.setAttribute("y",-panel_size/2.0)
image_zy.setAttribute("width",panel_size)
image_zy.setAttribute("height",panel_size)
panel_zy.insertBefore(image_zy,panel_zy.childNodes[1])
image_xyz = document.getElementById("image_xyz")
image_xyz.setAttribute("x",0)
image_xyz.setAttribute("y",0)
image_xyz.setAttribute("width",panel_size)
image_xyz.setAttribute("height",panel_size)
panel_xyz.insertBefore(image_xyz,panel_xyz.childNodes[1])
//
// draw axes
//
var axis_xy_x = document.createElementNS(svgNS,"line")
axis_xy_x.setAttribute("id","axis_xy_x")
axis_xy_x.setAttribute("x1",xpanel_xy(0))
axis_xy_x.setAttribute("y1",ypanel_xy(0))
axis_xy_x.setAttribute("x2",xpanel_xy(1))
axis_xy_x.setAttribute("y2",ypanel_xy(0))
axis_xy_x.setAttribute("stroke-width",axis_size)
axis_xy_x.setAttribute("stroke","red")
panel_xy.appendChild(axis_xy_x)
var axis_xy_y = document.createElementNS(svgNS,"line")
axis_xy_y.setAttribute("id","axis_xy_y")
axis_xy_y.setAttribute("x1",xpanel_xy(0))
axis_xy_y.setAttribute("y1",ypanel_xy(0))
axis_xy_y.setAttribute("x2",xpanel_xy(0))
axis_xy_y.setAttribute("y2",ypanel_xy(1))
axis_xy_y.setAttribute("stroke-width",axis_size)
axis_xy_y.setAttribute("stroke","green")
panel_xy.appendChild(axis_xy_y)
var axis_xz_x = document.createElementNS(svgNS,"line")
axis_xz_x.setAttribute("id","axis_xz_x")
axis_xz_x.setAttribute("x1",xpanel_xz(0))
axis_xz_x.setAttribute("y1",ypanel_xz(0))
axis_xz_x.setAttribute("x2",xpanel_xz(1))
axis_xz_x.setAttribute("y2",ypanel_xz(0))
axis_xz_x.setAttribute("stroke-width",axis_size)
axis_xz_x.setAttribute("stroke","red")
panel_xz.appendChild(axis_xz_x)
var axis_xz_z = document.createElementNS(svgNS,"line")
axis_xz_z.setAttribute("id","axis_xz_z")
axis_xz_z.setAttribute("x1",xpanel_xz(0))
axis_xz_z.setAttribute("y1",ypanel_xz(0))
axis_xz_z.setAttribute("x2",xpanel_xz(0))
axis_xz_z.setAttribute("y2",ypanel_xz(1))
axis_xz_z.setAttribute("stroke-width",axis_size)
axis_xz_z.setAttribute("stroke","blue")
panel_xz.appendChild(axis_xz_z)
var axis_zy_z = document.createElementNS(svgNS,"line")
axis_zy_z.setAttribute("id","axis_zy_z")
axis_zy_z.setAttribute("x1",xpanel_zy(0))
axis_zy_z.setAttribute("y1",ypanel_zy(0))
axis_zy_z.setAttribute("x2",xpanel_zy(1))
axis_zy_z.setAttribute("y2",ypanel_zy(0))
axis_zy_z.setAttribute("stroke-width",axis_size)
axis_zy_z.setAttribute("stroke","blue")
panel_zy.appendChild(axis_zy_z)
var axis_zy_y = document.createElementNS(svgNS,"line")
axis_zy_y.setAttribute("id","axis_zy_y")
axis_zy_y.setAttribute("x1",xpanel_zy(0))
axis_zy_y.setAttribute("y1",ypanel_zy(0))
axis_zy_y.setAttribute("x2",xpanel_zy(0))
axis_zy_y.setAttribute("y2",ypanel_zy(1))
axis_zy_y.setAttribute("stroke-width",axis_size)
axis_zy_y.setAttribute("stroke","green")
panel_zy.appendChild(axis_zy_y)
origin = xypanel_xyz(0,0,0)
xaxis = xypanel_xyz(1,0,0)
yaxis = xypanel_xyz(0,1,0)
zaxis = xypanel_xyz(0,0,1)
var axis_xyz_x = document.createElementNS(svgNS,"line")
axis_xyz_x.setAttribute("id","axis_xyz_x")
axis_xyz_x.setAttribute("x1",origin[0])
axis_xyz_x.setAttribute("y1",origin[1])
axis_xyz_x.setAttribute("x2",xaxis[0])
axis_xyz_x.setAttribute("y2",xaxis[1])
axis_xyz_x.setAttribute("stroke-width",axis_size)
axis_xyz_x.setAttribute("stroke","red")
panel_xyz.appendChild(axis_xyz_x)
var axis_xyz_y = document.createElementNS(svgNS,"line")
axis_xyz_y.setAttribute("id","axis_xyz_y")
axis_xyz_y.setAttribute("x1",origin[0])
axis_xyz_y.setAttribute("y1",origin[1])
axis_xyz_y.setAttribute("x2",yaxis[0])
axis_xyz_y.setAttribute("y2",yaxis[1])
axis_xyz_y.setAttribute("stroke-width",axis_size)
axis_xyz_y.setAttribute("stroke","green")
panel_xyz.appendChild(axis_xyz_y)
var axis_xyz_z = document.createElementNS(svgNS,"line")
axis_xyz_z.setAttribute("id","axis_xyz_z")
axis_xyz_z.setAttribute("x1",origin[0])
axis_xyz_z.setAttribute("y1",origin[1])
axis_xyz_z.setAttribute("x2",zaxis[0])
axis_xyz_z.setAttribute("y2",zaxis[1])
axis_xyz_z.setAttribute("stroke-width",axis_size)
axis_xyz_z.setAttribute("stroke","blue")
panel_xyz.appendChild(axis_xyz_z)
//
// label panels
//
text(text_font_size/2,2*menu_height+panel_size-text_font_size/2,
text_font_size,"rgb(200,0,0)","xy","xy")
text(text_font_size/2,2*menu_height+2*panel_size-text_font_size/2,
text_font_size,"rgb(200,0,0)","xz","xz")
text(panel_size+text_font_size/2,
2*menu_height+panel_size-text_font_size/2,
text_font_size,"rgb(200,0,0)","zy","zy")
text(panel_size+text_font_size/2,
2*menu_height+2*panel_size-text_font_size/2,
text_font_size,"rgb(200,0,0)","xyz","xyz")
//
// draw borders
//
var left_line = document.createElementNS(svgNS,"line")
left_line.setAttribute("x1",0)
left_line.setAttribute("y1",2*menu_height)
left_line.setAttribute("x2",0)
left_line.setAttribute("y2",2*menu_height+2*panel_size)
left_line.setAttribute("stroke-width",axis_size)
left_line.setAttribute("stroke",panel_border_color)
svg.appendChild(left_line)
var hmid_line = document.createElementNS(svgNS,"line")
hmid_line.setAttribute("id","hmid_line")
hmid_line.setAttribute("x1",panel_size)
hmid_line.setAttribute("y1",2*menu_height)
hmid_line.setAttribute("x2",panel_size)
hmid_line.setAttribute("y2",2*menu_height+2*panel_size)
hmid_line.setAttribute("stroke-width",axis_size)
hmid_line.setAttribute("stroke",panel_border_color)
svg.appendChild(hmid_line)
var right_line = document.createElementNS(svgNS,"line")
right_line.setAttribute("x1",2*panel_size)
right_line.setAttribute("y1",2*menu_height)
right_line.setAttribute("x2",2*panel_size)
right_line.setAttribute("y2",2*menu_height+2*panel_size)
right_line.setAttribute("stroke-width",axis_size)
right_line.setAttribute("stroke",panel_border_color)
svg.appendChild(right_line)
var vmid_line = document.createElementNS(svgNS,"line")
vmid_line.setAttribute("id","vmid_line")
vmid_line.setAttribute("x1",0)
vmid_line.setAttribute("y1",2*menu_height+panel_size)
vmid_line.setAttribute("x2",2*panel_size)
vmid_line.setAttribute("y2",2*menu_height+panel_size)
vmid_line.setAttribute("stroke-width",axis_size)
vmid_line.setAttribute("stroke",panel_border_color)
svg.appendChild(vmid_line)
var bot_line = document.createElementNS(svgNS,"line")
bot_line.setAttribute("x1",0)
bot_line.setAttribute("y1",2*menu_height+2*panel_size)
bot_line.setAttribute("x2",2*panel_size)
bot_line.setAttribute("y2",2*menu_height+2*panel_size)
bot_line.setAttribute("stroke-width",axis_size)
bot_line.setAttribute("stroke",panel_border_color)
svg.appendChild(bot_line)
}
//
// key handler
//
document.onkeydown = key_handler
function key_handler() {
edit_panel_div = document.getElementById("edit_panel_div")
if (edit_panel_div != null)
return
if (message == "") {
if (event.keyCode == 38) {
//
// zoom in
//
message = "(up) zoom in"
action(0)
}
else if (event.keyCode == 40) {
//
// zoom out
//
message = "(down) zoom out"
action(0)
}
else if (event.keyCode == 46) {
//
// del
//
if (highlighted_node != -1) {
if (event.shiftKey != 1) {
graph.delete_node(highlighted_node)
graph.evaluate()
graph.render()
}
else {
message = ""
graph.delete_nodes(node)
graph.evaluate()
graph.render()
}
}
else {
message = "node to delete? (can also del highlighted node)"
msg(message)
}
}
else if (String.fromCharCode(event.keyCode) == "C") {
message = "CAM"
CAM_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "E") {
message = "edit"
edit_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "F") {
message = "file"
file_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "O") {
message = "operators"
operators_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "S") {
message = "shapes"
shapes_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "T") {
message = "transforms"
transform_menu(0)
}
else if (String.fromCharCode(event.keyCode) == "V") {
message = "view"
view_menu(0)
}
}
else if (message == "shapes") {
if (String.fromCharCode(event.keyCode) == "R") {
message = "(r)ect. edge"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "E") {
message = "r(e)ct. center"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "N") {
message = "rect. cor(n)ers"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "C") {
message = "(c)irc. edge"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "I") {
message = "c(i)rc. center"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "A") {
message = "(a)rc"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "P") {
message = "elli(p)se"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "T") {
message = "(t)riangle"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "G") {
message = "right trian(g)le"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "L") {
message = "po(l)ygon"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "U") {
message = "c(u)be edge"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "B") {
message = "cu(b)e center"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "D") {
message = "pyrami(d)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "S") {
message = "(s)phere edge"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "H") {
message = "sp(h)ere center"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "X") {
message = "cylinder (x)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Y") {
message = "cylinder (y)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Z") {
message = "cylinder (z)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "O") {
message = "c(o)ne"
action(0)
}
else {
message = ""
shapes_menu(0)
}
}
else if (message == "operators") {
if (String.fromCharCode(event.keyCode) == "A") {
message = "(a)dd"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "I") {
message = "(i)ntersect"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "V") {
message = "in(v)ert"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "S") {
message = "(s)ubtract"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "C") {
message = "(c)learance"
action(0)
}
else {
message = ""
operators_menu(0)
}
}
else if (message == "transforms") {
if (String.fromCharCode(event.keyCode) == "D") {
message = "(d)uplicate"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "T") {
message = "(t)ranslate"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "O") {
message = "(o)rigin"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "X") {
message = "rotate (x)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Y") {
message = "rotate (y)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Z") {
message = "rotate (z)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "E") {
message = "(e)xtrude"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "S") {
message = "(s)cale xy"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "C") {
message = "s(c)ale xyz"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "W") {
message = "(w)arp z"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "R") {
message = "(r)epel"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "A") {
message = "(a)ttract"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "L") {
message = "(l)inear array"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "D") {
message = "ra(d)ial array"
action(0)
}
else {
message = ""
transform_menu(0)
}
}
else if (message == "edit") {
if (String.fromCharCode(event.keyCode) == "N") {
message = "(n)ode"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "L") {
message = "(l)ink"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "F") {
message = "(f)ixed link"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "D") {
message = "(d)elete node"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "C") {
message = "(c)ut nodes"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "M") {
message = "(m)ove nodes"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "U") {
message = "(u)ndo"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "X") {
message = "align (x)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Y") {
message = "align (y)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "Z") {
message = "align (z)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "2") {
message = "align xy (2)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "3") {
message = "align xyz (3)"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "G") {
message = "(g)rid size"
action(0)
}
else {
message = ""
edit_menu(0)
}
}
else if (message == "view") {
if (String.fromCharCode(event.keyCode) == "2") {
message = "(2)D"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "3") {
message = "(3)D"
action(0)
}
else if (event.keyCode == 38) {
message = "(up) zoom in"
action(0)
}
else if (event.keyCode == 40) {
message = "(down) zoom out"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "L") {
message = "(l)imits"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "R") {
message = "(r)esolution"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "E") {
message = "(e)xpression"
action(0)
}
else {
message = ""
view_menu(0)
}
}
else if (message == "file") {
if (String.fromCharCode(event.keyCode) == "O") {
message = "(o)pen .fab"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "S") {
message = "(s)ave .fab"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "M") {
message = "export .(m)ath"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "V") {
message = "export .s(v)g"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "T") {
message = "export .s(t)l"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "P") {
message = "export .(p)ng"
action(0)
}
else {
message = ""
file_menu(0)
}
}
else if (message == "CAM") {
if (String.fromCharCode(event.keyCode) == "F") {
message = "(f)abricate"
action(0)
}
else if (String.fromCharCode(event.keyCode) == "U") {
message = "(u)nits"
action(0)
}
else {
message = ""
edit_menu(0)
}
}
else
message = ""
}
//
// initialize and start event processing
//
init()
</script>
</body>
</html>