feat(view): solplate in the 3D model (2단계): wedges from the drawing's A, B, S; read the solplate table from DXF
Each bearing gets a solplate wedge: tapered along the 교축 with T1 on the 시점 side, underside at the bearing top (block top + h3). A, B come from the drawing's ELEVATION table, S and T1/T2 from the SOLPLATE table (NO, S(%), L, W, T, T1, T2), read by position. The 공통 규칙 (T 30, margin 100, h3 181) feed the plan; changing them regenerates the piers. A new "솔플레이트" part can be shown or hidden. A solplate table is read only when its S values are found; a missing S is reported. Also commits the option-1 test change (drawing EL.X minus Excel z). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1d8746d533
commit
a50f4f5ee5
10 files changed
+579
-13
No files matched your search
+32
-1
@@ -1,7 +1,8 @@
|
||||
import * as THREE from 'three';
|
||||
import type { PierModel } from '../core/geometry';
|
||||
import { solplateGeometry } from '../core/solplate';
|
||||
|
||||
export type PartName = 'coping' | 'columns' | 'footings' | 'piles' | 'blinding' | 'blocks' | 'pads' | 'ground';
|
||||
export type PartName = 'coping' | 'columns' | 'footings' | 'piles' | 'blinding' | 'blocks' | 'pads' | 'solplates' | 'ground';
|
||||
|
||||
export const PART_LABELS: Record<PartName, string> = {
|
||||
coping: '코핑',
|
||||
@@ -11,6 +12,7 @@ export const PART_LABELS: Record<PartName, string> = {
|
||||
blinding: '버림콘크리트',
|
||||
blocks: '받침블럭',
|
||||
pads: '모르타르 패드',
|
||||
solplates: '솔플레이트',
|
||||
ground: '지반',
|
||||
};
|
||||
|
||||
@@ -22,6 +24,7 @@ const COLORS: Record<PartName, number> = {
|
||||
blinding: 0xe6e2d8,
|
||||
blocks: 0xd6dde5,
|
||||
pads: 0x8898aa,
|
||||
solplates: 0x6f7c8a,
|
||||
ground: 0x6b8f4e,
|
||||
};
|
||||
|
||||
@@ -136,6 +139,11 @@ export function buildPierScene(m: PierModel): PierScene {
|
||||
pad.rotateY(turn);
|
||||
pad.translate(b.s, b.padTop - 0.025, b.n);
|
||||
add('pads', pad, 1, b.k);
|
||||
if (b.plan) {
|
||||
// Solplate: a wedge that tapers along the 교축 (T1 on the 시점 side), on the bearing (승인 2026-10-23).
|
||||
const sp = solplateGeometry(b, b.plan.h3, { A: b.plan.A, B: b.plan.B, margin: b.plan.margin, T: b.plan.T, slopePct: b.plan.S });
|
||||
add('solplates', wedgeGeometry(sp.corners), 1, b.k);
|
||||
}
|
||||
}
|
||||
|
||||
// Ground: a translucent plane at the ground EL, used only to judge soil cover (not a computed input).
|
||||
@@ -186,3 +194,26 @@ export function viewPosition(scene: PierScene, kind: ViewKind, m: PierModel): {
|
||||
};
|
||||
return { position: target.clone().add(dirs[kind].multiplyScalar(dist)), target };
|
||||
}
|
||||
|
||||
/**
|
||||
* A wedge from the eight corners of solplateGeometry: corner index (ai, ci, t) = (ai·2 + ci)·2 + t, with ai the 교축 side
|
||||
* (0 = 시점), ci the 교각축 직각 side and t 0 = underside, 1 = top. Each face is a quad split into two triangles.
|
||||
*/
|
||||
function wedgeGeometry(corners: [number, number, number][]): THREE.BufferGeometry {
|
||||
const idx = (ai: number, ci: number, t: number) => (ai * 2 + ci) * 2 + t;
|
||||
const quads = [
|
||||
[idx(0, 0, 0), idx(0, 1, 0), idx(1, 1, 0), idx(1, 0, 0)],
|
||||
[idx(0, 0, 1), idx(1, 0, 1), idx(1, 1, 1), idx(0, 1, 1)],
|
||||
[idx(0, 0, 0), idx(0, 1, 0), idx(0, 1, 1), idx(0, 0, 1)],
|
||||
[idx(1, 0, 0), idx(1, 0, 1), idx(1, 1, 1), idx(1, 1, 0)],
|
||||
[idx(0, 0, 0), idx(0, 0, 1), idx(1, 0, 1), idx(1, 0, 0)],
|
||||
[idx(0, 1, 0), idx(1, 1, 0), idx(1, 1, 1), idx(0, 1, 1)],
|
||||
];
|
||||
const index: number[] = [];
|
||||
for (const [q0, q1, q2, q3] of quads) index.push(q0, q1, q2, q0, q2, q3);
|
||||
const geo = new THREE.BufferGeometry();
|
||||
geo.setAttribute('position', new THREE.Float32BufferAttribute(corners.flat(), 3));
|
||||
geo.setIndex(index);
|
||||
geo.computeVertexNormals();
|
||||
return geo;
|
||||
}
|
||||
Reference in new issue
Block a user