From 63f498655f69b40efc1339b5ce5914c8d69c0958 Mon Sep 17 00:00:00 2001 From: HHY Date: Fri, 25 Sep 2026 03:38:31 -0700 Subject: [PATCH] =?UTF-8?q?chore:=20esbuild=20=E6=A0=A1=E9=AA=8C=E4=BA=A7?= =?UTF-8?q?=E7=89=A9=E4=B8=8D=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + frontend/scripts/.drawing-bundle.mjs | 311 ------------------------- frontend/src/types/.drawing-bundle.mjs | 311 ------------------------- 3 files changed, 1 insertion(+), 622 deletions(-) delete mode 100644 frontend/scripts/.drawing-bundle.mjs delete mode 100644 frontend/src/types/.drawing-bundle.mjs diff --git a/.gitignore b/.gitignore index 784d627..9ec499d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ data/dxf-study/ .env .tmp_token .tmp_*/ +*.drawing-bundle.mjs diff --git a/frontend/scripts/.drawing-bundle.mjs b/frontend/scripts/.drawing-bundle.mjs deleted file mode 100644 index 78fbd28..0000000 --- a/frontend/scripts/.drawing-bundle.mjs +++ /dev/null @@ -1,311 +0,0 @@ -// src/types/drawing.ts -var DEC_PRESETS = [ - { kind: "modern", label: "\u73B0\u4EE3\u8F7B\u5962", rows: 1, cols: 1, bw: 25, color: "#2b2b2b" }, - { kind: "italian", label: "\u610F\u5F0F\u7B80\u7EA6", rows: 1, cols: 1, bw: 18, color: "#9aa0a6" }, - { kind: "cream", label: "\u5976\u6CB9\u98CE", rows: 2, cols: 2, bw: 22, color: "#f3ece2" }, - { kind: "chinese", label: "\u4E2D\u5F0F", rows: 2, cols: 2, bw: 28, color: "#6b4a2b" }, - { kind: "european", label: "\u6B27\u5F0F\u53E4\u5178", rows: 3, cols: 3, bw: 20, color: "#c9a86a" }, - { kind: "french", label: "\u6CD5\u5F0F", rows: 2, cols: 2, bw: 16, color: "#d8c9a3" }, - { kind: "medit", label: "\u5730\u4E2D\u6D77", rows: 2, cols: 3, bw: 24, color: "#3a6ea5" }, - { kind: "pastoral", label: "\u7530\u56ED\u5BC6\u683C", rows: 4, cols: 4, bw: 14, color: "#ffffff" } -]; -function parseDrawing(raw) { - const dd = typeof raw === "string" ? JSON.parse(raw) : raw; - return dd; -} -function regionPoints(region) { - return region.map((seg) => ({ x: seg.ps.x, y: seg.ps.y })); -} -function bboxOf(points) { - const xs = points.map((p) => p.x); - const ys = points.map((p) => p.y); - return { x0: Math.min(...xs), y0: Math.min(...ys), x1: Math.max(...xs), y1: Math.max(...ys) }; -} -function spAxis(sp) { - const n = sp.line?.norm ?? { x: 1, y: 0 }; - return Math.abs(n.x) >= Math.abs(n.y) ? "v" : "h"; -} -function spPos(sp) { - return spAxis(sp) === "v" ? sp.line.pt.x : sp.line.pt.y; -} -function pointInRegion(p, region) { - let inside = false; - const pts = regionPoints(region); - for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) { - const xi = pts[i].x, yi = pts[i].y, xj = pts[j].x, yj = pts[j].y; - if (yi > p.y !== yj > p.y && p.x < (xj - xi) * (p.y - yi) / (yj - yi) + xi) inside = !inside; - } - return inside; -} -function dfsLeaves(node, out) { - if (node.kids.length === 0) { - out.push(node); - return; - } - node.kids.forEach((k) => dfsLeaves(k, out)); -} -function replayShape(shape) { - const base = (shape.polygon?.polygon ?? []).map((r) => r.filter((s) => s && typeof s === "object" && s.ps && s.pe && Number.isFinite(s.ps.x) && Number.isFinite(s.ps.y) && Number.isFinite(s.pe.x) && Number.isFinite(s.pe.y)).map((s) => ({ ps: { ...s.ps }, pe: { ...s.pe } }))).filter((r) => r.length >= 3); - const root = { segs: base[0] ?? [], kids: [] }; - const extraRoots = base.slice(1).map((segs) => ({ segs, kids: [] })); - const idMap = /* @__PURE__ */ new Map(); - const clips = []; - const allLeaves = () => { - const out = []; - dfsLeaves(root, out); - extraRoots.forEach((r) => dfsLeaves(r, out)); - return out; - }; - let spIdx = 0; - for (const sp of shape.mm?.sp ?? []) { - const myId = spIdx; - spIdx++; - if (!sp?.line?.pt || !sp.line.norm) continue; - const axis = spAxis(sp); - const pos = spPos(sp); - let target = null; - const nid = sp.polyId?.idx; - const cpos = sp.polyId?.pos; - if (Number.isInteger(nid) && nid >= 0) { - const node = nid === 0 ? root : idMap.get(nid); - if (node) { - if (node.kids.length === 0) target = node; - else if (Number.isInteger(cpos) && cpos >= 0 && cpos < node.kids.length) { - target = node.kids[cpos]; - } - } - } - if (!target) target = allLeaves().find((nd) => pointInRegion(sp.line.pt, nd.segs)) ?? null; - if (!target || target.segs.length < 3) continue; - const bb = bboxOf(regionPoints(target.segs)); - const lo = axis === "v" ? bb.x0 : bb.y0; - const hi = axis === "v" ? bb.x1 : bb.y1; - if (pos <= lo + 0.5 || pos >= hi - 0.5) { - clips.push({ sp, bb }); - idMap.set(myId, target); - continue; - } - const split = splitPolySegments(target.segs, axis, pos); - if (!split) { - clips.push({ sp, bb }); - idMap.set(myId, target); - continue; - } - const nrm = sp.line.norm; - const sideOf = (segs) => { - for (const s of segs) { - for (const p of [s.ps, s.pe]) { - const d = (p.x - sp.line.pt.x) * nrm.x + (p.y - sp.line.pt.y) * nrm.y; - if (Math.abs(d) > 1e-6) return d > 0; - } - } - return true; - }; - const c0 = sideOf(split.a) ? split.a : split.b; - target.kids = [{ segs: c0, kids: [] }, { segs: sideOf(split.a) ? split.b : split.a, kids: [] }]; - target.segs = []; - idMap.set(myId, target); - clips.push({ sp, bb }); - } - const leaves = allLeaves(); - const regions = leaves.map((l) => l.segs).filter((s) => s.length >= 3); - const nodeId = /* @__PURE__ */ new Map([[root, 0]]); - const leafRefs = []; - const walk = (node, id) => { - node.kids.forEach((k, i) => { - if (k.kids.length === 0) leafRefs.push({ idx: id, pos: i }); - else { - const kidId = nodeId.get(k); - if (kidId != null) walk(k, kidId); - } - }); - }; - if (root.kids.length === 0 && root.segs.length >= 3) leafRefs.push({ idx: 0, pos: 0 }); - else walk(root, 0); - extraRoots.forEach((r, i) => { - const eid = base.length + spIdx + i; - idMap.set(eid, r); - if (r.kids.length === 0) leafRefs.push({ idx: eid, pos: 0 }); - else walk(r, eid); - }); - const resolveRef = (idx, pos) => { - const node = idx === 0 ? root : idMap.get(idx); - if (!node) return null; - if (node.kids.length === 0) return node.segs; - if (Number.isInteger(pos) && pos >= 0 && pos < node.kids.length) { - const k = node.kids[pos]; - if (k.kids.length === 0) return k.segs; - const l = []; - dfsLeaves(k, l); - return l[0]?.segs ?? null; - } - return null; - }; - return { regions, clips, leafRefs, resolveRef }; -} -function splitPolySegments(region, axis, pos) { - const pts = regionPoints(region); - const n = pts.length; - const get = (p) => axis === "v" ? p.x : p.y; - const crossings = []; - for (let i = 0; i < n; i++) { - const a = pts[i], b = pts[(i + 1) % n]; - const da = get(a) - pos, db = get(b) - pos; - if (da < 0 && db > 0 || da > 0 && db < 0) { - const t = da / (da - db); - crossings.push({ - i, - p: axis === "v" ? { x: pos, y: a.y + (b.y - a.y) * t } : { x: a.x + (b.x - a.x) * t, y: pos } - }); - } - } - if (crossings.length !== 2) return null; - const [c1, c2] = crossings; - if (c1.i === c2.i) return null; - const collect = (from, to) => { - const ps = [from.p]; - for (let k = (from.i + 1) % n; ; k = (k + 1) % n) { - ps.push(pts[k]); - if (k === to.i) break; - } - ps.push(to.p); - return ps.filter((p, i) => i === 0 || Math.abs(p.x - ps[i - 1].x) > 0.01 || Math.abs(p.y - ps[i - 1].y) > 0.01); - }; - const toSegs = (ps) => { - const segs = []; - for (let i = 0; i < ps.length; i++) segs.push({ ps: ps[i], pe: ps[(i + 1) % ps.length], name: "segment" }); - return segs; - }; - const polyA = collect(c1, c2); - const polyB = collect(c2, c1); - if (polyA.length < 3 || polyB.length < 3) return null; - return { a: toSegs(polyA), b: toSegs(polyB) }; -} -function hmOf(sub) { - const hm = sub.hm; - return hm ?? {}; -} -function inferSashGlyphs(shape, replayed) { - let rr = null; - let regions; - if (replayed && !Array.isArray(replayed)) { - rr = replayed; - regions = rr.regions; - } else if (replayed) { - regions = replayed; - } else { - rr = replayShape(shape); - regions = rr.regions; - } - const regionBBs = regions.map((r) => bboxOf(regionPoints(r))); - const glyphs = []; - const bdRect = (bd) => { - if (!bd.from || !bd.to) return null; - const r = { - x0: Math.min(bd.from.x, bd.to.x), - y0: Math.min(bd.from.y, bd.to.y), - x1: Math.max(bd.from.x, bd.to.x), - y1: Math.max(bd.from.y, bd.to.y) - }; - const ok = [r.x0, r.y0, r.x1, r.y1].every((v) => Number.isFinite(v)); - return ok && !bd.hidden && r.x1 - r.x0 > 10 && r.y1 - r.y0 > 10 ? r : null; - }; - const kindOf = (sub) => String(sub.type) === "Slide" ? "sliding" : "casement"; - const rectOfRef = (ref) => { - if (!ref || !Number.isInteger(ref.idx) || ref.idx < 0) return null; - if (rr) { - const segs = rr.resolveRef(ref.idx, ref.pos); - if (segs && segs.length >= 3) return bboxOf(regionPoints(segs)); - } - const i = ref.idx; - return i < regionBBs.length ? regionBBs[i] : null; - }; - const iouR = (a, b) => { - const w = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0); - const h = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0); - if (w <= 0 || h <= 0) return 0; - const inter = w * h; - return inter / ((a.x1 - a.x0) * (a.y1 - a.y0) + (b.x1 - b.x0) * (b.y1 - b.y0) - inter); - }; - const pushGlyphs = (r, entries, sub, forceRect = false) => { - const kind = kindOf(sub); - const hm = hmOf(sub); - for (const e of entries) { - const rect = !forceRect ? rectOfRef(e.polyId) ?? r : r; - if (glyphs.some((g) => iouR(rect, g) > 0.15)) continue; - glyphs.push({ - x0: rect.x0, - y0: rect.y0, - x1: rect.x1, - y1: rect.y1, - od: e.od ?? sub.od ?? 90, - openToward: e.openToward ?? sub.openToward ?? hm.openToward, - openDirection: e.openDirection ?? hm.openDirection, - isDoor: Boolean(e.isDoor || sub.isDoor), - wtf: Boolean(e.wtf ?? sub.wtf ?? sub.withTurningFrame), - kind - }); - } - }; - const unmatched = []; - for (const sub of shape.sm ?? []) { - const type = String(sub.type ?? ""); - if (type === "Screen" || type === "DoubleScreen") continue; - const raw = sub.sashes?.length ? sub.sashes : [sub]; - const entries = raw.filter((e) => e && e.enabled !== false); - if (!entries.length) continue; - const n = Math.max(entries.length, type.startsWith("Double") ? 2 : 1); - let rect = sub.bd ? bdRect(sub.bd) : null; - if (!rect) rect = rectOfRef(sub.polyId); - if (rect) { - for (let k = 0; k < n; k++) { - const part = n > 1 ? { x0: rect.x0 + (rect.x1 - rect.x0) * k / n, y0: rect.y0, x1: rect.x0 + (rect.x1 - rect.x0) * (k + 1) / n, y1: rect.y1 } : rect; - pushGlyphs(part, [entries[Math.min(k, entries.length - 1)]], sub, n > 1); - } - continue; - } - unmatched.push({ sub, entries }); - } - if (unmatched.length && regions.length) { - const flatPts = []; - for (const r of regions) { - for (const seg of r) { - if (Number.isFinite(seg.ps?.x) && Number.isFinite(seg.ps?.y)) flatPts.push(seg.ps); - if (Number.isFinite(seg.pe?.x) && Number.isFinite(seg.pe?.y)) flatPts.push(seg.pe); - } - } - const fb = bboxOf(flatPts); - const K = unmatched.reduce((s, u) => s + u.entries.length, 0); - const colW = (fb.x1 - fb.x0) / K; - let i = 0; - for (const u of unmatched) { - for (const e of u.entries) { - glyphs.push({ - x0: fb.x0 + i * colW, - x1: fb.x0 + (i + 1) * colW, - y0: fb.y0, - y1: fb.y1, - od: e.od ?? u.sub.od ?? 90, - openToward: e.openToward ?? u.sub.openToward ?? hmOf(u.sub).openToward, - openDirection: e.openDirection ?? hmOf(u.sub).openDirection, - isDoor: Boolean(e.isDoor || u.sub.isDoor), - kind: kindOf(u.sub) - }); - i++; - } - } - } - return { regions, sashes: glyphs }; -} -export { - DEC_PRESETS, - bboxOf, - inferSashGlyphs, - parseDrawing, - pointInRegion, - regionPoints, - replayShape, - spAxis, - spPos, - splitPolySegments -}; diff --git a/frontend/src/types/.drawing-bundle.mjs b/frontend/src/types/.drawing-bundle.mjs deleted file mode 100644 index 78fbd28..0000000 --- a/frontend/src/types/.drawing-bundle.mjs +++ /dev/null @@ -1,311 +0,0 @@ -// src/types/drawing.ts -var DEC_PRESETS = [ - { kind: "modern", label: "\u73B0\u4EE3\u8F7B\u5962", rows: 1, cols: 1, bw: 25, color: "#2b2b2b" }, - { kind: "italian", label: "\u610F\u5F0F\u7B80\u7EA6", rows: 1, cols: 1, bw: 18, color: "#9aa0a6" }, - { kind: "cream", label: "\u5976\u6CB9\u98CE", rows: 2, cols: 2, bw: 22, color: "#f3ece2" }, - { kind: "chinese", label: "\u4E2D\u5F0F", rows: 2, cols: 2, bw: 28, color: "#6b4a2b" }, - { kind: "european", label: "\u6B27\u5F0F\u53E4\u5178", rows: 3, cols: 3, bw: 20, color: "#c9a86a" }, - { kind: "french", label: "\u6CD5\u5F0F", rows: 2, cols: 2, bw: 16, color: "#d8c9a3" }, - { kind: "medit", label: "\u5730\u4E2D\u6D77", rows: 2, cols: 3, bw: 24, color: "#3a6ea5" }, - { kind: "pastoral", label: "\u7530\u56ED\u5BC6\u683C", rows: 4, cols: 4, bw: 14, color: "#ffffff" } -]; -function parseDrawing(raw) { - const dd = typeof raw === "string" ? JSON.parse(raw) : raw; - return dd; -} -function regionPoints(region) { - return region.map((seg) => ({ x: seg.ps.x, y: seg.ps.y })); -} -function bboxOf(points) { - const xs = points.map((p) => p.x); - const ys = points.map((p) => p.y); - return { x0: Math.min(...xs), y0: Math.min(...ys), x1: Math.max(...xs), y1: Math.max(...ys) }; -} -function spAxis(sp) { - const n = sp.line?.norm ?? { x: 1, y: 0 }; - return Math.abs(n.x) >= Math.abs(n.y) ? "v" : "h"; -} -function spPos(sp) { - return spAxis(sp) === "v" ? sp.line.pt.x : sp.line.pt.y; -} -function pointInRegion(p, region) { - let inside = false; - const pts = regionPoints(region); - for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) { - const xi = pts[i].x, yi = pts[i].y, xj = pts[j].x, yj = pts[j].y; - if (yi > p.y !== yj > p.y && p.x < (xj - xi) * (p.y - yi) / (yj - yi) + xi) inside = !inside; - } - return inside; -} -function dfsLeaves(node, out) { - if (node.kids.length === 0) { - out.push(node); - return; - } - node.kids.forEach((k) => dfsLeaves(k, out)); -} -function replayShape(shape) { - const base = (shape.polygon?.polygon ?? []).map((r) => r.filter((s) => s && typeof s === "object" && s.ps && s.pe && Number.isFinite(s.ps.x) && Number.isFinite(s.ps.y) && Number.isFinite(s.pe.x) && Number.isFinite(s.pe.y)).map((s) => ({ ps: { ...s.ps }, pe: { ...s.pe } }))).filter((r) => r.length >= 3); - const root = { segs: base[0] ?? [], kids: [] }; - const extraRoots = base.slice(1).map((segs) => ({ segs, kids: [] })); - const idMap = /* @__PURE__ */ new Map(); - const clips = []; - const allLeaves = () => { - const out = []; - dfsLeaves(root, out); - extraRoots.forEach((r) => dfsLeaves(r, out)); - return out; - }; - let spIdx = 0; - for (const sp of shape.mm?.sp ?? []) { - const myId = spIdx; - spIdx++; - if (!sp?.line?.pt || !sp.line.norm) continue; - const axis = spAxis(sp); - const pos = spPos(sp); - let target = null; - const nid = sp.polyId?.idx; - const cpos = sp.polyId?.pos; - if (Number.isInteger(nid) && nid >= 0) { - const node = nid === 0 ? root : idMap.get(nid); - if (node) { - if (node.kids.length === 0) target = node; - else if (Number.isInteger(cpos) && cpos >= 0 && cpos < node.kids.length) { - target = node.kids[cpos]; - } - } - } - if (!target) target = allLeaves().find((nd) => pointInRegion(sp.line.pt, nd.segs)) ?? null; - if (!target || target.segs.length < 3) continue; - const bb = bboxOf(regionPoints(target.segs)); - const lo = axis === "v" ? bb.x0 : bb.y0; - const hi = axis === "v" ? bb.x1 : bb.y1; - if (pos <= lo + 0.5 || pos >= hi - 0.5) { - clips.push({ sp, bb }); - idMap.set(myId, target); - continue; - } - const split = splitPolySegments(target.segs, axis, pos); - if (!split) { - clips.push({ sp, bb }); - idMap.set(myId, target); - continue; - } - const nrm = sp.line.norm; - const sideOf = (segs) => { - for (const s of segs) { - for (const p of [s.ps, s.pe]) { - const d = (p.x - sp.line.pt.x) * nrm.x + (p.y - sp.line.pt.y) * nrm.y; - if (Math.abs(d) > 1e-6) return d > 0; - } - } - return true; - }; - const c0 = sideOf(split.a) ? split.a : split.b; - target.kids = [{ segs: c0, kids: [] }, { segs: sideOf(split.a) ? split.b : split.a, kids: [] }]; - target.segs = []; - idMap.set(myId, target); - clips.push({ sp, bb }); - } - const leaves = allLeaves(); - const regions = leaves.map((l) => l.segs).filter((s) => s.length >= 3); - const nodeId = /* @__PURE__ */ new Map([[root, 0]]); - const leafRefs = []; - const walk = (node, id) => { - node.kids.forEach((k, i) => { - if (k.kids.length === 0) leafRefs.push({ idx: id, pos: i }); - else { - const kidId = nodeId.get(k); - if (kidId != null) walk(k, kidId); - } - }); - }; - if (root.kids.length === 0 && root.segs.length >= 3) leafRefs.push({ idx: 0, pos: 0 }); - else walk(root, 0); - extraRoots.forEach((r, i) => { - const eid = base.length + spIdx + i; - idMap.set(eid, r); - if (r.kids.length === 0) leafRefs.push({ idx: eid, pos: 0 }); - else walk(r, eid); - }); - const resolveRef = (idx, pos) => { - const node = idx === 0 ? root : idMap.get(idx); - if (!node) return null; - if (node.kids.length === 0) return node.segs; - if (Number.isInteger(pos) && pos >= 0 && pos < node.kids.length) { - const k = node.kids[pos]; - if (k.kids.length === 0) return k.segs; - const l = []; - dfsLeaves(k, l); - return l[0]?.segs ?? null; - } - return null; - }; - return { regions, clips, leafRefs, resolveRef }; -} -function splitPolySegments(region, axis, pos) { - const pts = regionPoints(region); - const n = pts.length; - const get = (p) => axis === "v" ? p.x : p.y; - const crossings = []; - for (let i = 0; i < n; i++) { - const a = pts[i], b = pts[(i + 1) % n]; - const da = get(a) - pos, db = get(b) - pos; - if (da < 0 && db > 0 || da > 0 && db < 0) { - const t = da / (da - db); - crossings.push({ - i, - p: axis === "v" ? { x: pos, y: a.y + (b.y - a.y) * t } : { x: a.x + (b.x - a.x) * t, y: pos } - }); - } - } - if (crossings.length !== 2) return null; - const [c1, c2] = crossings; - if (c1.i === c2.i) return null; - const collect = (from, to) => { - const ps = [from.p]; - for (let k = (from.i + 1) % n; ; k = (k + 1) % n) { - ps.push(pts[k]); - if (k === to.i) break; - } - ps.push(to.p); - return ps.filter((p, i) => i === 0 || Math.abs(p.x - ps[i - 1].x) > 0.01 || Math.abs(p.y - ps[i - 1].y) > 0.01); - }; - const toSegs = (ps) => { - const segs = []; - for (let i = 0; i < ps.length; i++) segs.push({ ps: ps[i], pe: ps[(i + 1) % ps.length], name: "segment" }); - return segs; - }; - const polyA = collect(c1, c2); - const polyB = collect(c2, c1); - if (polyA.length < 3 || polyB.length < 3) return null; - return { a: toSegs(polyA), b: toSegs(polyB) }; -} -function hmOf(sub) { - const hm = sub.hm; - return hm ?? {}; -} -function inferSashGlyphs(shape, replayed) { - let rr = null; - let regions; - if (replayed && !Array.isArray(replayed)) { - rr = replayed; - regions = rr.regions; - } else if (replayed) { - regions = replayed; - } else { - rr = replayShape(shape); - regions = rr.regions; - } - const regionBBs = regions.map((r) => bboxOf(regionPoints(r))); - const glyphs = []; - const bdRect = (bd) => { - if (!bd.from || !bd.to) return null; - const r = { - x0: Math.min(bd.from.x, bd.to.x), - y0: Math.min(bd.from.y, bd.to.y), - x1: Math.max(bd.from.x, bd.to.x), - y1: Math.max(bd.from.y, bd.to.y) - }; - const ok = [r.x0, r.y0, r.x1, r.y1].every((v) => Number.isFinite(v)); - return ok && !bd.hidden && r.x1 - r.x0 > 10 && r.y1 - r.y0 > 10 ? r : null; - }; - const kindOf = (sub) => String(sub.type) === "Slide" ? "sliding" : "casement"; - const rectOfRef = (ref) => { - if (!ref || !Number.isInteger(ref.idx) || ref.idx < 0) return null; - if (rr) { - const segs = rr.resolveRef(ref.idx, ref.pos); - if (segs && segs.length >= 3) return bboxOf(regionPoints(segs)); - } - const i = ref.idx; - return i < regionBBs.length ? regionBBs[i] : null; - }; - const iouR = (a, b) => { - const w = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0); - const h = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0); - if (w <= 0 || h <= 0) return 0; - const inter = w * h; - return inter / ((a.x1 - a.x0) * (a.y1 - a.y0) + (b.x1 - b.x0) * (b.y1 - b.y0) - inter); - }; - const pushGlyphs = (r, entries, sub, forceRect = false) => { - const kind = kindOf(sub); - const hm = hmOf(sub); - for (const e of entries) { - const rect = !forceRect ? rectOfRef(e.polyId) ?? r : r; - if (glyphs.some((g) => iouR(rect, g) > 0.15)) continue; - glyphs.push({ - x0: rect.x0, - y0: rect.y0, - x1: rect.x1, - y1: rect.y1, - od: e.od ?? sub.od ?? 90, - openToward: e.openToward ?? sub.openToward ?? hm.openToward, - openDirection: e.openDirection ?? hm.openDirection, - isDoor: Boolean(e.isDoor || sub.isDoor), - wtf: Boolean(e.wtf ?? sub.wtf ?? sub.withTurningFrame), - kind - }); - } - }; - const unmatched = []; - for (const sub of shape.sm ?? []) { - const type = String(sub.type ?? ""); - if (type === "Screen" || type === "DoubleScreen") continue; - const raw = sub.sashes?.length ? sub.sashes : [sub]; - const entries = raw.filter((e) => e && e.enabled !== false); - if (!entries.length) continue; - const n = Math.max(entries.length, type.startsWith("Double") ? 2 : 1); - let rect = sub.bd ? bdRect(sub.bd) : null; - if (!rect) rect = rectOfRef(sub.polyId); - if (rect) { - for (let k = 0; k < n; k++) { - const part = n > 1 ? { x0: rect.x0 + (rect.x1 - rect.x0) * k / n, y0: rect.y0, x1: rect.x0 + (rect.x1 - rect.x0) * (k + 1) / n, y1: rect.y1 } : rect; - pushGlyphs(part, [entries[Math.min(k, entries.length - 1)]], sub, n > 1); - } - continue; - } - unmatched.push({ sub, entries }); - } - if (unmatched.length && regions.length) { - const flatPts = []; - for (const r of regions) { - for (const seg of r) { - if (Number.isFinite(seg.ps?.x) && Number.isFinite(seg.ps?.y)) flatPts.push(seg.ps); - if (Number.isFinite(seg.pe?.x) && Number.isFinite(seg.pe?.y)) flatPts.push(seg.pe); - } - } - const fb = bboxOf(flatPts); - const K = unmatched.reduce((s, u) => s + u.entries.length, 0); - const colW = (fb.x1 - fb.x0) / K; - let i = 0; - for (const u of unmatched) { - for (const e of u.entries) { - glyphs.push({ - x0: fb.x0 + i * colW, - x1: fb.x0 + (i + 1) * colW, - y0: fb.y0, - y1: fb.y1, - od: e.od ?? u.sub.od ?? 90, - openToward: e.openToward ?? u.sub.openToward ?? hmOf(u.sub).openToward, - openDirection: e.openDirection ?? hmOf(u.sub).openDirection, - isDoor: Boolean(e.isDoor || u.sub.isDoor), - kind: kindOf(u.sub) - }); - i++; - } - } - } - return { regions, sashes: glyphs }; -} -export { - DEC_PRESETS, - bboxOf, - inferSashGlyphs, - parseDrawing, - pointInRegion, - regionPoints, - replayShape, - spAxis, - spPos, - splitPolySegments -};