From d947963c282199e675df255144dd92b67990217b Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 16 Jun 2025 00:56:58 -0400 Subject: [PATCH] improve sketch bounds and handles --- src2/mesh/handles.js | 37 ++++++++++++++----------------------- src2/mesh/sketch.js | 28 ++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src2/mesh/handles.js b/src2/mesh/handles.js index f5cab378..fefcd446 100644 --- a/src2/mesh/handles.js +++ b/src2/mesh/handles.js @@ -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; } diff --git a/src2/mesh/sketch.js b/src2/mesh/sketch.js index 604d8fe3..be5504ba 100644 --- a/src2/mesh/sketch.js +++ b/src2/mesh/sketch.js @@ -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 = {}) {