fix focus, bounding box calc, edge edit
This commit is contained in:
parent
a0c2f8ffae
commit
9c85187923
6 changed files with 24 additions and 64 deletions
|
|
@ -230,7 +230,7 @@ function space_init(data) {
|
||||||
case 'KeyQ':
|
case 'KeyQ':
|
||||||
return api.settings();
|
return api.settings();
|
||||||
case 'KeyI':
|
case 'KeyI':
|
||||||
return shiftKey ? api.tool.invert() : api.file.import();
|
return api.file.import();
|
||||||
case 'KeyX':
|
case 'KeyX':
|
||||||
return api.file.export();
|
return api.file.export();
|
||||||
case 'KeyD':
|
case 'KeyD':
|
||||||
|
|
@ -251,8 +251,10 @@ function space_init(data) {
|
||||||
return;
|
return;
|
||||||
case 'KeyV':
|
case 'KeyV':
|
||||||
return shiftKey ? selection.show() : selection.focus();
|
return shiftKey ? selection.show() : selection.focus();
|
||||||
|
case 'KeyR':
|
||||||
|
return estop(evt, api.tool.rename());
|
||||||
case 'KeyN':
|
case 'KeyN':
|
||||||
return shiftKey ? estop(evt, api.tool.rename()) : api.normals();
|
return shiftKey ? api.tool.invert() : api.normals();
|
||||||
case 'KeyW':
|
case 'KeyW':
|
||||||
return api.wireframe();
|
return api.wireframe();
|
||||||
case 'KeyG':
|
case 'KeyG':
|
||||||
|
|
@ -371,7 +373,7 @@ function space_init(data) {
|
||||||
let obj = int?.object;
|
let obj = int?.object;
|
||||||
if (obj) api.selection.drag({ start: int.object });
|
if (obj) api.selection.drag({ start: int.object });
|
||||||
if (obj) obj.sketch_item?.sketch.drag({ start: int.object });
|
if (obj) obj.sketch_item?.sketch.drag({ start: int.object });
|
||||||
return event?.shiftKey ? undefined : api.objects(selection.count() ? true : false);
|
return event?.altKey ? undefined : api.objects(selection.count() ? true : false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// called two ways:
|
// called two ways:
|
||||||
|
|
@ -490,7 +492,6 @@ function space_init(data) {
|
||||||
|
|
||||||
function load_files(files) {
|
function load_files(files) {
|
||||||
log(`loading file...`);
|
log(`loading file...`);
|
||||||
let api = api;
|
|
||||||
let has_image = false;
|
let has_image = false;
|
||||||
let has_svg = false;
|
let has_svg = false;
|
||||||
let has_gbr = false;
|
let has_gbr = false;
|
||||||
|
|
|
||||||
|
|
@ -1526,14 +1526,14 @@ const api = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// @param object {THREE.Object3D | THREE.Object3D[] | Point}
|
// @param object {MeshObject | MeshObject[]}
|
||||||
focus(object) {
|
focus(object) {
|
||||||
let { center } = object.center ? object : meshUtil.bounds(object);
|
let { center } = meshUtil.bounds(object);
|
||||||
// when no valid objects supplied, set origin
|
// when no valid objects supplied, set origin
|
||||||
if (isNaN(center.x * center.y * center.z)) {
|
if (isNaN(center.x * center.y * center.z)) {
|
||||||
center = { x: 0, y: 0, z: 0 };
|
center = { x: 0, y: 0, z: 0 };
|
||||||
}
|
}
|
||||||
let { normal } = object;
|
let { normal } = object.object;
|
||||||
let left, up;
|
let left, up;
|
||||||
if (normal) {
|
if (normal) {
|
||||||
let { x, y, z } = normal;
|
let { x, y, z } = normal;
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,7 @@ function ui_build() {
|
||||||
menu_item('Flip Normals', tool.invert, ['bi-shift','I']),
|
menu_item('Flip Normals', tool.invert, ['bi-shift','I']),
|
||||||
menu_item('Triangulate', tool.triangulate, ['bi-shift','T']),
|
menu_item('Triangulate', tool.triangulate, ['bi-shift','T']),
|
||||||
menu_item('To Sketch', tool.toSketch),
|
menu_item('To Sketch', tool.toSketch),
|
||||||
|
hr(),
|
||||||
menu_item('Analyze', tool.analyze),
|
menu_item('Analyze', tool.analyze),
|
||||||
menu_item('Flatten', tool.flatten),
|
menu_item('Flatten', tool.flatten),
|
||||||
menu_item('Clean', tool.clean),
|
menu_item('Clean', tool.clean),
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
import { THREE, Line2, LineSegmentsGeometry, LineSegments2, LineGeometry, LineMaterial } from '../ext/three.js';
|
import { THREE, Line2, LineSegmentsGeometry, LineSegments2, LineGeometry, LineMaterial } from '../ext/three.js';
|
||||||
import { space as motoSpace } from '../moto/space.js';
|
import { space as motoSpace } from '../moto/space.js';
|
||||||
import { newPoint } from '../geo/point.js';
|
import { newPoint } from '../geo/point.js';
|
||||||
import { api as meshApi } from './api.js';
|
import { api } from './api.js';
|
||||||
|
|
||||||
const { Vector3, Group } = THREE;
|
const { Vector3, Group } = THREE;
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ function cmp(v1, v2) {
|
||||||
|
|
||||||
// points equal if all axis values are within tolerance of each other
|
// points equal if all axis values are within tolerance of each other
|
||||||
function eq(p1, p2) {
|
function eq(p1, p2) {
|
||||||
return
|
return true &&
|
||||||
cmp(p1.x, p2.x) &&
|
cmp(p1.x, p2.x) &&
|
||||||
cmp(p1.y, p2.y) &&
|
cmp(p1.y, p2.y) &&
|
||||||
cmp(p1.z, p2.z);
|
cmp(p1.z, p2.z);
|
||||||
|
|
@ -61,8 +61,6 @@ const edges = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { api } = meshApi;
|
|
||||||
|
|
||||||
isActive = true;
|
isActive = true;
|
||||||
selected.length = 0;
|
selected.length = 0;
|
||||||
obj.visible = false;
|
obj.visible = false;
|
||||||
|
|
@ -71,7 +69,7 @@ const edges = {
|
||||||
|
|
||||||
// enable temp mode
|
// enable temp mode
|
||||||
let state = edges.state = { obj };
|
let state = edges.state = { obj };
|
||||||
let models = state.models = api.selection.models();
|
let models = state.models = api.model.list();
|
||||||
let meshes = models.map(m => m.mesh);
|
let meshes = models.map(m => m.mesh);
|
||||||
|
|
||||||
// find closest facet edge to hover location
|
// find closest facet edge to hover location
|
||||||
|
|
@ -105,7 +103,7 @@ const edges = {
|
||||||
space.scene.remove(edges.selected);
|
space.scene.remove(edges.selected);
|
||||||
space.mouse.onHover(undefined);
|
space.mouse.onHover(undefined);
|
||||||
isActive = edges.state = undefined;
|
isActive = edges.state = undefined;
|
||||||
meshApi.api.selection.update();
|
api.selection.update();
|
||||||
},
|
},
|
||||||
|
|
||||||
async add() {
|
async add() {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class MeshObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
api.focus(this.object);
|
api.focus(this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,26 +69,25 @@ const util = {
|
||||||
// @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]}
|
// @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]}
|
||||||
// @returns bounds modified for moto.space
|
// @returns bounds modified for moto.space
|
||||||
bounds(object) {
|
bounds(object) {
|
||||||
|
// console.log({ bounds: object });
|
||||||
let box = new Box3();
|
let box = new Box3();
|
||||||
if (Array.isArray(object)) {
|
if (Array.isArray(object)) {
|
||||||
for (let o of object) {
|
for (let o of object) {
|
||||||
util.box3expand(box, o instanceof meshObject ? o.object : o);
|
box.union(o.bounds);
|
||||||
}
|
}
|
||||||
} else if (object) {
|
} else if (object) {
|
||||||
util.box3expand(box, object instanceof meshObject ? object.object : object);
|
box.union(object.bounds);
|
||||||
} else {
|
|
||||||
return box;
|
|
||||||
}
|
}
|
||||||
let bnd = {
|
let bnd = {
|
||||||
min: {
|
min: {
|
||||||
x: box.min.x,
|
x: box.min.x,
|
||||||
y: box.min.z,
|
y: box.min.y,
|
||||||
z: box.min.y
|
z: box.min.z
|
||||||
},
|
},
|
||||||
max: {
|
max: {
|
||||||
x: box.max.x,
|
x: box.max.x,
|
||||||
y: box.max.z,
|
y: box.max.y,
|
||||||
z: box.max.y
|
z: box.max.z
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
bnd.size = bnd.dim = {
|
bnd.size = bnd.dim = {
|
||||||
|
|
@ -97,52 +96,13 @@ const util = {
|
||||||
z: bnd.max.z - bnd.min.z
|
z: bnd.max.z - bnd.min.z
|
||||||
};
|
};
|
||||||
bnd.center = bnd.mid = {
|
bnd.center = bnd.mid = {
|
||||||
x: (bnd.max.x + bnd.min.x) / 2,
|
x: (bnd.max.x + bnd.min.x) / 2,
|
||||||
y: -(bnd.max.y + bnd.min.y) / 2,
|
y: -(bnd.max.y + bnd.min.y) / 2,
|
||||||
z: (bnd.max.z + bnd.min.z) / 2
|
z: (bnd.max.z + bnd.min.z) / 2
|
||||||
};
|
};
|
||||||
return bnd;
|
return bnd;
|
||||||
},
|
},
|
||||||
|
|
||||||
// bounding box workaround adapted from:
|
|
||||||
// https://discourse.threejs.org/t/bounding-box-bigger-than-concave-object-extrudegeometry/26073/2
|
|
||||||
// https://discourse.threejs.org/t/invalid-bounds-generated-for-some-orientations/33205
|
|
||||||
box3expand(box3, object) {
|
|
||||||
if (object._no_bounds) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let geometry = object.geometry;
|
|
||||||
object.updateWorldMatrix(geometry ? true : false, false);
|
|
||||||
|
|
||||||
if (geometry) {
|
|
||||||
let matrix = object.matrixWorld;
|
|
||||||
let bkey = [matrix.elements.map(v => v.round(5))].join(',')
|
|
||||||
let cached = boundsCache[object.id];
|
|
||||||
// geometry._model_invalid set on model.reload(), usually after a split
|
|
||||||
if (!cached || cached.bkey !== bkey || geometry._model_invalid) {
|
|
||||||
let position = geometry.attributes.position.clone();
|
|
||||||
position.applyMatrix4(new Matrix4().extractRotation(matrix));
|
|
||||||
let bounds = new Box3().setFromBufferAttribute(position);
|
|
||||||
// let scale = new Vector3().setFromMatrixScale(matrix);
|
|
||||||
// bounds.min.multiply(scale);
|
|
||||||
// bounds.max.multiply(scale);
|
|
||||||
cached = boundsCache[object.id] = { bkey, bounds };
|
|
||||||
geometry._model_invalid = undefined;
|
|
||||||
}
|
|
||||||
let bt = cached.bounds.clone();
|
|
||||||
let m4 = new Matrix4();
|
|
||||||
m4.setPosition(new Vector3().setFromMatrixPosition(object.matrixWorld));
|
|
||||||
bt.applyMatrix4(m4);
|
|
||||||
box3.union(bt);
|
|
||||||
}
|
|
||||||
|
|
||||||
let children = object.children;
|
|
||||||
for (let i = 0, l = children.length; i < l; i++) {
|
|
||||||
util.box3expand(box3, children[i]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// extract object fields into an array with optional rounding
|
// extract object fields into an array with optional rounding
|
||||||
extract(object, opt = {}) {
|
extract(object, opt = {}) {
|
||||||
let field = opt.fields || ['x', 'y', 'z'];
|
let field = opt.fields || ['x', 'y', 'z'];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue