Files
Aislo/resources/tester/helper_90_chute_band.cjs
T

85 lines
2.7 KiB
JavaScript

/* 90-2 도수로 · 돌붙임 띠 헬퍼 — `appendChuteBand`(B06_Section_UI_Cross_Wall_Hatch.ts)를 그 자리에서
* 트랜스파일해 흉내 DOM 에 그림 · 결과 = 띠 꼭짓점(m) · 돌 수(표준출력 JSON). 짝 = `test_90_chute_band.py`.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
function loadTs(file) {
const full = path.resolve(file);
if (cache.has(full)) return cache.get(full);
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => loadTs(path.join(path.dirname(full), `${request}.ts`));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
class Node {
constructor(tag) {
this.tag = tag;
this.attrs = {};
this.children = [];
}
setAttribute(k, v) {
this.attrs[k] = String(v);
}
getAttribute(k) {
return this.attrs[k] ?? null;
}
append(...kids) {
this.children.push(...kids);
}
set textContent(v) {
this.text = v;
}
}
globalThis.document = { createElementNS: (_ns, tag) => new Node(tag) };
const { appendChuteBand } = loadTs(
path.join(ROOT, "B06_Section", "B06_Section_UI_Cross_Wall_Hatch.ts"),
);
const SCALE = 100;
const run = (line) => {
const layer = new Node("g");
appendChuteBand(
layer,
[line],
{ structure: "돌붙임", thickness_m: 0.3 },
(o) => o * SCALE,
(e) => -e * SCALE,
);
const band = layer.children.find((k) => k.tag === "polygon");
const group = layer.children.find((k) => k.tag === "g");
const points = band.attrs.points.split(" ").map((p) => {
const [px, py] = p.split(",").map(Number);
return { offset: px / SCALE, elevation: -py / SCALE };
});
return {
points,
stones: group.children.filter((k) => k.tag === "rect").length,
clipped: group.attrs["clip-path"]?.startsWith("url(#") ?? false,
title: band.children[0]?.text ?? "",
};
};
const out = {
// 좌측 유출(+ 바깥) · 성토 1:1.2 → 단 사이 수평 조각 → 다시 성토(흙막이 단 사이 포함)
left: run([
{ offset: 5, elevation: 10 },
{ offset: 7.4, elevation: 8 },
{ offset: 8.4, elevation: 8 },
{ offset: 10.8, elevation: 6 },
]),
// 우측 유출(− 바깥) · 곧은 성토 한 줄
right: run([
{ offset: -5, elevation: 10 },
{ offset: -8.6, elevation: 7 },
]),
};
process.stdout.write(JSON.stringify(out));