add radial gpu option (work in progress)
This commit is contained in:
parent
49127b8296
commit
49a63fad04
8 changed files with 118 additions and 24 deletions
2
app.js
2
app.js
|
|
@ -578,6 +578,8 @@ function rewriteHtmlVersion(req, res, next) {
|
|||
if ([
|
||||
"/kiri/",
|
||||
"/mesh/",
|
||||
"/lib/gpu/raster.js",
|
||||
"/lib/gpu/raster-worker.js",
|
||||
"/lib/mesh/work.js",
|
||||
"/lib/kiri/run/worker.js",
|
||||
"/lib/kiri/run/minion.js",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"@gridspace/app-server": "github:gridspace/app-server#v0.0.19",
|
||||
"@gridspace/basic-ftp": "github:gridspace/basic-ftp#v5.0.5-gridspace",
|
||||
"@gridspace/net-level-client": "^0.2.3",
|
||||
"@gridspace/raster-path": "github:gridspace/raster-path#main",
|
||||
"@tracespace/parser": "^5.0.0-next.0",
|
||||
"@tweenjs/tween.js": "^16.6.0",
|
||||
"base64-js": "^1.5.1",
|
||||
|
|
|
|||
1
src/gpu/raster-worker.js
Symbolic link
1
src/gpu/raster-worker.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../node_modules/@gridspace/raster-path/src/web/webgpu-worker.js
|
||||
1
src/gpu/raster.js
Symbolic link
1
src/gpu/raster.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../node_modules/@gridspace/raster-path/src/index.js
|
||||
|
|
@ -943,6 +943,7 @@ export const conf = {
|
|||
threaded: true,
|
||||
units: "mm",
|
||||
view: null,
|
||||
webGPU: false,
|
||||
zoomSpeed: 1.0,
|
||||
},
|
||||
// default hidden ui groups
|
||||
|
|
|
|||
|
|
@ -142,26 +142,27 @@ function booleanSave() {
|
|||
if (control.antiAlias != ui.antiAlias.checked) {
|
||||
api.show.alert('Page Reload Required to Change Aliasing');
|
||||
}
|
||||
control.shiny = ui.shiny.checked;
|
||||
control.antiAlias = ui.antiAlias.checked;
|
||||
control.assembly = ui.assembly.checked;
|
||||
control.autoLayout = ui.autoLayout.checked;
|
||||
control.autoSave = ui.autoSave.checked;
|
||||
control.dark = ui.dark.checked;
|
||||
control.devel = ui.devel.checked;
|
||||
control.drawer = ui.drawer.checked;
|
||||
control.exportOcto = ui.exportOcto.checked;
|
||||
control.exportPreview = ui.exportPreview.checked;
|
||||
control.exportThumb = ui.exportThumb.checked;
|
||||
control.freeLayout = ui.freeLayout.checked;
|
||||
control.healMesh = ui.healMesh.checked;
|
||||
control.ortho = ui.ortho.checked;
|
||||
control.reverseZoom = ui.reverseZoom.checked;
|
||||
control.scrolls = ui.scrolls.checked;
|
||||
control.shiny = ui.shiny.checked;
|
||||
control.showOrigin = ui.showOrigin.checked;
|
||||
control.showRulers = ui.showRulers.checked;
|
||||
control.autoLayout = ui.autoLayout.checked;
|
||||
control.freeLayout = ui.freeLayout.checked;
|
||||
control.spaceRandoX = ui.spaceRandoX.checked;
|
||||
control.autoSave = ui.autoSave.checked;
|
||||
control.antiAlias = ui.antiAlias.checked;
|
||||
control.reverseZoom = ui.reverseZoom.checked;
|
||||
control.dark = ui.dark.checked;
|
||||
control.exportOcto = ui.exportOcto.checked;
|
||||
control.exportThumb = ui.exportThumb.checked;
|
||||
control.exportPreview = ui.exportPreview.checked;
|
||||
control.healMesh = ui.healMesh.checked;
|
||||
control.threaded = setThreaded(ui.threaded.checked);
|
||||
control.assembly = ui.assembly.checked;
|
||||
control.ortho = ui.ortho.checked;
|
||||
control.devel = ui.devel.checked;
|
||||
control.webGPU = ui.webGPU.checked;
|
||||
space.view.setZoom(control.reverseZoom, control.zoomSpeed);
|
||||
// platform.layout();
|
||||
api.conf.save();
|
||||
|
|
@ -1063,6 +1064,7 @@ function init_one() {
|
|||
healMesh: newBoolean(LANG.pt_heal_s, booleanSave, {title: LANG.pt_heal_l}),
|
||||
threaded: newBoolean(LANG.pt_thrd_s, booleanSave, {title: LANG.pt_thrd_l, modes:THREED}),
|
||||
assembly: newBoolean(LANG.pt_assy_s, booleanSave, {title: LANG.pt_assy_l, modes:THREED}),
|
||||
webGPU: newBoolean(LANG.pt_wgpu_s, booleanSave, {title: LANG.pt_wgpu_l, modes:THREED}),
|
||||
|
||||
prefadd: uc.checkpoint($('prefs-add')),
|
||||
|
||||
|
|
@ -1630,20 +1632,22 @@ function init_two() {
|
|||
space.platform.setZOff(0.05);
|
||||
|
||||
// restore UI state from settings
|
||||
ui.antiAlias.checked = control.antiAlias;
|
||||
ui.assembly.checked = control.assembly;
|
||||
ui.autoLayout.checked = control.autoLayout;
|
||||
ui.autoSave.checked = control.autoSave;
|
||||
ui.devel.checked = control.devel;
|
||||
ui.freeLayout.checked = control.freeLayout;
|
||||
ui.healMesh.checked = control.healMesh;
|
||||
ui.ortho.checked = control.ortho;
|
||||
ui.reverseZoom.checked = control.reverseZoom;
|
||||
ui.showOrigin.checked = control.showOrigin;
|
||||
ui.showRulers.checked = control.showRulers;
|
||||
ui.showSpeeds.checked = control.showSpeeds;
|
||||
ui.freeLayout.checked = control.freeLayout;
|
||||
ui.autoLayout.checked = control.autoLayout;
|
||||
ui.spaceRandoX.checked = control.spaceRandoX;
|
||||
ui.antiAlias.checked = control.antiAlias;
|
||||
ui.reverseZoom.checked = control.reverseZoom;
|
||||
ui.autoSave.checked = control.autoSave;
|
||||
ui.healMesh.checked = control.healMesh;
|
||||
ui.threaded.checked = setThreaded(control.threaded);
|
||||
ui.assembly.checked = control.assembly;
|
||||
ui.ortho.checked = control.ortho;
|
||||
ui.devel.checked = control.devel;
|
||||
ui.webGPU.checked = control.webGPU;
|
||||
|
||||
lineTypeSave();
|
||||
detailSave();
|
||||
updateStats();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { sliceConnect } from '../../../geo/slicer.js';
|
|||
import { newSlice } from '../../core/slice.js';
|
||||
import { Tool } from './tool.js';
|
||||
import { Slicer as topo_slicer } from './slicer_topo.js';
|
||||
import { RasterPath } from '../../../gpu/raster.js';
|
||||
|
||||
const RAD2DEG = 180 / Math.PI;
|
||||
const DEG2RAD = Math.PI / 180;
|
||||
|
|
@ -24,6 +25,7 @@ export class Topo {
|
|||
let { state, op, onupdate, ondone } = opt;
|
||||
let { widget, settings, tabs } = opt.state;
|
||||
let { controller, process } = settings;
|
||||
let { webGPU } = controller;
|
||||
|
||||
let axis = op.axis.toLowerCase(),
|
||||
tool = new Tool(settings, op.tool),
|
||||
|
|
@ -65,11 +67,14 @@ export class Topo {
|
|||
this.lineColor = state.settings.controller.dark ? 0xffff00 : 0x555500;
|
||||
this.offStart = op.offStart ?? 0;
|
||||
this.offEnd = op.offEnd ?? 0;
|
||||
this.bounds = bounds;
|
||||
this.gpu = webGPU ?? false;
|
||||
|
||||
onupdate(0, "lathe");
|
||||
|
||||
const range = this.range = { min: Infinity, max: -Infinity };
|
||||
const slices = this.sliced = await this.slice(scale(onupdate, 0.25, 0));
|
||||
|
||||
for (let slice of slices) {
|
||||
range.min = Math.min(range.min, slice.z);
|
||||
range.max = Math.max(range.max, slice.z);
|
||||
|
|
@ -91,7 +96,6 @@ export class Topo {
|
|||
const { vertices, resolution, tabverts, zoff, offStart, offEnd, tool, unit } = this;
|
||||
const { minions } = self.kiri_worker;
|
||||
const range = this.range = { min: Infinity, max: -Infinity };
|
||||
const box = this.box = new THREE.Box2();
|
||||
|
||||
// swap XZ in shared array
|
||||
for (let i = 0, l = vertices.length; i < l; i += 3) {
|
||||
|
|
@ -119,6 +123,11 @@ export class Topo {
|
|||
// re-create shared vertex array for workers
|
||||
this.vertices = [].appendAll(vertices).appendAll(tabverts).toFloat32().toShared();
|
||||
|
||||
// rp.rasterizeMesh(vertices, resolution).then(rpo => console.log({ rpo }));
|
||||
if (this.gpu) {
|
||||
return await this.sliceGPU(onupdate);
|
||||
}
|
||||
|
||||
const zSpan = range.max - range.min;
|
||||
const shards = Math.ceil(Math.min(25, vertices.length / 27000));
|
||||
const totalSteps = Math.ceil(zSpan / resolution);
|
||||
|
|
@ -151,6 +160,73 @@ export class Topo {
|
|||
}
|
||||
}
|
||||
|
||||
async sliceGPU(onupdate) {
|
||||
const { angle, linear, offStart, offEnd, resolution, tool, unit, vertices, zBottom } = this;
|
||||
|
||||
let gpu = new RasterPath({ workerName: "/lib/gpu/raster-worker.js" });
|
||||
await gpu.init();
|
||||
await gpu.initWorkerPool();
|
||||
|
||||
let tickperstep = Math.round(this.step / resolution);
|
||||
let bounds = this.bounds.clone();
|
||||
bounds.min.x += offStart * unit;
|
||||
bounds.max.x -= offEnd * unit;
|
||||
let output = await gpu.generateRadialToolpath(
|
||||
vertices,
|
||||
tool,
|
||||
angle,
|
||||
tickperstep,
|
||||
zBottom,
|
||||
resolution,
|
||||
bounds,
|
||||
(pct, msg) => { console.log({ pct, msg }) }
|
||||
);
|
||||
|
||||
// console.log({ tool, output, tickperstep });
|
||||
// const axis = new THREE.Vector3(1, 0, 0);
|
||||
let { numRotations, pointsPerLine, pathData } = output;
|
||||
let degPerRow = 360 / numRotations;
|
||||
let slices = this.gpu_slices = [];
|
||||
let xmult = tickperstep * resolution;
|
||||
let xoff = bounds.min.x;
|
||||
let rows = [];
|
||||
for (let i=0; i<numRotations; i++) {
|
||||
let lineData = pathData.slice(i * pointsPerLine, i * pointsPerLine + pointsPerLine);
|
||||
let points = Array.from(lineData).map((v,j) => newPoint(j * xmult + xoff, 0, v).setA(-i * degPerRow));
|
||||
// let points = Array.from(lineData).map((v,i) => [ i * xmult + xoff, 0, v ]).flat().toFloat32();
|
||||
// let rot = new THREE.Matrix4().makeRotationAxis(axis, (Math.PI / numRotations * 2) * i);
|
||||
// new THREE.BufferAttribute(points, 3).applyMatrix4(rot);
|
||||
// points = Array.from(points).group(3).map((v,i) => newPoint(v[0], v[1], v[2]));
|
||||
rows.push(points);
|
||||
}
|
||||
if (linear) {
|
||||
for (let i=0; i<rows.length; i++) {
|
||||
let slice = newSlice(i);
|
||||
slice.index = i;
|
||||
slice.camLines = [ newPolygon(rows[i]).setOpen() ];
|
||||
if (i % 2 === 1) slice.camLines[0].reverse();
|
||||
slices.push(slice);
|
||||
}
|
||||
} else {
|
||||
for (let i=0; i<pointsPerLine; i++) {
|
||||
let slice = newSlice(i);
|
||||
let points = rows.map(row => row[i]);
|
||||
// points.push(points[0].setA(points[0].a - 360));
|
||||
if (i % 2 === 1) points.reverse();
|
||||
slice.index = i;
|
||||
slice.camLines = [ newPolygon(points).setOpen() ];
|
||||
slices.push(slice);
|
||||
}
|
||||
}
|
||||
for (let slice of slices) {
|
||||
slice.output()
|
||||
.setLayer("lathe", { line: this.lineColor })
|
||||
.addPoly(slice.camLines[0].clone().applyRotations());
|
||||
}
|
||||
// console.log({ webGPU: output, slices });
|
||||
return slices;
|
||||
}
|
||||
|
||||
async sliceWorker(onupdate) {
|
||||
const { vertices, slices, resolution } = this;
|
||||
|
||||
|
|
@ -215,13 +291,19 @@ export class Topo {
|
|||
|
||||
async lathe(onupdate) {
|
||||
const { minions } = self.kiri_worker;
|
||||
if (minions?.running > 1) {
|
||||
if (this.gpu) {
|
||||
return await this.latheGPU(onupdate);
|
||||
} else if (minions?.running > 1) {
|
||||
return await this.latheMinions(onupdate);
|
||||
} else {
|
||||
return await this.latheWorker(onupdate);
|
||||
}
|
||||
}
|
||||
|
||||
async latheGPU(onupdate) {
|
||||
return this.gpu_slices;
|
||||
}
|
||||
|
||||
lathePath(slices, tool) {
|
||||
const { resolution, step, zBottom, maxo } = this;
|
||||
|
||||
|
|
|
|||
|
|
@ -323,6 +323,8 @@ self.lang['en-us'] = {
|
|||
pt_thrd_l: ["use parallel processing when browser supports nested workers. may increase memory pressure on larger models. disable if you are getting out of memory errors"],
|
||||
pt_assy_s: "assembly",
|
||||
pt_assy_l: ["use web assembly when supported by browser. if you experience artifacts or memory errors, try disabling this."],
|
||||
pt_wgpu_s: "web gpu",
|
||||
pt_wgpu_l: ["use web gpu when supported by browser"],
|
||||
|
||||
xp_menu: "exports",
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue