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':
|
||||
return api.settings();
|
||||
case 'KeyI':
|
||||
return shiftKey ? api.tool.invert() : api.file.import();
|
||||
return api.file.import();
|
||||
case 'KeyX':
|
||||
return api.file.export();
|
||||
case 'KeyD':
|
||||
|
|
@ -251,8 +251,10 @@ function space_init(data) {
|
|||
return;
|
||||
case 'KeyV':
|
||||
return shiftKey ? selection.show() : selection.focus();
|
||||
case 'KeyR':
|
||||
return estop(evt, api.tool.rename());
|
||||
case 'KeyN':
|
||||
return shiftKey ? estop(evt, api.tool.rename()) : api.normals();
|
||||
return shiftKey ? api.tool.invert() : api.normals();
|
||||
case 'KeyW':
|
||||
return api.wireframe();
|
||||
case 'KeyG':
|
||||
|
|
@ -371,7 +373,7 @@ function space_init(data) {
|
|||
let obj = int?.object;
|
||||
if (obj) api.selection.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:
|
||||
|
|
@ -490,7 +492,6 @@ function space_init(data) {
|
|||
|
||||
function load_files(files) {
|
||||
log(`loading file...`);
|
||||
let api = api;
|
||||
let has_image = false;
|
||||
let has_svg = false;
|
||||
let has_gbr = false;
|
||||
|
|
|
|||
|
|
@ -1526,14 +1526,14 @@ const api = {
|
|||
}
|
||||
},
|
||||
|
||||
// @param object {THREE.Object3D | THREE.Object3D[] | Point}
|
||||
// @param object {MeshObject | MeshObject[]}
|
||||
focus(object) {
|
||||
let { center } = object.center ? object : meshUtil.bounds(object);
|
||||
let { center } = meshUtil.bounds(object);
|
||||
// when no valid objects supplied, set origin
|
||||
if (isNaN(center.x * center.y * center.z)) {
|
||||
center = { x: 0, y: 0, z: 0 };
|
||||
}
|
||||
let { normal } = object;
|
||||
let { normal } = object.object;
|
||||
let left, up;
|
||||
if (normal) {
|
||||
let { x, y, z } = normal;
|
||||
|
|
|
|||
|
|
@ -510,6 +510,7 @@ function ui_build() {
|
|||
menu_item('Flip Normals', tool.invert, ['bi-shift','I']),
|
||||
menu_item('Triangulate', tool.triangulate, ['bi-shift','T']),
|
||||
menu_item('To Sketch', tool.toSketch),
|
||||
hr(),
|
||||
menu_item('Analyze', tool.analyze),
|
||||
menu_item('Flatten', tool.flatten),
|
||||
menu_item('Clean', tool.clean),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
import { THREE, Line2, LineSegmentsGeometry, LineSegments2, LineGeometry, LineMaterial } from '../ext/three.js';
|
||||
import { space as motoSpace } from '../moto/space.js';
|
||||
import { newPoint } from '../geo/point.js';
|
||||
import { api as meshApi } from './api.js';
|
||||
import { api } from './api.js';
|
||||
|
||||
const { Vector3, Group } = THREE;
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ function cmp(v1, v2) {
|
|||
|
||||
// points equal if all axis values are within tolerance of each other
|
||||
function eq(p1, p2) {
|
||||
return
|
||||
return true &&
|
||||
cmp(p1.x, p2.x) &&
|
||||
cmp(p1.y, p2.y) &&
|
||||
cmp(p1.z, p2.z);
|
||||
|
|
@ -61,8 +61,6 @@ const edges = {
|
|||
return;
|
||||
}
|
||||
|
||||
let { api } = meshApi;
|
||||
|
||||
isActive = true;
|
||||
selected.length = 0;
|
||||
obj.visible = false;
|
||||
|
|
@ -71,7 +69,7 @@ const edges = {
|
|||
|
||||
// enable temp mode
|
||||
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);
|
||||
|
||||
// find closest facet edge to hover location
|
||||
|
|
@ -105,7 +103,7 @@ const edges = {
|
|||
space.scene.remove(edges.selected);
|
||||
space.mouse.onHover(undefined);
|
||||
isActive = edges.state = undefined;
|
||||
meshApi.api.selection.update();
|
||||
api.selection.update();
|
||||
},
|
||||
|
||||
async add() {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class MeshObject {
|
|||
}
|
||||
|
||||
focus() {
|
||||
api.focus(this.object);
|
||||
api.focus(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,26 +69,25 @@ const util = {
|
|||
// @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]}
|
||||
// @returns bounds modified for moto.space
|
||||
bounds(object) {
|
||||
// console.log({ bounds: object });
|
||||
let box = new Box3();
|
||||
if (Array.isArray(object)) {
|
||||
for (let o of object) {
|
||||
util.box3expand(box, o instanceof meshObject ? o.object : o);
|
||||
box.union(o.bounds);
|
||||
}
|
||||
} else if (object) {
|
||||
util.box3expand(box, object instanceof meshObject ? object.object : object);
|
||||
} else {
|
||||
return box;
|
||||
box.union(object.bounds);
|
||||
}
|
||||
let bnd = {
|
||||
min: {
|
||||
x: box.min.x,
|
||||
y: box.min.z,
|
||||
z: box.min.y
|
||||
},
|
||||
y: box.min.y,
|
||||
z: box.min.z
|
||||
},
|
||||
max: {
|
||||
x: box.max.x,
|
||||
y: box.max.z,
|
||||
z: box.max.y
|
||||
y: box.max.y,
|
||||
z: box.max.z
|
||||
}
|
||||
};
|
||||
bnd.size = bnd.dim = {
|
||||
|
|
@ -97,52 +96,13 @@ const util = {
|
|||
z: bnd.max.z - bnd.min.z
|
||||
};
|
||||
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,
|
||||
z: (bnd.max.z + bnd.min.z) / 2
|
||||
z: (bnd.max.z + bnd.min.z) / 2
|
||||
};
|
||||
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, opt = {}) {
|
||||
let field = opt.fields || ['x', 'y', 'z'];
|
||||
|
|
|
|||
Loading…
Reference in a new issue