EmboDi / src /services /scan-context.mjs
xlt99's picture
Upload 180 files
970fc3e verified
Raw History Blame Contribute Delete
2.46 kB
import { readdir, readFile } from "node:fs/promises";
import { join } from "node:path";
import { scanContentAnchors } from "../shared/scan-structure.mjs";
import { validateContentAnchors } from "../shared/scan-furnishing.mjs";
async function resolveScanBlueprint(scene, sceneFolder) {
if (scene.scanReconstruction?.blueprint) return structuredClone(scene.scanReconstruction.blueprint);
let files;
try {
files = await readdir(join(sceneFolder, "scan-previews"));
} catch (error) {
if (error.code !== "ENOENT") throw error;
files = [];
}
for (const file of files.filter((f) => /^[a-f\d-]+\.json$/i.test(f)).sort()) {
const saved = JSON.parse(await readFile(join(sceneFolder, "scan-previews", file), "utf8"));
if (matchesScanGeometry(scene, saved.scene) && saved.survey?.planes && saved.alignment) return { planes: saved.survey.planes, alignment: saved.alignment, referenceFloor: saved.scene.objects.find((o) => o.id === "ground") };
}
throw new Error("Original scan for this scene was not found. Preview and apply the scan structure first.");
}
function matchesScanGeometry(scene, saved) {
if (!saved?.objects?.length) return false;
const current = new Map(scene.objects.map((o) => [o.id, o]));
return saved.objects.every((a) => {
const b = current.get(a.id);
return b && JSON.stringify([a.shape, a.position, a.size, a.rotation]) === JSON.stringify([b.shape, b.position, b.size, b.rotation]);
});
}
async function resolveScanContent(scene, sceneFolder) {
if (!scene.scanStructure) throw new Error("Apply the scan structure before adding scanned objects");
if (scene.scanStructure.contentAnchors) return validateContentAnchors(scene.scanStructure.contentAnchors);
let files;
try {
files = await readdir(join(sceneFolder, "scan-previews"));
} catch (error) {
if (error.code !== "ENOENT") throw error;
files = [];
}
for (const file of files.filter((f) => /^[a-f\d-]+\.json$/i.test(f)).sort()) {
const saved = JSON.parse(await readFile(join(sceneFolder, "scan-previews", file), "utf8"));
if (matchesScanGeometry(scene, saved.scene) && saved.survey?.planes && saved.alignment) return validateContentAnchors(scanContentAnchors(saved.survey.planes, saved.alignment, scene));
}
throw new Error("Matching original scan was not found. Current scene is preserved. Preview the scan structure again.");
}
export {
matchesScanGeometry,
resolveScanBlueprint,
resolveScanContent
};