initial migration, not vetted
This commit is contained in:
parent
41a32b8f68
commit
09bc6a5304
29 changed files with 122147 additions and 0 deletions
176
web/batch_glb_png/batch_render.js
Normal file
176
web/batch_glb_png/batch_render.js
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* batch_render.js
|
||||
* 20260228 ChatGPT
|
||||
* $Header$
|
||||
*
|
||||
* Example:
|
||||
* node batch_render.js job.json
|
||||
*/
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import http from 'node:http';
|
||||
import { pathToFileURL, fileURLToPath } from 'node:url';
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
function die (msg) { console.error(msg); process.exit(1); }
|
||||
function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
|
||||
|
||||
function listFiles(dir, suffix) {
|
||||
const out = [];
|
||||
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const full = path.join(dir, ent.name);
|
||||
if (ent.isDirectory()) out.push(...listFiles(full, suffix));
|
||||
else if (!suffix || ent.name.toLowerCase().endsWith(suffix)) out.push(full);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function sanitizeBasename(p) {
|
||||
const b = path.basename(p);
|
||||
return b.replace(/[^\w.\-]+/g, '_');
|
||||
}
|
||||
|
||||
function mimeTypeFor(p) {
|
||||
const ext = path.extname(p).toLowerCase();
|
||||
if (ext === '.html') return 'text/html; charset=utf-8';
|
||||
if (ext === '.js') return 'text/javascript; charset=utf-8';
|
||||
if (ext === '.json') return 'application/json; charset=utf-8';
|
||||
if (ext === '.glb') return 'model/gltf-binary';
|
||||
if (ext === '.gltf') return 'model/gltf+json; charset=utf-8';
|
||||
if (ext === '.bin') return 'application/octet-stream';
|
||||
if (ext === '.png') return 'image/png';
|
||||
if (ext === '.jpg' || ext === '.jpeg') return 'image/jpeg';
|
||||
if (ext === '.css') return 'text/css; charset=utf-8';
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
|
||||
// Serve static files from rootDir
|
||||
function startStaticServer(rootDir) {
|
||||
const server = http.createServer((req, res) => {
|
||||
try {
|
||||
const urlPath = decodeURIComponent((req.url || '/').split('?')[0]);
|
||||
const safePath = path.normalize(urlPath).replace(/^(\.\.(\/|\\|$))+/, '');
|
||||
const filePath = path.join(rootDir, safePath);
|
||||
|
||||
// Default route
|
||||
const finalPath = fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()
|
||||
? path.join(filePath, 'index.html')
|
||||
: filePath;
|
||||
|
||||
if (!fs.existsSync(finalPath) || !fs.statSync(finalPath).isFile()) {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
res.end('404\n');
|
||||
return;
|
||||
}
|
||||
|
||||
const data = fs.readFileSync(finalPath);
|
||||
res.writeHead(200, { 'Content-Type': mimeTypeFor(finalPath) });
|
||||
res.end(data);
|
||||
} catch (e) {
|
||||
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
res.end(`500\n${String(e)}\n`);
|
||||
}
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
const addr = server.address();
|
||||
resolve({ server, port: addr.port });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const jobPath = process.argv[2];
|
||||
if (!jobPath) die("Usage: node batch_render.js job.json");
|
||||
|
||||
const jobAbs = path.resolve(jobPath);
|
||||
const jobDir = path.dirname(jobAbs);
|
||||
const job = JSON.parse(fs.readFileSync(jobAbs, 'utf8'));
|
||||
|
||||
const profileAbs = path.resolve(jobDir, job.profile ?? die("job.profile missing"));
|
||||
const inputDirAbs = path.resolve(jobDir, job.input_dir ?? die("job.input_dir missing"));
|
||||
const outputDirAbs = path.resolve(jobDir, job.output_dir ?? die("job.output_dir missing"));
|
||||
const pattern = (job.pattern ?? ".glb").toLowerCase();
|
||||
|
||||
ensureDir(outputDirAbs);
|
||||
|
||||
const glbs = listFiles(inputDirAbs, pattern);
|
||||
if (glbs.length === 0) die(`No files ending with '${pattern}' found under ${inputDirAbs}`);
|
||||
|
||||
const renderHtmlAbs = path.resolve(jobDir, 'render.html');
|
||||
if (!fs.existsSync(renderHtmlAbs)) die(`Missing render.html at ${renderHtmlAbs}`);
|
||||
|
||||
// Start local server rooted at jobDir so render.html, libs/, glbs/, profile json are reachable
|
||||
const { server, port } = await startStaticServer(jobDir);
|
||||
const base = `http://127.0.0.1:${port}`;
|
||||
|
||||
// Load profile for viewport sizing
|
||||
const profile = JSON.parse(fs.readFileSync(profileAbs, 'utf8'));
|
||||
const vw = profile.output?.width ?? 1024;
|
||||
const vh = profile.output?.height ?? 768;
|
||||
const dpr = profile.output?.pixelRatio ?? 1;
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
headless: 'new',
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-gpu',
|
||||
'--use-gl=swiftshader',
|
||||
'--enable-unsafe-swiftshader'
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Log page-side failures clearly
|
||||
page.on('console', (msg) => console.log('PAGE console:', msg.type(), msg.text()));
|
||||
page.on('pageerror', (err) => console.log('PAGE error:', err));
|
||||
page.on('requestfailed', (req) => console.log('REQ failed:', req.url(), req.failure()?.errorText));
|
||||
|
||||
await page.setViewport({ width: vw, height: vh, deviceScaleFactor: dpr });
|
||||
|
||||
// Make URLs relative to server root
|
||||
const renderUrl = `${base}/render.html`;
|
||||
const profileUrl = `${base}/${encodeURIComponent(path.relative(jobDir, profileAbs)).replace(/%2F/g,'/')}`;
|
||||
|
||||
for (const glbAbs of glbs) {
|
||||
const rel = path.relative(jobDir, glbAbs);
|
||||
const glbUrl = `${base}/${encodeURIComponent(rel).replace(/%2F/g,'/')}`;
|
||||
|
||||
const outName = sanitizeBasename(glbAbs).replace(/\.glb$/i, '.png');
|
||||
const outAbs = path.join(outputDirAbs, outName);
|
||||
|
||||
const url = `${renderUrl}?glb=${encodeURIComponent(glbUrl)}&profile=${encodeURIComponent(profileUrl)}`;
|
||||
|
||||
// Don’t use networkidle0 here; module imports + GLB load can keep network “busy”
|
||||
await page.goto(url, { waitUntil: 'load' });
|
||||
|
||||
await page.waitForFunction(() => {
|
||||
return window.__RENDER_STATUS__ && window.__RENDER_STATUS__.ready === true;
|
||||
}, { timeout: 120000 }); // 2 minutes, GLBs can be chunky
|
||||
|
||||
const status = await page.evaluate(() => window.__RENDER_STATUS__);
|
||||
if (!status || !status.pngDataUrl) {
|
||||
throw new Error(`No pngDataUrl produced for ${glbAbs} (status=${JSON.stringify(status)})`);
|
||||
}
|
||||
|
||||
const b64 = status.pngDataUrl.replace(/^data:image\/png;base64,/, '');
|
||||
fs.writeFileSync(outAbs, Buffer.from(b64, 'base64'));
|
||||
console.log(`WROTE\t${outAbs}`);
|
||||
}
|
||||
|
||||
await page.close();
|
||||
} finally {
|
||||
await browser.close();
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => { console.error("ERROR:", e); process.exit(2); });
|
||||
6
web/batch_glb_png/job.json
Normal file
6
web/batch_glb_png/job.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"profile": "./three_profile_20260228_111725.json",
|
||||
"input_dir": "./glbs",
|
||||
"output_dir": "./pngs",
|
||||
"pattern": ".glb"
|
||||
}
|
||||
1
web/batch_glb_png/libs/GLTFLoader.js
Symbolic link
1
web/batch_glb_png/libs/GLTFLoader.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../vendor/three/addons/loaders/GLTFLoader.js
|
||||
1
web/batch_glb_png/libs/three.module.js
Symbolic link
1
web/batch_glb_png/libs/three.module.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../vendor/three/build/three.module.js
|
||||
91
web/batch_glb_png/link_glbs.sh
Executable file
91
web/batch_glb_png/link_glbs.sh
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
#!/bin/sh
|
||||
# 20260228 ChatGPT
|
||||
# $Header$
|
||||
#
|
||||
# Copy/paste:
|
||||
# cd ~/work/Voron/renderlab/web/batch_glb_png
|
||||
# chmod +x link_glbs.sh
|
||||
# ./link_glbs.sh /home/jlpoole/work/Voron/test1
|
||||
#
|
||||
# This creates symlinks under ./glbs/ pointing to every *.glb under ROOT.
|
||||
|
||||
set -eu
|
||||
|
||||
ROOT="${1:-}"
|
||||
[ -n "$ROOT" ] || { echo "Usage: $0 /path/to/root" >&2; exit 2; }
|
||||
[ -d "$ROOT" ] || { echo "ERROR: not a directory: $ROOT" >&2; exit 2; }
|
||||
|
||||
OUTDIR="./glbs"
|
||||
mkdir -p "$OUTDIR"
|
||||
|
||||
ts="$(date +%Y%m%d_%H%M%S)"
|
||||
log="link_glbs_${ts}.log"
|
||||
|
||||
# Make ROOT absolute and strip any trailing slash for consistent relpath math.
|
||||
ROOT_ABS="$(cd "$ROOT" && pwd)"
|
||||
ROOT_ABS="${ROOT_ABS%/}"
|
||||
|
||||
echo "ROOT: $ROOT_ABS" | tee "$log"
|
||||
echo "OUTDIR: $(cd "$OUTDIR" && pwd)" | tee -a "$log"
|
||||
echo "LOG: $log" | tee -a "$log"
|
||||
echo "" | tee -a "$log"
|
||||
|
||||
# Sanitize: turn a path into a filesystem-safe basename.
|
||||
# Example:
|
||||
# Klicky-Probe/Printers/Voron/.../Dock_mount_fixed_v2.stl.glb
|
||||
# becomes:
|
||||
# Klicky-Probe__Printers__Voron__...__Dock_mount_fixed_v2.stl.glb
|
||||
sanitize() {
|
||||
# shellcheck disable=SC2001
|
||||
echo "$1" \
|
||||
| sed 's|^/||' \
|
||||
| sed 's|/|__|g' \
|
||||
| sed 's|[^A-Za-z0-9._-]|_|g'
|
||||
}
|
||||
|
||||
count=0
|
||||
skipped=0
|
||||
collisions=0
|
||||
|
||||
# Use -print0 to handle spaces safely.
|
||||
find "$ROOT_ABS" -type f -name '*.glb' -print0 \
|
||||
| while IFS= read -r -d '' f; do
|
||||
# Compute relative path under ROOT_ABS
|
||||
rel="${f#$ROOT_ABS/}"
|
||||
|
||||
name="$(sanitize "$rel")"
|
||||
linkpath="$OUTDIR/$name"
|
||||
|
||||
# If the link exists and points to the same target, skip quietly.
|
||||
if [ -L "$linkpath" ]; then
|
||||
target="$(readlink "$linkpath" || true)"
|
||||
if [ "$target" = "$f" ]; then
|
||||
echo "SKIP (already linked): $linkpath -> $f" >> "$log"
|
||||
skipped=$((skipped+1))
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# If the name already exists but points elsewhere, disambiguate.
|
||||
if [ -e "$linkpath" ]; then
|
||||
i=1
|
||||
base="$linkpath"
|
||||
while [ -e "$linkpath" ]; do
|
||||
linkpath="${base%.glb}_$i.glb"
|
||||
i=$((i+1))
|
||||
done
|
||||
collisions=$((collisions+1))
|
||||
fi
|
||||
|
||||
ln -s "$f" "$linkpath"
|
||||
echo "LINK: $linkpath -> $f" >> "$log"
|
||||
count=$((count+1))
|
||||
done
|
||||
|
||||
# The while loop runs in a subshell in many /bin/sh implementations,
|
||||
# so counters above may not update. Summarize by counting log lines instead.
|
||||
linked_lines="$(grep -c '^LINK: ' "$log" 2>/dev/null || echo 0)"
|
||||
skipped_lines="$(grep -c '^SKIP ' "$log" 2>/dev/null || echo 0)"
|
||||
|
||||
echo "" | tee -a "$log"
|
||||
echo "DONE. linked=$linked_lines skipped=$skipped_lines (details in $log)" | tee -a "$log"
|
||||
135
web/batch_glb_png/link_glbs_20260228_152056.log
Normal file
135
web/batch_glb_png/link_glbs_20260228_152056.log
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
ROOT: /home/jlpoole/work/Voron/test1
|
||||
OUTDIR: /home/jlpoole/work/Voron/renderlab/web/batch_glb_png/glbs
|
||||
LOG: link_glbs_20260228_152056.log
|
||||
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Dock_mount_fixed_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Dock_mount_fixed_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Dock_sidemount_fixed_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Dock_sidemount_fixed_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Dock_sidemount_left_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Dock_sidemount_left_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Dock_sidemount_right_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Dock_sidemount_right_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__KlickyProbe_AB_mount_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/KlickyProbe_AB_mount_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Mount_magnet_holder.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Mount_magnet_holder.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Mount_magnet_pressfit_helper.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Mount_magnet_pressfit_helper.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Printers__Voron__v1.8_v2.4_Legacy_Trident__v1.8_v2.4_Legacy_Trident_STL__Mount_pressfit_holder_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Printers/Voron/v1.8_v2.4_Legacy_Trident/v1.8_v2.4_Legacy_Trident_STL/Mount_pressfit_holder_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__1mm_Spacer.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/1mm_Spacer.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__KlickyProbe_v2.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/KlickyProbe_v2.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__Probe_Dock_v2.1.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/Probe_Dock_v2.1.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__Probe_magnet_holder.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/Probe_magnet_holder.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__Probe_magnet_pressfit_helper.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/Probe_magnet_pressfit_helper.stl.glb
|
||||
LINK: ./glbs/Klicky-Probe__Probes__KlickyProbe__STL__Probe_pressfit_holder.stl.glb -> /home/jlpoole/work/Voron/test1/Klicky-Probe/Probes/KlickyProbe/STL/Probe_pressfit_holder.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__COB_Light_Strip__cob_light_strip_mount_100mm.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/COB Light Strip/cob_light_strip_mount_100mm.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__COB_Light_Strip__cob_light_strip_mount_150mm.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/COB Light Strip/cob_light_strip_mount_150mm.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__COB_Light_Strip__cob_light_strip_mount_50mm.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/COB Light Strip/cob_light_strip_mount_50mm.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__LDO_Door__handle_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/LDO Door/handle_a_x2.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__LDO_Door__handle_b.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/LDO Door/handle_b.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__LDO_Door__handle_b_nameplate.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/LDO Door/handle_b_nameplate.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__LDO_Door__screw_hinge_x3.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/LDO Door/screw_hinge_x3.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__exhaust_cover.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/exhaust_cover.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__handlebar_spacer_x4.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/handlebar_spacer_x4.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__ldo_bestagon_insert.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/ldo_bestagon_insert.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__led_fan_pcb_spacer_x2.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/led_fan_pcb_spacer_x2.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__nozzle_probe_ldo.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/nozzle_probe_ldo.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__z_belt_cover_a_led.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/z_belt_cover_a_led.stl.glb
|
||||
LINK: ./glbs/LDOVoron2__STLs__z_rail_stop_x4.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoron2/STLs/z_rail_stop_x4.stl.glb
|
||||
LINK: ./glbs/LDOVoronTrident__STLs__BTT_Pi_TFT4.3_Mount___a__faceplate.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoronTrident/STLs/BTT Pi TFT4.3 Mount/[a]_faceplate.stl.glb
|
||||
LINK: ./glbs/LDOVoronTrident__STLs__BTT_Pi_TFT4.3_Mount__mount.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoronTrident/STLs/BTT Pi TFT4.3 Mount/mount.stl.glb
|
||||
LINK: ./glbs/LDOVoronTrident__STLs__bed_wago_mount.stl.glb -> /home/jlpoole/work/Voron/test1/LDOVoronTrident/STLs/bed_wago_mount.stl.glb
|
||||
LINK: ./glbs/Leviathan__STLs__Leviathan_bracket_set.stl.glb -> /home/jlpoole/work/Voron/test1/Leviathan/STLs/Leviathan_bracket_set.stl.glb
|
||||
LINK: ./glbs/Nitehawk-SB__STLs__cw2_captive_pcb_cover.stl.glb -> /home/jlpoole/work/Voron/test1/Nitehawk-SB/STLs/cw2_captive_pcb_cover.stl.glb
|
||||
LINK: ./glbs/Nitehawk-SB__STLs__usb_adapter_mount.stl.glb -> /home/jlpoole/work/Voron/test1/Nitehawk-SB/STLs/usb_adapter_mount.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Electronics_Bay__lrs_200_psu_bracket_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Electronics_Bay/lrs_200_psu_bracket_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Electronics_Bay__pcb_din_clip_x3.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Electronics_Bay/pcb_din_clip_x3.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Electronics_Bay__wago_221-415_mount_3by5.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Electronics_Bay/wago_221-415_mount_3by5.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Exhaust_Filter__exhaust_filter_grill.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Exhaust_Filter/exhaust_filter_grill.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units___a__cable_cover.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/[a]_cable_cover.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units___a__z_chain_retainer_bracket_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/[a]_z_chain_retainer_bracket_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units__a_drive_frame_lower.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/a_drive_frame_lower.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units__a_drive_frame_upper.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/a_drive_frame_upper.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units__b_drive_frame_lower.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/b_drive_frame_lower.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__AB_Drive_Units__b_drive_frame_upper.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/AB_Drive_Units/b_drive_frame_upper.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers___a__tensioner_left.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/[a]_tensioner_left.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers___a__tensioner_right.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/[a]_tensioner_right.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers__front_idler_left_lower.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/front_idler_left_lower.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers__front_idler_left_upper.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/front_idler_left_upper.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers__front_idler_right_lower.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/front_idler_right_lower.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Front_Idlers__front_idler_right_upper.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Front_Idlers/front_idler_right_upper.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints___a__endstop_pod_D2F_switch.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/[a]_endstop_pod_D2F_switch.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints___a__xy_joint_cable_bridge_2hole.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/[a]_xy_joint_cable_bridge_2hole.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints__xy_joint_left_lower_MGN12.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/xy_joint_left_lower_MGN12.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints__xy_joint_left_upper_MGN12.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/xy_joint_left_upper_MGN12.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints__xy_joint_right_lower_MGN12.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/xy_joint_right_lower_MGN12.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__XY_Joints__xy_joint_right_upper_MGN12.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/XY_Joints/xy_joint_right_upper_MGN12.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__X_Carriage__probe_retainer_bracket.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/X_Carriage/probe_retainer_bracket.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__X_Carriage__x_frame_V2TR_MGN12_left.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/X_Carriage/x_frame_V2TR_MGN12_left.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__X_Axis__X_Carriage__x_frame_V2TR_MGN12_right.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/X_Axis/X_Carriage/x_frame_V2TR_MGN12_right.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Z_Joints__z_joint_lower_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Z_Joints/z_joint_lower_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__Z_Joints__z_joint_upper_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/Z_Joints/z_joint_upper_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry___a__z_belt_clip_lower_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/[a]_z_belt_clip_lower_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry___a__z_belt_clip_upper_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/[a]_z_belt_clip_upper_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__z_chain_bottom_anchor.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/z_chain_bottom_anchor.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Gantry__z_chain_guide.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Gantry/z_chain_guide.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__Front_Doors__latch_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/Front_Doors/latch_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__bottom_panel_clip_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/bottom_panel_clip_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__bottom_panel_hinge_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/bottom_panel_hinge_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__corner_panel_clip_4mm_x8.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/corner_panel_clip_4mm_x8.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__corner_panel_clip_6mm_x8.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/corner_panel_clip_6mm_x8.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__deck_support_4mm_x8.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/deck_support_4mm_x8.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__midspan_panel_clip_4mm_x7.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/midspan_panel_clip_4mm_x7.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__midspan_panel_clip_6mm_x8.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/midspan_panel_clip_6mm_x8.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__z_belt_cover_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/z_belt_cover_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Panel_Mounting__z_belt_cover_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Panel_Mounting/z_belt_cover_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__300__front_skirt_a_300.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/300/front_skirt_a_300.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__300__front_skirt_b_300.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/300/front_skirt_b_300.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__300__rear_center_skirt_300.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/300/rear_center_skirt_300.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__300__side_skirt_a_300_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/300/side_skirt_a_300_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__300__side_skirt_b_300_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/300/side_skirt_b_300_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__350__front_skirt_a_350.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/350/front_skirt_a_350.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__350__front_skirt_b_350.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/350/front_skirt_b_350.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__350__rear_center_skirt_350.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/350/rear_center_skirt_350.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__350__side_skirt_a_350_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/350/side_skirt_a_350_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__350__side_skirt_b_350_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/350/side_skirt_b_350_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__belt_guard_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_belt_guard_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__belt_guard_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_belt_guard_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__fan_grill_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_fan_grill_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__fan_grill_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_fan_grill_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__fan_grill_open_optional_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_fan_grill_open_optional_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__fan_grill_retainer_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_fan_grill_retainer_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts___a__keystone_blank_insert.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/[a]_keystone_blank_insert.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__keystone_panel.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/keystone_panel.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__power_inlet_IECGS_1mm.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/power_inlet_IECGS_1mm.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Skirts__side_fan_support_x2.STL.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Skirts/side_fan_support_x2.STL.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Spool_Management__bowden_retainer.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Spool_Management/bowden_retainer.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Spool_Management__spool_holder.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Spool_Management/spool_holder.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Test_Prints__Heatset_Practice.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Test_Prints/Heatset_Practice.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Tools__MGN12_rail_guide_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Tools/MGN12_rail_guide_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Tools__MGN9_rail_guide_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Tools/MGN9_rail_guide_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Tools__pulley_jig.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Tools/pulley_jig.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive___a__belt_tensioner_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/[a]_belt_tensioner_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive___a__belt_tensioner_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/[a]_belt_tensioner_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive___a__z_drive_baseplate_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/[a]_z_drive_baseplate_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive___a__z_drive_baseplate_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/[a]_z_drive_baseplate_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_drive_main_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_drive_main_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_drive_main_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_drive_main_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_drive_retainer_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_drive_retainer_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_drive_retainer_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_drive_retainer_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_motor_mount_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_motor_mount_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Drive__z_motor_mount_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Drive/z_motor_mount_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Idlers___a__z_tensioner_9mm_x4.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Idlers/[a]_z_tensioner_9mm_x4.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Idlers__z_tensioner_bracket_a_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Idlers/z_tensioner_bracket_a_x2.stl.glb
|
||||
LINK: ./glbs/Voron-2__STLs__Z_Idlers__z_tensioner_bracket_b_x2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-2/STLs/Z_Idlers/z_tensioner_bracket_b_x2.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive___a__guidler_a.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/[a]_guidler_a.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive___a__guidler_b.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/[a]_guidler_b.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive___a__latch.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/[a]_latch.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive___a__latch_shuttle.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/[a]_latch_shuttle.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive__main_body.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/main_body.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__Direct_Drive__motor_plate.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/Direct_Drive/motor_plate.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2___a__pcb_spacer.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/[a]_pcb_spacer.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Clockwork2__chain_anchor_2hole.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Clockwork2/chain_anchor_2hole.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner__Printheads__revo_voron__stealthburner_printhead_revo_voron_front.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/Printheads/revo_voron/stealthburner_printhead_revo_voron_front.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner__Printheads__revo_voron__stealthburner_printhead_revo_voron_rear_cw2.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/Printheads/revo_voron/stealthburner_printhead_revo_voron_rear_cw2.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner___a__stealthburner_main_body.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/[a]_stealthburner_main_body.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner___c__stealthburner_LED_diffuser.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/[c]_stealthburner_LED_diffuser.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner___o__stealthburner_LED_carrier.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/[o]_stealthburner_LED_carrier.stl.glb
|
||||
LINK: ./glbs/Voron-Stealthburner__STLs__Stealthburner___o__stealthburner_LED_diffuser_mask.stl.glb -> /home/jlpoole/work/Voron/test1/Voron-Stealthburner/STLs/Stealthburner/[o]_stealthburner_LED_diffuser_mask.stl.glb
|
||||
|
||||
DONE. linked=128 skipped=0
|
||||
0 (details in link_glbs_20260228_152056.log)
|
||||
5
web/batch_glb_png/node_modules/.gitignore
generated
vendored
Normal file
5
web/batch_glb_png/node_modules/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.bin
|
||||
.modules.yaml
|
||||
.pnpm
|
||||
.pnpm-workspace-state-v1.json
|
||||
puppeteer
|
||||
7
web/batch_glb_png/package.json
Normal file
7
web/batch_glb_png/package.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "batch_glb_png",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"puppeteer": "^24.37.5"
|
||||
}
|
||||
}
|
||||
868
web/batch_glb_png/pnpm-lock.yaml
generated
Normal file
868
web/batch_glb_png/pnpm-lock.yaml
generated
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
puppeteer:
|
||||
specifier: ^24.37.5
|
||||
version: 24.37.5
|
||||
|
||||
packages:
|
||||
|
||||
'@babel/code-frame@7.29.0':
|
||||
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5':
|
||||
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@puppeteer/browsers@2.13.0':
|
||||
resolution: {integrity: sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@tootallnate/quickjs-emscripten@0.23.0':
|
||||
resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
|
||||
|
||||
'@types/node@25.3.2':
|
||||
resolution: {integrity: sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q==}
|
||||
|
||||
'@types/yauzl@2.10.3':
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
|
||||
agent-base@7.1.4:
|
||||
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
ast-types@0.13.4:
|
||||
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
b4a@1.8.0:
|
||||
resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==}
|
||||
peerDependencies:
|
||||
react-native-b4a: '*'
|
||||
peerDependenciesMeta:
|
||||
react-native-b4a:
|
||||
optional: true
|
||||
|
||||
bare-events@2.8.2:
|
||||
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==}
|
||||
peerDependencies:
|
||||
bare-abort-controller: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-abort-controller:
|
||||
optional: true
|
||||
|
||||
bare-fs@4.5.5:
|
||||
resolution: {integrity: sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==}
|
||||
engines: {bare: '>=1.16.0'}
|
||||
peerDependencies:
|
||||
bare-buffer: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-buffer:
|
||||
optional: true
|
||||
|
||||
bare-os@3.7.0:
|
||||
resolution: {integrity: sha512-64Rcwj8qlnTZU8Ps6JJEdSmxBEUGgI7g8l+lMtsJLl4IsfTcHMTfJ188u2iGV6P6YPRZrtv72B2kjn+hp+Yv3g==}
|
||||
engines: {bare: '>=1.14.0'}
|
||||
|
||||
bare-path@3.0.0:
|
||||
resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
|
||||
|
||||
bare-stream@2.8.0:
|
||||
resolution: {integrity: sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==}
|
||||
peerDependencies:
|
||||
bare-buffer: '*'
|
||||
bare-events: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-buffer:
|
||||
optional: true
|
||||
bare-events:
|
||||
optional: true
|
||||
|
||||
bare-url@2.3.2:
|
||||
resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==}
|
||||
|
||||
basic-ftp@5.2.0:
|
||||
resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
buffer-crc32@0.2.13:
|
||||
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
|
||||
|
||||
callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
chromium-bidi@14.0.0:
|
||||
resolution: {integrity: sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==}
|
||||
peerDependencies:
|
||||
devtools-protocol: '*'
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
cosmiconfig@9.0.0:
|
||||
resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.9.5'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
data-uri-to-buffer@6.0.2:
|
||||
resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
degenerator@5.0.1:
|
||||
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
devtools-protocol@0.0.1566079:
|
||||
resolution: {integrity: sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
end-of-stream@1.4.5:
|
||||
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
||||
|
||||
env-paths@2.2.1:
|
||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
error-ex@1.3.4:
|
||||
resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
|
||||
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escodegen@2.1.0:
|
||||
resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
|
||||
engines: {node: '>=6.0'}
|
||||
hasBin: true
|
||||
|
||||
esprima@4.0.1:
|
||||
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
estraverse@5.3.0:
|
||||
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
|
||||
engines: {node: '>=4.0'}
|
||||
|
||||
esutils@2.0.3:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
events-universal@1.0.1:
|
||||
resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==}
|
||||
|
||||
extract-zip@2.0.1:
|
||||
resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
|
||||
engines: {node: '>= 10.17.0'}
|
||||
hasBin: true
|
||||
|
||||
fast-fifo@1.3.2:
|
||||
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
|
||||
|
||||
fd-slicer@1.1.0:
|
||||
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
get-stream@5.2.0:
|
||||
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
get-uri@6.0.5:
|
||||
resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
http-proxy-agent@7.0.2:
|
||||
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
https-proxy-agent@7.0.6:
|
||||
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
ip-address@10.1.0:
|
||||
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||
hasBin: true
|
||||
|
||||
json-parse-even-better-errors@2.3.1:
|
||||
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
|
||||
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
lru-cache@7.18.3:
|
||||
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
netmask@2.0.2:
|
||||
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
|
||||
once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
|
||||
pac-proxy-agent@7.2.0:
|
||||
resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
pac-resolver@7.0.1:
|
||||
resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
parse-json@5.2.0:
|
||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
pend@1.2.0:
|
||||
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
progress@2.0.3:
|
||||
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
proxy-agent@6.5.0:
|
||||
resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
pump@3.0.4:
|
||||
resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
|
||||
|
||||
puppeteer-core@24.37.5:
|
||||
resolution: {integrity: sha512-ybL7iE78YPN4T6J+sPLO7r0lSByp/0NN6PvfBEql219cOnttoTFzCWKiBOjstXSqi/OKpwae623DWAsL7cn2MQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
puppeteer@24.37.5:
|
||||
resolution: {integrity: sha512-3PAOIQLceyEmn1Fi76GkGO2EVxztv5OtdlB1m8hMUZL3f8KDHnlvXbvCXv+Ls7KzF1R0KdKBqLuT/Hhrok12hQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
smart-buffer@4.2.0:
|
||||
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
||||
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
||||
|
||||
socks-proxy-agent@8.0.5:
|
||||
resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
socks@2.8.7:
|
||||
resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==}
|
||||
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
|
||||
|
||||
source-map@0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
streamx@2.23.0:
|
||||
resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
tar-fs@3.1.1:
|
||||
resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==}
|
||||
|
||||
tar-stream@3.1.8:
|
||||
resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==}
|
||||
|
||||
teex@1.0.1:
|
||||
resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==}
|
||||
|
||||
text-decoder@1.2.7:
|
||||
resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
typed-query-selector@2.12.1:
|
||||
resolution: {integrity: sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==}
|
||||
|
||||
undici-types@7.18.2:
|
||||
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
||||
|
||||
webdriver-bidi-protocol@0.4.1:
|
||||
resolution: {integrity: sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
ws@8.19.0:
|
||||
resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yauzl@2.10.0:
|
||||
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
|
||||
|
||||
zod@3.25.76:
|
||||
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@babel/code-frame@7.29.0':
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
js-tokens: 4.0.0
|
||||
picocolors: 1.1.1
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5': {}
|
||||
|
||||
'@puppeteer/browsers@2.13.0':
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
extract-zip: 2.0.1
|
||||
progress: 2.0.3
|
||||
proxy-agent: 6.5.0
|
||||
semver: 7.7.4
|
||||
tar-fs: 3.1.1
|
||||
yargs: 17.7.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
|
||||
'@tootallnate/quickjs-emscripten@0.23.0': {}
|
||||
|
||||
'@types/node@25.3.2':
|
||||
dependencies:
|
||||
undici-types: 7.18.2
|
||||
optional: true
|
||||
|
||||
'@types/yauzl@2.10.3':
|
||||
dependencies:
|
||||
'@types/node': 25.3.2
|
||||
optional: true
|
||||
|
||||
agent-base@7.1.4: {}
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
ast-types@0.13.4:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
b4a@1.8.0: {}
|
||||
|
||||
bare-events@2.8.2: {}
|
||||
|
||||
bare-fs@4.5.5:
|
||||
dependencies:
|
||||
bare-events: 2.8.2
|
||||
bare-path: 3.0.0
|
||||
bare-stream: 2.8.0(bare-events@2.8.2)
|
||||
bare-url: 2.3.2
|
||||
fast-fifo: 1.3.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
bare-os@3.7.0: {}
|
||||
|
||||
bare-path@3.0.0:
|
||||
dependencies:
|
||||
bare-os: 3.7.0
|
||||
|
||||
bare-stream@2.8.0(bare-events@2.8.2):
|
||||
dependencies:
|
||||
streamx: 2.23.0
|
||||
teex: 1.0.1
|
||||
optionalDependencies:
|
||||
bare-events: 2.8.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
bare-url@2.3.2:
|
||||
dependencies:
|
||||
bare-path: 3.0.0
|
||||
|
||||
basic-ftp@5.2.0: {}
|
||||
|
||||
buffer-crc32@0.2.13: {}
|
||||
|
||||
callsites@3.1.0: {}
|
||||
|
||||
chromium-bidi@14.0.0(devtools-protocol@0.0.1566079):
|
||||
dependencies:
|
||||
devtools-protocol: 0.0.1566079
|
||||
mitt: 3.0.1
|
||||
zod: 3.25.76
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
cosmiconfig@9.0.0:
|
||||
dependencies:
|
||||
env-paths: 2.2.1
|
||||
import-fresh: 3.3.1
|
||||
js-yaml: 4.1.1
|
||||
parse-json: 5.2.0
|
||||
|
||||
data-uri-to-buffer@6.0.2: {}
|
||||
|
||||
debug@4.4.3:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
degenerator@5.0.1:
|
||||
dependencies:
|
||||
ast-types: 0.13.4
|
||||
escodegen: 2.1.0
|
||||
esprima: 4.0.1
|
||||
|
||||
devtools-protocol@0.0.1566079: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
end-of-stream@1.4.5:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
|
||||
env-paths@2.2.1: {}
|
||||
|
||||
error-ex@1.3.4:
|
||||
dependencies:
|
||||
is-arrayish: 0.2.1
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escodegen@2.1.0:
|
||||
dependencies:
|
||||
esprima: 4.0.1
|
||||
estraverse: 5.3.0
|
||||
esutils: 2.0.3
|
||||
optionalDependencies:
|
||||
source-map: 0.6.1
|
||||
|
||||
esprima@4.0.1: {}
|
||||
|
||||
estraverse@5.3.0: {}
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
events-universal@1.0.1:
|
||||
dependencies:
|
||||
bare-events: 2.8.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
|
||||
extract-zip@2.0.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
get-stream: 5.2.0
|
||||
yauzl: 2.10.0
|
||||
optionalDependencies:
|
||||
'@types/yauzl': 2.10.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
fast-fifo@1.3.2: {}
|
||||
|
||||
fd-slicer@1.1.0:
|
||||
dependencies:
|
||||
pend: 1.2.0
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
get-stream@5.2.0:
|
||||
dependencies:
|
||||
pump: 3.0.4
|
||||
|
||||
get-uri@6.0.5:
|
||||
dependencies:
|
||||
basic-ftp: 5.2.0
|
||||
data-uri-to-buffer: 6.0.2
|
||||
debug: 4.4.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
http-proxy-agent@7.0.2:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
https-proxy-agent@7.0.6:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
import-fresh@3.3.1:
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
|
||||
ip-address@10.1.0: {}
|
||||
|
||||
is-arrayish@0.2.1: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
json-parse-even-better-errors@2.3.1: {}
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
lru-cache@7.18.3: {}
|
||||
|
||||
mitt@3.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
netmask@2.0.2: {}
|
||||
|
||||
once@1.4.0:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
pac-proxy-agent@7.2.0:
|
||||
dependencies:
|
||||
'@tootallnate/quickjs-emscripten': 0.23.0
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.3
|
||||
get-uri: 6.0.5
|
||||
http-proxy-agent: 7.0.2
|
||||
https-proxy-agent: 7.0.6
|
||||
pac-resolver: 7.0.1
|
||||
socks-proxy-agent: 8.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
pac-resolver@7.0.1:
|
||||
dependencies:
|
||||
degenerator: 5.0.1
|
||||
netmask: 2.0.2
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
|
||||
parse-json@5.2.0:
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.0
|
||||
error-ex: 1.3.4
|
||||
json-parse-even-better-errors: 2.3.1
|
||||
lines-and-columns: 1.2.4
|
||||
|
||||
pend@1.2.0: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
progress@2.0.3: {}
|
||||
|
||||
proxy-agent@6.5.0:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.3
|
||||
http-proxy-agent: 7.0.2
|
||||
https-proxy-agent: 7.0.6
|
||||
lru-cache: 7.18.3
|
||||
pac-proxy-agent: 7.2.0
|
||||
proxy-from-env: 1.1.0
|
||||
socks-proxy-agent: 8.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
pump@3.0.4:
|
||||
dependencies:
|
||||
end-of-stream: 1.4.5
|
||||
once: 1.4.0
|
||||
|
||||
puppeteer-core@24.37.5:
|
||||
dependencies:
|
||||
'@puppeteer/browsers': 2.13.0
|
||||
chromium-bidi: 14.0.0(devtools-protocol@0.0.1566079)
|
||||
debug: 4.4.3
|
||||
devtools-protocol: 0.0.1566079
|
||||
typed-query-selector: 2.12.1
|
||||
webdriver-bidi-protocol: 0.4.1
|
||||
ws: 8.19.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
puppeteer@24.37.5:
|
||||
dependencies:
|
||||
'@puppeteer/browsers': 2.13.0
|
||||
chromium-bidi: 14.0.0(devtools-protocol@0.0.1566079)
|
||||
cosmiconfig: 9.0.0
|
||||
devtools-protocol: 0.0.1566079
|
||||
puppeteer-core: 24.37.5
|
||||
typed-query-selector: 2.12.1
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
|
||||
smart-buffer@4.2.0: {}
|
||||
|
||||
socks-proxy-agent@8.0.5:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.3
|
||||
socks: 2.8.7
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
socks@2.8.7:
|
||||
dependencies:
|
||||
ip-address: 10.1.0
|
||||
smart-buffer: 4.2.0
|
||||
|
||||
source-map@0.6.1:
|
||||
optional: true
|
||||
|
||||
streamx@2.23.0:
|
||||
dependencies:
|
||||
events-universal: 1.0.1
|
||||
fast-fifo: 1.3.2
|
||||
text-decoder: 1.2.7
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
tar-fs@3.1.1:
|
||||
dependencies:
|
||||
pump: 3.0.4
|
||||
tar-stream: 3.1.8
|
||||
optionalDependencies:
|
||||
bare-fs: 4.5.5
|
||||
bare-path: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
tar-stream@3.1.8:
|
||||
dependencies:
|
||||
b4a: 1.8.0
|
||||
bare-fs: 4.5.5
|
||||
fast-fifo: 1.3.2
|
||||
streamx: 2.23.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
teex@1.0.1:
|
||||
dependencies:
|
||||
streamx: 2.23.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
text-decoder@1.2.7:
|
||||
dependencies:
|
||||
b4a: 1.8.0
|
||||
transitivePeerDependencies:
|
||||
- react-native-b4a
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
typed-query-selector@2.12.1: {}
|
||||
|
||||
undici-types@7.18.2:
|
||||
optional: true
|
||||
|
||||
webdriver-bidi-protocol@0.4.1: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
ws@8.19.0: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yauzl@2.10.0:
|
||||
dependencies:
|
||||
buffer-crc32: 0.2.13
|
||||
fd-slicer: 1.1.0
|
||||
|
||||
zod@3.25.76: {}
|
||||
2
web/batch_glb_png/pnpm-workspace.yaml
Normal file
2
web/batch_glb_png/pnpm-workspace.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
onlyBuiltDependencies:
|
||||
- puppeteer
|
||||
153
web/batch_glb_png/render.html
Normal file
153
web/batch_glb_png/render.html
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Headless GLB Renderer</title>
|
||||
<style>
|
||||
html, body { margin:0; padding:0; background:#fff; overflow:hidden; }
|
||||
canvas { display:block; }
|
||||
</style>
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "./libs/three.module.js",
|
||||
"three/addons/": "./vendor/three/addons/"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
|
||||
function qs (k) { return new URLSearchParams(location.search).get(k); }
|
||||
|
||||
const glbUrl = qs('glb');
|
||||
const profileUrl = qs('profile');
|
||||
|
||||
window.__RENDER_STATUS__ = { ready:false, error:null, pngDataUrl:null };
|
||||
|
||||
if (!glbUrl || !profileUrl) {
|
||||
window.__RENDER_STATUS__.error = "Missing ?glb=... or ?profile=...";
|
||||
throw new Error(window.__RENDER_STATUS__.error);
|
||||
}
|
||||
|
||||
const profile = await (await fetch(profileUrl)).json();
|
||||
|
||||
// Renderer
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
preserveDrawingBuffer: true,
|
||||
alpha: false
|
||||
});
|
||||
renderer.setPixelRatio(profile.output?.pixelRatio ?? 1);
|
||||
renderer.setSize(profile.output?.width ?? 1024, profile.output?.height ?? 768, false);
|
||||
|
||||
// Three r152+ color management (safe-guard)
|
||||
if (THREE.SRGBColorSpace) renderer.outputColorSpace = THREE.SRGBColorSpace;
|
||||
|
||||
const bg = profile.scene?.background ?? 0xffffff;
|
||||
renderer.setClearColor(bg, 1);
|
||||
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
// Scene
|
||||
const scene = new THREE.Scene();
|
||||
|
||||
// Camera
|
||||
const cam = new THREE.PerspectiveCamera(
|
||||
profile.camera?.fov ?? 50,
|
||||
(profile.output?.width ?? 1024) / (profile.output?.height ?? 768),
|
||||
profile.camera?.near ?? 0.1,
|
||||
profile.camera?.far ?? 1000
|
||||
);
|
||||
cam.position.fromArray(profile.camera?.position ?? [0,0,10]);
|
||||
cam.up.fromArray(profile.camera?.up ?? [0,1,0]);
|
||||
|
||||
// We won’t use OrbitControls in headless; we just mimic its target by looking at it.
|
||||
const target = new THREE.Vector3().fromArray(profile.controls?.target ?? [0,0,0]);
|
||||
cam.lookAt(target);
|
||||
cam.updateProjectionMatrix();
|
||||
|
||||
// Lights
|
||||
const dir = new THREE.DirectionalLight(0xffffff, profile.lights?.directional?.intensity ?? 2.0);
|
||||
dir.position.fromArray(profile.lights?.directional?.position ?? [5,5,5]);
|
||||
scene.add(dir);
|
||||
|
||||
const amb = new THREE.AmbientLight(0xffffff, profile.lights?.ambient?.intensity ?? 0.5);
|
||||
scene.add(amb);
|
||||
|
||||
// Load GLB
|
||||
const loader = new GLTFLoader();
|
||||
const gltf = await loader.loadAsync(glbUrl);
|
||||
const root = gltf.scene;
|
||||
scene.add(root);
|
||||
|
||||
// --- Fit-to-frame while keeping the profile's viewing direction ---
|
||||
const box = new THREE.Box3().setFromObject(root);
|
||||
const size = box.getSize(new THREE.Vector3());
|
||||
const center = box.getCenter(new THREE.Vector3());
|
||||
|
||||
// Use profile target if present, but still re-center model so target makes sense
|
||||
const profTarget = new THREE.Vector3().fromArray(profile.controls?.target ?? [0, 0, 0]);
|
||||
|
||||
// Shift the model so its center sits at the profile target (usually [0,0,0] or your saved target)
|
||||
root.position.sub(center).add(profTarget);
|
||||
|
||||
// Recompute bounds after shifting
|
||||
const box2 = new THREE.Box3().setFromObject(root);
|
||||
const size2 = box2.getSize(new THREE.Vector3());
|
||||
const center2 = box2.getCenter(new THREE.Vector3());
|
||||
|
||||
// Keep the same view direction as the profile camera->target vector
|
||||
const profCamPos = new THREE.Vector3().fromArray(profile.camera?.position ?? [0, 0, 10]);
|
||||
const viewDir = profCamPos.clone().sub(profTarget).normalize();
|
||||
|
||||
// Compute distance so the whole object fits the camera FOV
|
||||
|
||||
const maxDim = Math.max(size2.x, size2.y, size2.z, 1e-6);
|
||||
const fov = cam.fov * (Math.PI / 180);
|
||||
const fitPadding = profile.camera?.fitPadding ?? 1.15; // you can add this to JSON later
|
||||
const distance = (maxDim / 2) / Math.tan(fov / 2) * fitPadding;
|
||||
|
||||
// Position camera and aim
|
||||
cam.position.copy(center2).add(viewDir.multiplyScalar(distance));
|
||||
cam.lookAt(center2);
|
||||
cam.updateProjectionMatrix();
|
||||
|
||||
// Adjust near/far safely
|
||||
cam.near = Math.max(0.01, distance / 100);
|
||||
cam.far = distance * 100;
|
||||
cam.updateProjectionMatrix();
|
||||
|
||||
// Apply renderParams
|
||||
const wireframe = !!profile.renderParams?.wireframe;
|
||||
root.traverse((obj) => {
|
||||
if (obj.isMesh && obj.material) {
|
||||
// If multi-material
|
||||
if (Array.isArray(obj.material)) {
|
||||
obj.material.forEach(m => { m.wireframe = wireframe; m.needsUpdate = true; });
|
||||
} else {
|
||||
obj.material.wireframe = wireframe;
|
||||
obj.material.needsUpdate = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: edges overlay if you later add it (kept off unless you implement lines).
|
||||
// profile.renderParams.edgeAngle is available; current lab.html uses it to build edges.
|
||||
|
||||
renderer.render(scene, cam);
|
||||
|
||||
// Give the GPU a beat (helps on some headless setups)
|
||||
await new Promise(r => setTimeout(r, 50));
|
||||
|
||||
window.__RENDER_STATUS__.pngDataUrl = renderer.domElement.toDataURL('image/png');
|
||||
window.__RENDER_STATUS__.ready = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
52
web/batch_glb_png/three_profile_20260228_111725.json
Normal file
52
web/batch_glb_png/three_profile_20260228_111725.json
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"provenance": "lab.html exportProfile Sat Feb 28 2026 11:17:25 GMT-0800 (Pacific Standard Time)",
|
||||
"output": {
|
||||
"width": 1227,
|
||||
"height": 994,
|
||||
"pixelRatio": 1
|
||||
},
|
||||
"scene": {
|
||||
"background": 16777215
|
||||
},
|
||||
"camera": {
|
||||
"type": "PerspectiveCamera",
|
||||
"fov": 50,
|
||||
"near": 0.1,
|
||||
"far": 1000,
|
||||
"position": [
|
||||
-12.932153617745264,
|
||||
18.85116776875012,
|
||||
19.470685732446455
|
||||
],
|
||||
"up": [
|
||||
0,
|
||||
1,
|
||||
0
|
||||
]
|
||||
},
|
||||
"controls": {
|
||||
"target": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"renderParams": {
|
||||
"wireframe": false,
|
||||
"edgeAngle": 30,
|
||||
"lightIntensity": 3
|
||||
},
|
||||
"lights": {
|
||||
"directional": {
|
||||
"position": [
|
||||
5,
|
||||
5,
|
||||
5
|
||||
],
|
||||
"intensity": 3
|
||||
},
|
||||
"ambient": {
|
||||
"intensity": 0.6
|
||||
}
|
||||
}
|
||||
}
|
||||
1
web/batch_glb_png/vendor
Symbolic link
1
web/batch_glb_png/vendor
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../vendor
|
||||
1
web/glb
Symbolic link
1
web/glb
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../glb/
|
||||
192
web/lab.html
Normal file
192
web/lab.html
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>RenderLab v1</title>
|
||||
<style>
|
||||
body { margin:0; background:white; }
|
||||
canvas { display:block; }
|
||||
</style>
|
||||
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "./vendor/three/build/three.module.js",
|
||||
"three/addons/": "./vendor/three/addons/"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
||||
import GUI from 'three/addons/libs/lil-gui.module.min.js';
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xffffff);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(50, innerWidth/innerHeight, 0.1, 1000);
|
||||
camera.position.set(3,3,3);
|
||||
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
preserveDrawingBuffer: true, // <-- critical for toDataURL on many setups
|
||||
alpha: false // ensure opaque canvas
|
||||
});
|
||||
renderer.setSize(innerWidth, innerHeight);
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setClearColor(0xffffff, 1); // opaque white
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const controls = new OrbitControls(camera, renderer.domElement);
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
light.position.set(5,5,5);
|
||||
scene.add(light);
|
||||
|
||||
const ambient = new THREE.AmbientLight(0xffffff, 0.6);
|
||||
scene.add(ambient);
|
||||
|
||||
let mesh, edgeLines;
|
||||
|
||||
const loader = new GLTFLoader();
|
||||
loader.load('./glb/part.glb', gltf => {
|
||||
|
||||
mesh = gltf.scene.children[0];
|
||||
|
||||
mesh.material = new THREE.MeshStandardMaterial({
|
||||
color: 0xdddddd,
|
||||
roughness: 0.9,
|
||||
metalness: 0
|
||||
});
|
||||
|
||||
scene.add(mesh);
|
||||
addEdges(30);
|
||||
|
||||
});
|
||||
|
||||
function ts_yyyymmdd_hhmiss () {
|
||||
const d = new Date();
|
||||
const pad = n => String(n).padStart(2,'0');
|
||||
return (
|
||||
d.getFullYear() +
|
||||
pad(d.getMonth()+1) +
|
||||
pad(d.getDate()) + '_' +
|
||||
pad(d.getHours()) +
|
||||
pad(d.getMinutes()) +
|
||||
pad(d.getSeconds())
|
||||
);
|
||||
}
|
||||
|
||||
function downloadTextFile (filename, text) {
|
||||
const blob = new Blob([text], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
function addEdges(angle) {
|
||||
if (!mesh) return;
|
||||
if (edgeLines) scene.remove(edgeLines);
|
||||
|
||||
const edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
||||
edgeLines = new THREE.LineSegments(
|
||||
edges,
|
||||
new THREE.LineBasicMaterial({ color: 0x000000 })
|
||||
);
|
||||
|
||||
scene.add(edgeLines);
|
||||
}
|
||||
|
||||
|
||||
const params = {
|
||||
wireframe: false,
|
||||
edgeAngle: 30,
|
||||
lightIntensity: 1.5,
|
||||
|
||||
savePNG: () => {
|
||||
renderer.render(scene, camera); // recommended before capture
|
||||
const link = document.createElement('a');
|
||||
link.download = 'render.png';
|
||||
link.href = renderer.domElement.toDataURL("image/png");
|
||||
link.click();
|
||||
},
|
||||
|
||||
exportProfile: () => {
|
||||
controls.update(); // ensure target is current
|
||||
|
||||
const profile = {
|
||||
provenance: `lab.html exportProfile ${new Date().toString()}`,
|
||||
|
||||
output: {
|
||||
width: renderer.domElement.width,
|
||||
height: renderer.domElement.height,
|
||||
pixelRatio: renderer.getPixelRatio()
|
||||
},
|
||||
|
||||
scene: {
|
||||
background: scene.background?.getHex?.() ?? null
|
||||
},
|
||||
|
||||
camera: {
|
||||
type: 'PerspectiveCamera',
|
||||
fov: camera.fov,
|
||||
near: camera.near,
|
||||
far: camera.far,
|
||||
position: camera.position.toArray(),
|
||||
up: camera.up.toArray()
|
||||
},
|
||||
|
||||
controls: {
|
||||
target: controls.target.toArray()
|
||||
},
|
||||
|
||||
renderParams: {
|
||||
wireframe: params.wireframe,
|
||||
edgeAngle: params.edgeAngle,
|
||||
lightIntensity: params.lightIntensity
|
||||
},
|
||||
|
||||
lights: {
|
||||
directional: { position: light.position.toArray(), intensity: light.intensity },
|
||||
ambient: { intensity: ambient.intensity }
|
||||
}
|
||||
};
|
||||
|
||||
const fn = `three_profile_${ts_yyyymmdd_hhmiss()}.json`;
|
||||
downloadTextFile(fn, JSON.stringify(profile, null, 2));
|
||||
console.log('Exported profile:', profile);
|
||||
}
|
||||
};
|
||||
|
||||
const gui = new GUI();
|
||||
gui.add(params, 'wireframe').onChange(v => {
|
||||
if (mesh) mesh.material.wireframe = v;
|
||||
});
|
||||
gui.add(params, 'edgeAngle', 1, 90).onChange(v => addEdges(v));
|
||||
gui.add(params, 'lightIntensity', 0, 3).onChange(v => light.intensity = v);
|
||||
gui.add(params, 'savePNG');
|
||||
gui.add(params, 'exportProfile');
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
camera.aspect = innerWidth/innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(innerWidth, innerHeight);
|
||||
});
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
animate();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
104
web/lab.html~
Normal file
104
web/lab.html~
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>RenderLab v1</title>
|
||||
<style>
|
||||
body { margin:0; background:white; }
|
||||
canvas { display:block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
|
||||
import * as THREE from './threejs/three.module.js';
|
||||
import { GLTFLoader } from './threejs/GLTFLoader.js';
|
||||
import { OrbitControls } from './threejs/OrbitControls.js';
|
||||
import GUI from './threejs/lil-gui.module.min.js';
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xffffff);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(50, innerWidth/innerHeight, 0.1, 1000);
|
||||
camera.position.set(3,3,3);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias:true });
|
||||
renderer.setSize(innerWidth, innerHeight);
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const controls = new OrbitControls(camera, renderer.domElement);
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
light.position.set(5,5,5);
|
||||
scene.add(light);
|
||||
|
||||
const ambient = new THREE.AmbientLight(0xffffff, 0.6);
|
||||
scene.add(ambient);
|
||||
|
||||
let mesh, edgeLines;
|
||||
|
||||
const loader = new GLTFLoader();
|
||||
loader.load('./glb/part.glb', gltf => {
|
||||
|
||||
mesh = gltf.scene.children[0];
|
||||
|
||||
mesh.material = new THREE.MeshStandardMaterial({
|
||||
color: 0xdddddd,
|
||||
roughness: 0.9,
|
||||
metalness: 0
|
||||
});
|
||||
|
||||
scene.add(mesh);
|
||||
addEdges(30);
|
||||
|
||||
});
|
||||
|
||||
function addEdges(angle) {
|
||||
if (!mesh) return;
|
||||
if (edgeLines) scene.remove(edgeLines);
|
||||
|
||||
const edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
||||
edgeLines = new THREE.LineSegments(
|
||||
edges,
|
||||
new THREE.LineBasicMaterial({ color: 0x000000 })
|
||||
);
|
||||
|
||||
scene.add(edgeLines);
|
||||
}
|
||||
|
||||
const params = {
|
||||
wireframe: false,
|
||||
edgeAngle: 30,
|
||||
lightIntensity: 1.5,
|
||||
savePNG: () => {
|
||||
const link = document.createElement('a');
|
||||
link.download = 'render.png';
|
||||
link.href = renderer.domElement.toDataURL("image/png");
|
||||
link.click();
|
||||
}
|
||||
};
|
||||
|
||||
const gui = new GUI();
|
||||
gui.add(params, 'wireframe').onChange(v => {
|
||||
if (mesh) mesh.material.wireframe = v;
|
||||
});
|
||||
gui.add(params, 'edgeAngle', 1, 90).onChange(v => addEdges(v));
|
||||
gui.add(params, 'lightIntensity', 0, 3).onChange(v => light.intensity = v);
|
||||
gui.add(params, 'savePNG');
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
camera.aspect = innerWidth/innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(innerWidth, innerHeight);
|
||||
});
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
animate();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
4663
web/threejs/GLTFLoader.js
Normal file
4663
web/threejs/GLTFLoader.js
Normal file
File diff suppressed because it is too large
Load diff
1417
web/threejs/OrbitControls.js
Normal file
1417
web/threejs/OrbitControls.js
Normal file
File diff suppressed because it is too large
Load diff
8
web/threejs/lil-gui.module.min.js
vendored
Normal file
8
web/threejs/lil-gui.module.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
53044
web/threejs/three.module.js
Normal file
53044
web/threejs/three.module.js
Normal file
File diff suppressed because one or more lines are too long
1417
web/vendor/three/addons/controls/OrbitControls.js
vendored
Normal file
1417
web/vendor/three/addons/controls/OrbitControls.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
web/vendor/three/addons/libs/lil-gui.module.min.js
vendored
Normal file
8
web/vendor/three/addons/libs/lil-gui.module.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4663
web/vendor/three/addons/loaders/GLTFLoader.js
vendored
Normal file
4663
web/vendor/three/addons/loaders/GLTFLoader.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1375
web/vendor/three/addons/utils/BufferGeometryUtils.js
vendored
Normal file
1375
web/vendor/three/addons/utils/BufferGeometryUtils.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
53044
web/vendor/three/build/three.module.js
vendored
Normal file
53044
web/vendor/three/build/three.module.js
vendored
Normal file
File diff suppressed because one or more lines are too long
78
web/wireframe_viewer.html
Normal file
78
web/wireframe_viewer.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GLB Wireframe Viewer</title>
|
||||
<style>
|
||||
body { margin:0; background:white; }
|
||||
canvas { display:block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
|
||||
import * as THREE from './three.module.js';
|
||||
import { GLTFLoader } from './GLTFLoader.js';
|
||||
import { OrbitControls } from './OrbitControls.js';
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xffffff);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(50, innerWidth/innerHeight, 0.1, 1000);
|
||||
camera.position.set(3,3,3);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias:true });
|
||||
renderer.setSize(innerWidth, innerHeight);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const controls = new OrbitControls(camera, renderer.domElement);
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
light.position.set(5,5,5);
|
||||
scene.add(light);
|
||||
|
||||
let mesh, edgeLines;
|
||||
|
||||
const loader = new GLTFLoader();
|
||||
loader.load('part.glb', gltf => {
|
||||
|
||||
mesh = gltf.scene.children[0];
|
||||
|
||||
mesh.material = new THREE.MeshStandardMaterial({
|
||||
color: 0xdddddd,
|
||||
roughness: 0.9,
|
||||
metalness: 0
|
||||
});
|
||||
|
||||
scene.add(mesh);
|
||||
|
||||
addEdges(30);
|
||||
|
||||
});
|
||||
|
||||
function addEdges(angle) {
|
||||
if (edgeLines) scene.remove(edgeLines);
|
||||
|
||||
const edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
||||
edgeLines = new THREE.LineSegments(
|
||||
edges,
|
||||
new THREE.LineBasicMaterial({ color: 0x000000 })
|
||||
);
|
||||
|
||||
scene.add(edgeLines);
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', e => {
|
||||
if (e.key === 'w') mesh.material.wireframe = !mesh.material.wireframe;
|
||||
if (e.key === 'e') addEdges(25);
|
||||
});
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
animate();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue