UNPKG

awv3

Version:
243 lines (202 loc) 8.98 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.DSU = exports.default = undefined; var _from = require('babel-runtime/core-js/array/from'); var _from2 = _interopRequireDefault(_from); var _map = require('babel-runtime/core-js/map'); var _map2 = _interopRequireDefault(_map); var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _set = require('babel-runtime/core-js/set'); var _set2 = _interopRequireDefault(_set); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _highlevel = require('../command/highlevel'); var _index = require('./index'); var _index2 = _interopRequireDefault(_index); var _type = require('./type'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var ConstraintAdder = function () { function ConstraintAdder(sketch) { (0, _classCallCheck3.default)(this, ConstraintAdder); // the sketch we are going to add constraints to this.sketch = sketch; // the list of constraint geomParams which really should be added this.constraints = []; // dsu structures for incident and inc-tangent point groups this.incidenceDsu = new DSU(); //this.tangencyDsu = new DSU(); // TODO! // sets of horizontal and vertical lines this.horizontalSet = new _set2.default(); this.verticalSet = new _set2.default(); // preprocess all objects and constraints currently on sketch this.init(); } (0, _createClass3.default)(ConstraintAdder, [{ key: 'init', value: function init() { // take all present constraints into account var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(this.sketch.children), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var object = _step.value; switch (object.state.class) { case _type.incidence.type: this.incidenceDsu.merge(object.entities[0].id, object.entities[1].id); break; case _type.verticality.type: this.verticalSet.add(object.entities[0].id); break; case _type.horizontality.type: this.horizontalSet.add(object.entities[0].id); break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } // add a new constraint to the internal buffer (if it is not excessive) }, { key: 'add', value: function add(type, entities) { var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (type.type !== undefined) type = type.type; var geomParams = { class: type, entities: entities, value: value }; // if a new constraint is not excessive, then take it into account switch (type) { case _type.incidence.type: // TODO: implement more complicated handling of incidence // Incidence is an equivalence either on points or on lines / arcs, but not on both together. // E.g.: if a point is incident to two lines, then these lines may be NOT incident. if (this.incidenceDsu.getHead(entities[0].id) !== this.incidenceDsu.getHead(entities[1].id)) this.incidenceDsu.merge(entities[0].id, entities[1].id);else return; break; case _type.verticality.type: if (!this.verticalSet.has(entities[0].id)) this.verticalSet.add(entities[0].id);else return; break; case _type.horizontality.type: if (!this.horizontalSet.has(entities[0].id)) this.horizontalSet.add(entities[0].id);else return; break; default: // TODO: optimize this O(N) search if (this.constraints.some(function (constr) { return isExcessive(geomParams, constr); })) return; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = (0, _getIterator3.default)(this.sketch.children), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var object = _step2.value; if (isExcessive(geomParams, object.geomParams)) return; } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } break; } this.constraints.push(geomParams); } // return constraint statements in the internal buffer, clear the buffer }, { key: 'commit', value: function commit() { var _this = this; var statements = this.constraints.map(function (geomParams) { return (0, _highlevel.addCommand)(_this.sketch, geomParams); }); this.constraints = []; return statements; } }]); return ConstraintAdder; }(); exports.default = ConstraintAdder; function isExcessive(constr0, constr1) { if (constr0.class !== constr1.class) return false; if (constr0.entities.length !== constr1.entities.length) return false; if (constr0.value.value || constr1.value.value || constr0.value.expression || constr1.value.expression) return false; // ignore parametric constraints if (constr0.entities.every(function (obj, idx) { return obj.id === constr1.entities[idx].id; })) return true; var isBinaryCommutative = (0, _index2.default)(constr0.class).isCommutative; if (isBinaryCommutative && constr0.entities.every(function (obj, idx) { return obj.id === constr1.entities[1 - idx].id; })) return true; return false; } // Disjoint Set Union var DSU = exports.DSU = function () { function DSU() { (0, _classCallCheck3.default)(this, DSU); this.parents = new _map2.default(); } (0, _createClass3.default)(DSU, [{ key: 'getParent', value: function getParent(obj) { return this.parents.has(obj) ? this.parents.get(obj) : obj; } }, { key: 'setParent', value: function setParent(obj, par) { this.parents.set(obj, par); } }, { key: 'touch', value: function touch(obj) { if (!this.parents.has(obj)) this.parents.set(obj, obj); } }, { key: 'getHead', value: function getHead(obj) { var par = this.getParent(obj); if (par === obj) return obj; var head = this.getHead(par); this.setParent(obj, head); return head; } }, { key: 'merge', value: function merge(objA, objB) { this.touch(objA); this.touch(objB); objA = this.getHead(objA); objB = this.getHead(objB); Math.random() < 0.5 ? this.setParent(objA, objB) : this.setParent(objB, objA); } }, { key: 'getTouched', value: function getTouched() { return (0, _from2.default)(this.parents.keys()); } }]); return DSU; }();