diff --git a/package.json b/package.json index 76422b1..c38542c 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "type": "module", "scripts": { "dev": "vite", + "test": "node --test", "prebuild": "npm run check:template-sync", "build": "vite build", "build:pages": "npm run check:template-sync && vite build --base=/OpenBox3D/", diff --git a/src/design/layers.js b/src/design/layers.js index 54f43e9..94d3bcd 100644 --- a/src/design/layers.js +++ b/src/design/layers.js @@ -19,8 +19,15 @@ export function bboxOf(l) { } export function dpiOf(l) { - if (l.kind !== 'image' || !l.pxw) return 0; - return Math.round(l.pxw / (l.w / 25.4)); + if (l.kind !== 'image') return 0; + const pxw = Number(l.pxw || l.imgW), pxh = Number(l.imgH); + const w = Number(l.w), h = Number(l.h); + const crop = Array.isArray(l.crop) ? l.crop : [0, 0, 1, 1]; + const cropW = Number(crop[2]), cropH = Number(crop[3]); + if (![pxw, pxh, w, h, cropW, cropH].every(v => Number.isFinite(v) && v > 0)) return 0; + const dpiX = pxw * cropW / (w / 25.4); + const dpiY = pxh * cropH / (h / 25.4); + return Math.round(Math.min(dpiX, dpiY)); } // 图集 UV 用:每个面板(fill 多边形)的包围盒,供 3D 与导出对齐 diff --git a/src/ui/StructureView.jsx b/src/ui/StructureView.jsx index de27ca3..7bd5263 100644 --- a/src/ui/StructureView.jsx +++ b/src/ui/StructureView.jsx @@ -37,7 +37,14 @@ export function StructureView() { { k: '含出血', v: fmt(sw + 2 * s.bleed) + ' × ' + fmt(sh + 2 * s.bleed) }, { k: '纸厚 t', v: t + ' mm' } ].concat(specTpl[s.tpl] || []); - const checks = ['外轮廓闭合', '无自交 / 孤立线段', '最小刀距 ≥ 1.5 mm', '压痕两侧均有连接面', '出血 ≥ ' + m.bleed + ' mm(' + m.note + ')']; + const bleedOk = s.bleed >= m.bleed; + const checks = [ + { label: '外轮廓闭合:未自动检测', dot: '#9a8f7e' }, + { label: '自交 / 孤立线段:未自动检测', dot: '#9a8f7e' }, + { label: '最小刀距 ≥ 1.5 mm:未自动检测', dot: '#9a8f7e' }, + { label: '压痕两侧均有连接面:未自动检测', dot: '#9a8f7e' }, + { label: '出血 ' + s.bleed + ' mm ' + (bleedOk ? '≥' : '<') + ' 材质建议 ' + m.bleed + ' mm(' + m.note + ')', dot: bleedOk ? '#3f9e5f' : '#d05a2a' } + ]; const compNote = s.tpl === 'rte' || s.tpl === 'ste' ? '当前:W+t · L+t · W+t · L+2t,高度 H+t' : s.tpl === 'mailer' ? '当前:楞厚 t=' + t + ',侧墙 H+t,盖宽 W+3t' : s.tpl === 'cyl' ? '当前:直径 D=L,筒身 24 段卷合,盖为 24 边形' : s.tpl === 'hex' ? '当前:边长 W,六棱筒,盖为正六边形' : '当前:盖/套筒按 +1mm/边 放量'; const editOn = s.editMode; const typeOvrCount = Object.keys(s.typeOvr).length; @@ -123,8 +130,8 @@ export function StructureView() {