rethink scale and rotation for selections
This commit is contained in:
parent
7b7acca47d
commit
4d026fce98
4 changed files with 170 additions and 96 deletions
114
js/kiri-init.js
114
js/kiri-init.js
|
|
@ -29,8 +29,7 @@ var gs_kiri_init = exports;
|
||||||
STARTMODE = SETUP.sm && SETUP.sm.length === 1 ? SETUP.sm[0] : null,
|
STARTMODE = SETUP.sm && SETUP.sm.length === 1 ? SETUP.sm[0] : null,
|
||||||
SPACE = KIRI.space,
|
SPACE = KIRI.space,
|
||||||
STATS = API.stats,
|
STATS = API.stats,
|
||||||
ROT = Math.PI/2,
|
DEG = Math.PI/180,
|
||||||
ROT5 = ROT / 9,
|
|
||||||
ALL = [MODES.FDM, MODES.LASER, MODES.CAM],
|
ALL = [MODES.FDM, MODES.LASER, MODES.CAM],
|
||||||
CAM = [MODES.CAM],
|
CAM = [MODES.CAM],
|
||||||
FDM = [MODES.FDM],
|
FDM = [MODES.FDM],
|
||||||
|
|
@ -1110,13 +1109,15 @@ var gs_kiri_init = exports;
|
||||||
progress: $('progress').style,
|
progress: $('progress').style,
|
||||||
prostatus: $('prostatus'),
|
prostatus: $('prostatus'),
|
||||||
selection: $('selection'),
|
selection: $('selection'),
|
||||||
selWidth: $('sel_width'),
|
sizeX: $('size_x'),
|
||||||
selHeight: $('sel_height'),
|
sizeY: $('size_y'),
|
||||||
selDepth: $('sel_depth'),
|
sizeZ: $('size_z'),
|
||||||
scaleX: $('scale_x'),
|
scaleX: $('scale_x'),
|
||||||
scaleY: $('scale_y'),
|
scaleY: $('scale_y'),
|
||||||
scaleZ: $('scale_z'),
|
scaleZ: $('scale_z'),
|
||||||
scaleUniform: $('scale_uni'),
|
lockX: $('lock_x'),
|
||||||
|
lockY: $('lock_y'),
|
||||||
|
lockZ: $('lock_z'),
|
||||||
stock: $('stock'),
|
stock: $('stock'),
|
||||||
stockWidth: $('stock-width'),
|
stockWidth: $('stock-width'),
|
||||||
stockDepth: $('stock-width'),
|
stockDepth: $('stock-width'),
|
||||||
|
|
@ -1454,22 +1455,67 @@ var gs_kiri_init = exports;
|
||||||
'drop', dropHandler
|
'drop', dropHandler
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
function selectionSize(e) {
|
||||||
|
let dv = parseFloat(e.target.value || 1),
|
||||||
|
pv = parseFloat(e.target.was || 1),
|
||||||
|
ra = dv / pv,
|
||||||
|
xv = parseFloat(UI.sizeX.was),
|
||||||
|
yv = parseFloat(UI.sizeY.was),
|
||||||
|
zv = parseFloat(UI.sizeZ.was),
|
||||||
|
xr = (UI.lockX.checked ? ra : 1),
|
||||||
|
yr = (UI.lockY.checked ? ra : 1),
|
||||||
|
zr = (UI.lockZ.checked ? ra : 1);
|
||||||
|
API.selection.scale(xr,yr,zr);
|
||||||
|
UI.sizeX.was = UI.sizeX.value = xv * xr;
|
||||||
|
UI.sizeY.was = UI.sizeY.value = yv * yr;
|
||||||
|
UI.sizeZ.was = UI.sizeZ.value = zv * zr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectionScale(e) {
|
||||||
|
let dv = parseFloat(e.target.value || 1),
|
||||||
|
pv = parseFloat(e.target.was || 1),
|
||||||
|
ra = dv / pv,
|
||||||
|
xv = parseFloat(UI.scaleX.was),
|
||||||
|
yv = parseFloat(UI.scaleY.was),
|
||||||
|
zv = parseFloat(UI.scaleZ.was),
|
||||||
|
xr = (UI.lockX.checked ? ra : 1),
|
||||||
|
yr = (UI.lockY.checked ? ra : 1),
|
||||||
|
zr = (UI.lockZ.checked ? ra : 1);
|
||||||
|
API.selection.scale(xr,yr,zr);
|
||||||
|
UI.scaleX.was = UI.scaleX.value = xv * xr;
|
||||||
|
UI.scaleY.was = UI.scaleY.value = yv * yr;
|
||||||
|
UI.scaleZ.was = UI.scaleZ.value = zv * zr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectionRotate(e) {
|
||||||
|
let deg = parseFloat(e.target.value) * DEG;
|
||||||
|
e.target.value = 0;
|
||||||
|
switch (e.target.id.split('').pop()) {
|
||||||
|
case 'x': return API.selection.rotate(deg,0,0);
|
||||||
|
case 'y': return API.selection.rotate(0,deg,0);
|
||||||
|
case 'z': return API.selection.rotate(0,0,deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SPACE.onEnterKey([
|
SPACE.onEnterKey([
|
||||||
UI.layerSpan, function() { API.show.slices() },
|
UI.layerSpan, function() { API.show.slices() },
|
||||||
UI.layerID, function() { API.show.layer(UI.layerID.value) },
|
UI.layerID, function() { API.show.layer(UI.layerID.value) },
|
||||||
|
UI.scaleX, selectionScale,
|
||||||
UI.scaleX, selection.scale,
|
UI.scaleY, selectionScale,
|
||||||
UI.scaleY, selection.scale,
|
UI.scaleZ, selectionScale,
|
||||||
UI.scaleZ, selection.scale,
|
UI.sizeX, selectionSize,
|
||||||
|
UI.sizeY, selectionSize,
|
||||||
UI.toolName, updateTool,
|
UI.sizeZ, selectionSize,
|
||||||
UI.toolNum, updateTool,
|
UI.toolName, updateTool,
|
||||||
UI.toolFluteDiam, updateTool,
|
UI.toolNum, updateTool,
|
||||||
UI.toolFluteLen, updateTool,
|
UI.toolFluteDiam, updateTool,
|
||||||
UI.toolShaftDiam, updateTool,
|
UI.toolFluteLen, updateTool,
|
||||||
UI.toolShaftLen, updateTool,
|
UI.toolShaftDiam, updateTool,
|
||||||
// UI.toolTaperAngle, updateTool,
|
UI.toolShaftLen, updateTool,
|
||||||
UI.toolTaperTip, updateTool,
|
UI.toolTaperTip, updateTool,
|
||||||
|
$('rot_x'), selectionRotate,
|
||||||
|
$('rot_y'), selectionRotate,
|
||||||
|
$('rot_z'), selectionRotate
|
||||||
]);
|
]);
|
||||||
|
|
||||||
UI.layerID.convert = UC.toFloat.bind(UI.layerID);
|
UI.layerID.convert = UC.toFloat.bind(UI.layerID);
|
||||||
|
|
@ -1485,12 +1531,26 @@ var gs_kiri_init = exports;
|
||||||
UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px';
|
UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px';
|
||||||
};
|
};
|
||||||
|
|
||||||
$('x-').onclick = function(ev) { API.selection.rotate(ev.shiftKey ? -ROT5 : -ROT,0,0) };
|
// $('rot_x').onkeypress = (ev) => {
|
||||||
$('x+').onclick = function(ev) { API.selection.rotate(ev.shiftKey ? ROT5 : ROT,0,0) };
|
// if (ev.key === 'Enter') {
|
||||||
$('y-').onclick = function(ev) { API.selection.rotate(0,ev.shiftKey ? -ROT5 : -ROT,0) };
|
// API.selection.rotate(parseFloat(ev.target.value)*DEG,0,0);
|
||||||
$('y+').onclick = function(ev) { API.selection.rotate(0,ev.shiftKey ? ROT5 : ROT,0) };
|
// ev.target.value = 0;
|
||||||
$('z-').onclick = function(ev) { API.selection.rotate(0,0,ev.shiftKey ? ROT5 : ROT) };
|
// }
|
||||||
$('z+').onclick = function(ev) { API.selection.rotate(0,0,ev.shiftKey ? -ROT5 : -ROT) };
|
// };
|
||||||
|
//
|
||||||
|
// $('rot_y').onkeypress = (ev) => {
|
||||||
|
// if (ev.key === 'Enter') {
|
||||||
|
// API.selection.rotate(0,parseFloat(ev.target.value)*DEG,0);
|
||||||
|
// ev.target.value = 0;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// $('rot_z').onkeypress = (ev) => {
|
||||||
|
// if (ev.key === 'Enter') {
|
||||||
|
// API.selection.rotate(0,0,parseFloat(ev.target.value)*DEG);
|
||||||
|
// ev.target.value = 0;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) {
|
UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) {
|
||||||
API.widgets.opacity(parseInt(UI.modelOpacity.value)/100);
|
API.widgets.opacity(parseInt(UI.modelOpacity.value)/100);
|
||||||
|
|
|
||||||
58
js/kiri.js
58
js/kiri.js
|
|
@ -86,6 +86,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
||||||
rotate: rotateSelection,
|
rotate: rotateSelection,
|
||||||
meshes: function() { return selectedMeshes.slice() },
|
meshes: function() { return selectedMeshes.slice() },
|
||||||
widgets: function() { return selectedMeshes.slice().map(m => m.widget) },
|
widgets: function() { return selectedMeshes.slice().map(m => m.widget) },
|
||||||
|
for_groups: forSelectedGroups,
|
||||||
for_meshes: forSelectedMeshes,
|
for_meshes: forSelectedMeshes,
|
||||||
for_widgets: forSelectedWidgets
|
for_widgets: forSelectedWidgets
|
||||||
};
|
};
|
||||||
|
|
@ -824,18 +825,19 @@ self.kiri.copyright = exports.COPYRIGHT;
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
||||||
function updateSelectedInfo() {
|
function updateSelectedInfo() {
|
||||||
let bounds = new THREE.Box3();
|
let bounds = new THREE.Box3(), track;
|
||||||
forSelectedMeshes(mesh => {
|
forSelectedMeshes(mesh => {
|
||||||
bounds = bounds.union(mesh.getBoundingBox());
|
bounds = bounds.union(mesh.getBoundingBox());
|
||||||
|
track = mesh.widget.track;
|
||||||
});
|
});
|
||||||
if (bounds.min.x === Infinity) {
|
if (bounds.min.x === Infinity) {
|
||||||
if (selectedMeshes.length === 0) {
|
if (selectedMeshes.length === 0) {
|
||||||
UI.selWidth.innerHTML = '0';
|
UI.sizeX.value = 0;
|
||||||
UI.selDepth.innerHTML = '0';
|
UI.sizeY.value = 0;
|
||||||
UI.selHeight.innerHTML = '0';
|
UI.sizeZ.value = 0;
|
||||||
UI.scaleX.value = '';
|
UI.scaleX.value = 1;
|
||||||
UI.scaleY.value = '';
|
UI.scaleY.value = 1;
|
||||||
UI.scaleZ.value = '';
|
UI.scaleZ.value = 1;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -843,12 +845,12 @@ self.kiri.copyright = exports.COPYRIGHT;
|
||||||
dy = bounds.max.y - bounds.min.y,
|
dy = bounds.max.y - bounds.min.y,
|
||||||
dz = bounds.max.z - bounds.min.z,
|
dz = bounds.max.z - bounds.min.z,
|
||||||
scale = unitScale();
|
scale = unitScale();
|
||||||
UI.selWidth.innerHTML = UTIL.round(dx/scale,2);
|
UI.sizeX.value = UI.sizeX.was = UTIL.round(dx/scale,2);
|
||||||
UI.selDepth.innerHTML = UTIL.round(dy/scale,2);
|
UI.sizeY.value = UI.sizeY.was = UTIL.round(dy/scale,2);
|
||||||
UI.selHeight.innerHTML = UTIL.round(dz/scale,2);
|
UI.sizeZ.value = UI.sizeZ.was = UTIL.round(dz/scale,2);
|
||||||
UI.scaleX.value = 1;
|
UI.scaleX.value = UI.scaleX.was = track.scale.x;
|
||||||
UI.scaleY.value = 1;
|
UI.scaleY.value = UI.scaleY.was = track.scale.y;
|
||||||
UI.scaleZ.value = 1;
|
UI.scaleZ.value = UI.scaleZ.was = track.scale.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOpacity(value) {
|
function setOpacity(value) {
|
||||||
|
|
@ -864,42 +866,20 @@ self.kiri.copyright = exports.COPYRIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
function scaleSelection() {
|
function scaleSelection() {
|
||||||
if (arguments.length === 1) {
|
let args = arguments;
|
||||||
scaleSelectionUI(...arguments);
|
forSelectedGroups(function (w) {
|
||||||
} else {
|
w.scale(...args);
|
||||||
let args = arguments;
|
});
|
||||||
forSelectedGroups(function (w) {
|
|
||||||
w.scale(...args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// skip update if last argument is strictly 'false'
|
// skip update if last argument is strictly 'false'
|
||||||
if ([...arguments].pop() === false) {
|
if ([...arguments].pop() === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateSelectedInfo();
|
updateSelectedInfo();
|
||||||
UI.scaleX.value = 1;
|
|
||||||
UI.scaleY.value = 1;
|
|
||||||
UI.scaleZ.value = 1;
|
|
||||||
platform.compute_max_z();
|
platform.compute_max_z();
|
||||||
platform.update_stock(true);
|
platform.update_stock(true);
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
function scaleSelectionUI(ev) {
|
|
||||||
let dv = parseFloat(ev.target.value || 1);
|
|
||||||
if (UI.scaleUniform.checked) {
|
|
||||||
UI.scaleX.value = dv;
|
|
||||||
UI.scaleY.value = dv;
|
|
||||||
UI.scaleZ.value = dv;
|
|
||||||
}
|
|
||||||
let x = parseFloat(UI.scaleX.value || dv),
|
|
||||||
y = parseFloat(UI.scaleY.value || dv),
|
|
||||||
z = parseFloat(UI.scaleZ.value || dv);
|
|
||||||
forSelectedGroups(function (w) {
|
|
||||||
w.scale(x,y,z);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function rotateSelection(x, y, z) {
|
function rotateSelection(x, y, z) {
|
||||||
forSelectedGroups(function (w) {
|
forSelectedGroups(function (w) {
|
||||||
w.rotate(x, y, z);
|
w.rotate(x, y, z);
|
||||||
|
|
|
||||||
|
|
@ -152,39 +152,62 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- selection info -->
|
<!-- selection info -->
|
||||||
<div id="widget-info">
|
<div id="widget-info">
|
||||||
<span id="selection">
|
<div id="selection">
|
||||||
<label class="label">width:</label><label id="sel_width" class="value">mm</label>
|
<span class="sel-span">
|
||||||
<label class="label">depth:</label><label id="sel_depth" class="value">mm</label>
|
|
||||||
<label class="label">height:</label><label id="sel_height" class="value">mm</label>
|
|
||||||
|
|
||||||
<div class="sel-span">
|
|
||||||
<label class="label">scale</label>
|
<label class="label">scale</label>
|
||||||
<div id="sel-scale" class="sel-pop">
|
<div id="sel-scale" class="sel-pop">
|
||||||
<div>
|
<table>
|
||||||
<label class="label">x</label><input id="scale_x" size="3" value="1"/>
|
<tr>
|
||||||
<label class="label">y</label><input id="scale_y" size="3" value="1"/>
|
<th></th>
|
||||||
<label class="label">z</label><input id="scale_z" size="3" value="1"/>
|
<td><label>size</label></td>
|
||||||
<label class="label">uniform</label><input type="checkbox" id="scale_uni" checked>
|
<td><label>scale</label></td>
|
||||||
</div>
|
<td><label>lock</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label>x</label></td>
|
||||||
|
<td><input id="size_x" size="8" class="value"/></td>
|
||||||
|
<td><input id="scale_x" size="3" class="value" value="1"/></td>
|
||||||
|
<td><input id="lock_x" type="checkbox" checked/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label>y</label></td>
|
||||||
|
<td><input id="size_y" size="8" class="value"/></td>
|
||||||
|
<td><input id="scale_y" size="3" class="value" value="1"/></td>
|
||||||
|
<td><input id="lock_y" type="checkbox" checked/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label>z</label></td>
|
||||||
|
<td><input id="size_z" size="8" class="value"/></td>
|
||||||
|
<td><input id="scale_z" size="3" class="value" value="1"/></td>
|
||||||
|
<td><input id="lock_z" type="checkbox" checked/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</span>
|
||||||
|
<span class="sel-span">
|
||||||
<div class="sel-span">
|
|
||||||
<label class="label">rotate</label>
|
<label class="label">rotate</label>
|
||||||
<div id="sel-rotate" class="sel-pop">
|
<div id="sel-rotate" class="sel-pop">
|
||||||
<div>
|
<table>
|
||||||
<button id="x+" title="hold SHIFT to rotate 5 degrees">x+</button><button id="x-" title="hold SHIFT to rotate 5 degrees">x-</button>
|
<tr><td>
|
||||||
<button id="y+" title="hold SHIFT to rotate 5 degrees">y+</button><button id="y-" title="hold SHIFT to rotate 5 degrees">y-</button>
|
<label>z</label>
|
||||||
<button id="z+" title="hold SHIFT to rotate 5 degrees">z+</button><button id="z-" title="hold SHIFT to rotate 5 degrees">z-</button>
|
<input id="rot_z" class="value" size="5"/ value="0">
|
||||||
</div>
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
<label>y</label>
|
||||||
|
<input id="rot_y" class="value" size="5"/ value="0">
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
<label>x</label>
|
||||||
|
<input id="rot_x" class="value" size="5"/ value="0">
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</span>
|
||||||
|
<span class="sel-span">
|
||||||
<div class="sel-span">
|
|
||||||
<label class="label">extruder</label>
|
<label class="label">extruder</label>
|
||||||
<div class="sel-pop"><div id="sel-ext"></div></div>
|
<div class="sel-pop"><div id="sel-ext"></div></div>
|
||||||
</div>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
<span id="stock">
|
<span id="stock">
|
||||||
<label class="label">stock</label>
|
<label class="label">stock</label>
|
||||||
<label id="stock-width" class="value">mm</label> x
|
<label id="stock-width" class="value">mm</label> x
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ input[type=range]::-moz-focus-outer {
|
||||||
left: 0;
|
left: 0;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
.sel-pop div {
|
.sel-pop div, .sel-pop table {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
@ -76,29 +76,40 @@ input[type=range]::-moz-focus-outer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
bottom: 3px;
|
bottom: -5px;
|
||||||
}
|
}
|
||||||
#widget-info span {
|
#widget-info span {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 3px 8px 8px 8px;
|
margin: 0 3px 0 3px;
|
||||||
|
padding: 3px 10px 10px 10px;
|
||||||
background-color: rgba(170,221,255,0.75);
|
background-color: rgba(170,221,255,0.75);
|
||||||
color: rgba(0,0,0,0.5);
|
font-weight: bold;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
#widget-info label {
|
#widget-info label {
|
||||||
border: 0;
|
border: 0;
|
||||||
|
color: rgba(0,0,0,0.75);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
#widget-info .value {
|
#widget-info .value {
|
||||||
font-weight: bold;
|
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
outline: none;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
#widget-info .value:focus {
|
||||||
|
background-color: #fec;
|
||||||
|
}
|
||||||
#widget-info button {
|
#widget-info button {
|
||||||
margin: 0 2px 0 2px !important;
|
margin: 0 2px 0 2px !important;
|
||||||
border: 1px solid rgba(255,255,255,0.75);
|
border: 1px solid rgba(255,255,255,0.75);
|
||||||
}
|
}
|
||||||
|
#sel-ext {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
#stock,#selection {
|
#stock,#selection {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue