more missing code, module adaptations

This commit is contained in:
Stewart Allen 2025-06-14 11:11:20 -04:00
commit 3ba4e3c5ec
17 changed files with 172 additions and 82 deletions

View file

@ -170,9 +170,9 @@ class DataReader {
}
}
window.ArrayWriter = ArrayWriter;
window.DataWriter = DataWriter;
window.DataReader = DataReader;
self.ArrayWriter = ArrayWriter;
self.DataWriter = DataWriter;
self.DataReader = DataReader;
// Export for ES modules
export { ArrayWriter, DataWriter, DataReader };

View file

@ -7,7 +7,7 @@ import {
LineSegmentsGeometry, MeshBVHLib } from '../ext/three.js';
// Make THREE available globally
window.THREE = THREE;
self.THREE = THREE;
THREE.BufferGeometryUtils = BufferGeometryUtils;
THREE.SVGLoader = SVGLoader.SVGLoader;
THREE.LineMaterial = LineMaterial;

View file

@ -843,10 +843,9 @@ function v2pr(rec) {
return p;
}
const earcut = window.earcut;
const earcut = self.earcut;
// Export the base object and its properties
export { base };
export { earcut };
export const { config, key, util, paths } = base;
export { newPoint };

View file

@ -12,11 +12,7 @@ const precision = 0.001;
const factor = 1/precision;
function log() {
if (root?.mesh?.log) {
root.mesh.log(...arguments)
} else if (root.debug === true) {
console.log(...arguments);
}
console.log(...arguments);
}
export const CSG = {

View file

@ -2,7 +2,8 @@
"use strict";
import { base, util, paths, config, newPoint } from './base.js';
import { base, util, paths, config } from './base.js';
import { newPoint } from './point.js';
import { ClipperLib } from '../ext/clip2.esm.js';
const { sqr, numOrDefault } = util;

View file

@ -1,23 +1,15 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
/**
* basic slice and line connection. In future, replace kiri's fdm and cam slicers
* with wrappers on this one.
*/
// dep: geo.base
// dep: geo.line
// dep: geo.point
// dep: geo.polygon
// dep: geo.polygons
import { newPolygon, newPoint, newOrderedLine } from '../geo/polygon.js';
gapp.register("geo.slicer", [], (root, exports) => {
const { base } = root;
const { config, util, polygons } = base
const POLY = base.polygons;
import { newOrderedLine } from './line.js';
import { newPolygon } from '../geo/polygon.js';
import { polygons } from '../geo/polygons.js';
import { newPoint } from '../geo/point.js';
import { util } from '../mesh/util.js';
import { config } from '../geo/base.js';
function dval(v, dv) {
return v !== undefined ? v : dv;
@ -32,7 +24,7 @@ function dval(v, dv) {
* @param {Point[]} points vertex array
* @param {Object} options slicing parameters
*/
async function slice(points, options = {}) {
export async function slice(points, options = {}) {
let zMin = options.zMin || 0,
zMax = options.zMax || 0,
zInc = options.zInc || 0,
@ -322,7 +314,7 @@ function makeZLine(phash, p1, p2, coplanar, edge) {
*
* @param {number} z
*/
async function sliceZ(z, points, options = {}) {
export async function sliceZ(z, points, options = {}) {
if (Array.isArray(z)) {
return Promise.all(z.map(z => sliceZ(z, points, options)));
}
@ -458,7 +450,7 @@ async function sliceZ(z, points, options = {}) {
* @param {number} [index]
* @returns {Array}
*/
function sliceConnect(input, z, opt = {}) {
export function sliceConnect(input, z, opt = {}) {
let { debug, both } = opt;
if (both) {
@ -782,7 +774,7 @@ function sliceConnect(input, z, opt = {}) {
* @param {Line[]} lines
* @returns {Line[]}
*/
function removeDuplicateLines(lines) {
export function removeDuplicateLines(lines) {
let output = [],
tmplines = [],
points = [],
@ -873,12 +865,11 @@ function removeDuplicateLines(lines) {
return output;
}
gapp.overlay(base, {
export const slicer = {
slice,
sliceZ,
slicePost: {},
sliceDedup: removeDuplicateLines,
sliceConnect
});
}
});

View file

@ -1,5 +1,7 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
// import '../mesh/work.js';
import '../add/array.js';
import '../add/class.js';
import '../add/three.js';
@ -77,7 +79,7 @@ function init() {
motoClient.on('ready', restore_space);
// start worker
motoClient.start(`/code/mesh_work?${version}`);
motoClient.start(`/v2/lib/mesh/work.js?${version}`);
// trigger space event binding
call.space_init({ space: motoSpace, platform });

View file

@ -1,9 +1,8 @@
const service_worker = navigator.serviceWorker;
import { license } from '../moto/license.js';
import { version } from '../moto/license.js';
async function start_service_worker() {
const version = license.version;
function debug() {
console.log(`[${version}]`, ...arguments);
}

View file

@ -1614,7 +1614,7 @@ broker.wrapObject(model, 'model');
broker.wrapObject(group, 'group');
// optimize db writes by merging updates
prefs.save = meshUtil.deferWrap(prefs.save, 100);
// prefs.save = meshUtil.deferWrap(prefs.save, 100);
export {
selection,

View file

@ -7,6 +7,7 @@ import { util } from './util.js';
import { space } from '../moto/space.js';
import { split } from './split.js';
import { newPolygon } from '../geo/polygon.js';
import { version } from '../moto/license.js';
const { div, label, input, hr } = h;
const { dbug } = api;
@ -525,7 +526,7 @@ function ui_build() {
div({ class: "menu" }, [
div('Help'),
div({ class: "menu-items" }, [
menu_item('About', () => { api.welcome(license.version) }),
menu_item('About', () => { api.welcome(version) }),
hr(),
menu_item('Documentation', api.help),
menu_item('Report Bugs', api.bugs),

View file

@ -1,13 +1,13 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
import { THREE } from '../ext/three.js';
const { Matrix4, Vector3, Box3, Box3Helper, Quaternion } = THREE;
import { broker as motoBroker } from '../moto/broker.js';
import { client as motoClient } from '../moto/client.js';
import { space as motoSpace } from '../moto/space.js';
import { api as meshApi } from './api.js';
import { util as meshUtil } from './util.js';
const { Matrix4, Vector3, Box3, Box3Helper, Quaternion } = THREE;
const worker = motoClient.fn;
const lookUp = new Vector3(0,0,-1);

View file

@ -1,11 +1,10 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
import { THREE } from '../ext/three.js';
const { Matrix4, Matrix3, Vector3, Box3, LineSegments, BufferGeometry, Float32BufferAttribute, LineBasicMaterial } = THREE;
import { license as motoLicense } from '../moto/license.js';
import { api as meshApi } from './api.js';
import { object as meshObject } from './object.js';
const { Matrix4, Matrix3, Vector3, Box3, LineSegments, BufferGeometry, Float32BufferAttribute, LineBasicMaterial } = THREE;
const deferFn = [];
const boundsCache = {};

View file

@ -1,23 +1,21 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
import { THREE } from '../ext/three.js';
const { Triangle, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
import { license as motoLicense } from '../moto/license.js';
import "../ext/earcut.js";
import '../add/array.js';
import '../add/class.js';
import '../add/three.js';
import { version } from '../moto/license.js';
import { client as motoClient } from '../moto/client.js';
import { worker as motoWorker } from '../moto/worker.js';
import { util as meshUtil } from './util.js';
import { worker } from '../moto/worker.js';
import { sliceConnect } from '../geo/slicer.js';
import { newPolygon } from '../geo/polygon.js';
import { polygons } from '../geo/polygons.js';
import { CSG } from '../geo/csg.js';
import { util } from './util.js';
import { tool as meshTool } from './tool.js';
import { CSG, newPoint, newPolygon, sliceConnect, polygons } from '../geo/base.js';
import { line as geoLine } from '../geo/line.js';
import { point as geoPoint } from '../geo/point.js';
import { polygon as geoPolygon } from '../geo/polygon.js';
import { polygons as geoPolygons } from '../geo/polygons.js';
import { bounds as geoBounds } from '../geo/bounds.js';
import { slicer as geoSlicer } from '../geo/slicer.js';
import { csg as geoCsg } from '../geo/csg.js';
import { broker } from '../moto/broker.js';
import { api } from './api.js';
import { model } from './model.js';
import { THREE } from '../ext/three.js';
const { Triangle, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
const cache = {};
@ -25,7 +23,7 @@ const cache = {};
const work = { cache };
// start worker pool (disabled for now with *0)
motoClient.start(`/code/mesh_pool?${license.version}`, motoClient.max() * 0);
motoClient.start(`/v2/lib/mesh/pool.js?${version}`, motoClient.max() * 0);
function log(msg) {
return motoWorker.publish("mesh.log", msg);
@ -444,9 +442,9 @@ const model = {
const zh = height || 15;
const verts = poly.extrude(zh, { chamfer });
if (twist) {
const rad = base.util.toRadians(twist);
const rad = util.toRadians(twist);
for (let i=0; i<verts.length; i += 3) {
let [x, y] = base.util.rotate(
let [x, y] = util.rotate(
verts[i],
verts[i+1],
rad * (verts[i+2] / zh)
@ -567,8 +565,105 @@ const model = {
}
};
const group = {
add(data) {
let { id, model } = data;
},
remove(data) {
let { id, model } = data;
}
};
const object = {
meta(data) {
let { id, meta } = data;
cacheUpdate(id, meta);
},
create(data) {
let { id, type } = data;
cache[id] = { id, type };
},
destroy(data) {
delete cache[data.id];
}
};
const file = {
export(data, send) {
let header = `# Generated By Mesh:Tool @ https://grid.space/mesh (units = millimeters)`;
let { format, recs } = data;
let vtot = 0;
for (let rec of recs) {
let { id } = rec;
let vs = rec.varr = Array.from(translate_encode(id)).map(v => v.round(5));
vtot += (vs.length / 3);
}
switch (format) {
case "obj":
let p = 1;
let obj = [header];
for (let rec of recs) {
let { file, varr } = rec;
obj.push(`g ${file}`);
for (let i=0; i<varr.length; p += 3) {
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
obj.push(`f ${p} ${p+1} ${p+2}`);
}
}
return obj.join('\n');
case "stl":
let stl = new Uint8Array(80 + 4 + vtot/3 * 50);
let dat = new DataView(stl.buffer);
let pos = 84;
header.split('').forEach((c,i) => {
dat.setUint8(i, c.charCodeAt(0));
});
// todo put Mesh:Tool info in header
dat.setInt32(80, vtot/3, true);
for (let rec of recs) {
let { id, matrix, file, varr } = rec;
for (let i=0, l=varr.length; i<l;) {
let p0 = new Vector3(varr[i++], varr[i++], varr[i++]);
let p1 = new Vector3(varr[i++], varr[i++], varr[i++]);
let p2 = new Vector3(varr[i++], varr[i++], varr[i++]);
let norm = computeFaceNormal(p0, p1, p2);
dat.setFloat32(pos + 0, norm.x, true);
dat.setFloat32(pos + 4, norm.y, true);
dat.setFloat32(pos + 8, norm.z, true);
dat.setFloat32(pos + 12, p0.x, true);
dat.setFloat32(pos + 16, p0.y, true);
dat.setFloat32(pos + 20, p0.z, true);
dat.setFloat32(pos + 24, p1.x, true);
dat.setFloat32(pos + 28, p1.y, true);
dat.setFloat32(pos + 32, p1.z, true);
dat.setFloat32(pos + 36, p2.x, true);
dat.setFloat32(pos + 40, p2.y, true);
dat.setFloat32(pos + 44, p2.z, true);
pos += 50;
}
}
return stl;
default:
throw `invalid format "${format}"`;
}
}
};
function debug() {
console.log({work_cache: cache});
}
export { work, log, model, debug };
worker.bindObject({
debug,
model,
group,
object,
file
});
worker.ready();

View file

@ -150,7 +150,7 @@ const client = {
if (self.createWorker) {
return self.createWorker();
} else {
return new Worker(workurl = url);
return new Worker(workurl = url, { type: 'module' });
}
},
@ -188,9 +188,14 @@ const client = {
let worker = client.spawn(workurl);
worker.run = null;
worker.index = i;
worker.onerror = function(e) {
console.log({ worker_error: e });
}
worker.onmessageerror = function(e) {
console.log({ worker_message_error: e });
}
worker.onmessage = function(e) {
let reply = e.data;
// handle special case for task binding
if (reply.bind) {
client.bind(reply.bind);

View file

@ -7,3 +7,4 @@ const terms = {
};
export const license = terms;
export const version = terms.VERSION;

View file

@ -1,8 +1,7 @@
// code for a ServiceWorker that provides support for running cached/offline
import { license } from './license.js';
import { version } from './license.js';
const version = license.version;
const origin = self.location.origin;
const stats = {
hit: 0,

View file

@ -15,8 +15,8 @@ const {
const nav = navigator;
let WIN = window,
DOC = document,
let WIN = self.window || {},
DOC = self.document,
SCENE = new Scene(),
WORLD = new Group(),
PI = Math.PI,
@ -130,25 +130,27 @@ let WIN = window,
hiddenKey,
vizChange,
docVisible = true,
antiAlias = window.devicePixelRatio <= 1,
antiAlias = WIN.devicePixelRatio <= 1,
lastAction = Date.now(),
renderTime = 0,
fps = 0;
if (typeof DOC.hidden !== "undefined") {
hiddenKey = "hidden";
vizChange = "visibilitychange";
} else if (typeof DOC.msHidden !== "undefined") {
hiddenKey = "msHidden";
vizChange = "msvisibilitychange";
} else if (typeof DOC.webkitHidden !== "undefined") {
hiddenKey = "webkitHidden";
vizChange = "webkitvisibilitychange";
}
if (DOC) {
if (typeof DOC.hidden !== "undefined") {
hiddenKey = "hidden";
vizChange = "visibilitychange";
} else if (typeof DOC.msHidden !== "undefined") {
hiddenKey = "msHidden";
vizChange = "msvisibilitychange";
} else if (typeof DOC.webkitHidden !== "undefined") {
hiddenKey = "webkitHidden";
vizChange = "webkitvisibilitychange";
}
DOC.addEventListener(vizChange, () => {
docVisible = DOC[hiddenKey] ? false : true;
}, false);
DOC.addEventListener(vizChange, () => {
docVisible = DOC[hiddenKey] ? false : true;
}, false);
}
function updateLastAction() {
lastAction = Date.now();
@ -172,7 +174,7 @@ WORLD.contains = (obj) => {
******************************************************************* */
function tweenit() {
TWEEN.update();
self.TWEEN?.update();
setTimeout(tweenit, tweenDelay);
}