mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-16 05:23:19 +01:00
embed undo/redo engine
This commit is contained in:
parent
242cba46a4
commit
8d32652b81
11 changed files with 355 additions and 305 deletions
|
|
@ -61,6 +61,8 @@ TCAD.TWO.utils.setStyle = function(style, ctx, scale) {
|
|||
TCAD.TWO.Viewer = function(canvas) {
|
||||
|
||||
this.canvas = canvas;
|
||||
this.io = new TCAD.IO(this);
|
||||
this.historyManager = new TCAD.HistoryManager(this);
|
||||
var viewer = this;
|
||||
function updateCanvasSize() {
|
||||
canvas.width = canvas.parentNode.offsetWidth;
|
||||
|
|
@ -346,6 +348,11 @@ TCAD.TWO.Layer = function(name, style) {
|
|||
this.objects = [];
|
||||
};
|
||||
|
||||
TCAD.TWO.Viewer.prototype.fullHeavyUIRefresh = function() {
|
||||
this.refresh();
|
||||
this.parametricManager.notify();
|
||||
};
|
||||
|
||||
TCAD.TWO.Polygon = function(points) {
|
||||
this.points = points;
|
||||
this.style = null;
|
||||
|
|
@ -684,8 +691,8 @@ TCAD.TWO.ToolManager.prototype.getTool = function() {
|
|||
TCAD.TWO.PanTool = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.dragging = false;
|
||||
this.x = 0.0;
|
||||
this.y = 0.0;
|
||||
this.originX = this.x = 0.0;
|
||||
this.originY = this.y = 0.0;
|
||||
};
|
||||
|
||||
TCAD.TWO.PanTool.prototype.keydown = function(e) {};
|
||||
|
|
@ -732,8 +739,8 @@ TCAD.TWO.PanTool.prototype.mousedown = function(e) {
|
|||
|
||||
this.dragging = true;
|
||||
this.deselectOnUp = true;
|
||||
this.x = e.pageX;
|
||||
this.y = e.pageY;
|
||||
this.originX = this.x = e.pageX;
|
||||
this.originY = this.y = e.pageY;
|
||||
};
|
||||
|
||||
TCAD.TWO.PanTool.prototype.mouseup = function(e) {
|
||||
|
|
@ -743,6 +750,10 @@ TCAD.TWO.PanTool.prototype.mouseup = function(e) {
|
|||
this.viewer.refresh();
|
||||
}
|
||||
this.deselectOnUp = false;
|
||||
var traveled = TCAD.math.distance(this.originX, this.x, this.originY, this.y);
|
||||
if (traveled > 10) {
|
||||
this.viewer.historyManager.lightCheckpoint(10);
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.TWO.PanTool.prototype.mousewheel = function(e) {
|
||||
|
|
|
|||
117
web/app/sketcher/history.js
Normal file
117
web/app/sketcher/history.js
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
TCAD.HistoryManager = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.dmp = new diff_match_patch();
|
||||
this.historyPointer = -1;
|
||||
this.diffs = [];
|
||||
this._counter = 0;
|
||||
};
|
||||
|
||||
|
||||
TCAD.HistoryManager.prototype.init = function(sketchData) {
|
||||
this.lastCheckpoint = sketchData;
|
||||
this.diffs = [];
|
||||
this.historyPointer = -1;
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.undo = function () {
|
||||
console.log("Undo " + this.diffs.length);
|
||||
var currentState = this.viewer.io.serializeSketch();
|
||||
if (currentState == this.lastCheckpoint) {
|
||||
if (this.historyPointer != -1) {
|
||||
var diff = this.diffs[this.historyPointer];
|
||||
this.lastCheckpoint = this.applyDiff(this.lastCheckpoint, diff);
|
||||
this.viewer.io.loadSketch(this.lastCheckpoint);
|
||||
this.viewer.fullHeavyUIRefresh();
|
||||
this.historyPointer --;
|
||||
}
|
||||
} else {
|
||||
var diffToCurr = this.getDiff(currentState, this.lastCheckpoint);
|
||||
if (this.historyPointer != this.diffs.length - 1) {
|
||||
this.diffs.splice(this.historyPointer + 1, this.diffs.length - this.historyPointer + 1)
|
||||
}
|
||||
this.diffs.push(diffToCurr);
|
||||
this.viewer.io.loadSketch(this.lastCheckpoint);
|
||||
this.viewer.fullHeavyUIRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.lightCheckpoint = function (weight) {
|
||||
this._counter += weight;
|
||||
if (this._counter >= 100) {
|
||||
this.checkpoint();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.checkpoint = function () {
|
||||
try {
|
||||
this._checkpoint();
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype._checkpoint = function () {
|
||||
this._counter = 0;
|
||||
var currentState = this.viewer.io.serializeSketch();
|
||||
if (currentState == this.lastCheckpoint) {
|
||||
return;
|
||||
}
|
||||
var diffToCurr = this.getDiff(currentState, this.lastCheckpoint);
|
||||
if (this.historyPointer != this.diffs.length - 1) {
|
||||
this.diffs.splice(this.historyPointer + 1, this.diffs.length - this.historyPointer + 1)
|
||||
}
|
||||
this.diffs.push(diffToCurr);
|
||||
this.historyPointer = this.diffs.length - 1;
|
||||
this.lastCheckpoint = currentState;
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.redo = function () {
|
||||
var currentState = this.viewer.io.serializeSketch();
|
||||
if (currentState != this.lastCheckpoint) {
|
||||
return;
|
||||
}
|
||||
if (this.historyPointer != this.diffs.length - 1 && this.diffs.length != 0) {
|
||||
this.historyPointer ++;
|
||||
var diff = this.diffs[this.historyPointer];
|
||||
this.lastCheckpoint = this.applyDiffInv(this.lastCheckpoint, diff);
|
||||
this.viewer.io.loadSketch(this.lastCheckpoint);
|
||||
this.viewer.fullHeavyUIRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.applyDiff = function (text1, diff) {
|
||||
var dmp = this.dmp;
|
||||
var results = dmp.patch_apply(diff, text1);
|
||||
return results[0];
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.applyDiffInv = function (text1, diff) {
|
||||
this.reversePatch(diff);
|
||||
var result = this.applyDiff(text1, diff);
|
||||
this.reversePatch(diff);
|
||||
return result;
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.reversePatch = function (plist) {
|
||||
for (var i = 0; i < plist.length; i++) {
|
||||
var patch = plist[i];
|
||||
for (var j = 0; j < patch.diffs.length; j++) {
|
||||
var diff = patch.diffs[j];
|
||||
diff[0] *= -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.HistoryManager.prototype.getDiff = function (text1, text2) {
|
||||
var dmp = this.dmp;
|
||||
var diff = dmp.diff_main(text1, text2, true);
|
||||
|
||||
if (diff.length > 2) {
|
||||
dmp.diff_cleanupSemantic(diff);
|
||||
}
|
||||
|
||||
var patch_list = dmp.patch_make(text1, text2, diff);
|
||||
//var patch_text = dmp.patch_toText(patch_list);
|
||||
//console.log(patch_list);
|
||||
return patch_list;
|
||||
};
|
||||
208
web/app/sketcher/io.js
Normal file
208
web/app/sketcher/io.js
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
TCAD.IO = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.loadSketch = function(sketchData) {
|
||||
return this._loadSketch(JSON.parse(sketchData));
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.serializeSketch = function() {
|
||||
return JSON.stringify(this._serializeSketch());
|
||||
};
|
||||
|
||||
TCAD.IO.prototype._loadSketch = function(sketch) {
|
||||
|
||||
this.cleanUpData();
|
||||
|
||||
var index = {};
|
||||
|
||||
function endPoint(p) {
|
||||
var id = p[0];
|
||||
var ep = index[id];
|
||||
if (ep !== undefined) {
|
||||
return
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
var layerIdGen = 0;
|
||||
function getLayer(viewer, name) {
|
||||
if (name === undefined) {
|
||||
name = "layer_" + layerIdGen++;
|
||||
} else {
|
||||
if (name === viewer.dimLayer.name) {
|
||||
return viewer.dimLayer;
|
||||
}
|
||||
for (var i = 0; i < viewer.layers.length; ++i) {
|
||||
if (name === viewer.layers[i].name) {
|
||||
return viewer.layers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
var layer = new TCAD.TWO.Layer(name, TCAD.TWO.Styles.DEFAULT);
|
||||
viewer.layers.push(layer);
|
||||
return layer;
|
||||
}
|
||||
var activeLayerCandidate = this.viewer.layers.length;
|
||||
if (sketch.layers !== undefined) {
|
||||
for (var l = 0; l < sketch.layers.length; ++l) {
|
||||
var layer = getLayer(this.viewer, sketch.layers[l].name);
|
||||
for (var i = 0; i < sketch.layers[l].data.length; ++i) {
|
||||
var obj = sketch.layers[l].data[i];
|
||||
var skobj = null;
|
||||
if (obj._class === 'TCAD.TWO.Segment') {
|
||||
var a = endPoint(obj.points[0]);
|
||||
var b = endPoint(obj.points[1]);
|
||||
skobj = new TCAD.TWO.Segment(a, b);
|
||||
} else if (obj._class === 'TCAD.TWO.EndPoint') {
|
||||
skobj = endPoint(obj.location);
|
||||
} else if (obj._class === 'TCAD.TWO.Arc') {
|
||||
var a = endPoint(obj.points[0]);
|
||||
var b = endPoint(obj.points[1]);
|
||||
var c = endPoint(obj.points[2]);
|
||||
skobj = new TCAD.TWO.Arc(a, b, c);
|
||||
skobj.stabilize(this.viewer);
|
||||
} else if (obj._class === 'TCAD.TWO.Circle') {
|
||||
var c = endPoint(obj.c);
|
||||
skobj = new TCAD.TWO.Circle(c);
|
||||
skobj.r.set(obj.r);
|
||||
} else if (obj._class === 'TCAD.TWO.HDimension') {
|
||||
skobj = new TCAD.TWO.HDimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
} else if (obj._class === 'TCAD.TWO.VDimension') {
|
||||
skobj = new TCAD.TWO.VDimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
} else if (obj._class === 'TCAD.TWO.Dimension') {
|
||||
skobj = new TCAD.TWO.Dimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
}
|
||||
if (skobj != null) {
|
||||
if (!!obj.aux) skobj.accept(function(o){o.aux = true; return true;});
|
||||
if (obj.edge !== undefined) {
|
||||
skobj.edge = obj.edge;
|
||||
}
|
||||
layer.objects.push(skobj);
|
||||
skobj.layer = layer;
|
||||
index[obj.id] = skobj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < this.viewer.dimLayer.objects.length; ++i) {
|
||||
obj = this.viewer.dimLayer.objects[i];
|
||||
//if (obj._class === 'TCAD.TWO.Dimension' || obj._class === 'TCAD.TWO.HDimension' || obj._class === 'TCAD.TWO.VDimension') {
|
||||
obj.a = index[obj.a];
|
||||
obj.b = index[obj.b];
|
||||
//}
|
||||
}
|
||||
|
||||
if (sketch.boundary !== undefined && sketch.boundary != null) {
|
||||
this.updateBoundary(sketch.boundary);
|
||||
}
|
||||
|
||||
if (sketch.constraints !== undefined) {
|
||||
for (var i = 0; i < sketch.constraints.length; ++i) {
|
||||
var c = this.parseConstr(sketch.constraints[i], index);
|
||||
this.viewer.parametricManager._add(c);
|
||||
}
|
||||
this.viewer.parametricManager.notify();
|
||||
}
|
||||
if (activeLayerCandidate < this.viewer.layers.length) {
|
||||
this.viewer.setActiveLayer(this.viewer.layers[activeLayerCandidate]);
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.cleanUpData = function() {
|
||||
for (var l = 0; l < this.viewer.layers.length; ++l) {
|
||||
var layer = this.viewer.layers[l];
|
||||
if (layer.objects.length != 0) {
|
||||
layer.objects = [];
|
||||
}
|
||||
}
|
||||
this.viewer.deselectAll();
|
||||
TCAD.TWO.utils.ID_COUNTER = 0;
|
||||
if (this.viewer.parametricManager.subSystems.length != 0) {
|
||||
this.viewer.parametricManager.subSystems = [];
|
||||
this.viewer.parametricManager.notify();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.IO.prototype._serializeSketch = function() {
|
||||
var sketch = {};
|
||||
//sketch.boundary = boundary;
|
||||
sketch.layers = [];
|
||||
function point(p) {
|
||||
return [ p.id, [p._x.id, p.x], [p._y.id, p.y] ];
|
||||
}
|
||||
var toSave = [this.viewer.dimLayers, this.viewer.layers];
|
||||
for (var t = 0; t < toSave.length; ++t) {
|
||||
var layers = toSave[t];
|
||||
for (var l = 0; l < layers.length; ++l) {
|
||||
var layer = layers[l];
|
||||
var isBoundary = layer.name === '';
|
||||
var toLayer = {name : layer.name, data : []};
|
||||
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};
|
||||
if (obj.aux) to.aux = obj.aux;
|
||||
if (obj.edge !== undefined) to.edge = obj.edge;
|
||||
toLayer.data.push(to);
|
||||
if (obj._class === 'TCAD.TWO.Segment') {
|
||||
to.points = [point(obj.a), point(obj.b)];
|
||||
} else if (obj._class === 'TCAD.TWO.EndPoint') {
|
||||
to.location = point(obj);
|
||||
} else if (obj._class === 'TCAD.TWO.Arc') {
|
||||
to.points = [point(obj.a), point(obj.b), point(obj.c)];
|
||||
} else if (obj._class === 'TCAD.TWO.Circle') {
|
||||
to.c = point(obj.c);
|
||||
to.r = obj.r.get();
|
||||
} else if (obj._class === 'TCAD.TWO.Dimension' || obj._class === 'TCAD.TWO.HDimension' || obj._class === 'TCAD.TWO.VDimension') {
|
||||
to.a = obj.a.id;
|
||||
to.b = obj.b.id;
|
||||
to.flip = obj.flip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var constrs = sketch.constraints = [];
|
||||
var subSystems = this.viewer.parametricManager.subSystems;
|
||||
for (var j = 0; j < subSystems.length; j++) {
|
||||
var sub = subSystems[j];
|
||||
for (var i = 0; i < sub.constraints.length; ++i) {
|
||||
if (!sub.constraints[i].aux) {
|
||||
constrs.push(this.serializeConstr(sub.constraints[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return sketch;
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.parseConstr = function (c, index) {
|
||||
function find(id) {
|
||||
var p = index[id];
|
||||
if (!p) {
|
||||
throw "CAN'T READ SKETCH. Object ref is not found.";
|
||||
}
|
||||
return p;
|
||||
}
|
||||
var name = c[0];
|
||||
var ps = c[1];
|
||||
var constrCreate = TCAD.TWO.Constraints.Factory[name];
|
||||
if (constrCreate === undefined) {
|
||||
throw "CAN'T READ SKETCH. Constraint " + name + " hasn't been registered.";
|
||||
}
|
||||
return constrCreate(find, ps);
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.serializeConstr = function (c) {
|
||||
return c.serialize();
|
||||
};
|
||||
|
||||
|
|
@ -6,10 +6,6 @@ TCAD.App2D = function() {
|
|||
this.viewer = new TCAD.TWO.Viewer(document.getElementById('viewer'));
|
||||
this.boundaryLayer = new TCAD.TWO.Layer("default", TCAD.TWO.Styles.DEFAULT);
|
||||
this.viewer.layers.push(this.boundaryLayer);
|
||||
this.dmp = new diff_match_patch();
|
||||
this.historyPointer = -1;
|
||||
this.diffs = [];
|
||||
|
||||
var app = this;
|
||||
|
||||
this.actions = {};
|
||||
|
|
@ -23,15 +19,15 @@ TCAD.App2D = function() {
|
|||
};
|
||||
|
||||
this.registerAction('undo', "Undo", function () {
|
||||
app.undo();
|
||||
app.viewer.historyManager.undo();
|
||||
});
|
||||
|
||||
this.registerAction('redo', "Redo", function () {
|
||||
app.redo();
|
||||
app.viewer.historyManager.redo();
|
||||
});
|
||||
|
||||
this.registerAction('checkpoint', "Checkpoint", function () {
|
||||
app.checkpoint();
|
||||
app.viewer.historyManager.checkpoint();
|
||||
});
|
||||
|
||||
this.registerAction('addPoint', "Add Point", function () {
|
||||
|
|
@ -74,7 +70,7 @@ TCAD.App2D = function() {
|
|||
});
|
||||
|
||||
this.registerAction('save', "Save", function () {
|
||||
var sketchData = app.saveSketch();
|
||||
var sketchData = app.viewer.io.serializeSketch();
|
||||
console.log(sketchData);
|
||||
var sketchId = app.getSketchId();
|
||||
localStorage.setItem(app.getSketchId(), sketchData);
|
||||
|
|
@ -138,7 +134,7 @@ TCAD.App2D = function() {
|
|||
});
|
||||
|
||||
this.registerAction('CLEAN UP', "Clean All Draw", function () {
|
||||
app.cleanUp();
|
||||
app.cleanUpData();
|
||||
app.viewer.refresh();
|
||||
});
|
||||
};
|
||||
|
|
@ -146,193 +142,13 @@ TCAD.App2D = function() {
|
|||
TCAD.App2D.prototype.loadFromLocalStorage = function() {
|
||||
var sketchId = this.getSketchId();
|
||||
var sketchData = localStorage.getItem(sketchId);
|
||||
var boundary = null;
|
||||
if (sketchData != null) {
|
||||
this.lastCheckpoint = sketchData;
|
||||
this.diffs = [];
|
||||
this.historyPointer = -1;
|
||||
|
||||
var sketch = JSON.parse(sketchData);
|
||||
boundary = this.loadSketch(sketch);
|
||||
this.viewer.historyManager.init(sketchData);
|
||||
this.viewer.io.loadSketch(sketchData);
|
||||
}
|
||||
this.viewer.repaint();
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.cleanUp = function() {
|
||||
for (var l = 0; l < this.viewer.layers.length; ++l) {
|
||||
var layer = this.viewer.layers[l];
|
||||
if (layer.objects.length != 0) {
|
||||
layer.objects = [];
|
||||
}
|
||||
}
|
||||
this.viewer.deselectAll();
|
||||
TCAD.TWO.utils.ID_COUNTER = 0;
|
||||
if (this.viewer.parametricManager.subSystems.length != 0) {
|
||||
this.viewer.parametricManager.subSystems = [];
|
||||
this.viewer.parametricManager.notify();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.saveSketch = function() {
|
||||
var sketch = {};
|
||||
//sketch.boundary = boundary;
|
||||
sketch.layers = [];
|
||||
function point(p) {
|
||||
return [ p.id, [p._x.id, p.x], [p._y.id, p.y] ];
|
||||
}
|
||||
var toSave = [this.viewer.dimLayers, this.viewer.layers]
|
||||
for (var t = 0; t < toSave.length; ++t) {
|
||||
var layers = toSave[t];
|
||||
for (var l = 0; l < layers.length; ++l) {
|
||||
var layer = layers[l];
|
||||
var isBoundary = layer.name === '';
|
||||
var toLayer = {name : layer.name, data : []};
|
||||
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};
|
||||
if (obj.aux) to.aux = obj.aux;
|
||||
if (obj.edge !== undefined) to.edge = obj.edge;
|
||||
toLayer.data.push(to);
|
||||
if (obj._class === 'TCAD.TWO.Segment') {
|
||||
to.points = [point(obj.a), point(obj.b)];
|
||||
} else if (obj._class === 'TCAD.TWO.EndPoint') {
|
||||
to.location = point(obj);
|
||||
} else if (obj._class === 'TCAD.TWO.Arc') {
|
||||
to.points = [point(obj.a), point(obj.b), point(obj.c)];
|
||||
} else if (obj._class === 'TCAD.TWO.Circle') {
|
||||
to.c = point(obj.c);
|
||||
to.r = obj.r.get();
|
||||
} else if (obj._class === 'TCAD.TWO.Dimension' || obj._class === 'TCAD.TWO.HDimension' || obj._class === 'TCAD.TWO.VDimension') {
|
||||
to.a = obj.a.id;
|
||||
to.b = obj.b.id;
|
||||
to.flip = obj.flip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var constrs = sketch.constraints = [];
|
||||
var subSystems = this.viewer.parametricManager.subSystems;
|
||||
for (var j = 0; j < subSystems.length; j++) {
|
||||
var sub = subSystems[j];
|
||||
for (var i = 0; i < sub.constraints.length; ++i) {
|
||||
if (!sub.constraints[i].aux) {
|
||||
constrs.push(this.serializeConstr(sub.constraints[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return JSON.stringify(sketch);
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.loadSketch = function(sketch) {
|
||||
|
||||
this.cleanUp();
|
||||
|
||||
var index = {};
|
||||
|
||||
function endPoint(p) {
|
||||
var id = p[0];
|
||||
var ep = index[id];
|
||||
if (ep !== undefined) {
|
||||
return
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
var layerIdGen = 0;
|
||||
function getLayer(viewer, name) {
|
||||
if (name === undefined) {
|
||||
name = "layer_" + layerIdGen++;
|
||||
} else {
|
||||
if (name === viewer.dimLayer.name) {
|
||||
return viewer.dimLayer;
|
||||
}
|
||||
for (var i = 0; i < viewer.layers.length; ++i) {
|
||||
if (name === viewer.layers[i].name) {
|
||||
return viewer.layers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
var layer = new TCAD.TWO.Layer(name, TCAD.TWO.Styles.DEFAULT);
|
||||
viewer.layers.push(layer);
|
||||
return layer;
|
||||
}
|
||||
var activeLayerCandidate = this.viewer.layers.length;
|
||||
if (sketch.layers !== undefined) {
|
||||
for (var l = 0; l < sketch.layers.length; ++l) {
|
||||
var layer = getLayer(this.viewer, sketch.layers[l].name);
|
||||
for (var i = 0; i < sketch.layers[l].data.length; ++i) {
|
||||
var obj = sketch.layers[l].data[i];
|
||||
var skobj = null;
|
||||
if (obj._class === 'TCAD.TWO.Segment') {
|
||||
var a = endPoint(obj.points[0]);
|
||||
var b = endPoint(obj.points[1]);
|
||||
skobj = new TCAD.TWO.Segment(a, b);
|
||||
} else if (obj._class === 'TCAD.TWO.EndPoint') {
|
||||
skobj = endPoint(obj.location);
|
||||
} else if (obj._class === 'TCAD.TWO.Arc') {
|
||||
var a = endPoint(obj.points[0]);
|
||||
var b = endPoint(obj.points[1]);
|
||||
var c = endPoint(obj.points[2]);
|
||||
skobj = new TCAD.TWO.Arc(a, b, c);
|
||||
skobj.stabilize(this.viewer);
|
||||
} else if (obj._class === 'TCAD.TWO.Circle') {
|
||||
var c = endPoint(obj.c);
|
||||
skobj = new TCAD.TWO.Circle(c);
|
||||
skobj.r.set(obj.r);
|
||||
} else if (obj._class === 'TCAD.TWO.HDimension') {
|
||||
skobj = new TCAD.TWO.HDimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
} else if (obj._class === 'TCAD.TWO.VDimension') {
|
||||
skobj = new TCAD.TWO.VDimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
} else if (obj._class === 'TCAD.TWO.Dimension') {
|
||||
skobj = new TCAD.TWO.Dimension(obj.a, obj.b);
|
||||
skobj.flip = obj.flip;
|
||||
}
|
||||
if (skobj != null) {
|
||||
if (!!obj.aux) skobj.accept(function(o){o.aux = true; return true;});
|
||||
if (obj.edge !== undefined) {
|
||||
skobj.edge = obj.edge;
|
||||
}
|
||||
layer.objects.push(skobj);
|
||||
skobj.layer = layer;
|
||||
index[obj.id] = skobj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < this.viewer.dimLayer.objects.length; ++i) {
|
||||
obj = this.viewer.dimLayer.objects[i];
|
||||
//if (obj._class === 'TCAD.TWO.Dimension' || obj._class === 'TCAD.TWO.HDimension' || obj._class === 'TCAD.TWO.VDimension') {
|
||||
obj.a = index[obj.a];
|
||||
obj.b = index[obj.b];
|
||||
//}
|
||||
}
|
||||
|
||||
if (sketch.boundary !== undefined && sketch.boundary != null) {
|
||||
this.updateBoundary(sketch.boundary);
|
||||
}
|
||||
|
||||
if (sketch.constraints !== undefined) {
|
||||
for (var i = 0; i < sketch.constraints.length; ++i) {
|
||||
var c = this.parseConstr(sketch.constraints[i], index);
|
||||
this.viewer.parametricManager._add(c);
|
||||
}
|
||||
this.viewer.parametricManager.notify();
|
||||
}
|
||||
if (activeLayerCandidate < this.viewer.layers.length) {
|
||||
this.viewer.setActiveLayer(this.viewer.layers[activeLayerCandidate]);
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.updateBoundary = function (boundary) {
|
||||
|
||||
var edges = [];
|
||||
|
|
@ -382,27 +198,6 @@ TCAD.App2D.prototype.updateBoundary = function (boundary) {
|
|||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.parseConstr = function (c, index) {
|
||||
function find(id) {
|
||||
var p = index[id];
|
||||
if (!p) {
|
||||
throw "CAN'T READ SKETCH. Object ref is not found.";
|
||||
}
|
||||
return p;
|
||||
}
|
||||
var name = c[0];
|
||||
var ps = c[1];
|
||||
var constrCreate = TCAD.TWO.Constraints.Factory[name];
|
||||
if (constrCreate === undefined) {
|
||||
throw "CAN'T READ SKETCH. Constraint " + name + " hasn't been registered.";
|
||||
}
|
||||
return constrCreate(find, ps);
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.serializeConstr = function (c) {
|
||||
return c.serialize();
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.getSketchId = function() {
|
||||
var id = window.location.hash.substring(1);
|
||||
if (!id) {
|
||||
|
|
@ -410,91 +205,3 @@ TCAD.App2D.prototype.getSketchId = function() {
|
|||
}
|
||||
return "TCAD.projects." + id;
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.undo = function () {
|
||||
var currentState = this.saveSketch();
|
||||
if (currentState == this.lastCheckpoint) {
|
||||
if (this.historyPointer != -1) {
|
||||
var diff = this.diffs[this.historyPointer];
|
||||
this.lastCheckpoint = this.applyDiff(this.lastCheckpoint, diff);
|
||||
this.loadSketch(JSON.parse(this.lastCheckpoint));
|
||||
this.viewer.refresh();
|
||||
console.log(this.lastCheckpoint);
|
||||
this.historyPointer --;
|
||||
}
|
||||
} else {
|
||||
var diffToCurr = this.getDiff(currentState, this.lastCheckpoint);
|
||||
if (this.historyPointer != this.diffs.length - 1) {
|
||||
this.diffs.splice(this.historyPointer + 1, this.diffs.length - this.historyPointer + 1)
|
||||
}
|
||||
this.diffs.push(diffToCurr);
|
||||
this.loadSketch(JSON.parse(this.lastCheckpoint));
|
||||
this.viewer.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.checkpoint = function () {
|
||||
var currentState = this.saveSketch();
|
||||
if (currentState == this.lastCheckpoint) {
|
||||
return;
|
||||
}
|
||||
var diffToCurr = this.getDiff(currentState, this.lastCheckpoint);
|
||||
if (this.historyPointer != this.diffs.length - 1) {
|
||||
this.diffs.splice(this.historyPointer + 1, this.diffs.length - this.historyPointer + 1)
|
||||
}
|
||||
this.diffs.push(diffToCurr);
|
||||
this.historyPointer = this.diffs.length - 1;
|
||||
this.lastCheckpoint = currentState;
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.redo = function () {
|
||||
var currentState = this.saveSketch();
|
||||
if (currentState != this.lastCheckpoint) {
|
||||
return;
|
||||
}
|
||||
if (this.historyPointer != this.diffs.length - 1 && this.diffs.length != 0) {
|
||||
this.historyPointer ++;
|
||||
var diff = this.diffs[this.historyPointer];
|
||||
this.lastCheckpoint = this.applyDiffInv(this.lastCheckpoint, diff);
|
||||
console.log(this.lastCheckpoint);
|
||||
this.loadSketch(JSON.parse(this.lastCheckpoint));
|
||||
this.viewer.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.applyDiff = function (text1, diff) {
|
||||
var dmp = this.dmp;
|
||||
var results = dmp.patch_apply(diff, text1);
|
||||
return results[0];
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.applyDiffInv = function (text1, diff) {
|
||||
this.reversePatch(diff);
|
||||
var result = this.applyDiff(text1, diff);
|
||||
this.reversePatch(diff);
|
||||
return result;
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.reversePatch = function (plist) {
|
||||
for (var i = 0; i < plist.length; i++) {
|
||||
var patch = plist[i];
|
||||
for (var j = 0; j < patch.diffs.length; j++) {
|
||||
var diff = patch.diffs[j];
|
||||
diff[0] *= -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.App2D.prototype.getDiff = function (text1, text2) {
|
||||
var dmp = this.dmp;
|
||||
var diff = dmp.diff_main(text1, text2, true);
|
||||
|
||||
if (diff.length > 2) {
|
||||
dmp.diff_cleanupSemantic(diff);
|
||||
}
|
||||
|
||||
var patch_list = dmp.patch_make(text1, text2, diff);
|
||||
//var patch_text = dmp.patch_toText(patch_list);
|
||||
//console.log(patch_list);
|
||||
return patch_list;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ TCAD.TWO.ParametricManager.prototype.refresh = function() {
|
|||
|
||||
TCAD.TWO.ParametricManager.prototype.add = function(constr) {
|
||||
this._add(constr);
|
||||
this.viewer.historyManager.checkpoint();
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ TCAD.TWO.AddArcTool.prototype.mousemove = function(e) {
|
|||
|
||||
TCAD.TWO.AddArcTool.prototype.mouseup = function(e) {
|
||||
if (this.arc == null) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
var p = this.viewer.screenToModel(e);
|
||||
this.arc = new TCAD.TWO.Arc(
|
||||
new TCAD.TWO.EndPoint(p.x, p.y),
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ TCAD.TWO.EditCircleTool.prototype.solveRequest = function(rough) {
|
|||
|
||||
TCAD.TWO.EditCircleTool.prototype.mouseup = function(e) {
|
||||
if (this.circle == null) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
var p = this.viewer.screenToModel(e);
|
||||
this.circle = new TCAD.TWO.Circle(
|
||||
new TCAD.TWO.EndPoint(p.x, p.y)
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@ TCAD.TWO.AddDimTool.prototype.mouseup = function(e) {
|
|||
this.viewer.cleanSnap();
|
||||
|
||||
if (this.dim == null) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
this.dim = this.dimCreation(p, new TCAD.TWO.EndPoint(p.x, p.y));
|
||||
this.layer.objects.push(this.dim);
|
||||
this.viewer.refresh();
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ TCAD.TWO.AddPointTool.prototype.mousedown = function(e) {
|
|||
};
|
||||
|
||||
TCAD.TWO.AddPointTool.prototype.mouseup = function(e) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
var a = this.viewer.screenToModel(e);
|
||||
var p = new TCAD.TWO.EndPoint(a.x, a.y);
|
||||
var layer = this.viewer.activeLayer();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ TCAD.test.runSuite = function() {
|
|||
};
|
||||
|
||||
_loadFixture = function(name) {
|
||||
APP.loadSketch(TCAD.test.fixtures[name]);
|
||||
APP._loadSketch(TCAD.test.fixtures[name]);
|
||||
};
|
||||
|
||||
_loadFixturesToLocalStorage = function() {
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@
|
|||
<script src="lib/numeric-1.2.6.js"></script>
|
||||
<script src="lib/diff_match_patch.js"></script>
|
||||
<script src="app/sketcher/canvas.js"></script>
|
||||
<script src="app/sketcher/io.js"></script>
|
||||
<script src="app/sketcher/history.js"></script>
|
||||
<script src="app/sketcher/shapes/arc.js"></script>
|
||||
<script src="app/sketcher/shapes/circle.js"></script>
|
||||
<script src="app/sketcher/shapes/segment.js"></script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue