fix: v2.11 3D 全开/全关状态错误根治——分割树重放语义破译与扇五金解析重建

- polyId 语义破译: {idx,pos}=(分裂子树节点id,子区域序), 节点id=sp 0基序号, child0=法线指向侧
- replayShape 重写为树重放(锚点兜底), 704/31594/31729 全引用精确命中官方平面图, 798 扇矩形 100% 有效
- 坐标系修正: 模型 y 向下, 3D 翻转 y, 布局与原图一致
- 扇五金解析: Slide/DoubleSash=推拉, hm.openDirection 定铰链侧(含上悬), hm.openToward 定内外开, od=全开幅
- 移除错误的滑扇附着兜底; 2D 编辑器写回 polyId 同步树寻址
- 验证: 全关/46%/100% 三态截图 + ui-shots 6 页 + validate3d 全量 0 无效
This commit is contained in:
HHY
2026-09-23 04:09:40 -07:00
parent fbef67e450
commit c2c6359a65
17 changed files with 452 additions and 63 deletions
+4 -4
View File
@@ -59,7 +59,7 @@ let resizeDrag: null | { axis: 'w' | 'h' | 'wh'; startW: number; startH: number;
let moveDrag: null | { shapeIdx: number; spIdx: number; startPos: number; startX: number; startY: number; snapshot: string } = null
const selected = ref<{ shapeIdx: number; spIdx: number } | null>(null)
type Replay = { regions: Segment[][]; clips: { sp: SplitLine; bb: { x0: number; y0: number; x1: number; y1: number } }[] }
type Replay = ReturnType<typeof replayShape>
let replays: Replay[] = []
let lastTransform = { scale: 1, midX: 0, midY: 0, W: 0, H: 0 }
@@ -245,8 +245,8 @@ function drawFrame(
ctx.strokeRect(x0 + inset, y0 + inset, (x1 - x0) - inset * 2, (y1 - y0) - inset * 2)
}
// 扇(推断: 有效bd → polyId区域(双扇对半) → 帧bbox按扇数均分) — 共享推断模块
const glyphs = inferSashGlyphs(shape, rp.regions).sashes
// 扇(推断: 有效bd → polyId挂接区域 → 帧bbox按扇数均分) — 共享推断模块
const glyphs = inferSashGlyphs(shape, rp).sashes
for (const g of glyphs) {
const bx0 = tx(g.x0), bx1 = tx(g.x1), by0 = ty(g.y1), by1 = ty(g.y0)
const w = bx1 - bx0, h = by1 - by0
@@ -372,7 +372,7 @@ function onClick(e: MouseEvent) {
mm.sp = mm.sp ?? []
mm.sp.push({
line: { pt: mid, norm, name: 'line' },
polyId: { idx: ri, pos: rp.regions.length },
polyId: rp.leafRefs[ri] ?? { idx: ri, pos: rp.regions.length },
alignType: 0, equalSplit: 0, kw: axis === 'v', ws: false, reinforced: false, db: false,
} as any)
replayOne(si)