mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 01:44:19 +01:00
Dimension constants
This commit is contained in:
parent
db1ac31180
commit
fc7dd3c9e9
5 changed files with 154 additions and 31 deletions
|
|
@ -26,7 +26,13 @@ function start() {
|
|||
function infoStr(c) {
|
||||
if (c.SettableFields === undefined) return "";
|
||||
var info = Object.keys(c.SettableFields).map(function(f) {
|
||||
return Number(c[f]).toFixed(2);
|
||||
var val = c[f];
|
||||
var num = Number(val);
|
||||
if (isNaN(num)) {
|
||||
num = Number(app.viewer.parametricManager.constantResolver(val));
|
||||
return val + "(" + (isNaN(num) ? "?" : num.toFixed(2)) + ")" ;
|
||||
}
|
||||
return num.toFixed(2);
|
||||
}).join(", ");
|
||||
if (info.length != 0) {
|
||||
info = " <span style='font-size: 8px;'>[" + info + "]</span>";
|
||||
|
|
@ -76,8 +82,12 @@ function start() {
|
|||
for (var f in c.SettableFields) {
|
||||
var value = c[f];
|
||||
var intro = c.SettableFields[f];
|
||||
value = TCAD.TWO.utils.askNumber(intro, value.toFixed(4), prompt);
|
||||
c[f] = value;
|
||||
|
||||
|
||||
value = TCAD.TWO.utils.askNumber(intro, typeof(value) == "number" ? value.toFixed(4) : value, prompt, pm.constantResolver);
|
||||
if (value != null) {
|
||||
c[f] = value;
|
||||
}
|
||||
}
|
||||
app.viewer.parametricManager.refresh();
|
||||
}
|
||||
|
|
@ -161,13 +171,21 @@ function start() {
|
|||
app.viewer.bus.subscribe('dimScale', function(value) {
|
||||
dimScale.input.val(value);
|
||||
});
|
||||
app.dock.views['Dimensions'].node.append($('<textarea />', {css: {
|
||||
width: '100%',
|
||||
var constantTextArea = $('<textarea />', {placeholder : 'for example: A = 50', css: {
|
||||
width: '100%',
|
||||
resize: 'vertical',
|
||||
background: 'inherit',
|
||||
border : 'none',
|
||||
color: '#C4E1A4'
|
||||
} }));
|
||||
} });
|
||||
app.viewer.params.subscribe('constantDefinition', 'constantTextArea', function(value) {
|
||||
constantTextArea.val(value);
|
||||
})();
|
||||
constantTextArea.bind("change", function() {
|
||||
app.viewer.params.set('constantDefinition', $(this).val(), 'constantTextArea');
|
||||
});
|
||||
|
||||
app.dock.views['Dimensions'].node.append(constantTextArea);
|
||||
}
|
||||
window.___log = function(log) {
|
||||
$('#log').append( " *****************<br><br><br><br>");
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ TCAD.TWO.utils.setStyle = function(style, ctx, scale) {
|
|||
TCAD.TWO.Viewer = function(canvas) {
|
||||
|
||||
this.canvas = canvas;
|
||||
this.params = new TCAD.Parameters();
|
||||
this.io = new TCAD.IO(this);
|
||||
var viewer = this;
|
||||
this.retinaPxielRatio = window.devicePixelRatio > 1 ? window.devicePixelRatio : 1;
|
||||
|
|
|
|||
|
|
@ -141,6 +141,10 @@ TCAD.IO.prototype._loadSketch = function(sketch) {
|
|||
}
|
||||
this.viewer.parametricManager.notify();
|
||||
}
|
||||
var constants = sketch['constants'];
|
||||
if (constants !== undefined) {
|
||||
this.viewer.params.constantDefinition = constants;
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.IO.prototype.cleanUpData = function() {
|
||||
|
|
@ -208,7 +212,11 @@ TCAD.IO.prototype._serializeSketch = function() {
|
|||
constrs.push(this.serializeConstr(sub.constraints[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var constantDefinition = this.viewer.params.constantDefinition;
|
||||
if (constantDefinition !== undefined && constantDefinition != null && !/^\s*$/.test(constantDefinition)) {
|
||||
sketch['constants'] = constantDefinition;
|
||||
}
|
||||
return sketch;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,24 @@ TCAD.TWO.ParametricManager = function(viewer) {
|
|||
this.viewer = viewer;
|
||||
this.subSystems = [];
|
||||
this.listeners = [];
|
||||
this.constantTable = {};
|
||||
|
||||
this.viewer.params.define("constantDefinition", null);
|
||||
this.viewer.params.subscribe("constantDefinition", "parametricManager", this.rebuildConstantTable, this)();
|
||||
this.constantResolver = this.createConstantResolver();
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.createConstantResolver = function() {
|
||||
var pm = this;
|
||||
return function(value) {
|
||||
var _value = pm.constantTable[value];
|
||||
if (_value !== undefined) {
|
||||
value = _value;
|
||||
} else if (typeof(value) != 'number') {
|
||||
console.error("unable to resolve constant " + value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.notify = function(event) {
|
||||
|
|
@ -23,6 +41,29 @@ TCAD.TWO.ParametricManager.prototype.notify = function(event) {
|
|||
}
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.rebuildConstantTable = function(constantDefinition) {
|
||||
this.constantTable = {};
|
||||
if (constantDefinition == null) return;
|
||||
var lines = constantDefinition.split('\n');
|
||||
var prefix = "(function() { \n";
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
var m = line.match(/^\s*([^\s]+)\s*=(.+)$/);
|
||||
if (m != null && m.length == 3) {
|
||||
var constant = m[1];
|
||||
try {
|
||||
var value = eval(prefix + "return " + m[2] + "; \n})()");
|
||||
this.constantTable[constant] = value;
|
||||
prefix += constant + " = " + value + ";\n"
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.findComponents = function(constr) {
|
||||
if (this.subSystems.length === 0) {
|
||||
this.subSystems.push(new TCAD.TWO.SubSystem());
|
||||
|
|
@ -116,7 +157,7 @@ TCAD.TWO.ParametricManager.prototype.removeConstraintsByParams = function(ownedP
|
|||
var toRemove = [];
|
||||
var sub = this.subSystems[s];
|
||||
for (var i = 0; i < sub.constraints.length; ++i) {
|
||||
var sdataArr = sub.constraints[i].getSolveData();
|
||||
var sdataArr = sub.constraints[i].getSolveData(this.constantResolver);
|
||||
MAIN:
|
||||
for (var j = 0; j < sdataArr.length; j++) {
|
||||
var sdata = sdataArr[j];
|
||||
|
|
@ -259,7 +300,7 @@ TCAD.TWO.ParametricManager.prototype.p2lDistance = function(objs, promptCallback
|
|||
var ex = new TCAD.Vector(-(segment.b.y - segment.a.y), segment.b.x - segment.a.x).normalize();
|
||||
var distance = Math.abs(ex.dot(new TCAD.Vector(segment.a.x - target.x, segment.a.y - target.y)));
|
||||
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.P2LDistance.prototype.SettableFields.d, distance.toFixed(2), promptCallback);
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.P2LDistance.prototype.SettableFields.d, distance.toFixed(2), promptCallback, this.constantResolver);
|
||||
|
||||
if (promptDistance != null) {
|
||||
this.add(new TCAD.TWO.Constraints.P2LDistance(target, segment, promptDistance));
|
||||
|
|
@ -313,7 +354,7 @@ TCAD.TWO.ParametricManager.prototype.llAngle = function(objs, promptCallback) {
|
|||
|
||||
var angle = Math.atan2(dy2,dx2) - Math.atan2(dy1,dx1);
|
||||
angle *= 1 / Math.PI * 180;
|
||||
angle = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.Angle.prototype.SettableFields.angle, angle.toFixed(2), promptCallback);
|
||||
angle = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.Angle.prototype.SettableFields.angle, angle.toFixed(2), promptCallback, this.constantResolver);
|
||||
if (angle === null) return;
|
||||
this.add(new TCAD.TWO.Constraints.Angle(points[0], points[1], points[2], points[3], angle));
|
||||
};
|
||||
|
|
@ -327,19 +368,26 @@ TCAD.TWO.utils.constRef = function(value) {
|
|||
TCAD.TWO.ParametricManager.prototype.p2pDistance = function(objs, promptCallback) {
|
||||
var p = this._fetchTwoPoints(objs);
|
||||
var distance = new TCAD.Vector(p[1].x - p[0].x, p[1].y - p[0].y).length();
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.P2PDistance.prototype.SettableFields.d, distance.toFixed(2), promptCallback);
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.P2PDistance.prototype.SettableFields.d, distance.toFixed(2), promptCallback, this.constantResolver);
|
||||
|
||||
if (promptDistance != null) {
|
||||
this.add(new TCAD.TWO.Constraints.P2PDistance(p[0], p[1], promptDistance));
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.TWO.utils.askNumber = function(promptText, initValue, promptCallback) {
|
||||
var promptValue = promptCallback(promptText, initValue);
|
||||
if (promptValue != null) {
|
||||
promptValue = Number(promptValue);
|
||||
TCAD.TWO.utils.askNumber = function(promptText, initValue, promptCallback, resolver) {
|
||||
var promptValueStr = promptCallback(promptText, initValue);
|
||||
if (promptValueStr != null) {
|
||||
var promptValue = Number(promptValueStr);
|
||||
if (promptValue == promptValue) { // check for NaN
|
||||
return promptValue;
|
||||
} else {
|
||||
if (!!resolver) {
|
||||
promptValue = resolver(promptValueStr);
|
||||
if (promptValue == promptValue) {
|
||||
return promptValueStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
@ -348,7 +396,7 @@ TCAD.TWO.utils.askNumber = function(promptText, initValue, promptCallback) {
|
|||
TCAD.TWO.ParametricManager.prototype.radius = function(objs, promptCallback) {
|
||||
var arcs = this._fetchArkCirc(objs, 1);
|
||||
var radius = arcs[0].r.get();
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.Radius.prototype.SettableFields.d, radius.toFixed(2), promptCallback);
|
||||
var promptDistance = TCAD.TWO.utils.askNumber(TCAD.TWO.Constraints.Radius.prototype.SettableFields.d, radius.toFixed(2), promptCallback, this.constantResolver);
|
||||
if (promptDistance != null) {
|
||||
for (var i = 0; i < arcs.length; ++i) {
|
||||
this._add(new TCAD.TWO.Constraints.Radius(arcs[i], promptDistance));
|
||||
|
|
@ -414,7 +462,7 @@ TCAD.TWO.ParametricManager.prototype.getSolveData = function() {
|
|||
TCAD.TWO.ParametricManager.prototype.__getSolveData = function(constraints, out) {
|
||||
for (var i = 0; i < constraints.length; ++i) {
|
||||
var constraint = constraints[i];
|
||||
var data = constraint.getSolveData();
|
||||
var data = constraint.getSolveData(this.constantResolver);
|
||||
for (var j = 0; j < data.length; ++j) {
|
||||
data[j].push(constraint.reducible !== undefined);
|
||||
out.push(data[j]);
|
||||
|
|
@ -928,11 +976,11 @@ TCAD.TWO.Constraints.P2LDistance = function(p, l, d) {
|
|||
TCAD.TWO.Constraints.P2LDistance.prototype.NAME = 'P2LDistance';
|
||||
TCAD.TWO.Constraints.P2LDistance.prototype.UI_NAME = 'Distance P & L';
|
||||
|
||||
TCAD.TWO.Constraints.P2LDistance.prototype.getSolveData = function() {
|
||||
TCAD.TWO.Constraints.P2LDistance.prototype.getSolveData = function(resolver) {
|
||||
var params = [];
|
||||
this.p.collectParams(params);
|
||||
this.l.collectParams(params);
|
||||
return [[this.NAME, params, [this.d]]];
|
||||
return [[this.NAME, params, [resolver(this.d)]]];
|
||||
};
|
||||
|
||||
TCAD.TWO.Constraints.P2LDistance.prototype.serialize = function() {
|
||||
|
|
@ -1012,11 +1060,11 @@ TCAD.TWO.Constraints.P2PDistance = function(p1, p2, d) {
|
|||
TCAD.TWO.Constraints.P2PDistance.prototype.NAME = 'P2PDistance';
|
||||
TCAD.TWO.Constraints.P2PDistance.prototype.UI_NAME = 'Distance Points';
|
||||
|
||||
TCAD.TWO.Constraints.P2PDistance.prototype.getSolveData = function() {
|
||||
TCAD.TWO.Constraints.P2PDistance.prototype.getSolveData = function(resolver) {
|
||||
var params = [];
|
||||
this.p1.collectParams(params);
|
||||
this.p2.collectParams(params);
|
||||
return [[this.NAME, params, [this.d]]];
|
||||
return [[this.NAME, params, [resolver(this.d)]]];
|
||||
};
|
||||
|
||||
TCAD.TWO.Constraints.P2PDistance.prototype.serialize = function() {
|
||||
|
|
@ -1076,8 +1124,8 @@ TCAD.TWO.Constraints.Radius.prototype.NAME = 'Radius';
|
|||
TCAD.TWO.Constraints.Radius.prototype.UI_NAME = 'Radius Value';
|
||||
|
||||
|
||||
TCAD.TWO.Constraints.Radius.prototype.getSolveData = function() {
|
||||
return [['equalsTo', [this.arc.r], [this.d]]];
|
||||
TCAD.TWO.Constraints.Radius.prototype.getSolveData = function(resolver) {
|
||||
return [['equalsTo', [this.arc.r], [resolver(this.d)]]];
|
||||
};
|
||||
|
||||
TCAD.TWO.Constraints.Radius.prototype.serialize = function() {
|
||||
|
|
@ -1360,9 +1408,9 @@ TCAD.TWO.Constraints.Symmetry = function(point, line) {
|
|||
TCAD.TWO.Constraints.Symmetry.prototype.NAME = 'Symmetry';
|
||||
TCAD.TWO.Constraints.Symmetry.prototype.UI_NAME = 'Symmetry';
|
||||
|
||||
TCAD.TWO.Constraints.Symmetry.prototype.getSolveData = function() {
|
||||
var pointInMiddleData = TCAD.TWO.Constraints.PointInMiddle.prototype.getSolveData.call(this);
|
||||
var pointOnLineData = TCAD.TWO.Constraints.PointOnLine.prototype.getSolveData.call(this);
|
||||
TCAD.TWO.Constraints.Symmetry.prototype.getSolveData = function(resolver) {
|
||||
var pointInMiddleData = TCAD.TWO.Constraints.PointInMiddle.prototype.getSolveData.call(this, [resolver]);
|
||||
var pointOnLineData = TCAD.TWO.Constraints.PointOnLine.prototype.getSolveData.call(this, [resolver]);
|
||||
return pointInMiddleData.concat(pointOnLineData);
|
||||
};
|
||||
|
||||
|
|
@ -1387,18 +1435,14 @@ TCAD.TWO.Constraints.Angle = function(p1, p2, p3, p4, angle) {
|
|||
this.p3 = p3;
|
||||
this.p4 = p4;
|
||||
this._angle = new TCAD.TWO.Ref(0);
|
||||
Object.defineProperty(this, "angle", {
|
||||
get: function() {return this._angle.get() / Math.PI * 180},
|
||||
set: function(value) {
|
||||
this._angle.set(value / 180 * Math.PI)}
|
||||
});
|
||||
this.angle = angle;
|
||||
};
|
||||
|
||||
TCAD.TWO.Constraints.Angle.prototype.NAME = 'Angle';
|
||||
TCAD.TWO.Constraints.Angle.prototype.UI_NAME = 'Lines Angle';
|
||||
|
||||
TCAD.TWO.Constraints.Angle.prototype.getSolveData = function() {
|
||||
TCAD.TWO.Constraints.Angle.prototype.getSolveData = function(resolver) {
|
||||
this._angle.set(resolver(this.angle) / 180 * Math.PI);
|
||||
var params = [];
|
||||
this.p1.collectParams(params);
|
||||
this.p2.collectParams(params);
|
||||
|
|
|
|||
|
|
@ -196,6 +196,58 @@ TCAD.toolkit.Tree.prototype._fill = function(data, level) {
|
|||
}
|
||||
};
|
||||
|
||||
TCAD.Parameters = function() {
|
||||
this.listeners = {};
|
||||
};
|
||||
|
||||
TCAD.Parameters.prototype.define = function(name, initValue) {
|
||||
function fn(name) {
|
||||
return '___' + name;
|
||||
}
|
||||
this[fn(name)] = initValue;
|
||||
return Object.defineProperty(this, name, {
|
||||
get: function() { return this[fn(name)]},
|
||||
set: function(value) {
|
||||
var oldValue = this[fn(name)];
|
||||
this[fn(name)] = value;
|
||||
this.notify(name, value, oldValue);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
TCAD.Parameters.prototype.subscribe = function(name, listenerId, callback, scope) {
|
||||
var listenerList = this.listeners[name];
|
||||
if (listenerList === undefined) {
|
||||
listenerList = [];
|
||||
this.listeners[name] = listenerList;
|
||||
}
|
||||
var callbackFunc = scope === undefined ? callback : function() {
|
||||
callback.apply(scope, arguments);
|
||||
};
|
||||
listenerList.push([listenerId, callbackFunc]);
|
||||
var params = this;
|
||||
return (function () { callbackFunc(params[name], undefined, null) }); // return init function
|
||||
};
|
||||
|
||||
TCAD.Parameters.prototype.notify = function(name, newValue, oldValue) {
|
||||
var listenerList = this.listeners[name];
|
||||
if (listenerList !== undefined) {
|
||||
for (var i = 0; i < listenerList.length; i++) {
|
||||
var listenerId = listenerList[i][0];
|
||||
var callback = listenerList[i][1];
|
||||
if (listenerId == null || this.__currentSender == null || listenerId != this.__currentSender) {
|
||||
callback(newValue, oldValue, this.__currentSender);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.__currentSender = null;
|
||||
};
|
||||
|
||||
TCAD.Parameters.prototype.set = function(name, value, sender) {
|
||||
this.__currentSender = sender;
|
||||
this[name] = value;
|
||||
};
|
||||
|
||||
TCAD.Bus = function() {
|
||||
this.listeners = {};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue