feat: P0-7 玻璃装饰格条设计器(8风格/2D+3D渲染/算料计价)

This commit is contained in:
HHY
2026-09-25 03:38:18 -07:00
parent 40c16d56a1
commit 5fe6608ae1
10 changed files with 888 additions and 8 deletions
+24 -4
View File
@@ -58,7 +58,7 @@ import { ElMessage } from 'element-plus'
import * as THREE from 'three'
import {
bboxOf, inferSashGlyphs, parseDrawing, regionPoints, replayShape,
type DrawingData, type Pt,
type DecBar, type DrawingData, type Pt,
} from '../types/drawing'
import { profileGeo } from '../three/profileGeo'
@@ -268,7 +268,7 @@ function build(drawing: DrawingData) {
const regionBBs: BBox[] = regions.map(r => bboxOf(regionPoints(r)))
const used = new Set<number>()
const panels: { rect: BBox; sash: (typeof sashes)[number] }[] = []
const panels: { rect: BBox; sash: (typeof sashes)[number]; ri: number }[] = []
for (const s of sashes) {
const sb: BBox = { x0: s.x0, y0: s.y0, x1: s.x1, y1: s.y1 }
let best = -1, bestA = 0
@@ -277,7 +277,23 @@ function build(drawing: DrawingData) {
const a = overlapArea(sb, rb)
if (a > bestA) { bestA = a; best = ri }
})
if (best >= 0 && bestA > 0) { used.add(best); panels.push({ rect: regionBBs[best], sash: s }) }
if (best >= 0 && bestA > 0) { used.add(best); panels.push({ rect: regionBBs[best], sash: s, ri: best }) }
}
/** 装饰格条(自研 decs 扩展): 玻璃前表面加横竖格条体 */
const addDecBars = (parent: THREE.Group, dec: DecBar, w: number, h: number, mx: number, my: number, z: number) => {
const bw = Math.max(0.004, dec.bw * S)
const mat = new THREE.MeshStandardMaterial({
color: new THREE.Color(dec.color), roughness: 0.5, metalness: 0.3,
})
for (let i = 1; i <= dec.rows; i++) {
const y = my - h / 2 + (h * i) / (dec.rows + 1)
barX(parent, mat, w * 0.995, bw, DEPTH * 0.25, mx, y, z, 1)
}
for (let i = 1; i <= dec.cols; i++) {
const x = mx - w / 2 + (w * i) / (dec.cols + 1)
barY(parent, mat, h * 0.995, bw, DEPTH * 0.25, x, my, z, 1)
}
}
// 静态玻璃 + 中梃(区域薄型材)
@@ -295,10 +311,12 @@ function build(drawing: DrawingData) {
barX(frameGroup, mullionMat, w, t, DEPTH * 0.55, mx, my - h / 2 + t / 2, 0)
barY(frameGroup, mullionMat, h, t, DEPTH * 0.55, mx - w / 2 + t / 2, my, 0)
barY(frameGroup, mullionMat, h, t, DEPTH * 0.55, mx + w / 2 - t / 2, my, 0)
const dec = (shape.decs ?? []).find(d => d.ri === ri)
if (dec) addDecBars(frameGroup, dec, w, h, mx, my, 0.012)
})
// 扇面板(可开合)
panels.forEach(({ rect, sash: s }, k) => {
panels.forEach(({ rect, sash: s, ri }, k) => {
const w = (rect.x1 - rect.x0) * S, h = (rect.y1 - rect.y0) * S
const cxr = ((rect.x0 + rect.x1) / 2 - cx) * S
const cyr = (cy - (rect.y0 + rect.y1) / 2) * S
@@ -311,6 +329,8 @@ function build(drawing: DrawingData) {
barX(group, sashMat, w, t, DEPTH * 0.7, 0, -h / 2 + t / 2, 0)
barY(group, sashMat, h, t, DEPTH * 0.7, -w / 2 + t / 2, 0, 0)
barY(group, sashMat, h, t, DEPTH * 0.7, w / 2 - t / 2, 0, 0)
const dec = (shape.decs ?? []).find(d => d.ri === ri)
if (dec) addDecBars(group, dec, w, h, 0, 0, 0.011)
group.position.set(cxr, cyr, 0)
sashRoot.add(group)