3d viewer change
This commit is contained in:
1 parent
cbf05a9ee1
commit
1dbc73312b
17 files changed
+1413
-841
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { cp, mkdir, writeFile } from 'node:fs/promises';
|
||||
import { cp, mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
@@ -7,78 +7,169 @@ const frontendDir = path.resolve(
|
||||
'..',
|
||||
);
|
||||
const rootDir = path.resolve(frontendDir, '../..');
|
||||
const nodeModules = path.join(rootDir, 'node_modules');
|
||||
const publicDir = path.join(frontendDir, 'public');
|
||||
|
||||
const assets = [
|
||||
function resolvePackage(...parts) {
|
||||
const candidates = [
|
||||
path.join(frontendDir, 'node_modules', ...parts),
|
||||
path.join(rootDir, 'node_modules', ...parts),
|
||||
];
|
||||
return candidates;
|
||||
}
|
||||
|
||||
async function copyFirst(sources, destination) {
|
||||
const output = path.join(publicDir, destination);
|
||||
await mkdir(path.dirname(output), { recursive: true });
|
||||
let lastError;
|
||||
for (const source of sources) {
|
||||
try {
|
||||
await cp(source, output);
|
||||
return output;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
throw lastError ?? new Error(`Missing asset for ${destination}`);
|
||||
}
|
||||
|
||||
const cadAssets = [
|
||||
[
|
||||
'@mlightcad/cad-simple-viewer/dist/dxf-parser-worker.js',
|
||||
resolvePackage('@mlightcad/cad-simple-viewer/dist/dxf-parser-worker.js'),
|
||||
'assets/dxf-parser-worker.js',
|
||||
],
|
||||
[
|
||||
'@mlightcad/cad-simple-viewer/dist/libredwg-parser-worker.js',
|
||||
resolvePackage(
|
||||
'@mlightcad/cad-simple-viewer/dist/libredwg-parser-worker.js',
|
||||
),
|
||||
'assets/libredwg-parser-worker.js',
|
||||
],
|
||||
[
|
||||
'@mlightcad/cad-simple-viewer/dist/mtext-renderer-worker.js',
|
||||
resolvePackage(
|
||||
'@mlightcad/cad-simple-viewer/dist/mtext-renderer-worker.js',
|
||||
),
|
||||
'assets/mtext-renderer-worker.js',
|
||||
],
|
||||
[
|
||||
'occt-import-js/dist/occt-import-js.wasm',
|
||||
'viewer-assets/wasm/occt-import-js.wasm',
|
||||
],
|
||||
['web-ifc/web-ifc.wasm', 'viewer-assets/wasm/web-ifc.wasm'],
|
||||
[
|
||||
'@noto-pdf-ts/fonts-kr/dist/fonts/NotoSansKR-VF.ttf',
|
||||
resolvePackage('@noto-pdf-ts/fonts-kr/dist/fonts/NotoSansKR-VF.ttf'),
|
||||
'viewer-assets/cad-resources/fonts/NotoSansKR-VF.ttf',
|
||||
],
|
||||
[
|
||||
'@fontsource-variable/noto-sans-kr/LICENSE',
|
||||
resolvePackage('@fontsource-variable/noto-sans-kr/LICENSE'),
|
||||
'viewer-assets/cad-resources/fonts/OFL-1.1.txt',
|
||||
],
|
||||
];
|
||||
|
||||
const o3dvAssets = [
|
||||
[
|
||||
resolvePackage('rhino3dm/rhino3dm.min.js'),
|
||||
'viewer-assets/o3dv/rhino3dm.min.js',
|
||||
],
|
||||
[
|
||||
resolvePackage('rhino3dm/rhino3dm.wasm'),
|
||||
'viewer-assets/o3dv/rhino3dm.wasm',
|
||||
],
|
||||
[
|
||||
resolvePackage('web-ifc/web-ifc-api-iife.js'),
|
||||
'viewer-assets/o3dv/web-ifc-api-iife.js',
|
||||
],
|
||||
[resolvePackage('web-ifc/web-ifc.wasm'), 'viewer-assets/o3dv/web-ifc.wasm'],
|
||||
[
|
||||
resolvePackage('draco3d/draco_decoder_nodejs.js'),
|
||||
'viewer-assets/o3dv/draco_decoder_nodejs.min.js',
|
||||
],
|
||||
[
|
||||
resolvePackage('occt-import-js/dist/occt-import-js.js'),
|
||||
'viewer-assets/o3dv/occt-import-js.js',
|
||||
],
|
||||
[
|
||||
resolvePackage('occt-import-js/dist/occt-import-js-worker.js'),
|
||||
'viewer-assets/o3dv/occt-import-js-worker.js',
|
||||
],
|
||||
[
|
||||
resolvePackage('occt-import-js/dist/occt-import-js.wasm'),
|
||||
'viewer-assets/o3dv/occt-import-js.wasm',
|
||||
],
|
||||
[
|
||||
resolvePackage('occt-import-js/dist/license.occt-import-js.txt'),
|
||||
'viewer-assets/o3dv/licenses/license.occt-import-js.txt',
|
||||
],
|
||||
[
|
||||
resolvePackage('occt-import-js/dist/license.occt.txt'),
|
||||
'viewer-assets/o3dv/licenses/license.occt.txt',
|
||||
],
|
||||
[
|
||||
resolvePackage('online-3d-viewer/LICENSE.md'),
|
||||
'viewer-assets/o3dv/licenses/online-3d-viewer.LICENSE.md',
|
||||
],
|
||||
[
|
||||
resolvePackage('rhino3dm/README.md'),
|
||||
'viewer-assets/o3dv/licenses/rhino3dm.README.md',
|
||||
],
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
assets.map(async ([source, destination]) => {
|
||||
const output = path.join(publicDir, destination);
|
||||
await mkdir(path.dirname(output), { recursive: true });
|
||||
await cp(path.join(nodeModules, source), output);
|
||||
}),
|
||||
[...cadAssets, ...o3dvAssets].map(([sources, destination]) =>
|
||||
copyFirst(sources, destination),
|
||||
),
|
||||
);
|
||||
|
||||
const envmapCandidates = resolvePackage(
|
||||
'online-3d-viewer/website/assets/envmaps/fishermans_bastion',
|
||||
);
|
||||
const envmapDest = path.join(
|
||||
publicDir,
|
||||
'viewer-assets/o3dv/envmaps/fishermans_bastion',
|
||||
);
|
||||
await mkdir(path.dirname(envmapDest), { recursive: true });
|
||||
{
|
||||
let copied = false;
|
||||
for (const candidate of envmapCandidates) {
|
||||
try {
|
||||
await cp(candidate, envmapDest, { recursive: true });
|
||||
copied = true;
|
||||
break;
|
||||
} catch {
|
||||
// try next
|
||||
}
|
||||
}
|
||||
if (!copied) {
|
||||
throw new Error('Missing Online3DViewer envmap assets');
|
||||
}
|
||||
}
|
||||
|
||||
const resources = path.join(publicDir, 'viewer-assets', 'cad-resources');
|
||||
await mkdir(path.join(resources, 'fonts'), { recursive: true });
|
||||
await mkdir(path.join(resources, 'templates'), { recursive: true });
|
||||
const fontManifest = `${JSON.stringify(
|
||||
[
|
||||
{
|
||||
name: [
|
||||
'Noto Sans KR',
|
||||
'arial',
|
||||
'batang',
|
||||
'dotum',
|
||||
'ghs',
|
||||
'gulim',
|
||||
'hztxt',
|
||||
'isocpeur',
|
||||
'malgun',
|
||||
'malgun gothic',
|
||||
'pmingliu',
|
||||
'romans',
|
||||
'sanss___',
|
||||
'simplex',
|
||||
'swisscbo',
|
||||
'whgtxt',
|
||||
'whs',
|
||||
],
|
||||
file: 'NotoSansKR-VF.ttf',
|
||||
type: 'mesh',
|
||||
description: 'Open-source Korean CAD fallback (SIL OFL 1.1)',
|
||||
},
|
||||
],
|
||||
null,
|
||||
2,
|
||||
)}\n`;
|
||||
[
|
||||
{
|
||||
name: [
|
||||
'Noto Sans KR',
|
||||
'arial',
|
||||
'batang',
|
||||
'dotum',
|
||||
'ghs',
|
||||
'gulim',
|
||||
'hztxt',
|
||||
'isocpeur',
|
||||
'malgun',
|
||||
'malgun gothic',
|
||||
'pmingliu',
|
||||
'romans',
|
||||
'sanss___',
|
||||
'simplex',
|
||||
'swisscbo',
|
||||
'whgtxt',
|
||||
'whs',
|
||||
],
|
||||
file: 'NotoSansKR-VF.ttf',
|
||||
type: 'mesh',
|
||||
description: 'Open-source Korean CAD fallback (SIL OFL 1.1)',
|
||||
},
|
||||
],
|
||||
null,
|
||||
2,
|
||||
)}\n`;
|
||||
await Promise.all([
|
||||
writeFile(path.join(resources, 'fonts.json'), fontManifest),
|
||||
writeFile(path.join(resources, 'fonts', 'fonts.json'), fontManifest),
|
||||
@@ -92,3 +183,58 @@ await writeFile(
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
await writeFile(
|
||||
path.join(publicDir, 'viewer-assets/o3dv/README.txt'),
|
||||
[
|
||||
'Self-hosted Online3DViewer external libraries.',
|
||||
'CDN URLs in online-3d-viewer are rewritten to /viewer-assets/o3dv/.',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
const O3DV_BASE = '/viewer-assets/o3dv/';
|
||||
const replacements = [
|
||||
[
|
||||
'https://cdn.jsdelivr.net/npm/occt-import-js@0.0.22/dist/',
|
||||
O3DV_BASE,
|
||||
],
|
||||
[
|
||||
'https://cdn.jsdelivr.net/npm/rhino3dm@8.17.0/rhino3dm.min.js',
|
||||
`${O3DV_BASE}rhino3dm.min.js`,
|
||||
],
|
||||
[
|
||||
'https://cdn.jsdelivr.net/npm/web-ifc@0.0.68/web-ifc-api-iife.js',
|
||||
`${O3DV_BASE}web-ifc-api-iife.js`,
|
||||
],
|
||||
[
|
||||
'https://cdn.jsdelivr.net/npm/draco3d@1.5.7/draco_decoder_nodejs.min.js',
|
||||
`${O3DV_BASE}draco_decoder_nodejs.min.js`,
|
||||
],
|
||||
];
|
||||
|
||||
async function patchO3dvFile(relativePath) {
|
||||
for (const candidate of resolvePackage(relativePath)) {
|
||||
try {
|
||||
let source = await readFile(candidate, 'utf8');
|
||||
let changed = false;
|
||||
for (const [from, to] of replacements) {
|
||||
if (source.includes(from)) {
|
||||
source = source.split(from).join(to);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
await writeFile(candidate, source);
|
||||
console.log(`patched ${candidate}`);
|
||||
}
|
||||
return;
|
||||
} catch {
|
||||
// try next path
|
||||
}
|
||||
}
|
||||
throw new Error(`Could not patch ${relativePath}`);
|
||||
}
|
||||
|
||||
await patchO3dvFile('online-3d-viewer/build/engine/o3dv.module.js');
|
||||
await patchO3dvFile('online-3d-viewer/build/engine/o3dv.min.js');
|
||||
Reference in new issue
Block a user