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
JavaScript
"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]],