UNPKG

gs-json

Version:

gs-JSON is a domain agnostic unifying 3D file format for geometric and semantic modelling (hence the 'gs').

1,259 lines (1,147 loc) 212 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Kernel = undefined; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _arr2 = require("./libs/arr/arr"); var _enums = require("./enums"); var _geom = require("./geom"); var _topo_trees = require("./libs/topo_trees/topo_trees"); var _three = require("three"); var three = _interopRequireWildcard(_three); var _threex = require("./libs/threex/threex"); var threex = _interopRequireWildcard(_threex); var _uuid = require("./libs/uuid/uuid"); 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 _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Kernel Class * This class controls all access to the data and ensures that the data remains consistent. * No other class should have any direct access to this data. */ var Kernel = exports.Kernel = function () { /** * Construct a new model. If data is provided, the model will be populated with this data. * @param * @return */ function Kernel(model, data) { var _this = this; _classCallCheck(this, Kernel); this._model = model; this._geom = new _geom.Geom(this); this._attribs = new Map(); this._attribs.set(_enums.EGeomType.points, new Map()); this._attribs.set(_enums.EGeomType.objs, new Map()); this._attribs.set(_enums.EGeomType.vertices, new Map()); this._attribs.set(_enums.EGeomType.edges, new Map()); this._attribs.set(_enums.EGeomType.wires, new Map()); this._attribs.set(_enums.EGeomType.faces, new Map()); this._groups = new Map(); this._topos_trees = new Map(); // Set the data if (data && data.metadata !== undefined) { this._metadata = data.metadata; } else { this._metadata = { filetype: "gs-json", version: "0.1.8", uuid: (0, _uuid.create_UUID)() }; } // Geom points if (data && data.geom !== undefined && data.geom.points !== undefined) { data.geom.points[0].forEach(function (p, i) { return p === null && delete data.geom.points[0][i]; }); this._points = data.geom.points; } else { this._points = [[], [null]]; } // Geom objs if (data && data.geom !== undefined && data.geom.objs !== undefined) { data.geom.objs.forEach(function (o, i) { return o === null && delete data.geom.objs[i]; }); this._objs = data.geom.objs; } else { this._objs = []; } // Attributes if (data && data.attribs && data.attribs.points !== undefined) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { var _loop = function _loop() { var attrib_data = _step.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.points).set(attrib_data.name, attrib_data); }; for (var _iterator = data.attribs.points[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { _loop(); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } if (data && data.attribs && data.attribs.objs !== undefined) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { var _loop2 = function _loop2() { var attrib_data = _step2.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.objs).set(attrib_data.name, attrib_data); }; for (var _iterator2 = data.attribs.objs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { _loop2(); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } if (data && data.attribs && data.attribs.vertices !== undefined) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { var _loop3 = function _loop3() { var attrib_data = _step3.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.vertices).set(attrib_data.name, attrib_data); }; for (var _iterator3 = data.attribs.vertices[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { _loop3(); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } if (data && data.attribs && data.attribs.edges !== undefined) { var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { var _loop4 = function _loop4() { var attrib_data = _step4.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.edges).set(attrib_data.name, attrib_data); }; for (var _iterator4 = data.attribs.edges[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { _loop4(); } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } if (data && data.attribs && data.attribs.wires !== undefined) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { var _loop5 = function _loop5() { var attrib_data = _step5.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.wires).set(attrib_data.name, attrib_data); }; for (var _iterator5 = data.attribs.wires[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { _loop5(); } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } } if (data && data.attribs && data.attribs.faces !== undefined) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { var _loop6 = function _loop6() { var attrib_data = _step6.value; attrib_data.values[0].forEach(function (d, i) { return d === null && delete attrib_data.values[0][i]; }); _this._attribs.get(_enums.EGeomType.faces).set(attrib_data.name, attrib_data); }; for (var _iterator6 = data.attribs.faces[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { _loop6(); } } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } } // Groups if (data && data.attribs && data.groups !== undefined) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = data.groups[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var group_data = _step7.value; if (group_data.parent === undefined) { group_data.parent = null; } if (group_data.objs === undefined) { group_data.objs = []; } if (group_data.points === undefined) { group_data.points = []; } this._topos_trees.set(group_data.name, new _topo_trees.TopoTree(group_data.topos)); group_data.topos = undefined; this._groups.set(group_data.name, group_data); } } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } } } // Model General ------------------------------------------------------------------------------ /** * Exports the model as json data. * @param * @return */ _createClass(Kernel, [{ key: "modelToJSON", value: function modelToJSON() { var jsonData = { metadata: this._metadata, geom: { points: this._points, objs: this._objs } }; if (this._attribs !== undefined) { jsonData.attribs = {}; if (this._attribs.get(_enums.EGeomType.points) !== undefined) { jsonData.attribs.points = Array.from(this._attribs.get(_enums.EGeomType.points).values()); } if (this._attribs.get(_enums.EGeomType.vertices) !== undefined) { jsonData.attribs.vertices = Array.from(this._attribs.get(_enums.EGeomType.vertices).values()); } if (this._attribs.get(_enums.EGeomType.edges) !== undefined) { jsonData.attribs.edges = Array.from(this._attribs.get(_enums.EGeomType.edges).values()); } if (this._attribs.get(_enums.EGeomType.wires) !== undefined) { jsonData.attribs.wires = Array.from(this._attribs.get(_enums.EGeomType.wires).values()); } if (this._attribs.get(_enums.EGeomType.faces) !== undefined) { jsonData.attribs.faces = Array.from(this._attribs.get(_enums.EGeomType.faces).values()); } if (this._attribs.get(_enums.EGeomType.objs) !== undefined) { jsonData.attribs.objs = Array.from(this._attribs.get(_enums.EGeomType.objs).values()); } } //TODO add topos to groups // In the IGroupData, groups data consists of the following: // name: string; // parent?: string; // objs?: number[]; // topos?: TTreeData; <<< This is an array of 2 x TreeBranch2, and 4 x TreeBranch3 // points?: number[]; // props?: Array<[string, any]>; // This kernel maintains a this._groups Map of such data, group_name -> group_data // When saving, the evalues of teh map are saved if (this._groups !== undefined) { jsonData.groups = Array.from(this._groups.values()); var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = jsonData.groups[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var group = _step8.value; group.topos = []; //TODO add the topo data here } } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } } return JSON.stringify(jsonData, null, 4); } /** * to be completed * @param * @return */ }, { key: "modelPurge", value: function modelPurge() { this._purgeDelUnusedPoints(); this._purgeDelUnusedPointValues(); } /** * to be completed * @param * @return */ }, { key: "modelValidate", value: function modelValidate() { throw new Error("Method not implemented."); } // The Model object --------------------------------------------------------------------------- /** * Get the Model object * @return The Model object */ }, { key: "getModel", value: function getModel() { return this._model; } /** * Get the Geom object * @return The Model object */ }, { key: "getGeom", value: function getGeom() { return this._geom; } // Model attributes --------------------------------------------------------------------------- /** * Find attributes in the model of a particular type. * @param * @return */ }, { key: "modelFindAttribs", value: function modelFindAttribs(geom_type) { switch (geom_type) { case _enums.EGeomType.points: return Array.from(this._attribs.get(geom_type).values()); case _enums.EGeomType.objs: return Array.from(this._attribs.get(geom_type).values()); case _enums.EGeomType.faces: return Array.from(this._attribs.get(geom_type).values()); case _enums.EGeomType.wires: return Array.from(this._attribs.get(geom_type).values()); case _enums.EGeomType.edges: return Array.from(this._attribs.get(geom_type).values()); case _enums.EGeomType.vertices: return Array.from(this._attribs.get(geom_type).values()); } } /** * Get all the attributes in the model. * @param * @return */ }, { key: "modelGetAllAttribs", value: function modelGetAllAttribs() { return [].concat(_toConsumableArray(this.modelFindAttribs(_enums.EGeomType.points)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.vertices)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.edges)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.wires)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.faces)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.objs))); } /** * Get all attributes in the model, except point attributes. * @param * @return */ }, { key: "modelGetAllAttribsExcPoints", value: function modelGetAllAttribsExcPoints() { return [].concat(_toConsumableArray(this.modelFindAttribs(_enums.EGeomType.vertices)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.edges)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.wires)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.faces)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.objs))); } /** * Get all entity attributes in the model. * @param * @return */ }, { key: "modelGetAllEntAttribs", value: function modelGetAllEntAttribs() { return [].concat(_toConsumableArray(this.modelFindAttribs(_enums.EGeomType.points)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.objs))); } /** * Get all topo attributes in the model. * @param * @return */ }, { key: "modelGetAllTopoAttribs", value: function modelGetAllTopoAttribs() { return [].concat(_toConsumableArray(this.modelFindAttribs(_enums.EGeomType.vertices)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.edges)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.wires)), _toConsumableArray(this.modelFindAttribs(_enums.EGeomType.faces))); } /** * Get an attribute from the model. * @param * @return */ }, { key: "modelGetAttrib", value: function modelGetAttrib(name, geom_type) { return this._attribs.get(geom_type).get(name); } /** * Add a new attribute to the model. * @param * @return */ }, { key: "modelAddAttrib", value: function modelAddAttrib(name, geom_type, data_type) { if (this.modelHasAttrib(name, geom_type)) { return this.modelGetAttrib(name, geom_type); } // name = name.replace(/\s/g, "_"); var data = { data_type: _enums.mapDataTypeToString.get(data_type), geom_type: _enums.mapGeomTypeToString.get(geom_type), name: name, values: [[], [null]] }; // save and return data this._attribs.get(geom_type).set(name, data); // populate the attribute with indexes all pointing to the null value this._newAttribAddObjsAndPoints(name, geom_type); // return the new attribute return this._attribs.get(geom_type).get(name); } /** * Delete an attribute from the model. * @param * @return */ }, { key: "modelDelAttrib", value: function modelDelAttrib(name, geom_type) { return this._attribs.get(geom_type).delete(name); } /** * Check is a model has an attribute. * @param * @return */ }, { key: "modelHasAttrib", value: function modelHasAttrib(name, geom_type) { return this._attribs.get(geom_type).has(name); } // Model Groups ------------------------------------------------------------------------------- /** * Get all the groups in the model. * @param * @return */ }, { key: "modelGetAllGroups", value: function modelGetAllGroups() { return Array.from(this._groups.values()); } /** * Get one group in the model. * @param * @return */ }, { key: "modelGetGroup", value: function modelGetGroup(name) { return this._groups.get(name); } /** * Add a new group to the model. * If a group with this name already exists, then that group is returned. * @param * @return */ }, { key: "modelAddGroup", value: function modelAddGroup(name, parent) { if (this.modelHasGroup(name)) { return this.modelGetGroup(name); } var data = { name: name, parent: null, objs: [], points: [] }; if (parent !== undefined) { if (this._groups.has(parent)) { data.parent = parent; } else { throw new Error("Parent group does not exist."); } } this._groups.set(name, data); this._topos_trees.set(name, new _topo_trees.TopoTree()); return data; } /** * Delete a group from the model. * @param * @return */ }, { key: "modelDelGroup", value: function modelDelGroup(name) { var group = this._groups.delete(name); var tree = this._topos_trees.delete(name); return group && tree; } /** * Check if the group exists in the model. * @param * @return */ }, { key: "modelHasGroup", value: function modelHasGroup(name) { return this._groups.has(name); } // Geom Points -------------------------------------------------------------------------------- /** * Check if the geometry has this point * @param * @return */ }, { key: "geomHasPoint", value: function geomHasPoint(id) { return this._points[0][id] !== undefined; } /** * Adds a new point to the model at position xyz. * @param cartesian xyz coordinates are required to create a point * @return a instance of type Point is returned */ }, { key: "geomAddPoint", value: function geomAddPoint(xyz) { var new_id = this._points[0].length; // next in sparse array // create the point this._points[0].push(0); // add a point to the points list this.pointSetPosition(new_id, xyz); // update point attributes this._newPointAddToAttribs(new_id); return new_id; } /** * Add a set of points to the model based on an array of xyz positions. * @param * @return */ }, { key: "geomAddPoints", value: function geomAddPoints(xyzs) { var _this2 = this; return xyzs.map(function (xyz) { return _this2.geomAddPoint(xyz); }); } /** * Copy a point. The new point will have the same position as the original point. * If copy_attribs is true, then the copied point will have the same attributes as the original point. * @param id * @param copy_attribs * @return */ }, { key: "geomCopyPoint", value: function geomCopyPoint(id) { var copy_attribs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var new_id = this._points[0].length; // create the ray this._points[0].push(this._points[0][id]); // add the point, set same position // update all attributes this._copiedPointAddToAttribs(new_id, id, copy_attribs); // return the new id return new_id; } /** * Copy a set of points. The new points will have the same positions as the original points. * If copy_attribs is true, then the copied points will have the same attribute values as the original points. * @param ids * @param copy_attribs * @return */ }, { key: "geomCopyPoints", value: function geomCopyPoints(ids) { var _this3 = this; var copy_attribs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; return ids.map(function (id) { return _this3.geomCopyPoint(id, copy_attribs); }); } /** * Delete a point from the model. * @param * @return */ }, { key: "geomDelPoint", value: function geomDelPoint(id) { // delete the point from the geometry array if (this._points[0][id] === undefined) { return false; } // delete the point delete this._points[0][id]; // delete the point from any geometrc objects this._updateObjsForDelPoint(id); // delete the point from attribs this._updateAttribsForDelPoint(id); // delete the points from groups this._updateGroupsForDelPoint(id); // all seem ok return true; } /** * Delete a list of points from the model. * @param * @return */ }, { key: "geomDelPoints", value: function geomDelPoints(ids) { var ok = true; var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = ids[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var id = _step9.value; if (this.geomHasPoint(id)) { if (!this.geomDelPoint(id)) { ok = false; } } } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } return ok; } /** * Returns the number of points in the model. * @param * @return */ }, { key: "geomNumPoints", value: function geomNumPoints() { return this._points[0].filter(function (n) { return n !== undefined; }).length; // ignores empty slots in spare array } /** * Get the list of all point IDs in the model. * The list does not include the empty slots. * @param * @return */ }, { key: "geomGetPointIDs", value: function geomGetPointIDs() { var point_ids = []; this._points[0].forEach(function (v, i) { return v !== undefined && point_ids.push(i); }); // ignores empty slots in spare array return point_ids; } /** * Calculates the centroid of a set of points, as the average of all point positions. * @param * @return */ }, { key: "geomCalcPointsCentroid", value: function geomCalcPointsCentroid(ids) { if (ids.length === 1) { return [this._points[1][this._points[0][ids[0]]][0], this._points[1][this._points[0][ids[0]]][1], this._points[1][this._points[0][ids[0]]][2]]; } var centroid = [0, 0, 0]; var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = ids[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var id = _step10.value; centroid[0] += this._points[1][this._points[0][id]][0]; centroid[1] += this._points[1][this._points[0][id]][1]; centroid[2] += this._points[1][this._points[0][id]][2]; } } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } centroid[0] = centroid[0] / ids.length; centroid[1] = centroid[1] / ids.length; centroid[2] = centroid[2] / ids.length; return centroid; } /** * Merge points, replaces these points with a new point. * @param * @return */ }, { key: "geomMergePoints", value: function geomMergePoints(ids) { // calc the center point var centre = this.geomCalcPointsCentroid(ids); // replace old with new var new_point_id = this.geomAddPoint(centre); var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { for (var _iterator11 = ids[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var id = _step11.value; this._swapAllObjsPoint(id, new_point_id); } } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } this.geomDelPoints(ids); // return the new point, the centre of the old points return new_point_id; } /** * Merge points. * @param * @return */ }, { key: "geomMergePointsByTol", value: function geomMergePointsByTol(ids, tolerance) { if (ids === undefined) { ids = this.geomGetPointIDs(); } // get all the points that are closer than tolerance, store the data in some maps var dist_map = new Map(); var cluster_map = new Map(); for (var i = 0; i < ids.length - 1; i++) { for (var j = i + 1; j < ids.length; j++) { var id_i = ids[i]; var id_j = ids[j]; var pos_i = this._points[1][this._points[0][id_i]]; var pos_j = this._points[1][this._points[0][id_j]]; var dist_sq = this._distanceSquared(pos_i, pos_j, tolerance); if (dist_sq !== null) { var id_pair = [id_i, id_j].sort(); // populate dist map if (!dist_map.has(id_pair[0])) { dist_map.set(id_pair[0], new Map()); } dist_map.get(id_pair[0]).set(id_pair[1], dist_sq); // populate cluster map if (!cluster_map.has(id_i)) { cluster_map.set(id_i, []); } cluster_map.get(id_i).push(id_j); if (!cluster_map.has(id_j)) { cluster_map.set(id_j, []); } cluster_map.get(id_j).push(id_i); } } } // create array, reverse sort, so that points with most neighbours end up at the top var cluster_arr = []; var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { for (var _iterator12 = cluster_map.entries()[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { var _step12$value = _slicedToArray(_step12.value, 2), id = _step12$value[0], n = _step12$value[1]; cluster_arr.push({ id: id, n: n }); } } catch (err) { _didIteratorError12 = true; _iteratorError12 = err; } finally { try { if (!_iteratorNormalCompletion12 && _iterator12.return) { _iterator12.return(); } } finally { if (_didIteratorError12) { throw _iteratorError12; } } } cluster_arr.sort(function (a, b) { return b.n.length - a.n.length; }); // create a cluster map, filter the clusters so that the center points do not overlap var consumed_ids = new Set(); var cluster_no_overlap_map = new Map(); var _iteratorNormalCompletion13 = true; var _didIteratorError13 = false; var _iteratorError13 = undefined; try { for (var _iterator13 = cluster_arr[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { var cluster = _step13.value; if (!consumed_ids.has(cluster.id)) { cluster_no_overlap_map.set(cluster.id, []); cluster.n.forEach(function (id) { return consumed_ids.add(id); }); } } // put each point into the closest cluster } catch (err) { _didIteratorError13 = true; _iteratorError13 = err; } finally { try { if (!_iteratorNormalCompletion13 && _iterator13.return) { _iterator13.return(); } } finally { if (_didIteratorError13) { throw _iteratorError13; } } } var _iteratorNormalCompletion14 = true; var _didIteratorError14 = false; var _iteratorError14 = undefined; try { for (var _iterator14 = cluster_map.entries()[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { var _step14$value = _slicedToArray(_step14.value, 2), id = _step14$value[0], n = _step14$value[1]; if (cluster_no_overlap_map.has(id)) { cluster_no_overlap_map.get(id).push(id); } else { // create a list of options, where to put this id var options = []; var _iteratorNormalCompletion16 = true; var _didIteratorError16 = false; var _iteratorError16 = undefined; try { for (var _iterator16 = n[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { var _option = _step16.value; if (cluster_no_overlap_map.has(_option)) { options.push(_option); } } // choose an option } catch (err) { _didIteratorError16 = true; _iteratorError16 = err; } finally { try { if (!_iteratorNormalCompletion16 && _iterator16.return) { _iterator16.return(); } } finally { if (_didIteratorError16) { throw _iteratorError16; } } } if (options.length === 0) { console.log("This looks like an error!!!"); } else if (options.length === 1) { cluster_no_overlap_map.get(options[0]).push(id); } else { var closest = options[0]; var min_dist = tolerance; var _iteratorNormalCompletion17 = true; var _didIteratorError17 = false; var _iteratorError17 = undefined; try { for (var _iterator17 = options[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { var option = _step17.value; var _id_pair = [id, option].sort(); var vec = dist_map.get(_id_pair[0]).get(_id_pair[1]); var dist = vec[0] + vec[1] + vec[2]; if (dist < min_dist) { closest = option; min_dist = dist; } } } catch (err) { _didIteratorError17 = true; _iteratorError17 = err; } finally { try { if (!_iteratorNormalCompletion17 && _iterator17.return) { _iterator17.return(); } } finally { if (_didIteratorError17) { throw _iteratorError17; } } } cluster_no_overlap_map.get(closest).push(id); } } } // now process the clusters } catch (err) { _didIteratorError14 = true; _iteratorError14 = err; } finally { try { if (!_iteratorNormalCompletion14 && _iterator14.return) { _iterator14.return(); } } finally { if (_didIteratorError14) { throw _iteratorError14; } } } var new_point_ids = []; var old_point_ids = []; var _iteratorNormalCompletion15 = true; var _didIteratorError15 = false; var _iteratorError15 = undefined; try { for (var _iterator15 = cluster_no_overlap_map.entries()[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { var _step15$value = _slicedToArray(_step15.value, 2), cluster_id = _step15$value[0], _cluster = _step15$value[1]; // calc the center point var centre = this.geomCalcPointsCentroid(_cluster); // replace old with new var new_point_id = this.geomAddPoint(centre); var _iteratorNormalCompletion18 = true; var _didIteratorError18 = false; var _iteratorError18 = undefined; try { for (var _iterator18 = _cluster[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) { var old_point_id = _step18.value; this._swapAllObjsPoint(old_point_id, new_point_id); old_point_ids.push(old_point_id); } } catch (err) { _didIteratorError18 = true; _iteratorError18 = err; } finally { try { if (!_iteratorNormalCompletion18 && _iterator18.return) { _iterator18.return(); } } finally { if (_didIteratorError18) { throw _iteratorError18; } } } new_point_ids.push(new_point_id); } } catch (err) { _didIteratorError15 = true; _iteratorError15 = err; } finally { try { if (!_iteratorNormalCompletion15 && _iterator15.return) { _iterator15.return(); } } finally { if (_didIteratorError15) { throw _iteratorError15; } } } this.geomDelPoints(old_point_ids); // return the new points, the centre of each cluster return new_point_ids; } /** * Merge all points in the model, given a tolerance. * @param * @return */ }, { key: "geomMergeAllPoints", value: function geomMergeAllPoints(tolerance) { return this.geomMergePointsByTol(this.geomGetPointIDs(), tolerance); } /** * Transform the position of the array of points. * @param * @param */ }, { key: "geomXformPoints", value: function geomXformPoints(ids, matrix) { var _iteratorNormalCompletion19 = true; var _didIteratorError19 = false; var _iteratorError19 = undefined; try { for (var _iterator19 = ids[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) { var id = _step19.value; this.pointSetPosition(id, threex.multXYZMatrix(this.pointGetPosition(id), matrix)); } } catch (err) { _didIteratorError19 = true; _iteratorError19 = err; } finally { try { if (!_iteratorNormalCompletion19 && _iterator19.return) { _iterator19.return(); } } finally { if (_didIteratorError19) { throw _iteratorError19; } } } } // Geom Object Constructors------------------------------------------------------------------------------ /** * Adds a new ray to the model that passes through a sequence of points. * @param origin The ray origin point. * @param dir The ray direction, as a vector. * @return ID of object. */ }, { key: "geomAddRay", value: function geomAddRay(origin_id, ray_vec) { var new_id = this._objs.length; // create the ray this._objs.push([[[origin_id]], [], [1 /* ray */, ray_vec]]); // add the obj // update all attributes this._newObjAddToAttribs(new_id); // return the new pline return new_id; } /** * Adds a new plane to the model defined by an origin and two vectors. * @param origin_id The plane origin point. * @param axes Three orthogonal aaxes as XYZ vectors * @return ID of object. */ }, { key: "geomAddPlane", value: function geomAddPlane(origin_id, axes) { var new_id = this._objs.length; // add the obj this._objs.push([[[origin_id]],