split widget into core and app-ui subclass
This commit is contained in:
parent
b45e2ba9b4
commit
24c0316cf8
13 changed files with 275 additions and 221 deletions
|
|
@ -22,7 +22,7 @@ import { local } from './local.js';
|
||||||
import { local as dataLocal } from '../../data/local.js';
|
import { local as dataLocal } from '../../data/local.js';
|
||||||
import { modal } from './modal.js';
|
import { modal } from './modal.js';
|
||||||
import { mode as modeModule, process as processModule } from './mode.js';
|
import { mode as modeModule, process as processModule } from './mode.js';
|
||||||
import { newWidget } from '../core/widget.js';
|
import { newWidget } from './widget.js';
|
||||||
import { noop, ajax, o2js, js2o, utils } from '../core/utils.js';
|
import { noop, ajax, o2js, js2o, utils } from '../core/utils.js';
|
||||||
import { openFiles } from './files.js';
|
import { openFiles } from './files.js';
|
||||||
import { platform } from './platform.js';
|
import { platform } from './platform.js';
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import { api } from './api.js';
|
import { api } from './api.js';
|
||||||
import { load } from '../../load/file.js';
|
import { load } from '../../load/file.js';
|
||||||
import { newWidget } from '../core/widget.js';
|
import { newWidget } from './widget.js';
|
||||||
import { VIEWS } from '../core/consts.js';
|
import { VIEWS } from '../core/consts.js';
|
||||||
import { widgets } from '../core/widgets.js';
|
import { widgets } from '../core/widgets.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { selection } from './selected.js';
|
import { selection } from './selected.js';
|
||||||
import { Widget } from '../core/widget.js';
|
import { Widget } from './widget.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge selected widgets into a group.
|
* Merge selected widgets into a group.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { $ } from '../../moto/webui.js';
|
import { $ } from '../../moto/webui.js';
|
||||||
import { api } from './api.js';
|
import { api } from './api.js';
|
||||||
import { newWidget } from '../core/widget.js';
|
import { newWidget } from './widget.js';
|
||||||
import { platform } from './platform.js';
|
import { platform } from './platform.js';
|
||||||
import { settings } from './conf/manager.js';
|
import { settings } from './conf/manager.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { newBounds } from '../../geo/bounds.js';
|
||||||
import { Packer } from './pack.js';
|
import { Packer } from './pack.js';
|
||||||
import { space } from '../../moto/space.js';
|
import { space } from '../../moto/space.js';
|
||||||
import { THREE } from '../../ext/three.js';
|
import { THREE } from '../../ext/three.js';
|
||||||
import { Widget, newWidget } from '../core/widget.js';
|
import { Widget, newWidget } from './widget.js';
|
||||||
|
|
||||||
const V0 = new THREE.Vector3(0,0,0);
|
const V0 = new THREE.Vector3(0,0,0);
|
||||||
|
|
||||||
|
|
|
||||||
253
src/kiri/app/widget.js
Normal file
253
src/kiri/app/widget.js
Normal file
|
|
@ -0,0 +1,253 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { Widget as WidgetCore } from '../core/widget.js';
|
||||||
|
import { util } from '../../geo/base.js';
|
||||||
|
import { avgc } from '../core/utils.js';
|
||||||
|
|
||||||
|
const solid_opacity = 1.0;
|
||||||
|
|
||||||
|
function catalog() { return self.kiri_catalog };
|
||||||
|
function index() { return self.kiri_catalog.index }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI-enhanced Widget subclass for main thread
|
||||||
|
* Adds rendering, persistence, and visual state management
|
||||||
|
*/
|
||||||
|
class Widget extends WidgetCore {
|
||||||
|
/**
|
||||||
|
* Save widget geometry to catalog
|
||||||
|
*/
|
||||||
|
saveToCatalog(filename, overwrite) {
|
||||||
|
if (!filename) {
|
||||||
|
filename = this.meta.file;
|
||||||
|
}
|
||||||
|
if (this.grouped && !overwrite) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const widget = this;
|
||||||
|
const mark = Date.now();
|
||||||
|
const vertices = widget.getGeoVertices({ unroll: true }).slice();
|
||||||
|
widget.meta.file = filename;
|
||||||
|
widget.meta.save = mark;
|
||||||
|
catalog().putFile(filename, vertices, () => {
|
||||||
|
console.log("saved mesh ["+(vertices.length/3)+"] time ["+(Date.now()-mark)+"]");
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save widget state to index
|
||||||
|
*/
|
||||||
|
saveState(ondone) {
|
||||||
|
if (!ondone) {
|
||||||
|
clearTimeout(this._save_timer);
|
||||||
|
this._save_timer = setTimeout(() => {
|
||||||
|
this._save_timer = undefined;
|
||||||
|
this.saveState(() => {});
|
||||||
|
}, 1500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const widget = this;
|
||||||
|
index().put('ws-save-'+this.id, {
|
||||||
|
geo: widget.getGeoVertices({ unroll: false }).slice(),
|
||||||
|
track: widget.track,
|
||||||
|
group: this.group.id,
|
||||||
|
meta: this.meta,
|
||||||
|
anno: this.annotations()
|
||||||
|
}, result => {
|
||||||
|
widget.meta.saved = Date.now();
|
||||||
|
if (ondone) ondone();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set mesh material color
|
||||||
|
*/
|
||||||
|
setColor(color, settings, save = true) {
|
||||||
|
if (settings) {
|
||||||
|
console.trace('legacy call with settings');
|
||||||
|
}
|
||||||
|
if (Array.isArray(color)) {
|
||||||
|
color = color[this.getExtruder() % color.length];
|
||||||
|
}
|
||||||
|
if (save) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
let material = this.getMaterial();
|
||||||
|
material.color.set(this.meta.disabled ? avgc(0x888888, color, 3) : color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current visual state
|
||||||
|
*/
|
||||||
|
getVisualState() {
|
||||||
|
return {
|
||||||
|
edges: this.outline ? true : false,
|
||||||
|
wires: this.wire ? true : false,
|
||||||
|
opacity: this.getMaterial().opacity
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set visual state
|
||||||
|
*/
|
||||||
|
setVisualState({ edges, wires, opacity}) {
|
||||||
|
this.cache.vizstate = this.getVisualState();
|
||||||
|
this.setEdges(edges ?? false);
|
||||||
|
this.setWireframe(wires ?? false);
|
||||||
|
this.setOpacity(opacity ?? 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh visual state
|
||||||
|
*/
|
||||||
|
refreshVisualState() {
|
||||||
|
this.setVisualState(this.getVisualState());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore previous visual state
|
||||||
|
*/
|
||||||
|
restoreVisualState() {
|
||||||
|
if (this.cache.vizstate) {
|
||||||
|
this.setVisualState(this.cache.vizstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set material opacity
|
||||||
|
*/
|
||||||
|
setOpacity(value) {
|
||||||
|
const mat = this.getMaterial();
|
||||||
|
if (value <= 0.0) {
|
||||||
|
mat.transparent = solid_opacity < 1.0;
|
||||||
|
mat.opacity = solid_opacity;
|
||||||
|
mat.visible = false;
|
||||||
|
} else if (util.inRange(value, 0.0, solid_opacity)) {
|
||||||
|
mat.transparent = value < 1.0;
|
||||||
|
mat.opacity = value;
|
||||||
|
mat.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set edge rendering
|
||||||
|
*/
|
||||||
|
setEdges(set) {
|
||||||
|
if (!(this.api && this.api.conf)) {
|
||||||
|
// missing api features in engine mode
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mesh = this.mesh;
|
||||||
|
if (set && set.toggle) {
|
||||||
|
set = this.outline ? false : true;
|
||||||
|
}
|
||||||
|
if (this.outline) {
|
||||||
|
mesh.remove(this.outline);
|
||||||
|
this.outline = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (set) {
|
||||||
|
let dark = this.api.space.is_dark();
|
||||||
|
let cam = this.api.mode.is_cam();
|
||||||
|
let color = dark ? 0x444444 : 0x888888;
|
||||||
|
let angle = this.api.conf.get().controller.edgeangle || 20;
|
||||||
|
let edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
||||||
|
let material = new THREE.LineBasicMaterial({ color });
|
||||||
|
this.outline = new THREE.LineSegments(edges, material);
|
||||||
|
this.outline.renderOrder = -20;
|
||||||
|
mesh.add(this.outline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set wireframe rendering
|
||||||
|
*/
|
||||||
|
setWireframe(set, color, opacity) {
|
||||||
|
if (!(this.api && this.api.conf)) {
|
||||||
|
// missing api features in engine mode
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mesh = this.mesh,
|
||||||
|
widget = this;
|
||||||
|
if (this.wire) {
|
||||||
|
this.setOpacity(solid_opacity);
|
||||||
|
mesh.remove(this.wire);
|
||||||
|
this.wire = null;
|
||||||
|
}
|
||||||
|
if (set) {
|
||||||
|
let dark = this.api.space.is_dark();
|
||||||
|
let mat = new THREE.MeshBasicMaterial({
|
||||||
|
wireframe: true,
|
||||||
|
color: dark ? 0xaaaaaa : 0,
|
||||||
|
opacity: 0.5,
|
||||||
|
transparent: true
|
||||||
|
})
|
||||||
|
let wire = widget.wire = new THREE.Mesh(mesh.geometry.shallowClone(), mat);
|
||||||
|
mesh.add(wire);
|
||||||
|
}
|
||||||
|
if (this.api.view.is_arrange()) {
|
||||||
|
this.setColor(this.color);
|
||||||
|
} else {
|
||||||
|
this.setColor(0x888888,undefined,false);
|
||||||
|
}
|
||||||
|
if (opacity !== undefined) {
|
||||||
|
widget.setOpacity(opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load widget from catalog
|
||||||
|
*/
|
||||||
|
static loadFromCatalog(filename, ondone) {
|
||||||
|
catalog().getFile(filename, function(data) {
|
||||||
|
let widget = new Widget().loadVertices(data);
|
||||||
|
widget.meta.file = filename;
|
||||||
|
ondone(widget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load widget from saved state
|
||||||
|
*/
|
||||||
|
static loadFromState(id, ondone, move) {
|
||||||
|
const Group = Widget.Groups;
|
||||||
|
index().get('ws-save-'+id, function(data) {
|
||||||
|
if (data) {
|
||||||
|
let vertices = data.geo || data,
|
||||||
|
track = data.track || undefined,
|
||||||
|
group = data.group || id,
|
||||||
|
anno = data.anno || undefined,
|
||||||
|
widget = new Widget(id, Group.forid(group)),
|
||||||
|
meta = data.meta || widget.meta,
|
||||||
|
ptr = widget.loadVertices(vertices);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete widget from saved state
|
||||||
|
*/
|
||||||
|
static deleteFromState(id,ondone) {
|
||||||
|
index().remove('ws-save-'+id, ondone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory function to create UI-enhanced widgets
|
||||||
|
*/
|
||||||
|
function newWidget(id, group) {
|
||||||
|
return new Widget(id, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Widget, newWidget };
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import { api } from './api.js';
|
import { api } from './api.js';
|
||||||
import { noop } from '../core/utils.js';
|
import { noop } from '../core/utils.js';
|
||||||
import { codec } from '../core/codec.js';
|
import { codec } from '../core/codec.js';
|
||||||
import { Widget } from '../core/widget.js';
|
import { Widget } from './widget.js';
|
||||||
import { newPrint } from '../core/print.js';
|
import { newPrint } from '../core/print.js';
|
||||||
|
|
||||||
// this code runs in kiri's main loop
|
// this code runs in kiri's main loop
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { selection } from './selected.js';
|
||||||
import { settings } from './conf/manager.js';
|
import { settings } from './conf/manager.js';
|
||||||
import { space as SPACE } from '../../moto/space.js';
|
import { space as SPACE } from '../../moto/space.js';
|
||||||
import { utils } from '../core/utils.js';
|
import { utils } from '../core/utils.js';
|
||||||
import { Widget } from '../core/widget.js';
|
import { Widget } from './widget.js';
|
||||||
import { Index } from '../../data/index.js';
|
import { Index } from '../../data/index.js';
|
||||||
|
|
||||||
const { o2js, js2o, ls2o, parseOpt } = utils;
|
const { o2js, js2o, ls2o, parseOpt } = utils;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { base } from '../../geo/base.js';
|
|
||||||
import { avgc } from './utils.js';
|
|
||||||
import { util as mesh_util } from '../../mesh/util.js';
|
import { util as mesh_util } from '../../mesh/util.js';
|
||||||
import { tool as mesh_tool } from '../../mesh/tool.js';
|
import { tool as mesh_tool } from '../../mesh/tool.js';
|
||||||
import { verticesToPoints } from '../../geo/points.js';
|
import { verticesToPoints } from '../../geo/points.js';
|
||||||
|
|
@ -10,21 +8,13 @@ import { newPolygon } from '../../geo/polygon.js';
|
||||||
import { polygons as POLY } from '../../geo/polygons.js';
|
import { polygons as POLY } from '../../geo/polygons.js';
|
||||||
import { checkOverUnderOn, intersectPoints } from '../../geo/slicer.js';
|
import { checkOverUnderOn, intersectPoints } from '../../geo/slicer.js';
|
||||||
|
|
||||||
const { inRange, time } = base.util;
|
const sharedArrayClass = self.SharedArrayBuffer || undefined;
|
||||||
|
const hasSharedArrays = sharedArrayClass ? true : false;
|
||||||
const solid_opacity = 1.0;
|
const solid_opacity = 1.0;
|
||||||
const groups = [];
|
const groups = [];
|
||||||
|
|
||||||
const sharedArrayClass = self.SharedArrayBuffer || undefined;
|
|
||||||
const hasSharedArrays = sharedArrayClass ? true : false;
|
|
||||||
|
|
||||||
let nextId = 0;
|
let nextId = 0;
|
||||||
|
|
||||||
function newWidget(id,group) { return new Widget(id,group) }
|
|
||||||
|
|
||||||
// todo: fix ui-only path thus this unorthodox binding vs importing api
|
|
||||||
function catalog() { return self.kiri_catalog };
|
|
||||||
function index() { return self.kiri_catalog.index }
|
|
||||||
|
|
||||||
class Widget {
|
class Widget {
|
||||||
constructor(id, group) {
|
constructor(id, group) {
|
||||||
this.api = self.kiri_api;
|
this.api = self.kiri_api;
|
||||||
|
|
@ -98,46 +88,6 @@ class Widget {
|
||||||
this.support = false;
|
this.support = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveToCatalog(filename, overwrite) {
|
|
||||||
if (!filename) {
|
|
||||||
filename = this.meta.file;
|
|
||||||
}
|
|
||||||
if (this.grouped && !overwrite) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
const widget = this;
|
|
||||||
const mark = time();
|
|
||||||
const vertices = widget.getGeoVertices({ unroll: true }).slice();
|
|
||||||
widget.meta.file = filename;
|
|
||||||
widget.meta.save = mark;
|
|
||||||
catalog().putFile(filename, vertices, () => {
|
|
||||||
console.log("saved mesh ["+(vertices.length/3)+"] time ["+(time()-mark)+"]");
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveState(ondone) {
|
|
||||||
if (!ondone) {
|
|
||||||
clearTimeout(this._save_timer);
|
|
||||||
this._save_timer = setTimeout(() => {
|
|
||||||
this._save_timer = undefined;
|
|
||||||
this.saveState(() => {});
|
|
||||||
}, 1500);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const widget = this;
|
|
||||||
index().put('ws-save-'+this.id, {
|
|
||||||
geo: widget.getGeoVertices({ unroll: false }).slice(),
|
|
||||||
track: widget.track,
|
|
||||||
group: this.group.id,
|
|
||||||
meta: this.meta,
|
|
||||||
anno: this.annotations()
|
|
||||||
}, result => {
|
|
||||||
widget.meta.saved = time();
|
|
||||||
if (ondone) ondone();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
annotations() {
|
annotations() {
|
||||||
let o = Object.clone(this.anno);
|
let o = Object.clone(this.anno);
|
||||||
if (o.support) {
|
if (o.support) {
|
||||||
|
|
@ -311,23 +261,6 @@ class Widget {
|
||||||
this.slices = null;
|
this.slices = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} color
|
|
||||||
*/
|
|
||||||
setColor(color, settings, save = true) {
|
|
||||||
if (settings) {
|
|
||||||
console.trace('legacy call with settings');
|
|
||||||
}
|
|
||||||
if (Array.isArray(color)) {
|
|
||||||
color = color[this.getExtruder() % color.length];
|
|
||||||
}
|
|
||||||
if (save) {
|
|
||||||
this.color = color;
|
|
||||||
}
|
|
||||||
let material = this.getMaterial();
|
|
||||||
material.color.set(this.meta.disabled ? avgc(0x888888, color, 3) : color);
|
|
||||||
}
|
|
||||||
|
|
||||||
getColor() {
|
getColor() {
|
||||||
return this.color;
|
return this.color;
|
||||||
}
|
}
|
||||||
|
|
@ -362,47 +295,6 @@ class Widget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getVisualState() {
|
|
||||||
return {
|
|
||||||
edges: this.outline ? true : false,
|
|
||||||
wires: this.wire ? true : false,
|
|
||||||
opacity: this.getMaterial().opacity
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
setVisualState({ edges, wires, opacity}) {
|
|
||||||
this.cache.vizstate = this.getVisualState();
|
|
||||||
this.setEdges(edges ?? false);
|
|
||||||
this.setWireframe(wires ?? false);
|
|
||||||
this.setOpacity(opacity ?? 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshVisualState() {
|
|
||||||
this.setVisualState(this.getVisualState());
|
|
||||||
}
|
|
||||||
|
|
||||||
restoreVisualState() {
|
|
||||||
if (this.cache.vizstate) {
|
|
||||||
this.setVisualState(this.cache.vizstate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} value
|
|
||||||
*/
|
|
||||||
setOpacity(value) {
|
|
||||||
const mesh = this.mesh;
|
|
||||||
const mat = this.getMaterial();
|
|
||||||
if (value <= 0.0) {
|
|
||||||
mat.transparent = solid_opacity < 1.0;
|
|
||||||
mat.opacity = solid_opacity;
|
|
||||||
mat.visible = false;
|
|
||||||
} else if (inRange(value, 0.0, solid_opacity)) {
|
|
||||||
mat.transparent = value < 1.0;
|
|
||||||
mat.opacity = value;
|
|
||||||
mat.visible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleVisibility(bool) {
|
toggleVisibility(bool) {
|
||||||
const mat = this.getMaterial();
|
const mat = this.getMaterial();
|
||||||
|
|
@ -574,10 +466,10 @@ class Widget {
|
||||||
let mesh = this.mesh,
|
let mesh = this.mesh,
|
||||||
scale = this.track.scale;
|
scale = this.track.scale;
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
this.setWireframe(false);
|
if (this.setWireframe) this.setWireframe(false);
|
||||||
this.clearSlices();
|
this.clearSlices();
|
||||||
mesh.geometry.applyMatrix4(new THREE.Matrix4().makeScale(x, y, z));
|
mesh.geometry.applyMatrix4(new THREE.Matrix4().makeScale(x, y, z));
|
||||||
if (this.outline) {
|
if (this.outline && this.setEdges) {
|
||||||
this.setEdges(true);
|
this.setEdges(true);
|
||||||
}
|
}
|
||||||
scale.x *= (x || 1.0);
|
scale.x *= (x || 1.0);
|
||||||
|
|
@ -593,7 +485,7 @@ class Widget {
|
||||||
if (center) {
|
if (center) {
|
||||||
this.center(false);
|
this.center(false);
|
||||||
}
|
}
|
||||||
if (this.outline) {
|
if (this.outline && this.setEdges) {
|
||||||
this.setEdges(true);
|
this.setEdges(true);
|
||||||
}
|
}
|
||||||
if ((x || y || z) && this.api && this.api.event) {
|
if ((x || y || z) && this.api && this.api.event) {
|
||||||
|
|
@ -604,7 +496,7 @@ class Widget {
|
||||||
_rotate(x, y, z, temp) {
|
_rotate(x, y, z, temp) {
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
this.setWireframe(false);
|
if (this.setWireframe) this.setWireframe(false);
|
||||||
this.clearSlices();
|
this.clearSlices();
|
||||||
}
|
}
|
||||||
let m4 = new THREE.Matrix4();
|
let m4 = new THREE.Matrix4();
|
||||||
|
|
@ -633,7 +525,7 @@ class Widget {
|
||||||
this.roto = [];
|
this.roto = [];
|
||||||
this.center();
|
this.center();
|
||||||
this.setModified();
|
this.setModified();
|
||||||
this.refreshVisualState();
|
if (this.refreshVisualState) this.refreshVisualState();
|
||||||
}
|
}
|
||||||
|
|
||||||
mirror() {
|
mirror() {
|
||||||
|
|
@ -648,7 +540,7 @@ class Widget {
|
||||||
|
|
||||||
_mirror() {
|
_mirror() {
|
||||||
this.clearSlices();
|
this.clearSlices();
|
||||||
this.setWireframe(false);
|
if (this.setWireframe) this.setWireframe(false);
|
||||||
let geo = this.mesh.geometry, ot = this.track;
|
let geo = this.mesh.geometry, ot = this.track;
|
||||||
let pos = geo.attributes.position;
|
let pos = geo.attributes.position;
|
||||||
let arr = pos.array;
|
let arr = pos.array;
|
||||||
|
|
@ -782,65 +674,6 @@ class Widget {
|
||||||
return Date.now() - mark;
|
return Date.now() - mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEdges(set) {
|
|
||||||
if (!(this.api && this.api.conf)) {
|
|
||||||
// missing api features in engine mode
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mesh = this.mesh;
|
|
||||||
if (set && set.toggle) {
|
|
||||||
set = this.outline ? false : true;
|
|
||||||
}
|
|
||||||
if (this.outline) {
|
|
||||||
mesh.remove(this.outline);
|
|
||||||
this.outline = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (set) {
|
|
||||||
let dark = this.api.space.is_dark();
|
|
||||||
let cam = this.api.mode.is_cam();
|
|
||||||
let color = dark ? 0x444444 : 0x888888;
|
|
||||||
let angle = this.api.conf.get().controller.edgeangle || 20;
|
|
||||||
let edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
|
||||||
let material = new THREE.LineBasicMaterial({ color });
|
|
||||||
this.outline = new THREE.LineSegments(edges, material);
|
|
||||||
this.outline.renderOrder = -20;
|
|
||||||
mesh.add(this.outline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setWireframe(set, color, opacity) {
|
|
||||||
if (!(this.api && this.api.conf)) {
|
|
||||||
// missing api features in engine mode
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mesh = this.mesh,
|
|
||||||
widget = this;
|
|
||||||
if (this.wire) {
|
|
||||||
this.setOpacity(solid_opacity);
|
|
||||||
mesh.remove(this.wire);
|
|
||||||
this.wire = null;
|
|
||||||
}
|
|
||||||
if (set) {
|
|
||||||
let dark = this.api.space.is_dark();
|
|
||||||
let mat = new THREE.MeshBasicMaterial({
|
|
||||||
wireframe: true,
|
|
||||||
color: dark ? 0xaaaaaa : 0,
|
|
||||||
opacity: 0.5,
|
|
||||||
transparent: true
|
|
||||||
})
|
|
||||||
let wire = widget.wire = new THREE.Mesh(mesh.geometry.shallowClone(), mat);
|
|
||||||
mesh.add(wire);
|
|
||||||
}
|
|
||||||
if (this.api.view.is_arrange()) {
|
|
||||||
this.setColor(this.color);
|
|
||||||
} else {
|
|
||||||
this.setColor(0x888888,undefined,false);
|
|
||||||
}
|
|
||||||
if (opacity !== undefined) {
|
|
||||||
widget.setOpacity(opacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
this.mesh.visible = true;
|
this.mesh.visible = true;
|
||||||
|
|
@ -1076,40 +909,8 @@ const Group = Widget.Groups = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Widget.loadFromCatalog = function(filename, ondone) {
|
function newWidget(id,group) {
|
||||||
catalog().getFile(filename, function(data) {
|
return new Widget(id,group);
|
||||||
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,
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { Widget, newWidget };
|
export { Widget, newWidget };
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import { $ } from '../../moto/webui.js';
|
import { $ } from '../../moto/webui.js';
|
||||||
import { api } from '../app/api.js';
|
import { api } from '../app/api.js';
|
||||||
import { load } from '../../load/file.js';
|
import { load } from '../../load/file.js';
|
||||||
import { Widget, newWidget } from './widget.js';
|
import { Widget, newWidget } from '../app/widget.js';
|
||||||
|
|
||||||
let WIDGETS = [];
|
let WIDGETS = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { holeSelOn, selectHolesDone, clearHolesRec } from './cl-hole.js';
|
||||||
import { surfaceOn, surfaceDone } from './cl-surface.js';
|
import { surfaceOn, surfaceDone } from './cl-surface.js';
|
||||||
import { helicalOn, helicalDone } from './cl-helical.js';
|
import { helicalOn, helicalDone } from './cl-helical.js';
|
||||||
import { originSelectDone } from './cl-origin.js';
|
import { originSelectDone } from './cl-origin.js';
|
||||||
import { Widget, newWidget } from '../../core/widget.js';
|
import { Widget, newWidget } from '../../app/widget.js';
|
||||||
import { space } from '../../../moto/space.js';
|
import { space } from '../../../moto/space.js';
|
||||||
import { recreateTabs } from './cl-tab.js';
|
import { recreateTabs } from './cl-tab.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { client } from '../../app/workers.js';
|
||||||
import { addbox, delbox, getlastbox } from '../../core/boxes.js';
|
import { addbox, delbox, getlastbox } from '../../core/boxes.js';
|
||||||
import { Layers } from '../../app/layers.js';
|
import { Layers } from '../../app/layers.js';
|
||||||
import { Stack } from '../../app/stack.js';
|
import { Stack } from '../../app/stack.js';
|
||||||
import { Widget, newWidget } from '../../core/widget.js';
|
import { Widget, newWidget } from '../../app/widget.js';
|
||||||
import { space } from '../../../moto/space.js';
|
import { space } from '../../../moto/space.js';
|
||||||
|
|
||||||
const { Matrix4, Vector3, BufferAttribute, BufferGeometryUtils, Raycaster, Euler } = THREE;
|
const { Matrix4, Vector3, BufferAttribute, BufferGeometryUtils, Raycaster, Euler } = THREE;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { api } from '../app/api.js';
|
||||||
import { conf } from '../app/conf/defaults.js';
|
import { conf } from '../app/conf/defaults.js';
|
||||||
import { client } from '../app/workers.js';
|
import { client } from '../app/workers.js';
|
||||||
import { load } from '../../load/file.js';
|
import { load } from '../../load/file.js';
|
||||||
import { newWidget } from '../core/widget.js';
|
import { newWidget } from '../app/widget.js';
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
constructor({ workURL, poolURL } = {}) {
|
constructor({ workURL, poolURL } = {}) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue