refactor widget as class. patch engine, frame, cli
This commit is contained in:
parent
8e208c99d5
commit
74d3d8752c
9 changed files with 300 additions and 306 deletions
4
app.js
4
app.js
|
|
@ -404,6 +404,7 @@ const script = {
|
||||||
"geo/mesh",
|
"geo/mesh",
|
||||||
// "moto/broker",
|
// "moto/broker",
|
||||||
"kiri/pack",
|
"kiri/pack",
|
||||||
|
"kiri/utils",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
"kiri-mode/fdm/fill",
|
"kiri-mode/fdm/fill",
|
||||||
|
|
@ -453,6 +454,7 @@ const script = {
|
||||||
"geo/slicer",
|
"geo/slicer",
|
||||||
"kiri-mode/fdm/driver",
|
"kiri-mode/fdm/driver",
|
||||||
"kiri-mode/fdm/slice",
|
"kiri-mode/fdm/slice",
|
||||||
|
"kiri/utils",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
"kiri/widget",
|
"kiri/widget",
|
||||||
|
|
@ -472,6 +474,7 @@ const script = {
|
||||||
"geo/base",
|
"geo/base",
|
||||||
"geo/point",
|
"geo/point",
|
||||||
"geo/points",
|
"geo/points",
|
||||||
|
"geo/paths",
|
||||||
"geo/slope",
|
"geo/slope",
|
||||||
"geo/line",
|
"geo/line",
|
||||||
"geo/bounds",
|
"geo/bounds",
|
||||||
|
|
@ -481,6 +484,7 @@ const script = {
|
||||||
"load/obj",
|
"load/obj",
|
||||||
"load/stl",
|
"load/stl",
|
||||||
"kiri/conf",
|
"kiri/conf",
|
||||||
|
"kiri/utils",
|
||||||
"kiri/client",
|
"kiri/client",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
[
|
[
|
||||||
"main/gapp",
|
"main/gapp",
|
||||||
"moto/license",
|
"moto/license",
|
||||||
|
"moto/broker",
|
||||||
"main/kiri",
|
"main/kiri",
|
||||||
"ext/three",
|
"ext/three",
|
||||||
"ext/pngjs",
|
"ext/pngjs",
|
||||||
|
|
@ -13,18 +14,22 @@
|
||||||
"geo/base",
|
"geo/base",
|
||||||
"geo/point",
|
"geo/point",
|
||||||
"geo/points",
|
"geo/points",
|
||||||
|
"geo/paths",
|
||||||
"geo/slope",
|
"geo/slope",
|
||||||
"geo/line",
|
"geo/line",
|
||||||
"geo/bounds",
|
"geo/bounds",
|
||||||
"geo/polygons",
|
"geo/polygons",
|
||||||
"geo/polygon",
|
"geo/polygon",
|
||||||
"geo/gyroid",
|
"geo/gyroid",
|
||||||
|
"geo/slicer",
|
||||||
|
"load/obj",
|
||||||
|
"load/stl",
|
||||||
"kiri/conf",
|
"kiri/conf",
|
||||||
"kiri/pack",
|
"kiri/pack",
|
||||||
"kiri/client",
|
"kiri/client",
|
||||||
"kiri/engine",
|
"kiri/engine",
|
||||||
|
"kiri/utils",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/slicer",
|
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
"kiri-mode/fdm/fill",
|
"kiri-mode/fdm/fill",
|
||||||
"kiri-mode/fdm/driver",
|
"kiri-mode/fdm/driver",
|
||||||
|
|
@ -48,5 +53,4 @@
|
||||||
"kiri/print",
|
"kiri/print",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
"kiri/worker",
|
"kiri/worker",
|
||||||
"load/stl"
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
kiri.load(function() {
|
self.kiri.load(function() {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
let KIRI = self.kiri,
|
||||||
CAM = KIRI.driver.CAM,
|
CAM = KIRI.driver.CAM,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
const { base, kiri } = self;
|
const { base, kiri, noop } = self;
|
||||||
const { driver, fill, fill_fixed, newSlice, utils } = kiri;
|
const { driver, fill, fill_fixed, newSlice, utils } = kiri;
|
||||||
const { config, polygons, util, newPoint } = base;
|
const { config, polygons, util, newPoint } = base;
|
||||||
const { fillArea } = polygons;
|
const { fillArea } = polygons;
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,8 @@ let exports_save = exports,
|
||||||
gapp = {},
|
gapp = {},
|
||||||
geo = {},
|
geo = {},
|
||||||
self = this.self = {
|
self = this.self = {
|
||||||
THREE,
|
|
||||||
gapp,
|
gapp,
|
||||||
kiri: { driver: {}, loader: [] },
|
THREE,
|
||||||
location: { hostname: 'local', port: 0, protocol: 'fake' },
|
location: { hostname: 'local', port: 0, protocol: 'fake' },
|
||||||
postMessage: (msg) => {
|
postMessage: (msg) => {
|
||||||
self.kiri.client.onmessage({data:msg});
|
self.kiri.client.onmessage({data:msg});
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.load) {
|
if (data.load) {
|
||||||
platformLoad(data.load, (verts, widget) => {
|
api.platform.load(data.load, (verts, widget) => {
|
||||||
send({event: "loaded", data: [ widget.id ]});
|
send({event: "loaded", data: [ widget.id ]});
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -2044,7 +2044,7 @@
|
||||||
function loadFile() {
|
function loadFile() {
|
||||||
$('load-file').onchange = function(event) {
|
$('load-file').onchange = function(event) {
|
||||||
console.log(event);
|
console.log(event);
|
||||||
platformLoadFiles(event.target.files);
|
api.platform.load_files(event.target.files);
|
||||||
};
|
};
|
||||||
$('load-file').click();
|
$('load-file').click();
|
||||||
// alert2("drag/drop STL files onto platform to import\nreload page to return to last saved state");
|
// alert2("drag/drop STL files onto platform to import\nreload page to return to last saved state");
|
||||||
|
|
|
||||||
|
|
@ -793,7 +793,7 @@ const platform = api.platform = {
|
||||||
show_axes: space.platform.showAxes,
|
show_axes: space.platform.showAxes,
|
||||||
show_volume: space.platform.showVolume,
|
show_volume: space.platform.showVolume,
|
||||||
top_z() { return topZ },
|
top_z() { return topZ },
|
||||||
clear() { clearWorkspace(); saveWorkspace(true) }
|
clear() { api.space.clear(); api.space.save(true) }
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,26 @@ function js2o(s,def) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// split 24 bit color into [ r, g, b ]
|
||||||
|
function rgb(c) {
|
||||||
|
return [ (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 24 bit color from [ r, g, b ] array
|
||||||
|
function a2c(a) {
|
||||||
|
return (a[0] << 16) | (a[1] << 8) | a[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// average two color arrays with weighting @ return 24 bit color
|
||||||
|
function avgc(c1, c2, w = 3) {
|
||||||
|
let r1 = rgb(c1);
|
||||||
|
let r2 = rgb(c2);
|
||||||
|
let d = (w + 2);
|
||||||
|
return ((r1[0] * w + r2[0]) / d) << 16
|
||||||
|
| ((r1[1] * w + r2[1]) / d) << 8
|
||||||
|
| ((r1[2] * w + r2[2]) / d);
|
||||||
|
}
|
||||||
|
|
||||||
function areEqual(o1, o2) {
|
function areEqual(o1, o2) {
|
||||||
if (o1 == o2) return true;
|
if (o1 == o2) return true;
|
||||||
if (Array.isArray(o1) && Array.isArray(o2)) {
|
if (Array.isArray(o1) && Array.isArray(o2)) {
|
||||||
|
|
@ -76,6 +96,9 @@ kiri.utils = {
|
||||||
ajax,
|
ajax,
|
||||||
o2js,
|
o2js,
|
||||||
js2o,
|
js2o,
|
||||||
|
avgc,
|
||||||
|
rgb,
|
||||||
|
a2c
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -4,145 +4,29 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
if (self.kiri.Widget) return;
|
if (self.kiri.Widget) return;
|
||||||
|
|
||||||
const { base, kiri } = self;
|
const { base, kiri } = self;
|
||||||
const { driver } = kiri;
|
const { api, driver, utils } = kiri;
|
||||||
const { config, util, polygons } = base;
|
const { config, util, polygons } = base;
|
||||||
const { Mesh, newPoint, verticesToPoints } = base;
|
const { Mesh, newPoint, verticesToPoints } = base;
|
||||||
const { inRange, time } = util;
|
const { inRange, time } = util;
|
||||||
|
const { rgb, avgc } = utils;
|
||||||
|
|
||||||
const POLY = polygons;
|
const POLY = polygons;
|
||||||
const PRO = Widget.prototype;
|
const solid_opacity = 1.0;
|
||||||
const solid_opacity = 1.0;
|
const groups = [];
|
||||||
|
|
||||||
let nextId = 0,
|
let nextId = 0;
|
||||||
groups = [];
|
|
||||||
|
|
||||||
kiri.Widget = Widget;
|
function newWidget(id,group) { return new Widget(id,group) }
|
||||||
kiri.newWidget = newWidget;
|
|
||||||
|
|
||||||
function newWidget(id,group) { return new Widget(id,group) }
|
function catalog() { return kiri.catalog }
|
||||||
|
|
||||||
function catalog() { return kiri.catalog }
|
function index() { return catalog().index }
|
||||||
|
|
||||||
function index() { return catalog().index }
|
class Widget {
|
||||||
|
constructor(id, group) {
|
||||||
/** ******************************************************************
|
|
||||||
* Group helpers
|
|
||||||
******************************************************************* */
|
|
||||||
|
|
||||||
const Group = Widget.Groups = {
|
|
||||||
|
|
||||||
list: () => {
|
|
||||||
return groups.slice()
|
|
||||||
},
|
|
||||||
|
|
||||||
merge: (widgets) => {
|
|
||||||
let grps = widgets.map(w => w.group).uniq();
|
|
||||||
if (grps.length > 1) {
|
|
||||||
let root = grps.shift();
|
|
||||||
let rpos = root[0].track.pos;
|
|
||||||
for (let grp of grps) {
|
|
||||||
for (let w of grp) {
|
|
||||||
let wpos = w.track.pos;
|
|
||||||
w.group = root;
|
|
||||||
w.moveMesh(rpos.x - wpos.x, rpos.y - wpos.y, rpos.z - wpos.z);
|
|
||||||
w._move(rpos.x, rpos.y, rpos.z, true);
|
|
||||||
root.push(w);
|
|
||||||
}
|
|
||||||
groups.splice(groups.indexOf(grp),1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
split: (widgets) => {
|
|
||||||
for (let group of widgets.map(w => w.group).uniq()) {
|
|
||||||
groups.splice(groups.indexOf(group),1);
|
|
||||||
for (let widget of group) {
|
|
||||||
let nugroup = Group.forid(widget.id);
|
|
||||||
nugroup.push(widget);
|
|
||||||
widget.group = nugroup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
forid: function(id) {
|
|
||||||
for (let i=0; i<groups.length; i++) {
|
|
||||||
if (groups[i].id === id) return groups[i];
|
|
||||||
}
|
|
||||||
let group = [];
|
|
||||||
group.id = id;
|
|
||||||
groups.push(group);
|
|
||||||
return group;
|
|
||||||
},
|
|
||||||
|
|
||||||
remove: function(widget) {
|
|
||||||
groups.slice().forEach(group => {
|
|
||||||
let pos = group.indexOf(widget);
|
|
||||||
if (pos >= 0) {
|
|
||||||
group.splice(pos,1);
|
|
||||||
}
|
|
||||||
if (group.length === 0) {
|
|
||||||
pos = groups.indexOf(group);
|
|
||||||
groups.splice(pos,1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
blocks: function() {
|
|
||||||
return groups.map(group => {
|
|
||||||
return {
|
|
||||||
w: group[0].track.box.w,
|
|
||||||
h: group[0].track.box.h,
|
|
||||||
move: (x,y,z,abs) => {
|
|
||||||
group.forEach(widget => {
|
|
||||||
widget.mesh.material.visible = true;
|
|
||||||
widget._move(x, y, z, abs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
loadDone: function() {
|
|
||||||
groups.forEach(group => {
|
|
||||||
if (!group.centered) {
|
|
||||||
group[0].center();
|
|
||||||
group.centered = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
bounds: function(group) {
|
|
||||||
let bounds = null;
|
|
||||||
group.forEach(widget => {
|
|
||||||
let wb = widget.mesh.getBoundingBox(true);
|
|
||||||
if (bounds) {
|
|
||||||
bounds = bounds.union(wb);
|
|
||||||
} else {
|
|
||||||
bounds = wb;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return bounds;
|
|
||||||
},
|
|
||||||
|
|
||||||
clear: function() {
|
|
||||||
groups.length = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// class Widget {
|
|
||||||
// constructor(id, group) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @params {String} [id]
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function Widget(id, group) {
|
|
||||||
this.id = id || new Date().getTime().toString(36)+(nextId++);
|
this.id = id || new Date().getTime().toString(36)+(nextId++);
|
||||||
this.grouped = group ? true : false;
|
this.grouped = group ? true : false;
|
||||||
this.group = group || [];
|
this.group = group || [];
|
||||||
|
|
@ -209,69 +93,24 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
this.support = false;
|
this.support = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ******************************************************************
|
saveToCatalog(filename) {
|
||||||
* Widget Class Functions
|
|
||||||
******************************************************************* */
|
|
||||||
|
|
||||||
Widget.loadFromCatalog = function(filename, ondone) {
|
|
||||||
catalog().getFile(filename, function(data) {
|
|
||||||
let widget = newWidget().loadVertices(data);
|
|
||||||
widget.meta.file = filename;
|
|
||||||
ondone(widget);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Widget.loadFromState = function(id, ondone, move) {
|
|
||||||
index().get('ws-save-'+id, function(data) {
|
|
||||||
if (data) {
|
|
||||||
let vertices = data.geo || data,
|
|
||||||
indices = data.ind || undefined,
|
|
||||||
track = data.track || undefined,
|
|
||||||
group = data.group || id,
|
|
||||||
anno = data.anno || undefined,
|
|
||||||
widget = newWidget(id, Group.forid(group)),
|
|
||||||
meta = data.meta || widget.meta,
|
|
||||||
ptr = widget.loadVertices({vertices, indices});
|
|
||||||
widget.meta = meta;
|
|
||||||
widget.anno = anno || widget.anno;
|
|
||||||
// restore widget position if specified
|
|
||||||
if (move && track && track.pos) {
|
|
||||||
widget.track = track;
|
|
||||||
widget.move(track.pos.x, track.pos.y, track.pos.z, true);
|
|
||||||
}
|
|
||||||
ondone(ptr);
|
|
||||||
} else {
|
|
||||||
ondone(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Widget.deleteFromState = function(id,ondone) {
|
|
||||||
index().remove('ws-save-'+id, ondone);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** ******************************************************************
|
|
||||||
* Widget Prototype Functions
|
|
||||||
******************************************************************* */
|
|
||||||
|
|
||||||
PRO.saveToCatalog = function(filename) {
|
|
||||||
if (this.grouped) {
|
if (this.grouped) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
let widget = this;
|
const widget = this;
|
||||||
let time = time();
|
const mark = time();
|
||||||
widget.meta.file = filename;
|
widget.meta.file = filename;
|
||||||
widget.meta.save = time;
|
widget.meta.save = mark;
|
||||||
catalog().putFile(filename, this.getGeoVertices(true), function(vertices) {
|
catalog().putFile(filename, this.getGeoVertices(true), vertices => {
|
||||||
if (vertices && vertices.length) {
|
if (vertices && vertices.length) {
|
||||||
console.log("saving decimated mesh ["+vertices.length+"] time ["+(time()-time)+"]");
|
console.log("saving decimated mesh ["+vertices.length+"] time ["+(time()-mark)+"]");
|
||||||
widget.loadVertices(vertices);
|
widget.loadVertices(vertices);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.saveState = function(ondone) {
|
saveState(ondone) {
|
||||||
if (!ondone) {
|
if (!ondone) {
|
||||||
clearTimeout(this._save_timer);
|
clearTimeout(this._save_timer);
|
||||||
this._save_timer = setTimeout(() => {
|
this._save_timer = setTimeout(() => {
|
||||||
|
|
@ -280,7 +119,7 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}, 1500);
|
}, 1500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let widget = this;
|
const widget = this;
|
||||||
index().put('ws-save-'+this.id, {
|
index().put('ws-save-'+this.id, {
|
||||||
geo: widget.getGeoVertices(false),
|
geo: widget.getGeoVertices(false),
|
||||||
ind: widget.getGeoIndices(),
|
ind: widget.getGeoIndices(),
|
||||||
|
|
@ -288,13 +127,13 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
group: this.group.id,
|
group: this.group.id,
|
||||||
meta: this.meta,
|
meta: this.meta,
|
||||||
anno: this.annotations()
|
anno: this.annotations()
|
||||||
}, function(result) {
|
}, result => {
|
||||||
widget.meta.saved = time();
|
widget.meta.saved = time();
|
||||||
if (ondone) ondone();
|
if (ondone) ondone();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.annotations = function() {
|
annotations() {
|
||||||
let o = Object.clone(this.anno);
|
let o = Object.clone(this.anno);
|
||||||
if (o.support) {
|
if (o.support) {
|
||||||
// clear out THREE.Box temps
|
// clear out THREE.Box temps
|
||||||
|
|
@ -303,14 +142,14 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Float32Array} vertices
|
* @param {Float32Array} vertices
|
||||||
* @returns {Widget}
|
* @returns {Widget}
|
||||||
*/
|
*/
|
||||||
PRO.loadVertices = function(data, options = { index: false }) {
|
loadVertices(data, options = { index: false }) {
|
||||||
let vertices,
|
let vertices,
|
||||||
indices,
|
indices,
|
||||||
autoscale = false;
|
autoscale = false;
|
||||||
|
|
@ -369,19 +208,21 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
this.points = null;
|
this.points = null;
|
||||||
return this.loadGeometry(geo);
|
return this.loadGeometry(geo);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.loadData = PRO.loadVertices;
|
loadData() {
|
||||||
|
return this.loadVertices(...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
PRO.setModified = function() {
|
setModified() {
|
||||||
this.modified = true;
|
this.modified = true;
|
||||||
if (this.mesh && this.mesh.geometry) {
|
if (this.mesh && this.mesh.geometry) {
|
||||||
// this fixes ray intersections after the mesh is modified
|
// this fixes ray intersections after the mesh is modified
|
||||||
this.mesh.geometry.boundingSphere = null;
|
this.mesh.geometry.boundingSphere = null;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.indexGeo = function() {
|
indexGeo() {
|
||||||
let indices = this.getGeoIndices();
|
let indices = this.getGeoIndices();
|
||||||
if (!indices) {
|
if (!indices) {
|
||||||
let mesh = new Mesh({vertices: this.getGeoVertices()});
|
let mesh = new Mesh({vertices: this.getGeoVertices()});
|
||||||
|
|
@ -389,9 +230,9 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
indices = Uint32Array.from(mesh.faces.map(v => v/3));
|
indices = Uint32Array.from(mesh.faces.map(v => v/3));
|
||||||
this.loadData({vertices, indices});
|
this.loadData({vertices, indices});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.heal = function(debug, refresh) {
|
heal(debug, refresh) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
let mesh = this.debugMesh().heal();
|
let mesh = this.debugMesh().heal();
|
||||||
let verts = mesh.vertices;
|
let verts = mesh.vertices;
|
||||||
|
|
@ -437,22 +278,22 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
resolve(this.modified);
|
resolve(this.modified);
|
||||||
}, refresh);
|
}, refresh);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.debugMesh = function(precision) {
|
debugMesh(precision) {
|
||||||
return new base.Mesh({precision, vertices: this.getVertices().array});
|
return new base.Mesh({precision, vertices: this.getVertices().array});
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getVertices = function() {
|
getVertices() {
|
||||||
return this.mesh.geometry.attributes.position;
|
return this.mesh.geometry.attributes.position;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {THREE.Geometry} geometry
|
* @param {THREE.Geometry} geometry
|
||||||
* @returns {Widget}
|
* @returns {Widget}
|
||||||
*/
|
*/
|
||||||
PRO.loadGeometry = function(geometry) {
|
loadGeometry(geometry) {
|
||||||
let mesh = new THREE.Mesh(
|
const mesh = new THREE.Mesh(
|
||||||
geometry,
|
geometry,
|
||||||
new THREE.MeshPhongMaterial({
|
new THREE.MeshPhongMaterial({
|
||||||
color: 0xffff00,
|
color: 0xffff00,
|
||||||
|
|
@ -474,25 +315,25 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
// invalidates points cache (like any scale/rotation)
|
// invalidates points cache (like any scale/rotation)
|
||||||
this.center(true);
|
this.center(true);
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.groupBounds = function() {
|
groupBounds() {
|
||||||
return Group.bounds(this.group);
|
return Group.bounds(this.group);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Point[]} points
|
* @param {Point[]} points
|
||||||
* @returns {Widget}
|
* @returns {Widget}
|
||||||
*/
|
*/
|
||||||
PRO.setPoints = function(points) {
|
setPoints(points) {
|
||||||
this.points = points || null;
|
this.points = points || null;
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove slice data and their views
|
* remove slice data and their views
|
||||||
*/
|
*/
|
||||||
PRO.clearSlices = function() {
|
clearSlices() {
|
||||||
let slices = this.slices,
|
let slices = this.slices,
|
||||||
mesh = this.mesh;
|
mesh = this.mesh;
|
||||||
if (slices && mesh && mesh.remove) {
|
if (slices && mesh && mesh.remove) {
|
||||||
|
|
@ -501,25 +342,12 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.slices = null;
|
this.slices = null;
|
||||||
};
|
|
||||||
|
|
||||||
function rgb(c) {
|
|
||||||
return [ c >> 16, (c >> 8) & 0xff , c & 0xff ];
|
|
||||||
}
|
|
||||||
|
|
||||||
function avgc(c1, c2, w) {
|
|
||||||
let r1 = rgb(c1);
|
|
||||||
let r2 = rgb(c2);
|
|
||||||
let d = (w + 2);
|
|
||||||
return ((r1[0] * w + r2[0]) / d) << 16
|
|
||||||
| ((r1[1] * w + r2[1]) / d) << 8
|
|
||||||
| ((r1[2] * w + r2[2]) / d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} color
|
* @param {number} color
|
||||||
*/
|
*/
|
||||||
PRO.setColor = function(color, settings, save = true) {
|
setColor(color, settings, save = true) {
|
||||||
if (settings) {
|
if (settings) {
|
||||||
console.trace('legacy call with settings');
|
console.trace('legacy call with settings');
|
||||||
}
|
}
|
||||||
|
|
@ -531,17 +359,17 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}
|
}
|
||||||
let material = this.mesh.material;
|
let material = this.mesh.material;
|
||||||
material.color.set(this.meta.disabled ? avgc(0x888888, color, 3) : color);
|
material.color.set(this.meta.disabled ? avgc(0x888888, color, 3) : color);
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getColor = function() {
|
getColor() {
|
||||||
return this.color;
|
return this.color;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} value
|
* @param {number} value
|
||||||
*/
|
*/
|
||||||
PRO.setOpacity = function(value) {
|
setOpacity(value) {
|
||||||
let mesh = this.mesh;
|
const mesh = this.mesh;
|
||||||
if (value <= 0.0) {
|
if (value <= 0.0) {
|
||||||
mesh.material.transparent = solid_opacity < 1.0;
|
mesh.material.transparent = solid_opacity < 1.0;
|
||||||
mesh.material.opacity = solid_opacity;
|
mesh.material.opacity = solid_opacity;
|
||||||
|
|
@ -551,12 +379,12 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
mesh.material.opacity = value;
|
mesh.material.opacity = value;
|
||||||
mesh.material.visible = true;
|
mesh.material.visible = true;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* center geometry bottom (on platform) at 0,0,0
|
* center geometry bottom (on platform) at 0,0,0
|
||||||
*/
|
*/
|
||||||
PRO.center = function(init) {
|
center(init) {
|
||||||
let bb = init ? this.mesh.getBoundingBox(true) : this.groupBounds(),
|
let bb = init ? this.mesh.getBoundingBox(true) : this.groupBounds(),
|
||||||
bm = bb.min.clone(),
|
bm = bb.min.clone(),
|
||||||
bM = bb.max.clone(),
|
bM = bb.max.clone(),
|
||||||
|
|
@ -572,13 +400,13 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by center() and Group.center()
|
* called by center() and Group.center()
|
||||||
* todo use new prototype.moveMesh()
|
* todo use new prototype.moveMesh()
|
||||||
*/
|
*/
|
||||||
PRO.moveMesh = function(x, y, z) {
|
moveMesh(x, y, z) {
|
||||||
let gap = this.mesh.geometry.attributes.position,
|
let gap = this.mesh.geometry.attributes.position,
|
||||||
pa = gap.array;
|
pa = gap.array;
|
||||||
// center point array on 0,0,0
|
// center point array on 0,0,0
|
||||||
|
|
@ -599,14 +427,14 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
// invalidate cached points
|
// invalidate cached points
|
||||||
this.points = null;
|
this.points = null;
|
||||||
this.setModified();
|
this.setModified();
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* moves top of widget to given Z
|
* moves top of widget to given Z
|
||||||
*
|
*
|
||||||
* @param {number} z position
|
* @param {number} z position
|
||||||
*/
|
*/
|
||||||
PRO.setTopZ = function(z) {
|
setTopZ(z) {
|
||||||
let mesh = this.mesh,
|
let mesh = this.mesh,
|
||||||
pos = this.track.pos,
|
pos = this.track.pos,
|
||||||
ltz = this.last_top_z || {},
|
ltz = this.last_top_z || {},
|
||||||
|
|
@ -626,20 +454,20 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
};
|
};
|
||||||
this.modified |= (ltz.pz !== ntz.pz || ltz.mpz !== ntz.mpz);
|
this.modified |= (ltz.pz !== ntz.pz || ltz.mpz !== ntz.mpz);
|
||||||
this.last_top_z = ntz;
|
this.last_top_z = ntz;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.cutZ = function(dist) {
|
cutZ(dist) {
|
||||||
this.track.zcut = dist;
|
this.track.zcut = dist;
|
||||||
this.setTopZ();
|
this.setTopZ();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.move = function(x, y, z, abs) {
|
move(x, y, z, abs) {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._move(x, y, z, abs);
|
w._move(x, y, z, abs);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO._move = function(x, y, z, abs) {
|
_move(x, y, z, abs) {
|
||||||
let mesh = this.mesh,
|
let mesh = this.mesh,
|
||||||
pos = this.track.pos,
|
pos = this.track.pos,
|
||||||
zcut = this.track.zcut || 0;
|
zcut = this.track.zcut || 0;
|
||||||
|
|
@ -660,18 +488,18 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}
|
}
|
||||||
if (x || y || z) {
|
if (x || y || z) {
|
||||||
this.setModified();
|
this.setModified();
|
||||||
kiri.api.event.emit('widget.move', {widget: this, pos});
|
api.event.emit('widget.move', {widget: this, pos});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
PRO.scale = function(x, y, z) {
|
scale(x, y, z) {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._scale(x, y, z);
|
w._scale(x, y, z);
|
||||||
});
|
});
|
||||||
this.center();
|
this.center();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO._scale = function(x, y, z) {
|
_scale(x, y, z) {
|
||||||
let mesh = this.mesh,
|
let mesh = this.mesh,
|
||||||
scale = this.track.scale;
|
scale = this.track.scale;
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
|
|
@ -682,22 +510,22 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
scale.y *= (y || 1.0);
|
scale.y *= (y || 1.0);
|
||||||
scale.z *= (z || 1.0);
|
scale.z *= (z || 1.0);
|
||||||
this.setModified();
|
this.setModified();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.rotate = function(x, y, z, temp) {
|
rotate(x, y, z, temp) {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._rotate(x, y, z, temp);
|
w._rotate(x, y, z, temp);
|
||||||
});
|
});
|
||||||
this.center(false);
|
this.center(false);
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.rotateRaw = function(x, y, z, temp) {
|
rotateRaw(x, y, z, temp) {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._rotate(x, y, z, temp);
|
w._rotate(x, y, z, temp);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO._rotate = function(x, y, z, temp) {
|
_rotate(x, y, z, temp) {
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
this.setWireframe(false);
|
this.setWireframe(false);
|
||||||
|
|
@ -719,25 +547,25 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
rot.z += (z || 0);
|
rot.z += (z || 0);
|
||||||
}
|
}
|
||||||
this.setModified();
|
this.setModified();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.unrotate = function() {
|
unrotate() {
|
||||||
this.roto.reverse().forEach(m => {
|
this.roto.reverse().forEach(m => {
|
||||||
this.mesh.geometry.applyMatrix4(m.clone().invert());
|
this.mesh.geometry.applyMatrix4(m.clone().invert());
|
||||||
});
|
});
|
||||||
this.roto = [];
|
this.roto = [];
|
||||||
this.center();
|
this.center();
|
||||||
this.setModified();
|
this.setModified();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.mirror = function() {
|
mirror() {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._mirror();
|
w._mirror();
|
||||||
});
|
});
|
||||||
this.center();
|
this.center();
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO._mirror = function() {
|
_mirror() {
|
||||||
this.clearSlices();
|
this.clearSlices();
|
||||||
this.setWireframe(false);
|
this.setWireframe(false);
|
||||||
let geo = this.mesh.geometry, ot = this.track;
|
let geo = this.mesh.geometry, ot = this.track;
|
||||||
|
|
@ -748,7 +576,7 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
for (let i=0; i<count; i++) {
|
for (let i=0; i<count; i++) {
|
||||||
arr[i*3] = -arr[i*3];
|
arr[i*3] = -arr[i*3];
|
||||||
}
|
}
|
||||||
// invert face vertices
|
// invert face vertex order
|
||||||
for (let i=0; i<count; i+=3) {
|
for (let i=0; i<count; i+=3) {
|
||||||
let x = arr[i*3+0];
|
let x = arr[i*3+0];
|
||||||
let y = arr[i*3+1];
|
let y = arr[i*3+1];
|
||||||
|
|
@ -766,9 +594,9 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
ot.mirror = !ot.mirror;
|
ot.mirror = !ot.mirror;
|
||||||
this.setModified();
|
this.setModified();
|
||||||
this.points = null;
|
this.points = null;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getGeoVertices = function(unroll) {
|
getGeoVertices(unroll) {
|
||||||
let geo = this.mesh.geometry;
|
let geo = this.mesh.geometry;
|
||||||
let pos = geo.getAttribute('position').array;
|
let pos = geo.getAttribute('position').array;
|
||||||
if (geo.index && unroll !== false) {
|
if (geo.index && unroll !== false) {
|
||||||
|
|
@ -787,14 +615,14 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
} else {
|
} else {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getGeoIndices = function() {
|
getGeoIndices() {
|
||||||
let indices = this.mesh.geometry.index;
|
let indices = this.mesh.geometry.index;
|
||||||
return indices ? indices.array : undefined;
|
return indices ? indices.array : undefined;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.iterPoints = function() {
|
iterPoints() {
|
||||||
let verts = this.getGeoVertices();
|
let verts = this.getGeoVertices();
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let count = verts.length;
|
let count = verts.length;
|
||||||
|
|
@ -807,9 +635,9 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getPoints = function() {
|
getPoints() {
|
||||||
if (!this.points) {
|
if (!this.points) {
|
||||||
// convert and cache points from geometry vertices
|
// convert and cache points from geometry vertices
|
||||||
this.points = verticesToPoints(this.getGeoVertices(), {
|
this.points = verticesToPoints(this.getGeoVertices(), {
|
||||||
|
|
@ -817,17 +645,17 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this.points;
|
return this.points;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getBoundingBox = function(refresh) {
|
getBoundingBox(refresh) {
|
||||||
if (!this.bounds || refresh) {
|
if (!this.bounds || refresh) {
|
||||||
this.bounds = new THREE.Box3();
|
this.bounds = new THREE.Box3();
|
||||||
this.bounds.setFromPoints(this.getPoints());
|
this.bounds.setFromPoints(this.getPoints());
|
||||||
}
|
}
|
||||||
return this.bounds;
|
return this.bounds;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getPositionBox = function() {
|
getPositionBox() {
|
||||||
let bounds = this.getBoundingBox().clone();
|
let bounds = this.getBoundingBox().clone();
|
||||||
let pos = this.track.pos;
|
let pos = this.track.pos;
|
||||||
bounds.min.x += pos.x;
|
bounds.min.x += pos.x;
|
||||||
|
|
@ -835,29 +663,24 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
bounds.min.y += pos.y;
|
bounds.min.y += pos.y;
|
||||||
bounds.max.y += pos.y;
|
bounds.max.y += pos.y;
|
||||||
return bounds;
|
return bounds;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.isModified = function() {
|
isModified() {
|
||||||
return this.modified;
|
return this.modified;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.getExtruder = function(settings) {
|
getExtruder(settings) {
|
||||||
if (settings) {
|
if (settings) {
|
||||||
console.trace('legacy call with settings');
|
console.trace('legacy call with settings');
|
||||||
}
|
}
|
||||||
return this.anno.extruder || 0;
|
return this.anno.extruder || 0;
|
||||||
// if (settings && settings.widget) {
|
}
|
||||||
// let rec = settings.widget[this.id];
|
|
||||||
// return rec && rec.extruder >= 0 ? rec.extruder : 0;
|
|
||||||
// }
|
|
||||||
// return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// allow worker code to run in same memspace as client
|
// allow worker code to run in same memspace as client
|
||||||
PRO.setInWorker = function() {
|
setInWorker() {
|
||||||
this.inWorker = true;
|
this.inWorker = true;
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* processes points into facets, then into slices
|
* processes points into facets, then into slices
|
||||||
|
|
@ -872,7 +695,7 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
* @params {Function} [ondone]
|
* @params {Function} [ondone]
|
||||||
* @params {Function} [onupdate]
|
* @params {Function} [onupdate]
|
||||||
*/
|
*/
|
||||||
PRO.slice = function(settings, ondone, onupdate) {
|
slice(settings, ondone, onupdate) {
|
||||||
let widget = this;
|
let widget = this;
|
||||||
let startTime = time();
|
let startTime = time();
|
||||||
|
|
||||||
|
|
@ -943,12 +766,12 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
// discard point cache
|
// discard point cache
|
||||||
widget.points = undefined;
|
widget.points = undefined;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* render to provided stack
|
* render to provided stack
|
||||||
*/
|
*/
|
||||||
PRO.render = function(stack) {
|
render(stack) {
|
||||||
const mark = Date.now();
|
const mark = Date.now();
|
||||||
this.slices.forEach(slice => {
|
this.slices.forEach(slice => {
|
||||||
if (slice.layers) {
|
if (slice.layers) {
|
||||||
|
|
@ -956,10 +779,10 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return Date.now() - mark;
|
return Date.now() - mark;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.setWireframe = function(set, color, opacity) {
|
setWireframe(set, color, opacity) {
|
||||||
if (!(kiri.api && kiri.api.conf)) {
|
if (!(api && api.conf)) {
|
||||||
// missing api features in engine mode
|
// missing api features in engine mode
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -971,7 +794,7 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
this.wire = null;
|
this.wire = null;
|
||||||
}
|
}
|
||||||
if (set) {
|
if (set) {
|
||||||
let dark = kiri.api.conf.get().controller.dark;
|
let dark = api.space.is_dark();
|
||||||
let mat = new THREE.MeshBasicMaterial({
|
let mat = new THREE.MeshBasicMaterial({
|
||||||
wireframe: true,
|
wireframe: true,
|
||||||
color: dark ? 0xaaaaaa : 0,
|
color: dark ? 0xaaaaaa : 0,
|
||||||
|
|
@ -981,7 +804,7 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
let wire = widget.wire = new THREE.Mesh(mesh.geometry.shallowClone(), mat);
|
let wire = widget.wire = new THREE.Mesh(mesh.geometry.shallowClone(), mat);
|
||||||
mesh.add(wire);
|
mesh.add(wire);
|
||||||
}
|
}
|
||||||
if (kiri.api.view.get() === kiri.consts.VIEWS.ARRANGE) {
|
if (api.view.is_arrange()) {
|
||||||
this.setColor(this.color);
|
this.setColor(this.color);
|
||||||
} else {
|
} else {
|
||||||
this.setColor(0x888888,undefined,false);
|
this.setColor(0x888888,undefined,false);
|
||||||
|
|
@ -989,14 +812,155 @@ console.log/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
if (opacity !== undefined) {
|
if (opacity !== undefined) {
|
||||||
widget.setOpacity(opacity);
|
widget.setOpacity(opacity);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.show = function() {
|
show() {
|
||||||
this.mesh.visible = true;
|
this.mesh.visible = true;
|
||||||
};
|
}
|
||||||
|
|
||||||
PRO.hide = function() {
|
hide() {
|
||||||
this.mesh.visible = false;
|
this.mesh.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget Grouping API
|
||||||
|
const Group = Widget.Groups = {
|
||||||
|
list() {
|
||||||
|
return groups.slice()
|
||||||
|
},
|
||||||
|
|
||||||
|
merge(widgets) {
|
||||||
|
let grps = widgets.map(w => w.group).uniq();
|
||||||
|
if (grps.length > 1) {
|
||||||
|
let root = grps.shift();
|
||||||
|
let rpos = root[0].track.pos;
|
||||||
|
for (let grp of grps) {
|
||||||
|
for (let w of grp) {
|
||||||
|
let wpos = w.track.pos;
|
||||||
|
w.group = root;
|
||||||
|
w.moveMesh(rpos.x - wpos.x, rpos.y - wpos.y, rpos.z - wpos.z);
|
||||||
|
w._move(rpos.x, rpos.y, rpos.z, true);
|
||||||
|
root.push(w);
|
||||||
|
}
|
||||||
|
groups.splice(groups.indexOf(grp),1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
split(widgets) {
|
||||||
|
for (let group of widgets.map(w => w.group).uniq()) {
|
||||||
|
groups.splice(groups.indexOf(group),1);
|
||||||
|
for (let widget of group) {
|
||||||
|
let nugroup = Group.forid(widget.id);
|
||||||
|
nugroup.push(widget);
|
||||||
|
widget.group = nugroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
forid(id) {
|
||||||
|
for (let i=0; i<groups.length; i++) {
|
||||||
|
if (groups[i].id === id) return groups[i];
|
||||||
|
}
|
||||||
|
let group = [];
|
||||||
|
group.id = id;
|
||||||
|
groups.push(group);
|
||||||
|
return group;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(widget) {
|
||||||
|
groups.slice().forEach(group => {
|
||||||
|
let pos = group.indexOf(widget);
|
||||||
|
if (pos >= 0) {
|
||||||
|
group.splice(pos,1);
|
||||||
|
}
|
||||||
|
if (group.length === 0) {
|
||||||
|
pos = groups.indexOf(group);
|
||||||
|
groups.splice(pos,1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
blocks() {
|
||||||
|
return groups.map(group => {
|
||||||
|
return {
|
||||||
|
w: group[0].track.box.w,
|
||||||
|
h: group[0].track.box.h,
|
||||||
|
move: (x,y,z,abs) => {
|
||||||
|
group.forEach(widget => {
|
||||||
|
widget.mesh.material.visible = true;
|
||||||
|
widget._move(x, y, z, abs);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
loadDone() {
|
||||||
|
groups.forEach(group => {
|
||||||
|
if (!group.centered) {
|
||||||
|
group[0].center();
|
||||||
|
group.centered = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
bounds(group) {
|
||||||
|
let bounds = null;
|
||||||
|
group.forEach(widget => {
|
||||||
|
let wb = widget.mesh.getBoundingBox(true);
|
||||||
|
if (bounds) {
|
||||||
|
bounds = bounds.union(wb);
|
||||||
|
} else {
|
||||||
|
bounds = wb;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return bounds;
|
||||||
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
groups.length = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Widget.loadFromCatalog = function(filename, ondone) {
|
||||||
|
catalog().getFile(filename, function(data) {
|
||||||
|
let widget = newWidget().loadVertices(data);
|
||||||
|
widget.meta.file = filename;
|
||||||
|
ondone(widget);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Widget.loadFromState = function(id, ondone, move) {
|
||||||
|
index().get('ws-save-'+id, function(data) {
|
||||||
|
if (data) {
|
||||||
|
let vertices = data.geo || data,
|
||||||
|
indices = data.ind || undefined,
|
||||||
|
track = data.track || undefined,
|
||||||
|
group = data.group || id,
|
||||||
|
anno = data.anno || undefined,
|
||||||
|
widget = newWidget(id, Group.forid(group)),
|
||||||
|
meta = data.meta || widget.meta,
|
||||||
|
ptr = widget.loadVertices({vertices, indices});
|
||||||
|
widget.meta = meta;
|
||||||
|
widget.anno = anno || widget.anno;
|
||||||
|
// restore widget position if specified
|
||||||
|
if (move && track && track.pos) {
|
||||||
|
widget.track = track;
|
||||||
|
widget.move(track.pos.x, track.pos.y, track.pos.z, true);
|
||||||
|
}
|
||||||
|
ondone(ptr);
|
||||||
|
} else {
|
||||||
|
ondone(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Widget.deleteFromState = function(id,ondone) {
|
||||||
|
index().remove('ws-save-'+id, ondone);
|
||||||
|
};
|
||||||
|
|
||||||
|
kiri.Widget = Widget;
|
||||||
|
kiri.newWidget = newWidget;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue