From ee2127dbcf2714a641b4edb5f99d35d9b36fd1cd Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 24 Aug 2024 23:24:03 -0400 Subject: [PATCH] checkpoint threads work --- src/mesh/api.js | 50 +++++++++++++++++++++++++++++++--------------- src/mesh/build.js | 1 + src/mesh/tool.js | 40 +++++++++++++++++++++++++++++++++++++ src/mesh/work.js | 26 +++++++++++++++++++++++- web/mesh/index.css | 8 ++++---- 5 files changed, 104 insertions(+), 21 deletions(-) diff --git a/src/mesh/api.js b/src/mesh/api.js index 22fdc3af..fb78b9a1 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -34,12 +34,12 @@ const selection = { }, // @returns {MeshObject[]} or all groups if not strict and no selection - list(strict) { + list(strict = false) { return selected.length || strict ? selected.slice() : groups.slice(); }, // return selected groups + groups from selected models - groups(strict) { + groups(strict = true) { let all = selection.list(strict); let grp = all.filter(s => s instanceof mesh.group); let mdl = all.filter(s => s instanceof mesh.model); @@ -50,7 +50,7 @@ const selection = { }, // return selected models + models from selected groups - models(strict) { + models(strict = true) { let all = selection.list(strict); let grp = all.filter(s => s instanceof mesh.group); let mdl = all.filter(s => s instanceof mesh.model); @@ -62,14 +62,14 @@ const selection = { return mdl; }, - sketch() { - return selection.sketches()[0]; - }, - sketches() { return selection.list(true).filter(s => s.type === 'sketch'); }, + sketch() { + return selection.sketches()[0]; + }, + sketch_items() { return selection.list(true).filter(s => s.type === 'sketch_item') }, @@ -329,7 +329,7 @@ const pattern = { } api.modal.dialog({ title: "circle pattern", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('total count'), h.input({ value: 3, size: 5, id: "_count" }), h.label('center x,y'), @@ -368,7 +368,7 @@ const pattern = { } api.modal.dialog({ title: "grid pattern", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('x count'), h.input({ value: 3, size: 5, id: "_x" }), h.label('y count'), @@ -451,7 +451,7 @@ let sketch = { } api.modal.dialog({ title: "extrude", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('height'), h.input({ value: opt.height || 10, size: 5, id: "_height" }), h.hr(), @@ -533,7 +533,7 @@ let sketch = { sketch.selection.ifcan((sketch, items) => { api.modal.dialog({ title: "rotate", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('angle'), h.input({ value: 90, size: 5, id: "_angle" }), h.button({ _: "rotate", onclick() { @@ -695,7 +695,7 @@ let add = { } api.modal.dialog({ title: "add circle", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('radius in mm'), h.input({ value: 10, size: 5, id: "_radius" }), h.hr(), @@ -726,7 +726,7 @@ let add = { } api.modal.dialog({ title: "add rectangle", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('width'), h.input({ value: 20, size: 5, id: "_width" }), h.label('height'), @@ -794,7 +794,7 @@ let add = { } api.modal.dialog({ title: "cylinder", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('diameter'), h.input({ value: 20, size: 5, id: "_diameter" }), h.label('height'), @@ -847,7 +847,7 @@ let add = { let last = api.prefs.map.gear = (api.prefs.map.gear || {}); api.modal.dialog({ title: "gear generator", - body: [ h.div({ class: "addgear" }, [ + body: [ h.div({ class: "additem" }, [ h.label('number of teeth'), h.input({ value: last.teeth || 20, size: 5, id: "_teeth" }), h.label('shaft diameter'), @@ -872,6 +872,24 @@ let add = { ]) ] }); api.modal.bound._teeth.focus(); + }, + + threads() { + worker.model_gen_threads({ + height: 50, + radius: 25, + turns: 5, + depth: 3, + steps: 50 + }).then(verts => { + const nmdl = new mesh.model({ file: "gear", mesh: verts.toFloat32() }); + const ngrp = group.new([ nmdl ]); + selection.set([ nmdl ]); + ngrp.floor(); + // Object.assign(last, params); + api.prefs.save(); + }); + } }; @@ -1159,7 +1177,7 @@ const tool = { }, indexFaces(models, opt = {}) { - models = fallback(models); + models = fallback(models, false); log('mapping faces').pin(); let promises = []; let mark = Date.now(); diff --git a/src/mesh/build.js b/src/mesh/build.js index 5f06f750..33ad9951 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -418,6 +418,7 @@ function ui_build() { menu_item('Add Cylinder', add.cylinder), menu_item('Add Cube', add.cube), menu_item('Add Gear', add.gear), + menu_item('Add Threads', add.threads), hr(), menu_item('Add Sketch', add.sketch), devel ? menu_item('Add Vertices', add.input) : undefined, diff --git a/src/mesh/tool.js b/src/mesh/tool.js index fa874a23..235bcd56 100644 --- a/src/mesh/tool.js +++ b/src/mesh/tool.js @@ -823,6 +823,46 @@ mesh.tool = class MeshTool { return { gear, pitch }; } + generateThreads(height, radius, turns, depth, steps) { + let verts = []; + let zstep = height / turns; + let rstep = (Math.PI * 2) / steps; + let z2step = zstep / steps; + let points = [] + let iter = 0; + let iter_max = turns * steps; + let mute_min = Math.round(steps * 1.25); + let mute_max = iter_max - mute_min; + for (let turn=0; turn mute_max ? rm + ((iter_max - iter) / mute_min) * depth : + // radius; + let angle0 = rstep * step - Math.PI/2; + let z0 = (zstep * turn) + (z2step * step); + let x0 = Math.cos(angle0) * (rm); + let y0 = Math.sin(angle0) * (rm); + let x1 = Math.cos(angle0) * (rx); + let y1 = Math.sin(angle0) * (rx); + let p0 = [ x1, y1, z0 + zstep/2 ]; + let p1 = [ x0, y0, z0 ]; + let p2 = [ x1, y1, z0 - zstep/2 ]; + let [ pp0, pp1, pp2 ] = points; + if (pp0 && pp1 && pp2) { + verts.push(...pp0, ...pp1, ...p0); + verts.push(...p0, ...pp1, ...p1); + verts.push(...pp1, ...pp2, ...p1); + verts.push(...p1, ...pp2, ...p2); + } + points = [ p0, p1, p2 ]; + } + } + return verts; + } + }; }); diff --git a/src/mesh/work.js b/src/mesh/work.js index b5749a15..93609785 100644 --- a/src/mesh/work.js +++ b/src/mesh/work.js @@ -221,7 +221,7 @@ let model = { let { id, z } = data; let scale = 100000; z = Math.round(z * scale) | 0; - let pos = translate_encode(id); + let pos = data.pos || translate_encode(id); let o1 = []; // new bottom let o2 = []; // new top let o1p = []; // o1 new split faces @@ -456,6 +456,30 @@ let model = { } } send.done(verts); + }, + + gen_threads(data, send) { + let { height, radius, turns, depth, steps } = data; + let zstep = height / turns; + height += zstep * 2; + turns += 2; + let verts = new mesh.tool().generateThreads( + height, + radius, + turns, + depth, + steps, + ); + // return send.done(verts); + let s0 = model.split({ + z: zstep, + pos: verts + }) + let s1 = model.split({ + z: height - zstep, + pos: s0.o2 + }); + send.done(s1.o1); } }; diff --git a/web/mesh/index.css b/web/mesh/index.css index fa5a1676..93e38d7a 100644 --- a/web/mesh/index.css +++ b/web/mesh/index.css @@ -294,21 +294,21 @@ button:hover { gap: 4px; } -.addact input, .addgear input { +.addact input, .additem input { text-align: center; } -.addgear { +.additem { gap: 5px 10px; display: grid; grid-template-columns: 1fr 50px; } -/* .addgear hr { +/* .additem hr { width: 100%; } */ -.addgear button, .addgear hr, .addgear code { +.additem button, .additem hr, .additem code { grid-column: span 2; text-align: center; }