feat(abut-rebar): ③ 교대 벽체 3D 철근 (W1–W11)
- 벽체 배근 경로를 저판 철근과 같은 교대 3D 철근에 추가 (buildAbutRebar3D). 선택 · 선택만 보기 · 색 기준 공통 - 테스트: 철근표 = 3D 개수, 모든 벽체 철근이 벽체 면 · 끝면 안, 저판 하면 철근망 위 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a17c9ebbb4
commit
a4c7bcabcf
3 files changed
+56
-10
No files matched your search
+5
-4
@@ -73,7 +73,7 @@ import { pileGeometry } from './core/geometry';
|
||||
import { rebarSummary, type RebarRow } from './core/rebar/summary';
|
||||
import { shearSegments } from './core/rebar/coping';
|
||||
import { buildRebar3D, type RebarColorMode, type RebarScene } from './view/rebar3d';
|
||||
import { buildAbutFootingRebar3D } from './view/abut-rebar3d';
|
||||
import { buildAbutRebar3D } from './view/abut-rebar3d';
|
||||
import { DEFAULT_MATERIAL, FCK_MEMBERS, fckChanged, fyOf, GRADE_CHOICES, IMPORTED_FCK, isAssumedMaterial, materialFor, materialFrom, type BendFactors, type FckByMember, type FckMember, type GradeKey, type Material } from './core/rebar/common';
|
||||
import { buildQuantity, quantityRows, type Quantity, type QuantityLine } from './core/rebar/quantity';
|
||||
import { groundElFor, parseGroundModel, strataRowsFor, type GroundMapLayer, type GroundModelFile } from './core/ground-model';
|
||||
@@ -682,12 +682,13 @@ function setupScene(): void {
|
||||
state.scene = scene;
|
||||
setView(state.view);
|
||||
}
|
||||
// ③ 교대 (2026-11-04): with the piers hidden, the selected abutment's 저판 rebar is the ③ rebar (표 · 3D 선택 공통).
|
||||
// ③ 교대 (2026-11-04): with the piers hidden, the selected abutment's 저판 · 벽체 rebar is the ③ rebar (표 · 3D 선택 공통).
|
||||
const abutRec = piersShown(state.stage, state.abutActive) ? undefined : state.abutments.find((a) => a.name === state.abutActive);
|
||||
const abutGroup = abutRec ? abutGroupByName.get(abutRec.name) : undefined;
|
||||
const footing = abutRec ? abutFootingBuilt(abutRec) : null;
|
||||
if (abutGroup && footing && footing.bottomEl !== undefined) {
|
||||
rebar3d = buildAbutFootingRebar3D(footing.geom, footing.result, footing.skewK, footing.backM, footing.bottomEl);
|
||||
if (abutRec && abutGroup && footing && footing.bottomEl !== undefined) {
|
||||
const wall = abutWallBuilt(abutRec, footing.result);
|
||||
rebar3d = buildAbutRebar3D(footing.geom, footing.result, footing.skewK, footing.backM, footing.bottomEl, wall?.result);
|
||||
rebar3d.group.applyMatrix4(abutGroup.matrix);
|
||||
rebar3d.group.visible = state.stage === 'rebar';
|
||||
rebar3d.setColorMode(state.rebarColor);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* 교대 저판 3D 철근 (③, 2026-11-04). Positions come from `abutFootingRebar` (no new rules here); the shapes follow the
|
||||
* 교대 3D 철근 (③, 2026-11-04): 저판 B1–B10과 벽체 W1–W11. Positions come from `abutFootingRebar` · `abutWallRebar`
|
||||
* (no new rules here; the 벽체 bars are its paths). The 저판 shapes follow the
|
||||
* 배근 삽도 (abut-footing-rebar-svg.ts): B1 ⊓ / B2 ⊔ / B3 · B4 직선, B5 ⊓ / B6 ⊔ / B7 · B8 직선, B9 연직, B10 측면, B1-S · B2-S.
|
||||
* Hooks and the bend radii are not drawn. Each bar is named by its 철근표 number, so the table, the 삽도 and the model
|
||||
* share one selection. Local frame = the abutment group's (x = s along the axis, y = EL, z = t toward the front).
|
||||
@@ -8,20 +9,23 @@ import * as THREE from 'three';
|
||||
import type { AbutFootingGeom, AbutFootingRebar } from '../core/abut/rebar/footing';
|
||||
import { NOMINAL_DIAMETER } from '../core/rebar/common';
|
||||
import { memberOfBar } from '../core/rebar/color';
|
||||
import { ABUT_WALL_SIZES, type AbutWallRebar } from '../core/abut/rebar/wall';
|
||||
import { ABUT_FOOTING_COLORS } from './abut-footing-rebar-svg';
|
||||
import { ABUT_WALL_COLORS } from './abut-wall-rebar-svg';
|
||||
import { rebarColor, rebarControls, type RebarScene } from './rebar3d';
|
||||
|
||||
type P3 = [number, number, number];
|
||||
|
||||
/**
|
||||
* @param skewK plan skew (s per m of t, `abutSkewK`), @param backM 저판 배면 t (m), @param bottomEl 기초 하단 EL (m).
|
||||
* @param skewK plan skew (s per m of t, `abutSkewK`), @param backM 저판 배면 t (m), @param bottomEl 기초 하단 EL (m),
|
||||
* @param wall 벽체 배근 (없으면 저판만).
|
||||
*/
|
||||
export function buildAbutFootingRebar3D(g: AbutFootingGeom, r: AbutFootingRebar, skewK: number, backM: number, bottomEl: number): RebarScene {
|
||||
export function buildAbutRebar3D(g: AbutFootingGeom, r: AbutFootingRebar, skewK: number, backM: number, bottomEl: number, wall?: AbutWallRebar): RebarScene {
|
||||
const group = new THREE.Group();
|
||||
group.name = 'abut-rebar';
|
||||
const byName = new Map<string, THREE.Mesh[]>();
|
||||
const C = Object.fromEntries(Object.entries(ABUT_FOOTING_COLORS).map(([k, v]) => [k, parseInt(v.slice(1), 16)])) as Record<keyof typeof ABUT_FOOTING_COLORS, number>;
|
||||
const sizeOf = new Map(r.bars.map((b) => [b.mark, b.size]));
|
||||
const sizeOf = new Map<string, keyof typeof NOMINAL_DIAMETER>([...r.bars.map((b) => [b.mark, b.size] as const), ...Object.entries(ABUT_WALL_SIZES)]);
|
||||
// (s, x, z) in mm: s along the skew grid (끝면과 나란히), x from the 배면, z from the 저판 하면.
|
||||
const P = (s: number, x: number, z: number): P3 => [s / 1000 + skewK * (backM + x / 1000), bottomEl + z / 1000, backM + x / 1000];
|
||||
// Option ②: square to the axis, s in the 삽도's frame (abutFootingRebarPlanSvg SQ), the same for every x.
|
||||
@@ -96,5 +100,12 @@ export function buildAbutFootingRebar3D(g: AbutFootingGeom, r: AbutFootingRebar,
|
||||
for (const x of [depth1, g.W - depth1]) add('B10-1', [P(e2, x, z1), P(g.L - e2, x, z1)], C.side);
|
||||
for (const s of [e2, g.L - e2]) add('B10-2', [P(s, depth1, z), P(s, g.W - depth1, z)], C.side);
|
||||
}
|
||||
// 벽체: the rule paths in (u, t, z) mm — u on the skew grid, t from the axis, z from the 저판 하면.
|
||||
if (wall) {
|
||||
const W = Object.fromEntries(Object.entries(ABUT_WALL_COLORS).map(([k, v]) => [k, parseInt(v.slice(1), 16)])) as Record<keyof typeof ABUT_WALL_COLORS, number>;
|
||||
const colorOf = (mark: string) =>
|
||||
['W1', 'W3', 'W4', 'W11'].includes(mark) ? W.vertical : mark === 'W7' ? W.tie : mark === 'W9' || mark === 'W10' ? W.step : W.horizontal;
|
||||
for (const p of wall.paths) add(p.mark, p.pts.map(([u, t, z]): P3 => [u / 1000 + (skewK * t) / 1000, bottomEl + z / 1000, t / 1000]), colorOf(p.mark));
|
||||
}
|
||||
return { group, byName, records: [], ...rebarControls(byName) };
|
||||
}
|
||||
Reference in new issue
Block a user