awv3
Version:
⚡ AWV3 embedded CAD
188 lines (147 loc) • 5.76 kB
JavaScript
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;
}();