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 ([
|
if ([
|
||||||
"/kiri/",
|
"/kiri/",
|
||||||
"/mesh/",
|
"/mesh/",
|
||||||
|
"/lib/gpu/raster.js",
|
||||||
|
"/lib/gpu/raster-worker.js",
|
||||||
"/lib/mesh/work.js",
|
"/lib/mesh/work.js",
|
||||||
"/lib/kiri/run/worker.js",
|
"/lib/kiri/run/worker.js",
|
||||||
"/lib/kiri/run/minion.js",
|
"/lib/kiri/run/minion.js",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
"@gridspace/app-server": "github:gridspace/app-server#v0.0.19",
|
"@gridspace/app-server": "github:gridspace/app-server#v0.0.19",
|
||||||
"@gridspace/basic-ftp": "github:gridspace/basic-ftp#v5.0.5-gridspace",
|
"@gridspace/basic-ftp": "github:gridspace/basic-ftp#v5.0.5-gridspace",
|
||||||
"@gridspace/net-level-client": "^0.2.3",
|
"@gridspace/net-level-client": "^0.2.3",
|
||||||
|
"@gridspace/raster-path": "github:gridspace/raster-path#main",
|
||||||
"@tracespace/parser": "^5.0.0-next.0",
|
"@tracespace/parser": "^5.0.0-next.0",
|
||||||
"@tweenjs/tween.js": "^16.6.0",
|
"@tweenjs/tween.js": "^16.6.0",
|
||||||
"base64-js": "^1.5.1",
|
"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,
|
threaded: true,
|
||||||
units: "mm",
|
units: "mm",
|
||||||
view: null,
|
view: null,
|
||||||
|
webGPU: false,
|
||||||
zoomSpeed: 1.0,
|
zoomSpeed: 1.0,
|
||||||
},
|
},
|
||||||
// default hidden ui groups
|
// default hidden ui groups
|
||||||
|
|
|
||||||
|
|
@ -142,26 +142,27 @@ function booleanSave() {
|
||||||
if (control.antiAlias != ui.antiAlias.checked) {
|
if (control.antiAlias != ui.antiAlias.checked) {
|
||||||
api.show.alert('Page Reload Required to Change Aliasing');
|
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.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.scrolls = ui.scrolls.checked;
|
||||||
|
control.shiny = ui.shiny.checked;
|
||||||
control.showOrigin = ui.showOrigin.checked;
|
control.showOrigin = ui.showOrigin.checked;
|
||||||
control.showRulers = ui.showRulers.checked;
|
control.showRulers = ui.showRulers.checked;
|
||||||
control.autoLayout = ui.autoLayout.checked;
|
|
||||||
control.freeLayout = ui.freeLayout.checked;
|
|
||||||
control.spaceRandoX = ui.spaceRandoX.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.threaded = setThreaded(ui.threaded.checked);
|
||||||
control.assembly = ui.assembly.checked;
|
control.webGPU = ui.webGPU.checked;
|
||||||
control.ortho = ui.ortho.checked;
|
|
||||||
control.devel = ui.devel.checked;
|
|
||||||
space.view.setZoom(control.reverseZoom, control.zoomSpeed);
|
space.view.setZoom(control.reverseZoom, control.zoomSpeed);
|
||||||
// platform.layout();
|
// platform.layout();
|
||||||
api.conf.save();
|
api.conf.save();
|
||||||
|
|
@ -1063,6 +1064,7 @@ function init_one() {
|
||||||
healMesh: newBoolean(LANG.pt_heal_s, booleanSave, {title: LANG.pt_heal_l}),
|
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}),
|
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}),
|
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')),
|
prefadd: uc.checkpoint($('prefs-add')),
|
||||||
|
|
||||||
|
|
@ -1630,20 +1632,22 @@ function init_two() {
|
||||||
space.platform.setZOff(0.05);
|
space.platform.setZOff(0.05);
|
||||||
|
|
||||||
// restore UI state from settings
|
// 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.showOrigin.checked = control.showOrigin;
|
||||||
ui.showRulers.checked = control.showRulers;
|
ui.showRulers.checked = control.showRulers;
|
||||||
ui.showSpeeds.checked = control.showSpeeds;
|
ui.showSpeeds.checked = control.showSpeeds;
|
||||||
ui.freeLayout.checked = control.freeLayout;
|
|
||||||
ui.autoLayout.checked = control.autoLayout;
|
|
||||||
ui.spaceRandoX.checked = control.spaceRandoX;
|
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.threaded.checked = setThreaded(control.threaded);
|
||||||
ui.assembly.checked = control.assembly;
|
ui.webGPU.checked = control.webGPU;
|
||||||
ui.ortho.checked = control.ortho;
|
|
||||||
ui.devel.checked = control.devel;
|
|
||||||
lineTypeSave();
|
lineTypeSave();
|
||||||
detailSave();
|
detailSave();
|
||||||
updateStats();
|
updateStats();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { sliceConnect } from '../../../geo/slicer.js';
|
||||||
import { newSlice } from '../../core/slice.js';
|
import { newSlice } from '../../core/slice.js';
|
||||||
import { Tool } from './tool.js';
|
import { Tool } from './tool.js';
|
||||||
import { Slicer as topo_slicer } from './slicer_topo.js';
|
import { Slicer as topo_slicer } from './slicer_topo.js';
|
||||||
|
import { RasterPath } from '../../../gpu/raster.js';
|
||||||
|
|
||||||
const RAD2DEG = 180 / Math.PI;
|
const RAD2DEG = 180 / Math.PI;
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
|
|
@ -24,6 +25,7 @@ export class Topo {
|
||||||
let { state, op, onupdate, ondone } = opt;
|
let { state, op, onupdate, ondone } = opt;
|
||||||
let { widget, settings, tabs } = opt.state;
|
let { widget, settings, tabs } = opt.state;
|
||||||
let { controller, process } = settings;
|
let { controller, process } = settings;
|
||||||
|
let { webGPU } = controller;
|
||||||
|
|
||||||
let axis = op.axis.toLowerCase(),
|
let axis = op.axis.toLowerCase(),
|
||||||
tool = new Tool(settings, op.tool),
|
tool = new Tool(settings, op.tool),
|
||||||
|
|
@ -65,11 +67,14 @@ export class Topo {
|
||||||
this.lineColor = state.settings.controller.dark ? 0xffff00 : 0x555500;
|
this.lineColor = state.settings.controller.dark ? 0xffff00 : 0x555500;
|
||||||
this.offStart = op.offStart ?? 0;
|
this.offStart = op.offStart ?? 0;
|
||||||
this.offEnd = op.offEnd ?? 0;
|
this.offEnd = op.offEnd ?? 0;
|
||||||
|
this.bounds = bounds;
|
||||||
|
this.gpu = webGPU ?? false;
|
||||||
|
|
||||||
onupdate(0, "lathe");
|
onupdate(0, "lathe");
|
||||||
|
|
||||||
const range = this.range = { min: Infinity, max: -Infinity };
|
const range = this.range = { min: Infinity, max: -Infinity };
|
||||||
const slices = this.sliced = await this.slice(scale(onupdate, 0.25, 0));
|
const slices = this.sliced = await this.slice(scale(onupdate, 0.25, 0));
|
||||||
|
|
||||||
for (let slice of slices) {
|
for (let slice of slices) {
|
||||||
range.min = Math.min(range.min, slice.z);
|
range.min = Math.min(range.min, slice.z);
|
||||||
range.max = Math.max(range.max, 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 { vertices, resolution, tabverts, zoff, offStart, offEnd, tool, unit } = this;
|
||||||
const { minions } = self.kiri_worker;
|
const { minions } = self.kiri_worker;
|
||||||
const range = this.range = { min: Infinity, max: -Infinity };
|
const range = this.range = { min: Infinity, max: -Infinity };
|
||||||
const box = this.box = new THREE.Box2();
|
|
||||||
|
|
||||||
// swap XZ in shared array
|
// swap XZ in shared array
|
||||||
for (let i = 0, l = vertices.length; i < l; i += 3) {
|
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
|
// re-create shared vertex array for workers
|
||||||
this.vertices = [].appendAll(vertices).appendAll(tabverts).toFloat32().toShared();
|
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 zSpan = range.max - range.min;
|
||||||
const shards = Math.ceil(Math.min(25, vertices.length / 27000));
|
const shards = Math.ceil(Math.min(25, vertices.length / 27000));
|
||||||
const totalSteps = Math.ceil(zSpan / resolution);
|
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) {
|
async sliceWorker(onupdate) {
|
||||||
const { vertices, slices, resolution } = this;
|
const { vertices, slices, resolution } = this;
|
||||||
|
|
||||||
|
|
@ -215,13 +291,19 @@ export class Topo {
|
||||||
|
|
||||||
async lathe(onupdate) {
|
async lathe(onupdate) {
|
||||||
const { minions } = self.kiri_worker;
|
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);
|
return await this.latheMinions(onupdate);
|
||||||
} else {
|
} else {
|
||||||
return await this.latheWorker(onupdate);
|
return await this.latheWorker(onupdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async latheGPU(onupdate) {
|
||||||
|
return this.gpu_slices;
|
||||||
|
}
|
||||||
|
|
||||||
lathePath(slices, tool) {
|
lathePath(slices, tool) {
|
||||||
const { resolution, step, zBottom, maxo } = this;
|
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_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_s: "assembly",
|
||||||
pt_assy_l: ["use web assembly when supported by browser. if you experience artifacts or memory errors, try disabling this."],
|
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",
|
xp_menu: "exports",
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue