Files
TJWaterFrontend_Refine/src/components/threeDimensional/sceneProtocol.ts
T
jiang 35b6819459
Generic Container CI/CD / test-build-publish (push) Successful in 17s
Frontend CI/CD v2 / build-test-publish-and-deploy (push) Successful in 18s
feat(3d): integrate ZJB scene with project context
2026-09-11 18:49:55 +08:00

166 lines
4.0 KiB
TypeScript

import type { SceneResultsPayload } from "./sceneData";
export const SCENE_CHANNEL = "tjwater:zjb-scene";
export const SCENE_PROTOCOL_VERSION = 2;
export type SceneMode =
| "network"
| "hydraulic"
| "map"
| "detail"
| "pump"
| "meters";
export type SceneDisplayMode = "global" | "coordinated";
export type SceneMetricMode = "uniform" | "velocity" | "pressure" | "direction";
export type SceneDirectionMode = "none" | "topology" | "results";
export type SceneLightingPreset = "day" | "studio" | "evening";
export type SceneQuality = "standard" | "high";
export type SceneNetworkStyle = {
scale: number;
mode: SceneMetricMode;
color: string;
missingColor: string;
lowColor: string;
highColor: string;
opacity: number;
roughness: number;
metalness: number;
nodes: boolean;
direction: SceneDirectionMode;
arrowColor: string;
autoRange: boolean;
min: number;
max: number;
};
export type SceneAppearance = {
preset: SceneLightingPreset;
exposure: number;
shadows: boolean;
effects: boolean;
quality: SceneQuality;
};
export type SceneCameraView = {
id: string;
label: string;
mode: SceneMode;
note?: string;
saved: boolean;
};
export type SceneCameraState = {
active: string | null;
note: string;
views: SceneCameraView[];
};
export type SceneStyleSummary = {
mode?: SceneMetricMode;
min?: number;
max?: number;
dataLinks?: number;
totalLinks?: number;
arrows?: number;
hasResults?: boolean;
resultTime?: string | null;
scale?: number;
};
export type SceneRuntimeState = {
mode: SceneMode;
status: string;
contextVisible: boolean;
roofVisible: boolean;
displayMode: SceneDisplayMode;
style: SceneNetworkStyle;
styleSummary: SceneStyleSummary;
appearance: SceneAppearance;
camera: SceneCameraState;
};
export type SceneAssetField = {
label: string;
value: string;
};
export type SceneAssetSection = {
title: string;
fields: SceneAssetField[];
};
export type SceneAssetNeighbor = {
id: string;
label: string;
};
export type SceneAssetSelection = {
assetId: string;
elementId: string;
kind: string;
title: string;
sections: SceneAssetSection[];
neighbors: SceneAssetNeighbor[];
};
export type SceneCommand =
| { name: "set-mode"; mode: SceneMode }
| { name: "visit-camera"; viewId: string }
| { name: "save-camera"; label: string }
| { name: "remove-camera"; viewId: string }
| { name: "set-style"; patch: Partial<SceneNetworkStyle> }
| { name: "reset-style" }
| { name: "set-display-mode"; mode: SceneDisplayMode }
| { name: "set-appearance"; patch: Partial<SceneAppearance> }
| { name: "toggle-context" }
| { name: "toggle-roof" }
| { name: "fit-view" }
| { name: "select-asset"; assetId: string }
| { name: "locate-selection" }
| { name: "clear-selection" };
type HostMessageBase = {
channel: typeof SCENE_CHANNEL;
version: typeof SCENE_PROTOCOL_VERSION;
projectCode: string;
modelId: string;
};
export type SceneHostMessage = HostMessageBase &
(
| { type: "results"; payload: SceneResultsPayload }
| { type: "clear-results" }
| { type: "command"; command: SceneCommand }
);
export type SceneRuntimeMessage = HostMessageBase &
(
| {
type: "ready";
nodeIds: string[];
linkIds: string[];
state: SceneRuntimeState;
}
| { type: "scene-state"; state: SceneRuntimeState }
| { type: "selection-changed"; selection: SceneAssetSelection | null }
| { type: "results-applied"; summary: SceneStyleSummary }
| { type: "results-cleared" }
| { type: "error"; message: string }
);
export const isSceneRuntimeMessage = (
input: unknown,
): input is SceneRuntimeMessage => {
if (!input || typeof input !== "object") return false;
const message = input as Partial<SceneRuntimeMessage>;
return (
message.channel === SCENE_CHANNEL &&
message.version === SCENE_PROTOCOL_VERSION &&
typeof message.projectCode === "string" &&
typeof message.modelId === "string" &&
typeof message.type === "string"
);
};