awv3
Version:
⚡ AWV3 embedded CAD
645 lines (512 loc) • 25.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _expressions = require('./expressions');
var _statements = require('./statements');
var _statements2 = _interopRequireDefault(_statements);
var _sketcher = require('../sketcher');
var _sketcher2 = _interopRequireDefault(_sketcher);
var _point = require('../sketcher/graphics/point');
var _point2 = _interopRequireDefault(_point);
var _line = require('../sketcher/graphics/line');
var _line2 = _interopRequireDefault(_line);
var _arc = require('../sketcher/graphics/arc');
var _arc2 = _interopRequireDefault(_arc);
var _object = require('../../three/object3');
var _object2 = _interopRequireDefault(_object);
var _three = require('three');
var THREE = _interopRequireWildcard(_three);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Sketch = function () {
function Sketch() {
(0, _classCallCheck3.default)(this, Sketch);
}
(0, _createClass3.default)(Sketch, [{
key: 'getPart',
value: function getPart() {
return this.parent.parent; // Part.SketchSet.Sketch
}
// Physically add objects to the sketch (in contrast to addAuxObject)
// If some objects were previously added with addAuxObject, automatically remove them from aux objects
// possible options:
// onServer (default: true) - whether to send commands to the server.
// onClient (default: true) - whether to add objects to children
// autoconstraint (default: false) - if true, then implied constraints are generated if neccessary.
// updateSketch (default: false) - whether to update sketch state for the whole sketch, not only for objets. Pass true when adding constraints.
}, {
key: 'addToSketch',
value: function addToSketch(objects) {
var _this = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (options.onServer === undefined) options.onServer = true;
if (options.onClient === undefined) options.onClient = true;
if (options.updateSketch === undefined) options.updateSketch = false;
if (options.autoconstraint === undefined) options.autoconstraint = false;
objects = [].concat(objects);
var sketcher = this.sketcher;
var view = sketcher.view;
if (objects.length === 0) return _promise2.default.resolve();
if (options.onClient) this.add.apply(this, objects); // must be done before server command so that parseObjectTree can find the objects in children
var afterServer = function afterServer() {
objects.forEach(function (obj) {
if (_this.sketchObjects.has(obj)) return;
_this.sketchObjects.add(obj);
_this.emit('SketchAdded', obj);
});
if (options.autoconstraint && sketcher.autoconstraintIncremental) {
//generate implied constraints for the objects just drawn by user
var autogen = new ConstraintGenerator(_this);
var constraints = autogen.generateImpliedConstraints(Sketch.ForObjectsWithChildren(objects));
if (constraints.length > 0) return _this.addToSketch(constraints, { updateSketch: true });
}
};
// add objects to the sketch on the server and, if successful, on the client
if (options.onServer) {
var statements = objects.map(function (object) {
return object.prepareAddOnServer(_this);
});
/* if (options.updateSketch)
statements.push(this.updateFromServer());*/
return _statements2.default.all(statements).execute(sketcher.socket).then(afterServer);
}
return _promise2.default.resolve(afterServer());
}
// Remove objects previously added with addToSketch
}, {
key: 'removeFromSketch',
value: function () {
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(objects) {
var _this2 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var sketcher, view, objectsCh, relatedConstraints, statements, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, obj, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, _obj;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (options.onServer === undefined) options.onServer = true;
if (options.onClient === undefined) options.onClient = true;
if (options.updateSketch === undefined) options.updateSketch = false;
objects = [].concat(objects);
sketcher = this.sketcher;
view = sketcher.view;
//add related constraints for removal (before objects)
objectsCh = Sketch.ForObjectsWithChildren(objects);
relatedConstraints = this.getConstraintsOnSketch(objectsCh);
objects = relatedConstraints.concat(objects.filter(function (obj) {
return relatedConstraints.indexOf(obj) === -1;
}));
objectsCh = relatedConstraints.concat(objectsCh.filter(function (obj) {
return relatedConstraints.indexOf(obj) === -1;
}));
// remove objects from the sketch on the server and, if successful, on the client
if (!options.onServer) {
_context.next = 15;
break;
}
statements = objects.map(function (object) {
return object.prepareRemoveOnServer(_this2);
});
if (options.updateSketch) statements.push(this.updateFromServer());
_context.next = 15;
return _statements2.default.all(statements).execute(sketcher.socket);
case 15:
if (!options.onClient) {
_context.next = 44;
break;
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 19;
_iterator = (0, _getIterator3.default)(objects);
case 21:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 30;
break;
}
obj = _step.value;
this.remove(obj);
_context.next = 26;
return this.emit('SketchRemoved', obj);
case 26:
//note: removed object is completely destroyed
obj.destroy();
case 27:
_iteratorNormalCompletion = true;
_context.next = 21;
break;
case 30:
_context.next = 36;
break;
case 32:
_context.prev = 32;
_context.t0 = _context['catch'](19);
_didIteratorError = true;
_iteratorError = _context.t0;
case 36:
_context.prev = 36;
_context.prev = 37;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 39:
_context.prev = 39;
if (!_didIteratorError) {
_context.next = 42;
break;
}
throw _iteratorError;
case 42:
return _context.finish(39);
case 43:
return _context.finish(36);
case 44:
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context.prev = 47;
for (_iterator2 = (0, _getIterator3.default)(objects); !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
_obj = _step2.value;
this.sketchObjects.delete(_obj);
}_context.next = 55;
break;
case 51:
_context.prev = 51;
_context.t1 = _context['catch'](47);
_didIteratorError2 = true;
_iteratorError2 = _context.t1;
case 55:
_context.prev = 55;
_context.prev = 56;
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
case 58:
_context.prev = 58;
if (!_didIteratorError2) {
_context.next = 61;
break;
}
throw _iteratorError2;
case 61:
return _context.finish(58);
case 62:
return _context.finish(55);
case 63:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[19, 32, 36, 44], [37,, 39, 43], [47, 51, 55, 63], [56,, 58, 62]]);
}));
function removeFromSketch(_x2, _x3) {
return _ref.apply(this, arguments);
}
return removeFromSketch;
}()
// Duplicate objects
}, {
key: 'copyObjects',
value: function copyObjects(objects, translate, rotate) {
var _this3 = this;
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var statement = (0, _expressions.Return)((0, _expressions.CopyObjects)(this, objects, translate, rotate));
// TODO: parsing objects returned from DuplicateObjects would be more efficient than
// updating the whole sketch. chooseTool is needed to add interactions to the new objects
return statement.and(this.updateFromServer()).then(function () {
return _this3.sketcher.chooseTool('empty');
});
}
// Return list of objects added with addToSketch (but not addAuxObject)
}, {
key: 'getObjectsOnSketch',
value: function getObjectsOnSketch() {
var _this4 = this;
return this.children.filter(function (c) {
return _this4.sketchObjects.has(c);
});
}
// Return list of constraints related to passed object or objects,
// or list of all constraints, if 'objects' parameter is undefined
}, {
key: 'getConstraintsOnSketch',
value: function getConstraintsOnSketch(objects) {
if (objects) objects = [].concat(objects);
var inObjectsList = function inObjectsList(elem) {
return !objects || objects.indexOf(elem) !== -1;
};
var isRelatedToObjects = function isRelatedToObjects(constr) {
return constr.args.some(inObjectsList);
};
var constraintsList = this.getObjectsOnSketch().filter(function (child) {
return child instanceof Constraint;
}).filter(isRelatedToObjects);
return constraintsList;
}
// Return ancestor of the object that is directly lying on the sketch
}, {
key: 'getAncestorOnSketch',
value: function getAncestorOnSketch(object) {
var _this5 = this;
object.traverseAncestors(function (ancestor) {
if (ancestor.parent === _this5) object = ancestor;
});
return object;
}
// Return true if object was added with addToSketch
}, {
key: 'isOnSketch',
value: function isOnSketch(object) {
return this.sketchObjects.has(object);
}
// Add auxiliary objects which shouldn't physically be on the sketch
// These objects will be displayed in sketch coordinates but not returned from getObjectsOnSketch
// Example of such objects: sketch's grid, preview line segment for polyline being created
}, {
key: 'addAuxObject',
value: function addAuxObject(objects /*, options*/) {
var _this6 = this;
objects = [].concat(objects);
var view = this.sketcher.view;
// we can't automatically remove objects from the sketch because
// it's an asynchronous action; this function should be synchronous
if (objects.some(function (object) {
return this.isOnSketch(object);
}, this)) throw "Sketch.addAuxObject: can't add object on sketch. Remove it first";
objects.forEach(function (obj) {
_this6.add(obj);
});
}
// Remove objects previously added with addAuxObject
}, {
key: 'removeAuxObject',
value: function removeAuxObject(objects /*, options*/) {
var _this7 = this;
objects = [].concat(objects);
var view = this.sketcher.view;
objects.forEach(function (obj) {
_this7.remove(obj);
//note: object is completely disposed (not usable afterwards)
obj.destroy();
});
}
}, {
key: 'showBox',
value: function showBox() {
this.addAuxObject(this.__box);
}
}, {
key: 'hideBox',
value: function hideBox() {
this.removeAuxObject(this.__box);
}
}, {
key: 'updateBox',
value: function updateBox() {
var _this8 = this;
this.updateMatrixWorld();
// bbox is bounding box in local to sketch coordinates
var bbox = new THREE.Box3();
var v1 = new THREE.Vector3();
this.getObjectsOnSketch().forEach(function (obj) {
return obj.traverseVisible(function (node) {
if (!(node.geometry instanceof THREE.Geometry)) return;
node.geometry.vertices.forEach(function (vertex) {
// translate vertex coordinates from local-to-node to local-to-sketch
v1.copy(vertex);
node.localToWorld(v1);
_this8.worldToLocal(v1);
bbox.expandByPoint(v1);
});
});
});
var thisBox = this.__box;
thisBox.material = new THREE.MeshPhongMaterial({
color: 0xffffff, emissive: 0xffffff, specular: 0xffffff, shininess: 1,
transparent: true, opacity: 0.3, depthWrite: false
});
if (bbox.isEmpty()) {
// (nothing on sketch)
thisBox.scale.set(1e-3, 1e-3, 1e-3);
thisBox.position.set(0, 0, 0);
} else {
//make box flat
bbox.min.z = -1e-3;
bbox.max.z = 1e-3;
// !nb: updates thisBox from bbox
bbox.size(thisBox.scale);
bbox.center(thisBox.position);
}
}
}, {
key: 'showDimensions',
value: function showDimensions() {
this.addAuxObject(this.__dimensions);
}
}, {
key: 'hideDimensions',
value: function hideDimensions() {
this.removeAuxObject(this.__dimensions);
}
// intercept graphical objects created on the server
}, {
key: 'updateDimensionsFactory',
value: function updateDimensionsFactory(input, result) {
var data = input.data;
var worldToLocal = new THREE.Matrix4().getInverse(this.matrix);
switch (input.type) {
case 'Cone':
//transform to sketch coordinates
var pos = new THREE.Vector3().fromArray(data.position).applyMatrix4(worldToLocal);
var dir = new THREE.Vector3().fromArray(data.axis).transformDirection(worldToLocal);
var height = dir.length();
var diam = Math.max(data.diameters[0], data.diameters[1]);
//create two-sided arrow
var geom = new THREE.Geometry();
geom.vertices.push(new THREE.Vector3(height, -diam / 2, 0), new THREE.Vector3(height, diam / 2, 0), new THREE.Vector3(0, 0, 0));
geom.faces.push(new THREE.Face3(0, 1, 2), new THREE.Face3(0, 2, 1));
geom.computeFaceNormals();
var mesh = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({ color: 0x7fff7f }));
//set position and orientation of arrow
mesh.position.copy(pos);
mesh.quaternion.setFromUnitVectors(new THREE.Vector3(1, 0, 0), dir);
result.push(mesh);
break;
case 'Text':
if (data.text == '@') break; //no idea why this trash comes
//note: only following types of text are properly supported:
// textType = 1 (screen-oriented, fixed-sized text)
// alignment = 0 (left/baseline-aligned text)
//create 3D text
var params = { size: 1, height: 0, font: this.sketcher.font };
var geom = new THREE.TextGeometry(data.text, params);
geom.computeBoundingBox(); //for debugging
var mesh = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({ color: 0x3fffbf }));
//set position in sketch coordinates
var obj = new THREE.Object3D();
//obj.fullName = factoryPart.name; //no idea what it is...
obj.mesh = mesh;
obj.add(mesh);
obj.position.fromArray(data.position).applyMatrix4(worldToLocal);
//add pixel-based sizing
obj.setGeomSizes = function (sizes) {
var s = sizes[0];
this.mesh.scale.set(s, s, s);
};
//register automatic updates
var view = this.sketcher.view;
result.push(obj);
break;
case 'Line':
data.geometry.applyMatrix(worldToLocal);
data.material = new THREE.MeshBasicMaterial({ color: 0x7fff7f });
result.push(data);
break;
}
}
}, {
key: 'showConstraints',
value: function showConstraints(obj) {
var constraints = this.getConstraintsOnSketch(obj);
if (constraints.length === 0) return;
obj.constraintsSubstrate.visible = true;
this.updateConstraints(obj);
constraints.forEach(function (child) {
return child.show();
});
}
}, {
key: 'hideConstraints',
value: function hideConstraints() {
var constraints = this.getConstraintsOnSketch();
constraints.forEach(function (child) {
child.args.forEach(function (arg) {
arg.hovered = false;
});
child.hide();
});
this.getObjectsOnSketch().forEach(function (obj) {
Sketch.ForObjectsWithChildren(obj, function (arg) {
if (arg.constraintsSubstrate) arg.constraintsSubstrate.visible = false;
});
});
}
}, {
key: 'updateConstraints',
value: function updateConstraints(obj) {
var substrate = obj.constraintsSubstrate;
var constraints = this.getConstraintsOnSketch(obj);
if (constraints.length === 0) {
obj.constraintsSubstrate.visible = false;
obj.interact.unhover && obj.interact.unhover();
return 0;
}
var len = constraints.length;
var scale = constraints[0].mesh.scale.x;
var size = 1.2 * scale;
substrate.scale.set(size * constraints.length, size, Math.min(size, 1));
var pos = obj.getSubstratePosition(substrate.scale.x, size);
substrate.position.set(pos.x, pos.y, -1);
var mostLeftX = substrate.position.x + obj.position.x - substrate.scale.x / 2;
var middleY = substrate.position.y + obj.position.y;
for (var i = 0; i < len; ++i) {
constraints[i].position.set(mostLeftX + (i + 0.5) * size, middleY, 0);
}
}
// for loop over object or objects, including child points
// if no callback specified, then all the objects are returned in array
}], [{
key: 'FindSketchOf',
value: function FindSketchOf(obj) {
while (obj) {
if (obj instanceof Sketch) return obj;
obj = obj.parent;
}
}
}, {
key: 'FindSketchSetOf',
value: function FindSketchSetOf(obj) {
var result;
obj.traverseAncestors(function (s) {
result = result || s.members.SketchSet;
});
return result;
}
}, {
key: 'ForObjectsWithChildren',
value: function ForObjectsWithChildren(objs, callback) {
var result = undefined;
if (!callback) {
result = [];
callback = function callback(obj) {
return result.push(obj);
};
}
objs = [].concat(objs);
objs.forEach(function (obj) {
if (!obj) return;
callback(obj);
if (obj instanceof _point2.default) return;
if (obj.points) obj.points.forEach(callback);
if (obj.centerPoint) callback(obj.centerPoint);
});
return result;
}
}]);
return Sketch;
}();
exports.default = Sketch;