feat(구조물표): 323-5 고름 한 칸 — 관 세션 id(옮겨도 그대로 · 저장 안 함) · 고름 강조 한 규칙(pickLights · 카드 형상 · 3D 같은 함수) · 그린 것마다 신원표(data-structure-id + data-part) · 같은 자리 거리 = PIPE_MATCH_M 하나 · 322-0 이 깬 옛 시험 도움 파일 · 줄 수 고침
- `design_pipe_ids.ts` — 장부(세션 pipe-ids) · pipe-s{차례} · 자리 → id(찾는 거리 안 가장 가까운 것) · followMovedPipe 가 id 를 새 자리로(고름 id 그대로 · 순환 import 없게 design_selection 에서 옮김) · 설계 페이지가 프로젝트를 정함(usePipeIds) · 자리 이름 만들기 열 곳 · 되읽기 둘 걷음 · 측점 계획 주인 = 세션 id(withPipeIds)
- `design_pick_match.ts` — pickLights(① id ② 같은 자리 ③ 고른 부분) · paintPicked(카드 통째 형상 · 부분 · 관 계열 · 포장층은 제 손잡이) · tagShape — 관 세트 벽 · 집수정 · 관 · 세월교 측벽 · 몸체 · BOX 끝 · C군 벽 · 물넘이 콘크리트에 신원표 · 형상 판정면은 통째 형상 · 콘크리트만
- 3D — 부재 맞춤 = pickLights(옛 0.01 걷음) · C군 벽 솔리드 = 구조물 id(덮는 측점 어디서 골라도 한 번 스윕한 벽이 켜짐)
- 322-0 이 깬 것 고침 — 노면공 흐름 도움 파일(165 · 231-1) 정의 판 확인 흉내 · design_view_profile 700줄(322-0 이 704)
- 시험: test_323_5_pick(세션 id · 옮김 · 강조 규칙 · 칠하기) · 옛 시험 도움 파일 흉내 · 기대 글 고침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
* ========================================================================== */
|
||||
|
||||
import * as THREE from "three";
|
||||
import { pickLights } from "../A00_Common/design/design_pick_match";
|
||||
import { isNear } from "../A00_Common/design/design_selection";
|
||||
|
||||
/** 3D에서 고른 부재의 신원표 — 메쉬 `userData`에 실려 있는 그 값이다. */
|
||||
export interface StructurePick {
|
||||
@@ -17,6 +19,8 @@ export interface StructurePick {
|
||||
kind: string;
|
||||
/** 부재키(`inlet`·`outlet`·`extra{i}`·`bextra{i}`·`own`·`basin`·`pipe`). 없을 수 있다. */
|
||||
key?: string;
|
||||
/** 구조물 id(323-5 · C군 벽) — 있으면 id 로 맞춤(고름 강조 한 규칙 `pickLights`). */
|
||||
structureId?: string | null;
|
||||
}
|
||||
|
||||
export interface StructurePickControls {
|
||||
@@ -64,18 +68,31 @@ export function bindStructurePick(options: {
|
||||
while (node) {
|
||||
const data = node.userData as Partial<StructurePick>;
|
||||
if (typeof data.chainageM === "number") {
|
||||
return { chainageM: data.chainageM, kind: String(data.kind ?? ""), key: data.key };
|
||||
return {
|
||||
chainageM: data.chainageM,
|
||||
kind: String(data.kind ?? ""),
|
||||
key: data.key,
|
||||
structureId: data.structureId,
|
||||
};
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 이 부재가 지금 고른 것인가 — 부재키가 없는 선택(측점만)은 그 측점 전부를 켠다. */
|
||||
/** 이 부재가 지금 고른 것인가 — 고름 강조 한 규칙(카드 형상과 같음 · 부재키가 없는 선택 = 그 자리 전부). */
|
||||
const asSelection = (pick: StructurePick) => ({
|
||||
chainageM: pick.chainageM,
|
||||
structureId: pick.structureId ?? null,
|
||||
partKey: pick.key,
|
||||
});
|
||||
const asTag = (pick: StructurePick) => ({
|
||||
chainageM: pick.chainageM,
|
||||
structureId: pick.structureId ?? null,
|
||||
part: pick.key,
|
||||
});
|
||||
function matches(tag: StructurePick): boolean {
|
||||
if (!selected) return false;
|
||||
if (Math.abs(tag.chainageM - selected.chainageM) >= 0.01) return false;
|
||||
return selected.key === undefined || tag.key === selected.key;
|
||||
return !!selected && pickLights(asSelection(selected), asTag(tag));
|
||||
}
|
||||
|
||||
function applyHighlight(): void {
|
||||
@@ -138,8 +155,8 @@ export function bindStructurePick(options: {
|
||||
if (!pick) return;
|
||||
const same =
|
||||
selected !== null &&
|
||||
Math.abs(selected.chainageM - pick.chainageM) < 0.01 &&
|
||||
selected.key === pick.key;
|
||||
selected.key === pick.key &&
|
||||
pickLights(asSelection(selected), asTag(pick));
|
||||
selected = same ? null : pick;
|
||||
applyHighlight();
|
||||
controls.onPick?.(selected);
|
||||
@@ -162,7 +179,7 @@ export function bindStructurePick(options: {
|
||||
selectAtChainage(chainageM) {
|
||||
// 3D에서 부재를 집어 이미 그 측점을 고른 상태면 그대로 둔다 — 되돌아온 동기화가
|
||||
// 부재 하나짜리 강조를 그 측점 전체로 넓히면 안 된다(2026-09-04).
|
||||
if (chainageM !== null && selected && Math.abs(selected.chainageM - chainageM) < 0.01) return;
|
||||
if (chainageM !== null && selected && isNear(selected.chainageM, chainageM)) return;
|
||||
selected = chainageM === null ? null : { chainageM, kind: "" };
|
||||
applyHighlight();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user