From 06b0974940685871f199cbe1b965f5692e822a48 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sun, 21 Jul 2024 22:57:32 -0400 Subject: [PATCH] missing edges module --- src/mesh/edges.js | 207 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/mesh/edges.js diff --git a/src/mesh/edges.js b/src/mesh/edges.js new file mode 100644 index 00000000..31328fc3 --- /dev/null +++ b/src/mesh/edges.js @@ -0,0 +1,207 @@ +/** Copyright Stewart Allen -- All Rights Reserved */ + +/** + * facet edge selecetor. allows for creating new facets + * when two connected edges share a single point. + */ + +"use strict"; + +// dep: moto.space +gapp.register("mesh.edges", [], (root, exports) => { + +const { Line2, LineMaterial, LineGeometry, Vector3, Group } = THREE; +const { base, mesh, moto } = root; +const { space } = moto; +const { newPoint } = base; + +let isActive; +let hovered; +let selected = []; + +// hovered edge object +let geo, mat, obj = new Line2( + geo = new LineGeometry(), + mat = new LineMaterial({ + linewidth: 6, + color: 0x88ff00, + alphaToCoverage: false, + }) + +); + +// split functions +let edges = { + active() { + return isActive ? true : false; + }, + + start() { + if (isActive) { + return; + } + + let { api } = mesh; + + isActive = true; + selected.length = 0; + obj.visible = false; + + space.scene.add(obj); + + // enable temp mode + let state = edges.state = { obj }; + let models = state.models = api.selection.models(); + let meshes = models.map(m => m.mesh); + + // find closest facet edge to hover location + space.mouse.onHover((int, event, ints) => { + if (!event) { + obj.visible = false; + return meshes; + } + if (event.buttons) { + return; + } + + obj.visible = true; + + let { point, face, object } = int; + let side = edges.closest_edge(point, face, object); + let { p0, p1 } = side; + let verts = side.verts = [ p0.x, -p0.z, p0.y, p1.x, -p1.z, p1.y ]; + geo.setPositions(verts); + hovered = { object, face, side }; + }); + isActive = true; + }, + + end() { + if (!isActive) { + return; + } + let space = moto.space; + space.scene.remove(obj); + space.scene.remove(edges.selected); + space.mouse.onHover(undefined); + isActive = edges.state = undefined; + mesh.api.selection.update(); + }, + + async add() { + if (selected.length === 2 && selected[0].object === selected[1].object) { + let verts = selected.map(s => [ s.side.p0, s.side.p1 ]).flat(); + // clean up floating point cruft for comparison + for (let v of verts) { + v.x = v.x.round(3); + v.y = v.y.round(3); + v.z = v.z.round(3); + } + // sort points so dups show up next to each other + let sort = verts.sort((a,b) => { + if (a.x !== b.x) { + return a.x - b.x; + } else if (a.y !== b.y) { + return a.y - b.y; + } else { + return a.z - b.z; + } + }).filter((point, index, arr) => { + return index === 0 || + point.x !== arr[index - 1].x || + point.y !== arr[index - 1].y || + point.z !== arr[index - 1].z; + }); + let model = selected[0].object.model; + if (verts.length === 3) { + await model.duplicate({ append: [ + sort[0].x, -sort[0].z, sort[0].y, + sort[1].x, -sort[1].z, sort[1].y, + sort[2].x, -sort[2].z, sort[2].y, + ]}); + model.remove(); + } else if (verts.length === 4) { + await model.duplicate({ append: [ + verts[0].x, -verts[0].z, verts[0].y, + verts[1].x, -verts[1].z, verts[1].y, + verts[2].x, -verts[2].z, verts[2].y, + verts[1].x, -verts[1].z, verts[1].y, + verts[2].x, -verts[2].z, verts[2].y, + verts[3].x, -verts[3].z, verts[3].y, + ]}); + model.remove(); + } + // refresh object target cache + edges.end(); + edges.start(); + } + }, + + clear() { + selected.length = 0; + space.scene.remove(edges.selected); + }, + + select() { + space.scene.remove(edges.selected); + + const { object, face, side } = hovered; + let add = true; + for (let i=0; i a.d - b.d)[0]; + } +} + +exports(edges); + +});