improve sketch bounds and handles

This commit is contained in:
Stewart Allen 2025-06-16 00:56:58 -04:00
commit d947963c28
2 changed files with 34 additions and 31 deletions

View file

@ -29,14 +29,14 @@ class TransformTool {
this.handleColor = 0x0088ff;
this.handleOpacity = 0.5;
this.visible = false;
// Create materials
this.handleMaterial = new MeshBasicMaterial({
color: this.handleColor,
transparent: true,
opacity: this.handleOpacity
});
this.edgeMaterial = new LineBasicMaterial({
color: this.handleColor,
transparent: true,
@ -56,6 +56,7 @@ class TransformTool {
selection_scale: () => this.update(),
selection_rotate: () => this.update(),
selection_qrotate: () => this.update(),
sketch_render: () => this.update(),
history_undo: () => this.update(),
history_redo: () => this.update(),
move: () => this.update(),
@ -95,18 +96,7 @@ class TransformTool {
if (sketch) {
// For sketches, use 2D mode
this.mode = '2d';
bounds = {
min: new Vector3(
sketch.center.x - sketch.scale.x/2,
sketch.center.y - sketch.scale.y/2,
0
),
max: new Vector3(
sketch.center.x + sketch.scale.x/2,
sketch.center.y + sketch.scale.y/2,
0
)
};
bounds = sketch.bounds;
} else {
// For models/groups, use 3D mode
this.mode = '3d';
@ -134,7 +124,7 @@ class TransformTool {
const { min, max } = this.bounds;
const corners = this.getCorners(min, max);
// Create handles for each corner
corners.forEach(corner => {
const handle = this.createHandle();
@ -207,12 +197,13 @@ class TransformTool {
getCorners(min, max) {
if (this.mode === '2d') {
// 2D mode - 4 corners in XY plane
// 2D mode - 4 corners in XY plane at z midline
const zMid = (min.z + max.z) / 2;
return [
new Vector3(min.x, min.y, 0),
new Vector3(max.x, min.y, 0),
new Vector3(max.x, max.y, 0),
new Vector3(min.x, max.y, 0)
new Vector3(min.x, min.y, zMid),
new Vector3(max.x, min.y, zMid),
new Vector3(max.x, max.y, zMid),
new Vector3(min.x, max.y, zMid)
];
} else {
// 3D mode - 8 corners of bounding box
@ -236,15 +227,15 @@ class TransformTool {
this.handleSize,
this.handleSize
);
// Create the handle mesh
const handle = new Mesh(geometry, this.handleMaterial);
// Add wireframe edges
const edges = new EdgesGeometry(geometry);
const line = new LineSegments(edges, this.edgeMaterial);
handle.add(line);
return handle;
}

View file

@ -2,7 +2,7 @@
import { client as motoClient } from '../moto/client.js';
import { space as motoSpace } from '../moto/space.js';
import { broker as motoBroker } from '../moto/broker.js';
import { broker } from '../moto/broker.js';
import { object as meshObject } from './object.js';
import { model as meshModel, materials } from './model.js';
import { util as meshUtil } from './util.js';
@ -11,7 +11,7 @@ import { newPolygon } from '../geo/polygon.js';
import { polygons } from '../geo/polygons.js';
import { THREE } from '../ext/three.js';
const { BufferGeometry, BufferAttribute, Quaternion, MeshBasicMaterial, LineBasicMaterial, LineSegments, DoubleSide, PlaneGeometry, EdgesGeometry, SphereGeometry, Vector3, Mesh, Group } = THREE;
const { BufferGeometry, BufferAttribute, Quaternion, MeshBasicMaterial, LineBasicMaterial, LineSegments, DoubleSide, PlaneGeometry, EdgesGeometry, SphereGeometry, Vector3, Box3, Mesh, Group } = THREE;
const worker = motoClient.fn;
const drag = {};
const hpos = [
@ -119,8 +119,19 @@ class MeshSketch extends meshObject {
}
get bounds() {
this.plane.geometry.computeBoundingBox();
return this.plane.geometry.boundingBox.clone();
const { scale, center } = this;
return new Box3(
new Vector3(
center.x - scale.x/2,
center.y - scale.y/2,
center.z
),
new Vector3(
center.x + scale.x/2,
center.y + scale.y/2,
center.z
)
);
}
get meshes() {
@ -152,7 +163,7 @@ class MeshSketch extends meshObject {
all() {
sketch.items.forEach(i => i.selected = true);
sketch.render();
motoBroker.publish('sketch_selections');
broker.publish('sketch_selections');
return sketch.items.length;
},
@ -162,7 +173,7 @@ class MeshSketch extends meshObject {
if (sel.length) {
sel.forEach(s => s.selected = false);
sketch.render();
motoBroker.publish('sketch_selections');
broker.publish('sketch_selections');
}
return sel.length;
},
@ -173,7 +184,7 @@ class MeshSketch extends meshObject {
if (sel.length) {
sketch.items = sketch.items.filter(i => !i.selected);
sketch.render();
motoBroker.publish('sketch_selections');
broker.publish('sketch_selections');
}
return sel.length;
},
@ -524,6 +535,7 @@ class MeshSketch extends meshObject {
}
this.update();
motoSpace.refresh();
broker.publish('sketch_render', this);
}
render_defer() {
@ -589,7 +601,7 @@ class SketchItem {
}
this.update();
sketch.render();
motoBroker.publish('sketch_selections');
broker.publish('sketch_selections');
}
extrude(z, opt = {}) {