UNPKG

awv3

Version:
188 lines (147 loc) 5.76 kB
import { addCommand } from '../command/highlevel'; import Constraint from './index'; import { incidence, horizontality, verticality } from './type'; var ConstraintAdder = /*#__PURE__*/ function () { function ConstraintAdder(sketch) { // 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 Set(); this.verticalSet = new Set(); // preprocess all objects and constraints currently on sketch this.init(); } var _proto = ConstraintAdder.prototype; _proto.init = function init() { // take all present constraints into account for (var _iterator = this.sketch.children, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _object = _ref; switch (_object.state.class) { case incidence.type: this.incidenceDsu.merge(_object.entities[0].id, _object.entities[1].id); break; case verticality.type: this.verticalSet.add(_object.entities[0].id); break; case horizontality.type: this.horizontalSet.add(_object.entities[0].id); break; } } }; // add a new constraint to the internal buffer (if it is not excessive) _proto.add = function add(type, entities, value) { if (value === void 0) { value = {}; } 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 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 verticality.type: if (!this.verticalSet.has(entities[0].id)) this.verticalSet.add(entities[0].id);else return; break; case 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; for (var _iterator2 = this.sketch.children, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } var _object2 = _ref2; if (isExcessive(geomParams, _object2.geomParams)) return; } break; } this.constraints.push(geomParams); }; // return constraint statements in the internal buffer, clear the buffer _proto.commit = function commit() { var _this = this; var statements = this.constraints.map(function (geomParams) { return addCommand(_this.sketch, geomParams); }); this.constraints = []; return statements; }; return ConstraintAdder; }(); export { ConstraintAdder as default }; 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 = Constraint(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 export var DSU = /*#__PURE__*/ function () { function DSU() { this.parents = new Map(); } var _proto2 = DSU.prototype; _proto2.getParent = function getParent(obj) { return this.parents.has(obj) ? this.parents.get(obj) : obj; }; _proto2.setParent = function setParent(obj, par) { this.parents.set(obj, par); }; _proto2.touch = function touch(obj) { if (!this.parents.has(obj)) this.parents.set(obj, obj); }; _proto2.getHead = function getHead(obj) { var par = this.getParent(obj); if (par === obj) return obj; var head = this.getHead(par); this.setParent(obj, head); return head; }; _proto2.merge = 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); }; _proto2.getTouched = function getTouched() { return Array.from(this.parents.keys()); }; return DSU; }();