feat(rebar): select several bars on ③ and show only the selected ones (선택만 보기)

The 철근표 has a selection checkbox per row. Select-all / clear and 선택만 보기 sit above the table. In 선택만 보기 the other
bars are hidden in 3D and the members stay at 50% for context. A 3D click or an alert [보기] selects one bar; the
selection clears when the member tab or the pier changes. The selection is screen state and is not saved to the project.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-23 09:57:04 +09:00
1 parent b3533b69df
commit f398b4341f
4 files changed
+78 -24

No files matched your search

+9 -11
View File
@@ -18,7 +18,8 @@ export interface RebarScene {
group: THREE.Group;
byName: Map<string, THREE.Mesh[]>;
/** Highlight one bar name (or none): the others are dimmed. */
highlight(name: string | null): void;
/** Emphasise the bars in `names` (all when null). The others are dimmed, or hidden when `isolate` is on (선택만 보기). */
show(names: ReadonlySet<string> | null, isolate: boolean): void;
/** Colour the bars by role (default, spec §6.7), by nominal diameter, or by member. */
setColorMode(mode: RebarColorMode): void;
/** Legend entries of the mode, only for the items this model has. Role mode has none (the role colours are in §6.7). */
@@ -436,20 +437,17 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
}
}
const highlight = (name: string | null) => {
const show = (names: ReadonlySet<string> | null, isolate: boolean) => {
// 커플러 as a name selects every coupler bar.
const isOn = (key: string) => names === null || names.has(key) || (names.has('커플러') && key.includes('커플러'));
for (const [key, meshes] of byName) {
const on = isOn(key);
for (const mesh of meshes) {
const mat = mesh.material as THREE.MeshStandardMaterial;
const on =
name === null ||
key === name ||
(name === '커플러' && key.includes('커플러')) ||
(name === '주철근 커플러' && key === '주철근 커플러') ||
(name === '띠철근 커플러' && key === '띠철근 커플러');
mat.transparent = !on;
mat.opacity = on ? 1 : 0.18;
const match = name !== null && (key === name || (name === '커플러' && key.includes('커플러')));
mat.emissive.setHex(match ? 0x6b5a00 : 0x000000);
mat.emissive.setHex(names !== null && on ? 0x6b5a00 : 0x000000);
mesh.visible = !isolate || on;
}
}
};
@@ -476,5 +474,5 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
const items = DIAMETER_GROUPS.map((g, i) => ({ label: g.label, color: hex(DIAMETER_COLORS[i]) })).filter((_, i) => present.has(i));
return present.has(-1) ? [...items, { label: '기타', color: hex(OTHER_COLOR) }] : items;
};
return { group, byName, highlight, setColorMode, legend };
return { group, byName, show, setColorMode, legend };
}