jsketcher/web/app/main2d.js
2014-10-28 21:58:39 -07:00

311 lines
9 KiB
JavaScript

var magic_k = 500;
TCAD.App2D = function() {
this.viewer = new TCAD.TWO.Viewer(document.getElementById('viewer'));
var layer = new TCAD.TWO.Layer("test", TCAD.TWO.Styles.DEFAULT);
this.viewer.layers.push(layer);
var sketchId = this.getSketchId();
var sketchData = localStorage.getItem(sketchId);
var boundary = null;
if (sketchData == null) {
//PUT SAMPLES
this.viewer.addSegment(20, 20, 300, 300, layer);
// var points = [{x: 10, y: 10}, {x: 100, y: 10}, {x: 100, y: 100}];
// var poly = new TCAD.TWO.Polygon(points);
// layer.objects.push(poly);
} else {
var sketch = JSON.parse(sketchData);
}
if (sketch != null) {
try {
this.loadSketch(sketch);
} catch(e) {
if (typeof(e) === String) {
console.error(e);
} else {
throw e;
}
}
}
this.viewer.repaint();
var app = this;
this.dat = new dat.GUI();
var gui = this.dat;
var actionsF = gui.addFolder('Add Object');
var actions = {
addSegment : function () {
app.viewer.toolManager.takeControl(new TCAD.TWO.AddSegmentTool(app.viewer, layer, false));
},
addMultiSegment : function () {
app.viewer.toolManager.takeControl(new TCAD.TWO.AddSegmentTool(app.viewer, layer, true));
},
addArc : function () {
app.viewer.toolManager.takeControl(new TCAD.TWO.AddArcTool(app.viewer, layer));
},
addCircle : function () {
app.viewer.toolManager.takeControl(new TCAD.TWO.EditCircleTool(app.viewer, layer));
},
pan : function() {
app.viewer.toolManager.releaseControl();
},
save : function() {
var sketch = {};
sketch.boundary = boundary;
sketch.layers = [];
sketch.index = {};
function point(p) {
return [ p.id, [p._x.id, p.x], [p._y.id, p.y] ];
}
for (var l = 0; l < app.viewer.layers.length; ++l) {
var layer = app.viewer.layers[l];
var toLayer = [];
sketch.layers.push(toLayer);
for (var i = 0; i < layer.objects.length; ++i) {
var obj = layer.objects[i];
var to = {id: obj.id, _class: obj._class};
toLayer.push(to);
if (obj._class === 'TCAD.TWO.Segment') {
to.points = [point(obj.a), point(obj.b)];
} else if (obj._class === 'TCAD.TWO.Arc') {
} else if (obj._class === 'TCAD.TWO.Circle') {
}
}
}
var constrs = sketch.constraints = [];
var sys = app.viewer.parametricManager.system;
for (var i = 0; i < sys.length; ++i) {
constrs.push(app.serializeConstr(sys[i]));
}
var sketchData = JSON.stringify(sketch);
console.log(sketchData);
var sketchId = app.getSketchId();
localStorage.setItem(app.getSketchId(), sketchData);
},
coincident : function() {
app.viewer.parametricManager.coincident(app.viewer.selected);
},
vertical : function() {
app.viewer.parametricManager.vertical(app.viewer.selected);
},
horizontal : function() {
app.viewer.parametricManager.horizontal(app.viewer.selected);
},
parallel : function() {
app.viewer.parametricManager.parallel(app.viewer.selected);
},
perpendicular : function() {
app.viewer.parametricManager.perpendicular(app.viewer.selected);
},
P2LDistance : function() {
app.viewer.parametricManager.p2lDistance(app.viewer.selected, prompt);
},
P2PDistance : function() {
app.viewer.parametricManager.p2pDistance(app.viewer.selected, prompt);
},
Radius : function() {
app.viewer.parametricManager.radius(app.viewer.selected, prompt);
},
"R = R" : function() {
app.viewer.parametricManager.rr(app.viewer.selected);
},
tangent : function() {
app.viewer.parametricManager.tangent(app.viewer.selected);
},
lock : function() {
app.viewer.parametricManager.lock(app.viewer.selected);
},
analyze : function() {
app.viewer.parametricManager.analyze(alert);
},
solve : function() {
app.viewer.parametricManager.solve([], 0);
app.viewer.refresh();
},
step : function() {
app.viewer.parametricManager.solve([], 0, 3);
app.viewer.refresh();
},
stepUNCMIN : function() {
app.viewer.parametricManager.solve([], 0, 4);
app.viewer.refresh();
}
};
actionsF.add(actions, 'addSegment');
actionsF.add(actions, 'addMultiSegment');
actionsF.add(actions, 'addArc');
actionsF.add(actions, 'addCircle');
actionsF.add(actions, 'pan');
actionsF.add(actions, 'save');
actionsF.add(actions, 'coincident');
actionsF.add(actions, 'vertical');
actionsF.add(actions, 'horizontal');
actionsF.add(actions, 'parallel');
actionsF.add(actions, 'perpendicular');
actionsF.add(actions, 'P2LDistance');
actionsF.add(actions, 'P2PDistance');
actionsF.add(actions, 'Radius');
actionsF.add(actions, 'R = R');
actionsF.add(actions, 'tangent');
actionsF.add(actions, 'lock');
actionsF.add(actions, 'solve');
actionsF.add(actions, 'step');
actionsF.add(actions, 'stepUNCMIN');
actionsF.add(actions, 'analyze');
actionsF.open();
};
TCAD.App2D.prototype.loadSketch = function(sketch) {
var boundary = sketch.boundary;
if (boundary != null) {
var bbox = this.makePolygon(boundary.shell, layer);
for (var i = 0; i < sketch.boundary.holes.length; ++i ) {
this.makePolygon(sketch.boundary.holes[i], layer);
}
this.viewer.showBounds(bbox[0], bbox[1], bbox[2], bbox[3])
}
var index = {};
function createEndPoint(p) {
var id = p[0];
var ep = new TCAD.TWO.EndPoint(p[1][1], p[2][1]);
index[p[1][0]] = ep._x;
index[p[2][0]] = ep._y;
index[id] = ep;
return ep;
}
for (var l = 0; l < sketch.layers.length; ++l) {
var layer = new TCAD.TWO.Layer("layer_" + l, TCAD.TWO.Styles.DEFAULT);
this.viewer.layers.push(layer);
for (var i = 0; i < sketch.layers[l].length; ++i) {
var obj = sketch.layers[l][i];
if (obj._class === 'TCAD.TWO.Segment') {
var a = createEndPoint(obj.points[0]);
var b = createEndPoint(obj.points[1]);
var line = new TCAD.TWO.Segment(a, b);
layer.objects.push(line);
line.layer = layer;
index[obj.id] = line;
} else if (obj._class === 'TCAD.TWO.Arc') {
} else if (obj._class === 'TCAD.TWO.Circle') {
}
}
}
for (var i = 0; i < sketch.constraints.length; ++i) {
var c = this.parseConstr(sketch.constraints[i], index);
this.viewer.parametricManager.system.push(c);
}
};
TCAD.App2D.prototype.parseConstr = function (c, index) {
function find(id) {
var p = index[id];
if (!p) throw "CAN'T READ SKETCH";
return p;
}
var name = c[0];
var ps = c[1];
switch (name) {
case "equal":
return new TCAD.TWO.Constraints.Equal(find(ps[0]), find(ps[1]));
case "equalsTo":
return new TCAD.TWO.Constraints.EqualsTo(find(ps[0]), ps[1]);
case "perpendicular":
return new TCAD.TWO.Constraints.Perpendicular(find(ps[0]), find(ps[1]));
case "parallel":
return new TCAD.TWO.Constraints.Parallel(find(ps[0]), find(ps[1]));
case "P2LDistance":
return new TCAD.TWO.Constraints.P2LDistance(find(ps[0]), find(ps[1]), ps[2]);
case "P2LDistanceV":
return new TCAD.TWO.Constraints.P2LDistanceV(find(ps[0]), find(ps[1]), find(ps[2]));
case "P2PDistance":
return new TCAD.TWO.Constraints.P2PDistance(find(ps[0]), find(ps[1]), ps[2]);
case "P2PDistanceV":
return new TCAD.TWO.Constraints.P2PDistanceV(find(ps[0]), find(ps[1]), find(ps[2]));
}
};
TCAD.App2D.prototype.serializeConstr = function (c) {
switch (c.NAME) {
case "equal":
return ['equal', [c.p1.id, c.p2.id]];
case "equalsTo":
return ['equalsTo', [c.p.id, c.v]];
case "perpendicular":
return ['perpendicular', [c.l1.id, c.l2.id]];
case "parallel":
return ['parallel', [c.l1.id, c.l2.id]];
case "P2LDistance":
return ['P2LDistance', [c.p.id, c.l.id, c.d]];
case "P2LDistanceV":
return ['P2LDistanceV', [c.p.id, c.l.id, c.d.get()]];
case "P2PDistance":
return ['P2PDistance', [c.p1.id, c.p2.id, c.d]];
case "P2PDistanceV":
return ['P2PDistanceV', [c.p1.id, c.p2.id, c.d.get()]];
}
};
TCAD.App2D.prototype.getSketchId = function() {
var id = window.location.hash.substring(1);
if (!!id) {
id = "untitled";
}
return "TCAD.projects." + id;
};
TCAD.App2D.prototype.makePolygon = function(points, layer) {
var n = points.length;
var k = magic_k;
var bounds = [Number.MAX_VALUE, Number.MAX_VALUE, - Number.MAX_VALUE, - Number.MAX_VALUE];
for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
var seg = this.viewer.addSegment(k*points[p].x, k*points[p].y, k*points[q].x, k*points[q].y, layer);
seg.aux = true;
seg.a.aux = true;
seg.b.aux = true;
bounds[0] = Math.min(bounds[0], k*points[p].x);
bounds[1] = Math.min(bounds[1], k*points[p].y);
bounds[2] = Math.max(bounds[2], k*points[q].x);
bounds[3] = Math.max(bounds[3], k*points[q].y);
}
return bounds;
};