add widget grouping for future multi-extruder setups
This commit is contained in:
parent
279f2ad0b3
commit
e9a04969ee
4 changed files with 243 additions and 128 deletions
|
|
@ -1021,9 +1021,10 @@ var gs_kiri_init = exports;
|
|||
SPACE.platform.setColor(0x555555);
|
||||
|
||||
let files = evt.dataTransfer.files,
|
||||
plate = files.length < 5 || confirm(`add ${files.length} objects to workspace?`);
|
||||
plate = files.length < 5 || confirm(`add ${files.length} objects to workspace?`),
|
||||
group = files.length < 2 ? undefined : confirm('group files?') ? [] : undefined;
|
||||
|
||||
if (plate) API.platform.load_files(files);
|
||||
if (plate) API.platform.load_files(files,group);
|
||||
}
|
||||
|
||||
function loadCatalogFile(e) {
|
||||
|
|
@ -1168,7 +1169,7 @@ var gs_kiri_init = exports;
|
|||
stockHeight: $('stock-width'),
|
||||
|
||||
device: UC.newGroup(LANG.dv_gr_dev, $('device'), {group:"ddev", nocompact:true}),
|
||||
deviceName: UC.newInput(LANG.dv_name_s, {title:LANG.dv_name_l, size:20, text:true}),
|
||||
deviceName: UC.newInput(LANG.dv_name_s, {title:LANG.dv_name_l, size:"60%", text:true}),
|
||||
setDeviceFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
|
||||
setDeviceNozzle: UC.newInput(LANG.dv_nozl_s, {title:LANG.dv_nozl_l, convert:UC.toFloat, modes:FDM}),
|
||||
setDeviceWidth: UC.newInput(LANG.dv_bedw_s, {title:LANG.dv_bedw_l, convert:UC.toInt}),
|
||||
|
|
@ -1181,8 +1182,8 @@ var gs_kiri_init = exports;
|
|||
setDeviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM}),
|
||||
|
||||
setDevice: UC.newGroup(LANG.dv_gr_gco, $('device'), {group:"dgco", nocompact:true}),
|
||||
setDeviceFan: UC.newInput(LANG.dv_fanp_s, {title:LANG.dv_fanp_l, modes:FDM, size:17, text:true}),
|
||||
setDeviceTrack: UC.newInput(LANG.dv_prog_s, {title:LANG.dv_prog_l, modes:FDM, size:17, text:true}),
|
||||
setDeviceFan: UC.newInput(LANG.dv_fanp_s, {title:LANG.dv_fanp_l, modes:FDM, size:"30%", text:true}),
|
||||
setDeviceTrack: UC.newInput(LANG.dv_prog_s, {title:LANG.dv_prog_l, modes:FDM, size:"30%", text:true}),
|
||||
setDeviceLayer: UC.newText(LANG.dv_layr_s, {title:LANG.dv_layr_l, modes:FDM, size:14, height: 2}),
|
||||
setDeviceToken: UC.newBoolean(LANG.dv_tksp_s, null, {title:LANG.dv_tksp_l, modes:CAM_LASER}),
|
||||
setDeviceStrip: UC.newBoolean(LANG.dv_strc_s, null, {title:LANG.dv_strc_l, modes:CAM}),
|
||||
|
|
@ -1604,11 +1605,11 @@ var gs_kiri_init = exports;
|
|||
API.selection.for_widgets(function(widget) {
|
||||
let wbnd = widget.getBoundingBox();
|
||||
let wwid = wbnd.max.x - wbnd.min.x;
|
||||
let wminx = widget.orient.pos.x + delta.x - wwid / 2;
|
||||
let wminx = widget.track.pos.x + delta.x - wwid / 2;
|
||||
let wmaxx = wminx + wwid + delta.x;
|
||||
if (wminx < bminx || wmaxx > bmaxx) return;
|
||||
let whei = wbnd.max.y - wbnd.min.y;
|
||||
let wminy = widget.orient.pos.y + delta.y - whei / 2;
|
||||
let wminy = widget.track.pos.y + delta.y - whei / 2;
|
||||
let wmaxy = wminy + whei + delta.y;
|
||||
if (wminy < bminy || wmaxy > bmaxy) return;
|
||||
widget.move(delta.x, delta.y, 0);
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var gs_kiri_widget = exports;
|
||||
let gs_kiri_widget = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.Widget) return;
|
||||
|
||||
var KIRI = self.kiri,
|
||||
let KIRI = self.kiri,
|
||||
DRIVERS = KIRI.driver,
|
||||
CAM = DRIVERS.CAM,
|
||||
FDM = DRIVERS.FDM,
|
||||
|
|
@ -37,12 +37,70 @@ var gs_kiri_widget = exports;
|
|||
time = UTIL.time,
|
||||
PRO = Widget.prototype,
|
||||
solid_opacity = 1.0,
|
||||
nextId = 0;
|
||||
nextId = 0,
|
||||
groups = [];
|
||||
|
||||
KIRI.Widget = Widget;
|
||||
KIRI.newWidget = newWidget;
|
||||
|
||||
function newWidget(id) { return new Widget(id) }
|
||||
function newWidget(id,group) { return new Widget(id,group) }
|
||||
|
||||
/** ******************************************************************
|
||||
* Group helpers
|
||||
******************************************************************* */
|
||||
|
||||
let Group = Widget.Groups = {
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
/** ******************************************************************
|
||||
* Constructor
|
||||
|
|
@ -52,8 +110,13 @@ var gs_kiri_widget = exports;
|
|||
* @params {String} [id]
|
||||
* @constructor
|
||||
*/
|
||||
function Widget(id) {
|
||||
function Widget(id,group) {
|
||||
this.id = id || new Date().getTime().toString(36)+(nextId++);
|
||||
this.group = group || [];
|
||||
this.group.push(this);
|
||||
if (groups.indexOf(this.group) < 0) {
|
||||
groups.push(this.group);
|
||||
}
|
||||
this.mesh = null;
|
||||
this.points = null;
|
||||
// todo resolve use of this vs. mesh.bounds
|
||||
|
|
@ -63,7 +126,13 @@ var gs_kiri_widget = exports;
|
|||
this.slices = null;
|
||||
this.settings = null;
|
||||
this.modified = true;
|
||||
this.orient = {
|
||||
this.track = {
|
||||
// box size for packer
|
||||
box: {
|
||||
w: 0,
|
||||
h: 0,
|
||||
d: 0
|
||||
},
|
||||
scale: {
|
||||
x: 1.0,
|
||||
y: 1.0,
|
||||
|
|
@ -100,18 +169,18 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
Widget.loadFromState = function(id, ondone, move) {
|
||||
var widget = newWidget();
|
||||
let widget = newWidget();
|
||||
widget.id = id;
|
||||
widget.saved = time();
|
||||
KIRI.odb.get('ws-save-'+id, function(data) {
|
||||
if (data) {
|
||||
var vertices = data.geo || data,
|
||||
orient = data.orient || null;
|
||||
let vertices = data.geo || data,
|
||||
track = data.track || null;
|
||||
ondone(widget.loadVertices(vertices));
|
||||
// restore widget position if specified
|
||||
if (move && orient && orient.pos) {
|
||||
widget.orient = orient;
|
||||
widget.move(orient.pos.x, orient.pos.y, orient.pos.z, true);
|
||||
if (move && track && track.pos) {
|
||||
widget.track = track;
|
||||
widget.move(track.pos.x, track.pos.y, track.pos.z, true);
|
||||
}
|
||||
} else {
|
||||
ondone(null);
|
||||
|
|
@ -132,7 +201,7 @@ var gs_kiri_widget = exports;
|
|||
* @returns {Array}
|
||||
*/
|
||||
Widget.verticesToPoints = function(array,decimate) {
|
||||
var parr = new Array(array.length / 3),
|
||||
let parr = new Array(array.length / 3),
|
||||
i = 0,
|
||||
j = 0,
|
||||
t = time(),
|
||||
|
|
@ -144,7 +213,7 @@ var gs_kiri_widget = exports;
|
|||
newpoints;
|
||||
// replace point objects with their equivalents
|
||||
while (i < array.length) {
|
||||
var p = newPoint(array[i++], array[i++], array[i++]),
|
||||
let p = newPoint(array[i++], array[i++], array[i++]),
|
||||
k = p.key,
|
||||
m = hash[k];
|
||||
if (!m) {
|
||||
|
|
@ -156,9 +225,9 @@ var gs_kiri_widget = exports;
|
|||
}
|
||||
// decimate until all point spacing > precision_decimate
|
||||
while (parr.length > BASE.config.decimate_threshold && decimate && BASE.config.precision_decimate > 0.0) {
|
||||
var lines = [], line, dec = 0;
|
||||
let lines = [], line, dec = 0;
|
||||
for (i=0; i<oldpoints; ) {
|
||||
var p1 = parr[i++],
|
||||
let p1 = parr[i++],
|
||||
p2 = parr[i++],
|
||||
p3 = parr[i++];
|
||||
lines.push( {p1:p1, p2:p2, d:SQRT(p1.distToSq3D(p2))} );
|
||||
|
|
@ -185,7 +254,7 @@ var gs_kiri_widget = exports;
|
|||
points = new Array(oldpoints);
|
||||
newpoints = 0;
|
||||
for (i=0; i<oldpoints; ) {
|
||||
var p1 = parr[i++],
|
||||
let p1 = parr[i++],
|
||||
p2 = parr[i++],
|
||||
p3 = parr[i++];
|
||||
// drop facets with two offset points
|
||||
|
|
@ -211,7 +280,7 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
Widget.pointsToVertices = function(points) {
|
||||
var vertices = new Float32Array(points.length * 3),
|
||||
let vertices = new Float32Array(points.length * 3),
|
||||
i = 0, vi = 0;
|
||||
while (i < points.length) {
|
||||
vertices[vi++] = points[i].x;
|
||||
|
|
@ -226,8 +295,8 @@ var gs_kiri_widget = exports;
|
|||
******************************************************************* */
|
||||
|
||||
PRO.saveToCatalog = function(filename) {
|
||||
var widget = this;
|
||||
var time = UTIL.time();
|
||||
let widget = this;
|
||||
let time = UTIL.time();
|
||||
KIRI.catalog.putFile(filename, this.getGeoVertices(), function(vertices) {
|
||||
if (vertices && vertices.length) {
|
||||
console.log("saving decimated mesh ["+vertices.length+"] time ["+(UTIL.time()-time)+"]");
|
||||
|
|
@ -238,8 +307,8 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.saveState = function(ondone) {
|
||||
var widget = this;
|
||||
KIRI.odb.put('ws-save-'+this.id, {geo:widget.getGeoVertices(), orient:widget.orient}, function(result) {
|
||||
let widget = this;
|
||||
KIRI.odb.put('ws-save-'+this.id, {geo:widget.getGeoVertices(), track:widget.track}, function(result) {
|
||||
widget.saved = time();
|
||||
if (ondone) ondone();
|
||||
});
|
||||
|
|
@ -258,7 +327,7 @@ var gs_kiri_widget = exports;
|
|||
this.points = null;
|
||||
return this;
|
||||
} else {
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
let geometry = new THREE.BufferGeometry();
|
||||
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
|
||||
return this.loadGeometry(geometry);
|
||||
}
|
||||
|
|
@ -269,7 +338,7 @@ var gs_kiri_widget = exports;
|
|||
* @returns {Widget}
|
||||
*/
|
||||
PRO.loadGeometry = function(geometry) {
|
||||
var mesh = new THREE.Mesh(
|
||||
let mesh = new THREE.Mesh(
|
||||
geometry,
|
||||
new THREE.MeshPhongMaterial({
|
||||
color: 0xffff00,
|
||||
|
|
@ -279,7 +348,6 @@ var gs_kiri_widget = exports;
|
|||
opacity: solid_opacity
|
||||
})
|
||||
);
|
||||
|
||||
// fix invalid normals
|
||||
geometry.computeFaceNormals();
|
||||
geometry.computeVertexNormals();
|
||||
|
|
@ -290,10 +358,14 @@ var gs_kiri_widget = exports;
|
|||
mesh.widget = this;
|
||||
this.mesh = mesh;
|
||||
// invalidates points cache (like any scale/rotation)
|
||||
this.center();
|
||||
this.center(true);
|
||||
return this;
|
||||
};
|
||||
|
||||
PRO.groupBounds = function() {
|
||||
return Group.bounds(this.group);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Point[]} points
|
||||
* @returns {Widget}
|
||||
|
|
@ -307,7 +379,7 @@ var gs_kiri_widget = exports;
|
|||
* remove slice data and their views
|
||||
*/
|
||||
PRO.clearSlices = function() {
|
||||
var slices = this.slices,
|
||||
let slices = this.slices,
|
||||
mesh = this.mesh;
|
||||
if (slices) {
|
||||
slices.forEach(function(slice) {
|
||||
|
|
@ -321,7 +393,7 @@ var gs_kiri_widget = exports;
|
|||
* @param {number} color
|
||||
*/
|
||||
PRO.setColor = function(color) {
|
||||
var material = this.mesh.material;
|
||||
let material = this.mesh.material;
|
||||
material.color.set(color);
|
||||
};
|
||||
|
||||
|
|
@ -329,7 +401,7 @@ var gs_kiri_widget = exports;
|
|||
* @param {number} value
|
||||
*/
|
||||
PRO.setOpacity = function(value) {
|
||||
var mesh = this.mesh;
|
||||
let mesh = this.mesh;
|
||||
if (value <= 0.0) {
|
||||
mesh.material.transparent = solid_opacity < 1.0;
|
||||
mesh.material.opacity = solid_opacity;
|
||||
|
|
@ -344,28 +416,42 @@ var gs_kiri_widget = exports;
|
|||
/**
|
||||
* center geometry bottom (on platform) at 0,0,0
|
||||
*/
|
||||
PRO.center = function() {
|
||||
var i = 0,
|
||||
mesh = this.mesh,
|
||||
geo = mesh.geometry,
|
||||
bb = mesh.getBoundingBox(true),
|
||||
PRO.center = function(init) {
|
||||
let bb = init ? this.mesh.getBoundingBox(true) : this.groupBounds(),
|
||||
bm = bb.min.clone(),
|
||||
bM = bb.max.clone(),
|
||||
bd = bM.sub(bm).multiplyScalar(0.5),
|
||||
gap = geo.attributes.position,
|
||||
dx = bm.x + bd.x,
|
||||
dy = bm.y + bd.y,
|
||||
dz = bm.z;
|
||||
// move mesh for each widget in group
|
||||
if (!init) {
|
||||
this.group.forEach(w => {
|
||||
w.moveMesh(dx,dy,dz);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* called by center() and Group.center()
|
||||
*/
|
||||
PRO.moveMesh = function(x, y, z) {
|
||||
let gap = this.mesh.geometry.attributes.position,
|
||||
pa = gap.array;
|
||||
// center point array on 0,0,0
|
||||
for ( ; i < pa.length; i += 3) {
|
||||
pa[i ] -= bm.x + bd.x;
|
||||
pa[i + 1] -= bm.y + bd.y;
|
||||
pa[i + 2] -= bm.z;
|
||||
for (let i=0; i < pa.length; i += 3) {
|
||||
pa[i ] -= x;
|
||||
pa[i + 1] -= y;
|
||||
pa[i + 2] -= z;
|
||||
}
|
||||
gap.needsUpdate = true;
|
||||
bb = mesh.getBoundingBox(true);
|
||||
let bb = this.groupBounds();
|
||||
this.track.box = {
|
||||
w: (bb.max.x - bb.min.x),
|
||||
h: (bb.max.y - bb.min.y),
|
||||
d: (bb.max.z - bb.min.z)
|
||||
};
|
||||
// for use with the packer
|
||||
mesh.w = (bb.max.x - bb.min.x);
|
||||
mesh.h = (bb.max.y - bb.min.y);
|
||||
mesh.d = (bb.max.z - bb.min.z);
|
||||
// invalidate cached points
|
||||
this.points = null;
|
||||
this.modified = true;
|
||||
|
|
@ -378,8 +464,8 @@ var gs_kiri_widget = exports;
|
|||
* @param {number} z position
|
||||
*/
|
||||
PRO.setTopZ = function(z) {
|
||||
var mesh = this.mesh,
|
||||
pos = this.orient.pos;
|
||||
let mesh = this.mesh,
|
||||
pos = this.track.pos;
|
||||
if (z) {
|
||||
pos.z = mesh.getBoundingBox().max.z - z;
|
||||
mesh.position.z = -pos.z - 0.01;
|
||||
|
|
@ -390,16 +476,15 @@ var gs_kiri_widget = exports;
|
|||
this.modified = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} z
|
||||
* @param {boolean} abs
|
||||
*/
|
||||
PRO.move = function(x, y, z, abs) {
|
||||
var mesh = this.mesh,
|
||||
pos = this.orient.pos;
|
||||
this.group.forEach(w => {
|
||||
w._move(x, y, z, abs);
|
||||
});
|
||||
};
|
||||
|
||||
PRO._move = function(x, y, z, abs) {
|
||||
let mesh = this.mesh,
|
||||
pos = this.track.pos;
|
||||
// do not allow moves in pure slice view
|
||||
if (!mesh.material.visible) return;
|
||||
if (abs) {
|
||||
|
|
@ -421,32 +506,33 @@ var gs_kiri_widget = exports;
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} z
|
||||
*/
|
||||
PRO.scale = function(x, y, z) {
|
||||
this.group.forEach(w => {
|
||||
w._scale(x, y, z);
|
||||
});
|
||||
this.center();
|
||||
};
|
||||
|
||||
PRO._scale = function(x, y, z) {
|
||||
let mesh = this.mesh,
|
||||
scale = this.orient.scale;
|
||||
scale = this.track.scale;
|
||||
this.bounds = null;
|
||||
this.setWireframe(false);
|
||||
this.clearSlices();
|
||||
mesh.geometry.applyMatrix4(new THREE.Matrix4().makeScale(x, y, z));
|
||||
this.center();
|
||||
scale.x *= (x || 1.0);
|
||||
scale.y *= (y || 1.0);
|
||||
scale.z *= (z || 1.0);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} z
|
||||
*/
|
||||
PRO.rotate = function(x, y, z) {
|
||||
this.group.forEach(w => {
|
||||
w._rotate(x, y, z);
|
||||
});
|
||||
this.center();
|
||||
};
|
||||
|
||||
PRO._rotate = function(x, y, z) {
|
||||
this.bounds = null;
|
||||
this.setWireframe(false);
|
||||
this.clearSlices();
|
||||
|
|
@ -458,9 +544,8 @@ var gs_kiri_widget = exports;
|
|||
m4 = m4.makeRotationFromQuaternion(x);
|
||||
}
|
||||
this.mesh.geometry.applyMatrix4(m4);
|
||||
this.center();
|
||||
if (euler) {
|
||||
let rot = this.orient.rot;
|
||||
let rot = this.track.rot;
|
||||
rot.x += (x || 0);
|
||||
rot.y += (y || 0);
|
||||
rot.z += (z || 0);
|
||||
|
|
@ -468,10 +553,17 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.mirror = function() {
|
||||
this.group.forEach(w => {
|
||||
w._mirror();
|
||||
});
|
||||
this.center();
|
||||
};
|
||||
|
||||
PRO._mirror = function() {
|
||||
this.setWireframe(false);
|
||||
this.clearSlices();
|
||||
var i,
|
||||
o = this.orient,
|
||||
let i,
|
||||
o = this.track,
|
||||
geo = this.mesh.geometry,
|
||||
at = geo.attributes,
|
||||
pa = at.position.array,
|
||||
|
|
@ -482,7 +574,6 @@ var gs_kiri_widget = exports;
|
|||
}
|
||||
geo.computeFaceNormals();
|
||||
geo.computeVertexNormals();
|
||||
this.center();
|
||||
o.mirror = !o.mirror;
|
||||
};
|
||||
|
||||
|
|
@ -499,7 +590,6 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.getBoundingBox = function(refresh) {
|
||||
// if (this.mesh) return this.mesh.getBoundingBox();
|
||||
if (!this.bounds || refresh) {
|
||||
this.bounds = new THREE.Box3();
|
||||
this.bounds.setFromPoints(this.getPoints());
|
||||
|
|
@ -526,7 +616,7 @@ var gs_kiri_widget = exports;
|
|||
* @params {boolean} [remote]
|
||||
*/
|
||||
PRO.slice = function(settings, ondone, onupdate, remote) {
|
||||
var widget = this,
|
||||
let widget = this,
|
||||
startTime = UTIL.time();
|
||||
|
||||
widget.settings = settings;
|
||||
|
|
@ -573,7 +663,7 @@ var gs_kiri_widget = exports;
|
|||
} else {
|
||||
|
||||
// executed from kiri-worker.js
|
||||
var catchdone = function(error) {
|
||||
let catchdone = function(error) {
|
||||
if (error) {
|
||||
return ondone(error);
|
||||
}
|
||||
|
|
@ -586,11 +676,11 @@ var gs_kiri_widget = exports;
|
|||
ondone();
|
||||
};
|
||||
|
||||
var catchupdate = function(progress, message) {
|
||||
let catchupdate = function(progress, message) {
|
||||
onupdate(progress, message);
|
||||
};
|
||||
|
||||
var driver = null;
|
||||
let driver = null;
|
||||
|
||||
switch (settings.mode) {
|
||||
case 'LASER': driver = LASER; break;
|
||||
|
|
@ -608,7 +698,7 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.getCamBounds = function(settings) {
|
||||
var bounds = this.getBoundingBox().clone();
|
||||
let bounds = this.getBoundingBox().clone();
|
||||
bounds.max.z += settings.process.camZTopOffset;
|
||||
return bounds;
|
||||
};
|
||||
|
|
@ -619,7 +709,7 @@ var gs_kiri_widget = exports;
|
|||
* @param {boolean} cam mode
|
||||
*/
|
||||
PRO.render = function(renderMode, cam) {
|
||||
var slices = this.slices;
|
||||
let slices = this.slices;
|
||||
if (!slices) return;
|
||||
// render outline
|
||||
slices.forEach(function(s) { s.renderOutline(renderMode) });
|
||||
|
|
@ -638,7 +728,7 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.hideSlices = function() {
|
||||
var showing = false;
|
||||
let showing = false;
|
||||
if (this.slices) this.slices.forEach(function(slice) {
|
||||
showing = showing || slice.view.visible;
|
||||
slice.view.visible = false;
|
||||
|
|
@ -651,7 +741,7 @@ var gs_kiri_widget = exports;
|
|||
};
|
||||
|
||||
PRO.setWireframe = function(set, color, opacity) {
|
||||
var mesh = this.mesh,
|
||||
let mesh = this.mesh,
|
||||
widget = this;
|
||||
if (this.wire) {
|
||||
mesh.remove(this.wire);
|
||||
|
|
|
|||
96
js/kiri.js
96
js/kiri.js
|
|
@ -58,7 +58,8 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
camTopZ = 0,
|
||||
topZ = 0,
|
||||
showFavorites = SDB.getItem('dev-favorites') === 'true',
|
||||
alerts = [];
|
||||
alerts = [],
|
||||
grouping = false;
|
||||
|
||||
// seed defaults. will get culled on save
|
||||
settings.sproc.FDM.default = clone(settings.process);
|
||||
|
|
@ -83,7 +84,6 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
move: moveSelection,
|
||||
scale: scaleSelection,
|
||||
rotate: rotateSelection,
|
||||
bounds: boundsSelection,
|
||||
meshes: function() { return selectedMeshes.slice() },
|
||||
widgets: function() { return selectedMeshes.slice().map(m => m.widget) },
|
||||
for_meshes: forSelectedMeshes,
|
||||
|
|
@ -106,7 +106,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
update_stock: platformUpdateStock,
|
||||
update_size: platformUpdateSize,
|
||||
update_top_z: platformUpdateTopZ,
|
||||
load_files: loadFiles
|
||||
load_files: loadFiles,
|
||||
group: platformGroup,
|
||||
group_done: platformGroupDone
|
||||
};
|
||||
|
||||
const color = {
|
||||
|
|
@ -449,8 +451,18 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
});
|
||||
}
|
||||
|
||||
function forSelectedGroups(f) {
|
||||
let m = selectedMeshes;
|
||||
if (m.length === 0 && WIDGETS.length === 1) m = [ WIDGETS[0].mesh ];
|
||||
let v = [];
|
||||
m.slice().forEach(function (mesh) {
|
||||
if (v.indexOf(mesh.widget.group) < 0) f(mesh.widget);
|
||||
v.push(mesh.widget.group);
|
||||
});
|
||||
}
|
||||
|
||||
function forSelectedWidgets(f) {
|
||||
var m = selectedMeshes;
|
||||
let m = selectedMeshes;
|
||||
if (m.length === 0 && WIDGETS.length === 1) m = [ WIDGETS[0].mesh ];
|
||||
m.slice().forEach(function (mesh) { f(mesh.widget) });
|
||||
}
|
||||
|
|
@ -816,9 +828,10 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
return
|
||||
}
|
||||
let scale = unitScale();
|
||||
UI.selWidth.innerHTML = UTIL.round(mesh.w/scale,2);
|
||||
UI.selDepth.innerHTML = UTIL.round(mesh.h/scale,2);
|
||||
UI.selHeight.innerHTML = UTIL.round(mesh.d/scale,2);
|
||||
let {w, h, d} = mesh.widget.track.box;
|
||||
UI.selWidth.innerHTML = UTIL.round(w/scale,2);
|
||||
UI.selDepth.innerHTML = UTIL.round(h/scale,2);
|
||||
UI.selHeight.innerHTML = UTIL.round(d/scale,2);
|
||||
UI.scaleX.value = 1;
|
||||
UI.scaleY.value = 1;
|
||||
UI.scaleZ.value = 1;
|
||||
|
|
@ -831,7 +844,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function moveSelection(x, y, z, abs) {
|
||||
forSelectedWidgets(function (w) { w.move(x, y, z, abs) });
|
||||
forSelectedGroups(function (w) { w.move(x, y, z, abs) });
|
||||
platform.update_stock();
|
||||
SPACE.update();
|
||||
}
|
||||
|
|
@ -846,7 +859,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
var x = parseFloat(UI.scaleX.value || dv),
|
||||
y = parseFloat(UI.scaleY.value || dv),
|
||||
z = parseFloat(UI.scaleZ.value || dv);
|
||||
forSelectedWidgets(function (w) {
|
||||
forSelectedGroups(function (w) {
|
||||
w.scale(x,y,z);
|
||||
meshUpdateInfo(w.mesh);
|
||||
});
|
||||
|
|
@ -859,20 +872,15 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function rotateSelection(x, y, z) {
|
||||
forSelectedWidgets(function (w) { w.rotate(x, y, z) });
|
||||
forSelectedGroups(function (w) {
|
||||
w.rotate(x, y, z);
|
||||
meshUpdateInfo(w.mesh);
|
||||
});
|
||||
platform.compute_max_z();
|
||||
platform.update_stock(true);
|
||||
SPACE.update();
|
||||
}
|
||||
|
||||
function boundsSelection() {
|
||||
var bounds = new THREE.Box3();
|
||||
forSelectedWidgets(function(widget) {
|
||||
bounds.union(widget.mesh.getBoundingBox());
|
||||
});
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/** ******************************************************************
|
||||
* Platform Functions
|
||||
******************************************************************* */
|
||||
|
|
@ -942,9 +950,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
function platformUpdateBounds() {
|
||||
var bounds = new THREE.Box3();
|
||||
forAllWidgets(function(widget) {
|
||||
let wp = widget.orient.pos;
|
||||
let wp = widget.track.pos;
|
||||
let wb = widget.mesh.getBoundingBox().clone();
|
||||
// wb.translate(widget.orient.pos);
|
||||
// wb.translate(widget.track.pos);
|
||||
bounds.union(wb);
|
||||
});
|
||||
return settings.bounds = bounds;
|
||||
|
|
@ -1034,14 +1042,28 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
SPACE.platform.setMaxZ(topZ);
|
||||
}
|
||||
|
||||
function platformGroup() {
|
||||
grouping = true;
|
||||
}
|
||||
|
||||
// called after all new widgets are loaded to update group positions
|
||||
function platformGroupDone() {
|
||||
grouping = false;
|
||||
Widget.Groups.loadDone();
|
||||
if (layoutOnAdd) platform.layout();
|
||||
}
|
||||
|
||||
function platformAdd(widget, shift, nolayout) {
|
||||
WIDGETS.push(widget);
|
||||
SPACE.platform.add(widget.mesh);
|
||||
platform.select(widget, shift);
|
||||
platform.compute_max_z();
|
||||
API.event.emit('widget.add', widget);
|
||||
if (nolayout) return;
|
||||
if (layoutOnAdd) platform.layout();
|
||||
API.event.emit('widget.add', widget);
|
||||
if (!grouping) {
|
||||
platformGroupDone();
|
||||
}
|
||||
}
|
||||
|
||||
function platformDelete(widget) {
|
||||
|
|
@ -1057,6 +1079,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
KIRI.work.clear(widget);
|
||||
WIDGETS.remove(widget);
|
||||
Widget.Groups.remove(widget);
|
||||
SPACE.platform.remove(widget.mesh);
|
||||
selectedMeshes.remove(widget.mesh);
|
||||
updateSliderMax();
|
||||
|
|
@ -1073,10 +1096,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
|
||||
function platformLayout(event, space) {
|
||||
var auto = UI.autoLayout.checked,
|
||||
layout = (viewMode === VIEWS.ARRANGE && auto),
|
||||
proc = settings.process,
|
||||
modified = false,
|
||||
oldmode = viewMode,
|
||||
layout = (viewMode === VIEWS.ARRANGE && auto),
|
||||
topZ = MODE === MODES.CAM ? camTopZ - proc.camZTopOffset : 0;
|
||||
|
||||
switch (MODE) {
|
||||
|
|
@ -1102,11 +1124,6 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
return SPACE.update();
|
||||
}
|
||||
|
||||
// check if any widget has been modified
|
||||
forAllWidgets(function(w) {
|
||||
modified |= w.isModified();
|
||||
});
|
||||
|
||||
var gap = space;
|
||||
|
||||
// in CNC mode with >1 widget, force layout with spacing @ 1.5x largest tool diameter
|
||||
|
|
@ -1121,7 +1138,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
mp = [sz.x, sz.y],
|
||||
ms = [mp[0] / 2, mp[1] / 2],
|
||||
mi = mp[0] > mp[1] ? [(mp[0] / mp[1]) * 10, 10] : [10, (mp[1] / mp[1]) * 10],
|
||||
c = meshArray().sort(function (a, b) { return (b.w * b.h) - (a.w * a.h) }),
|
||||
c = Widget.Groups.blocks().sort(function (a, b) { return (b.w * b.h) - (a.w * a.h) }),
|
||||
p = new MOTO.Pack(ms[0], ms[1], gap).fit(c);
|
||||
|
||||
while (!p.packed) {
|
||||
|
|
@ -1134,9 +1151,8 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
m = c[i];
|
||||
m.fit.x += m.w / 2 + p.pad;
|
||||
m.fit.y += m.h / 2 + p.pad;
|
||||
m.widget.move(p.max.w / 2 - m.fit.x, p.max.h / 2 - m.fit.y, 0, true);
|
||||
// m.widget.setTopZ(topZ);
|
||||
m.material.visible = true;
|
||||
m.move(p.max.w / 2 - m.fit.x, p.max.h / 2 - m.fit.y, 0, true);
|
||||
// m.material.visible = true;
|
||||
}
|
||||
|
||||
if (MODE === MODES.CAM) {
|
||||
|
|
@ -1167,7 +1183,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
let max = { x: -Infinity, y: -Infinity, z: -Infinity };
|
||||
forAllWidgets(function(widget) {
|
||||
let wbnd = widget.getBoundingBox(refresh);
|
||||
let wpos = widget.orient.pos;
|
||||
let wpos = widget.track.pos;
|
||||
min = {
|
||||
x: Math.min(min.x, wpos.x + wbnd.min.x),
|
||||
y: Math.min(min.y, wpos.y + wbnd.min.y),
|
||||
|
|
@ -1379,9 +1395,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
SDB.setItem('ws-settings', JSON.stringify(settings));
|
||||
}
|
||||
|
||||
function loadFiles(files) {
|
||||
for (var i=0; i<files.length; i++) {
|
||||
var reader = new FileReader(),
|
||||
function loadFiles(files,group) {
|
||||
let loaded = files.length;
|
||||
platform.group();
|
||||
for (let i=0; i<files.length; i++) {
|
||||
let reader = new FileReader(),
|
||||
lower = files[i].name.toLowerCase(),
|
||||
israw = lower.indexOf(".raw") > 0 || lower.indexOf('.') < 0,
|
||||
isstl = lower.indexOf(".stl") > 0,
|
||||
|
|
@ -1390,15 +1408,17 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
reader.file = files[i];
|
||||
reader.onloadend = function (e) {
|
||||
if (israw) platform.add(
|
||||
newWidget().loadVertices(JSON.parse(e.target.result).toFloat32())
|
||||
newWidget(undefined,group)
|
||||
.loadVertices(JSON.parse(e.target.result).toFloat32())
|
||||
);
|
||||
if (isstl) platform.add(
|
||||
newWidget()
|
||||
newWidget(undefined,group)
|
||||
.loadVertices(new MOTO.STL().parse(e.target.result))
|
||||
.saveToCatalog(e.target.file.name)
|
||||
);
|
||||
if (isgcode) loadCode(e.target.result, 'gcode');
|
||||
if (issvg) loadCode(e.target.result, 'svg');
|
||||
if (--loaded === 0) platform.group_done();
|
||||
};
|
||||
reader.readAsBinaryString(reader.file);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,7 +382,11 @@ var gs_moto_ui = exports;
|
|||
ip.setAttribute("rows", height);
|
||||
ip.setAttribute("wrap", "off");
|
||||
} else {
|
||||
ip.setAttribute("size", size);
|
||||
if (Number.isInteger(size)) {
|
||||
ip.setAttribute("size", size);
|
||||
} else {
|
||||
ip.setAttribute("style", `width:${size}`);
|
||||
}
|
||||
}
|
||||
ip.setAttribute("type", "text");
|
||||
row.style.display = hide ? 'none' : '';
|
||||
|
|
|
|||
Loading…
Reference in a new issue