...
 
Commits (12)
from flask import Flask, render_template, request, send_from_directory, abort, jsonify, Response
from flask_cors import CORS
from wtforms import Form, IntegerField, SubmitField
from wtforms import Form
from widgets import *
from os.path import join
import traceback
from svggen.library import getComponent
from svggen.api.composables.graph.Joint import FingerJoint
'''
known_models = [
wood_models = [
"Stool",
"SimpleTable",
"SimpleChair",
"RockerChair",
"Paperbot",
]
'''
known_models = [
paper_models = [
"BoatBase",
"Tug",
"Canoe",
"Catamaran",
"CatFoil",
"Trimaran",
"Paperbot",
]
known_models = dict([(x, 3) for x in wood_models] + [(x, 0.05) for x in paper_models])
known_types = {
"svg": ("unfolding", "image/svg+xml"),
"dxf": ("silhouette", "application/dxf"),
......@@ -42,6 +45,8 @@ def add_header(response):
def make(f, path, args, mkstl=True, mkdxf=True, mksvg=True):
# Default thickness: paper
t = 0.05
if path in known_models:
t = known_models[path]
for p, v in args.iteritems():
try:
......@@ -54,6 +59,7 @@ def make(f, path, args, mkstl=True, mkdxf=True, mksvg=True):
t = float(v)
except ValueError as e:
print "*** ERROR ***", repr(e)
traceback.print_exc()
pass
j = None
......@@ -66,9 +72,14 @@ def make(f, path, args, mkstl=True, mkdxf=True, mksvg=True):
thickness = t, joint = j)
except Exception as e:
print "*** ERROR ***", repr(e)
traceback.print_exc()
return repr(e)
return ss["graph"]
@app.route('/favicon.ico')
def favicon():
return send_from_directory(join(app.root_path, 'static'),'favicon.ico', mimetype='image/vnd.microsoft.icon')
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
@app.route('/<path:path>', methods=['GET', 'POST'])
def catchall(path):
......@@ -78,6 +89,7 @@ def catchall(path):
path, ext = path.split('.')
except ValueError as e:
print "*** ERROR ***", repr(e)
traceback.print_exc()
abort(400)
component = path
......@@ -87,6 +99,7 @@ def catchall(path):
f = getComponent(component)
except Exception as e:
print "*** ERROR ***", repr(e)
traceback.print_exc()
abort(404)
if ext == "json":
......@@ -103,19 +116,30 @@ def catchall(path):
else:
make(f, component, request.args)
t = known_models.get(component, 0.05)
paperthick = (t == 0.05 and "selected" or "")
woodthick = (t == 3 and "selected" or "")
class ParamForm(Form):
pass
for k, v in f.parameters.iteritems():
setattr(ParamForm, k, IntegerField("%s: " % k, default=v))
return render_template("combined.html", component=component, query=request.query_string, form=ParamForm())
md = f.metadata.get(k, {})
setattr(ParamForm, k, MyField("%s: " % k, md, default=v))
if "min" in md and "max" in md and "step" in md:
setattr(ParamForm, k + "_anim", ButtonField("Animate", render_kw={"onclick": "animvar(%s)" % k}))
return render_template("combined.html",
component=component,
paperthick=paperthick,
woodthick=woodthick,
query=request.query_string,
form=ParamForm())
print component
else:
string = "<html><body>"
for m in known_models:
for (m, t) in known_models.iteritems():
string += '<a href="' + m + '">' + m + "</a><br>"
string += "</body></html>"
return string
if (__name__ == "__main__"):
app.run(host= '0.0.0.0', port = 5000)
app.run(host= '0.0.0.0', port = 5001)
No preview for this file type
......@@ -68,10 +68,10 @@ function addShadowedLight( x, y, z, color, intensity ) {
var mesh;
var material = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
var loader = new THREE.STLLoader();
function stlload(stlmodel) {
// OBJECT
var loader = new THREE.STLLoader();
geometry = loader.parse( stlmodel );
......@@ -143,18 +143,40 @@ function makelinks(data) {
makelink(par, "svg", data["unfolding"]);
}
function remake() {
var stlarray = [];
function animvar(inpt) {
function remake_callback(data) {
stlarray.push(data["stl"])
i = parseFloat(inpt.value) + parseFloat(inpt.step)
if (i < parseFloat(inpt.max)) {
inpt.value = i;
remake(remake_callback);
}
}
function anim_callback(item, index) {
setTimeout(() => {stlreload(item);}, 10 * index);
}
if (stlarray.length) {
stlarray.forEach(anim_callback)
} else {
remake(remake_callback);
};
}
function remake(callback) {
var xhr = new XMLHttpRequest();
var formdata = new FormData(paramform);
console.log(directlink("stl"));
// Define what happens on successful data submission
xhr.addEventListener("load", function(event) {
console.log('success: ');
data = JSON.parse(event.target.responseText);
makelinks(data);
stlreload(data["stl"]);
svgreload(data["unfolding"]);
if (callback) callback(data);
});
// Define what happens in case of error
......
......@@ -17,14 +17,14 @@
<form id="paramform">
{% for field in form %}
<label>{{field.label}}</label> {{field}} <br>
{{field.label}} {{field(**{"onchange":"remake()"})}} <br>
{% endfor %}
<br><br>
Material:
<select name="$thickness">
<option value="0.05">Paper</option>
<option value="3">3mm plywood</option>
<option value="0.05" {{paperthick}} >Paper</option>
<option value="3" {{woodthick}} >3mm plywood</option>
<option value="5">5mm plywood</option>
</select> <br><br>
......
from wtforms.fields.html5 import DecimalField
from wtforms import SubmitField
from wtforms.widgets import html5
from wtforms import widgets
class MyField(DecimalField):
def __init__(self, label=None, md=None, **kwargs):
super(DecimalField, self).__init__(label, **kwargs)
self.widget = html5.NumberInput()
if md:
self.widget.min = md.get("min", None)
self.widget.max = md.get("max", None)
self.widget.step = md.get("step", None)
class ButtonField(SubmitField):
def __init__(self, label=None, **kwargs):
super(SubmitField, self).__init__(label, **kwargs)
self.widget = widgets.SubmitInput()
self.widget.input_type = "button"
......@@ -137,8 +137,24 @@ class CodeComposable(Composable):
return [self._components, self._virtualPins,
self._dataMap, self._controllerDirs]
def rmdirTemp(self):
# Remove temp directory
# Our portion is now empty, but do a recursive delete in case a previous
# program execution did not terminate correctly and did not clear out its temp files
for root, dirs, files in os.walk(self._tempOutputDir, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(self._tempOutputDir)
# Make the final output
def makeOutput(self, filedir, **kwargs):
if not filedir:
### XXX TODO : Handle return to string
self.rmdirTemp()
return
a = None
tab = ' '
res = '\nCodeComposable MakeOutput'
......@@ -338,15 +354,7 @@ class CodeComposable(Composable):
os.rmdir(controllerDir + self._insertionsDir)
os.rmdir(controllerDir)
# Remove temp directory
# Our portion is now empty, but do a recursive delete in case a previous
# program execution did not terminate correctly and did not clear out its temp files
for root, dirs, files in os.walk(self._tempOutputDir, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(self._tempOutputDir)
self.rmdirTemp()
fout = open(filedir + '/' + 'virtual_pins.txt', 'w+')
for num, port in enumerate(self._virtualPins):
......
......@@ -122,9 +122,13 @@ class ElectricalComposable(Composable):
if len(deviceRes) > 0:
fres += '\n\tDevice ' + device.getName() + ':'
fres += deviceRes
f = open(filedir + '/wiring_instructions.txt', 'w')
if filedir:
with open(filedir + '/wiring_instructions.txt', 'w') as f:
f.write(fres)
f.close()
else:
return fres
res += fres
#print fres
......
from svggen.api.component import Component
from svggen.api.Function import Function
self = Component()
self.addParameter("unit", 6.35)
self.addParameter("phase", 0, paramtype="animation", step=0.05, min=0, max=4)
self.addSubcomponent("ext","Extension")
self.addSubcomponent("rect","Rectangle")
self.addConstraint(("ext","l"), "unit")
self.addConstraint(("ext","w"), "unit")
self.addConstraint(("rect","l"), "unit")
self.addConstraint(("rect","w"), "unit")
self.addConstraint(("ext","angle"), "phase", "90 + 90*np.cos(2*x*np.pi)")
self.addConnection(("ext", "b"), ("rect","t"),angle=Function(params="phase", fnstring="-45 - 45*np.cos(2*x*np.pi)"))
self.inheritInterface("t",("ext","t"))
self.inheritInterface("b",("rect","b"))
self.inheritInterface("l",("rect","l"))
self.inheritInterface("r",("rect","r"))
self.toYaml("library/CardBot1DOF.yaml")
from svggen.api.component import Component
from svggen.api.Function import Function
self = Component()
self.addParameter("dphase", 1)
self.addSubcomponent("c1","CardBot1DOF", inherit=True, prefix=None)
self.addSubcomponent("c2","CardBot1DOF", inherit=True, prefix=None)
self.addConstraint(("c2", "phase"), ("phase", "dphase"), "(x[0] + 0.25 * x[1]) % 1")
self.addConnection(("c1", "l"), ("c2","t"),
angle=Function(params=("phase", "dphase"),
fnstring="-45 + 45*np.cos(2*(x[0]-0.25*x[1])*np.pi)"))
self.inheritInterface("t",("c1","t"))
self.inheritInterface("b",("c2","b"))
self.inheritInterface("l",("c2","l"))
self.inheritInterface("r",("c2","r"))
self.toYaml("library/CardBot2DOF.yaml")
from svggen.api.component import Component
from svggen.api.Function import Function
self = Component()
self.addSubcomponent("l1","CardBotLeg", inherit=True, prefix=None)
self.addSubcomponent("l2","CardBotLeg", inherit=True, prefix=None)
self.addSubcomponent("ra","Rectangle")
self.addSubcomponent("rb","Rectangle")
self.addSubcomponent("rc","Rectangle")
self.addSubcomponent("rd","Rectangle")
self.addSubcomponent("re","Rectangle")
self.addSubcomponent("rf","Rectangle")
self.addSubcomponent("rg","Rectangle")
self.delParameter("dphase")
self.addConstConstraint(("l1", "dphase"), 1)
self.addConstConstraint(("l2", "dphase"), -1)
self.addConstraint(("l2", "phase"), "phase", "(x + 0.5) % 1")
self.addConstraint(("ra", "w"), "unit")
self.addConstraint(("rb", "w"), "unit")
self.addConstraint(("rc", "w"), "unit")
self.addConstraint(("rd", "w"), "unit")
self.addConstraint(("re", "w"), "unit")
self.addConstraint(("rf", "w"), "unit")
self.addConstraint(("rg", "w"), "unit")
self.addConstraint(("ra", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("rb", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("rc", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("rd", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("re", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("rf", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("rg", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConnection(("ra", "t"), ("rb","b"))
self.addConnection(("rb", "t"), ("rc","b"))
self.addConnection(("rc", "t"), ("rd","b"))
self.addConnection(("rd", "t"), ("re","b"))
self.addConnection(("re", "t"), ("rf","b"))
self.addConnection(("rf", "t"), ("rg","b"))
self.addConnection(("ra", "l"), ("l2","l2"), angle=Function(params="phase", fnstring="45 + 45*np.cos(2*x*np.pi)"))
self.addConnection(("rd", "r"), ("l1","l1"), angle=Function(params="phase", fnstring="45 - 45*np.cos(2*x*np.pi)"))
self.addConnection(("rd", "l"), ("l2","l1"), angle=Function(params="phase", fnstring="45 + 45*np.cos(2*x*np.pi)"))
self.addConnection(("rg", "r"), ("l1","l2"), angle=Function(params="phase", fnstring="45 - 45*np.cos(2*x*np.pi)"))
self.toYaml("library/CardBot.yaml")
from svggen.api.component import Component
self = Component()
self.addParameter("height", 2)
self.addParameter("width", 2)
self.addSubcomponent("c1","CardBot2DOF", inherit=True, prefix=None)
self.addSubcomponent("c2","CardBot2DOF", inherit=True, prefix=None)
self.addSubcomponent("r1","Rectangle")
self.addSubcomponent("rm","Rectangle")
self.addSubcomponent("r2","Rectangle")
self.addSubcomponent("f1","Rectangle")
self.addSubcomponent("f2","Rectangle")
self.addConstraint(("r1", "l"), ("height", "unit"), "x[0] * x[1]")
self.addConstraint(("r2", "l"), ("height", "unit"), "x[0] * x[1]")
self.addConstraint(("rm", "l"), ("height", "unit"), "x[0] * x[1]")
self.addConstraint(("r1", "w"), "unit")
self.addConstraint(("r2", "w"), "unit")
self.addConstraint(("rm", "w"), "unit", "2*x")
self.addConstraint(("f1", "w"), "unit")
self.addConstraint(("f2", "w"), "unit")
self.addConstraint(("f1", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConstraint(("f2", "l"), ("width", "unit"), "x[0] * x[1]")
self.addConnection(("r1", "l"), ("c1","r"))
self.addConnection(("r2", "l"), ("c2","r"))
self.addConnection(("r1", "r"), ("f1","l"), angle=90)
self.addConnection(("r2", "r"), ("f2","l"), angle=90)
self.addConnection(("r1", "t"), ("rm","b"))
self.addConnection(("rm", "t"), ("r2","b"))
self.inheritInterface("l1", ("c1", "t"))
self.inheritInterface("l2", ("c2", "t"))
self.toYaml("library/CardBotLeg.yaml")
from svggen.api.component import Component
from svggen.api.Function import Function
c = Component()
c.addParameter("l")
c.addParameter("w")
c.addParameter("angle", 180)
c.addSubcomponent("top", "Rectangle")
c.addSubcomponent("bot", "Rectangle")
......@@ -15,7 +18,7 @@ c.addConstraint(("bot", "l"), "w")
c.addConstraint(("bot", "w"), "l", "x/2")
c.addConnection(("top", "b"),
("bot", "t"), angle=180)
("bot", "t"), angle=Function(params="angle", fnstring="x"))
c.inheritInterface("t", ("top", "t"))
c.inheritInterface("b", ("bot", "b"))
......
python CardBot1DOFBuilder.py
python CardBot2DOFBuilder.py
python CardBotLegBuilder.py
python CardBotBuilder.py
connections:
connection0:
- [ra, t]
- [rb, b]
- {}
connection1:
- [rb, t]
- [rc, b]
- {}
connection2:
- [rc, t]
- [rd, b]
- {}
connection3:
- [rd, t]
- [re, b]
- {}
connection4:
- [re, t]
- [rf, b]
- {}
connection5:
- [rf, t]
- [rg, b]
- {}
connection6:
- [ra, l]
- [l2, l2]
- angle: {function: 45 + 45*np.cos(2*x*np.pi), parameter: phase}
connection7:
- [rd, r]
- [l1, l1]
- angle: {function: 45 - 45*np.cos(2*x*np.pi), parameter: phase}
connection8:
- [rd, l]
- [l2, l1]
- angle: {function: 45 + 45*np.cos(2*x*np.pi), parameter: phase}
connection9:
- [rg, r]
- [l1, l2]
- angle: {function: 45 - 45*np.cos(2*x*np.pi), parameter: phase}
interfaces: {}
metadata:
height: {default: 2}
phase: {default: 0, max: 4, min: 0, paramtype: animation, step: 0.05}
unit: {default: 6.35}
width: {default: 2}
parameters: {height: 2, phase: 0, unit: 6.35, width: 2}
subcomponents:
l1:
classname: CardBotLeg
kwargs: {}
parameters:
dphase: 1
height: {parameter: height}
phase: {parameter: phase}
unit: {parameter: unit}
width: {parameter: width}
l2:
classname: CardBotLeg
kwargs: {}
parameters:
dphase: -1
height: {parameter: height}
phase: {function: (x + 0.5) % 1, parameter: phase}
unit: {parameter: unit}
width: {parameter: width}
ra:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
rb:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
rc:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
rd:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
re:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
rf:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
rg:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
connections:
connection0:
- [ext, b]
- [rect, t]
- angle: {function: -45 - 45*np.cos(2*x*np.pi), parameter: phase}
interfaces:
b: {interface: b, subcomponent: rect}
l: {interface: l, subcomponent: rect}
r: {interface: r, subcomponent: rect}
t: {interface: t, subcomponent: ext}
metadata:
phase: {default: 0, max: 4, min: 0, paramtype: animation, step: 0.05}
unit: {default: 6.35}
parameters: {phase: 0, unit: 6.35}
subcomponents:
ext:
classname: Extension
kwargs: {}
parameters:
angle: {function: 90 + 90*np.cos(2*x*np.pi), parameter: phase}
l: {parameter: unit}
w: {parameter: unit}
rect:
classname: Rectangle
kwargs: {}
parameters:
l: {parameter: unit}
w: {parameter: unit}
connections:
connection0:
- [c1, l]
- [c2, t]
- angle:
function: -45 + 45*np.cos(2*(x[0]-0.25*x[1])*np.pi)
parameter: [phase, dphase]
interfaces:
b: {interface: b, subcomponent: c2}
l: {interface: l, subcomponent: c2}
r: {interface: r, subcomponent: c2}
t: {interface: t, subcomponent: c1}
metadata:
dphase: {default: 1}
phase: {default: 0, max: 4, min: 0, paramtype: animation, step: 0.05}
unit: {default: 6.35}
parameters: {dphase: 1, phase: 0, unit: 6.35}
subcomponents:
c1:
classname: CardBot1DOF
kwargs: {}
parameters:
phase: {parameter: phase}
unit: {parameter: unit}
c2:
classname: CardBot1DOF
kwargs: {}
parameters:
phase:
function: (x[0] + 0.25 * x[1]) % 1
parameter: [phase, dphase]
unit: {parameter: unit}
connections:
connection0:
- [r1, l]
- [c1, r]
- {}
connection1:
- [r2, l]
- [c2, r]
- {}
connection2:
- [r1, r]
- [f1, l]
- {angle: 90}
connection3:
- [r2, r]
- [f2, l]
- {angle: 90}
connection4:
- [r1, t]
- [rm, b]
- {}
connection5:
- [rm, t]
- [r2, b]
- {}
interfaces:
l1: {interface: t, subcomponent: c1}
l2: {interface: t, subcomponent: c2}
metadata:
dphase: {default: 1}
height: {default: 2}
phase: {default: 0, max: 4, min: 0, paramtype: animation, step: 0.05}
unit: {default: 6.35}
width: {default: 2}
parameters: {dphase: 1, height: 2, phase: 0, unit: 6.35, width: 2}
subcomponents:
c1:
classname: CardBot2DOF
kwargs: {}
parameters:
dphase: {parameter: dphase}
phase: {parameter: phase}
unit: {parameter: unit}
c2:
classname: CardBot2DOF
kwargs: {}
parameters:
dphase: {parameter: dphase}
phase: {parameter: phase}
unit: {parameter: unit}
f1:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
f2:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [width, unit]
w: {parameter: unit}
r1:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [height, unit]
w: {parameter: unit}
r2:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [height, unit]
w: {parameter: unit}
rm:
classname: Rectangle
kwargs: {}
parameters:
l:
function: x[0] * x[1]
parameter: [height, unit]
w: {function: 2*x, parameter: unit}
......@@ -2,11 +2,15 @@ connections:
connection0:
- [top, b]
- [bot, t]
- {angle: 180}
- angle: {parameter: angle}
interfaces:
b: {interface: b, subcomponent: bot}
t: {interface: t, subcomponent: top}
parameters: {l: null, w: null}
metadata:
angle: {default: 180}
l: {default: null}
w: {default: null}
parameters: {angle: 180, l: null, w: null}
subcomponents:
bot:
classname: Rectangle
......