156 lines
4.5 KiB
TypeScript
156 lines
4.5 KiB
TypeScript
import { create } from 'zustand';
|
|
|
|
interface ModelInfo {
|
|
fileName: string;
|
|
fileSize: number;
|
|
url: string;
|
|
}
|
|
|
|
interface FineTuning {
|
|
posX: number;
|
|
posY: number;
|
|
posZ: number;
|
|
rotY: number;
|
|
}
|
|
|
|
type AnchorMode = 'tracking' | 'manual' | 'fine-tuning';
|
|
type InspectionResult = 'pending' | 'approved' | 'rejected';
|
|
type RenderMode = 'solid' | 'wireframe';
|
|
|
|
export interface MeasurePoint {
|
|
x: number;
|
|
y: number;
|
|
z: number;
|
|
}
|
|
|
|
export interface Measurement {
|
|
id: string;
|
|
pointA: MeasurePoint;
|
|
pointB: MeasurePoint;
|
|
distanceMM: number;
|
|
}
|
|
|
|
export interface ChecklistItem {
|
|
id: string;
|
|
label: string;
|
|
status: 'pending' | 'approved' | 'rejected';
|
|
note: string;
|
|
audioUrl: string | null;
|
|
}
|
|
|
|
const defaultChecklist: ChecklistItem[] = [
|
|
{ id: 'dimensions', label: 'Dimensões Gerais', status: 'pending', note: '', audioUrl: null },
|
|
{ id: 'plates', label: 'Posição das Placas', status: 'pending', note: '', audioUrl: null },
|
|
{ id: 'holes', label: 'Diâmetro dos Furos', status: 'pending', note: '', audioUrl: null },
|
|
{ id: 'weld', label: 'Especificação da Solda', status: 'pending', note: '', audioUrl: null },
|
|
];
|
|
|
|
interface ModelStore {
|
|
model: ModelInfo | null;
|
|
setModel: (model: ModelInfo | null) => void;
|
|
|
|
fineTuning: FineTuning;
|
|
setFineTuning: (ft: Partial<FineTuning>) => void;
|
|
resetFineTuning: () => void;
|
|
|
|
anchorMode: AnchorMode;
|
|
setAnchorMode: (mode: AnchorMode) => void;
|
|
|
|
inspectionResult: InspectionResult;
|
|
setInspectionResult: (result: InspectionResult) => void;
|
|
|
|
xrSupported: boolean | null;
|
|
setXrSupported: (supported: boolean | null) => void;
|
|
|
|
opacity: number;
|
|
setOpacity: (opacity: number) => void;
|
|
|
|
renderMode: RenderMode;
|
|
setRenderMode: (mode: RenderMode) => void;
|
|
|
|
checklist: ChecklistItem[];
|
|
setChecklistItemStatus: (id: string, status: 'approved' | 'rejected') => void;
|
|
setChecklistItemNote: (id: string, note: string) => void;
|
|
setChecklistItemAudio: (id: string, audioUrl: string | null) => void;
|
|
resetChecklist: () => void;
|
|
|
|
measureMode: boolean;
|
|
setMeasureMode: (on: boolean) => void;
|
|
measurePoints: MeasurePoint[];
|
|
addMeasurePoint: (p: MeasurePoint) => void;
|
|
measurements: Measurement[];
|
|
clearMeasurements: () => void;
|
|
removeMeasurement: (id: string) => void;
|
|
}
|
|
|
|
const defaultFineTuning: FineTuning = { posX: 0, posY: 0, posZ: 0, rotY: 0 };
|
|
|
|
export const useModelStore = create<ModelStore>((set) => ({
|
|
model: null,
|
|
setModel: (model) => set({ model }),
|
|
|
|
fineTuning: { ...defaultFineTuning },
|
|
setFineTuning: (ft) => set((state) => ({ fineTuning: { ...state.fineTuning, ...ft } })),
|
|
resetFineTuning: () => set({ fineTuning: { ...defaultFineTuning } }),
|
|
|
|
anchorMode: 'manual',
|
|
setAnchorMode: (anchorMode) => set({ anchorMode }),
|
|
|
|
inspectionResult: 'pending',
|
|
setInspectionResult: (inspectionResult) => set({ inspectionResult }),
|
|
|
|
xrSupported: null,
|
|
setXrSupported: (xrSupported) => set({ xrSupported }),
|
|
|
|
opacity: 1,
|
|
setOpacity: (opacity) => set({ opacity }),
|
|
|
|
renderMode: 'solid',
|
|
setRenderMode: (renderMode) => set({ renderMode }),
|
|
|
|
checklist: defaultChecklist.map(i => ({ ...i })),
|
|
setChecklistItemStatus: (id, status) => set((state) => ({
|
|
checklist: state.checklist.map(item =>
|
|
item.id === id ? { ...item, status } : item
|
|
),
|
|
})),
|
|
setChecklistItemNote: (id, note) => set((state) => ({
|
|
checklist: state.checklist.map(item =>
|
|
item.id === id ? { ...item, note } : item
|
|
),
|
|
})),
|
|
setChecklistItemAudio: (id, audioUrl) => set((state) => ({
|
|
checklist: state.checklist.map(item =>
|
|
item.id === id ? { ...item, audioUrl } : item
|
|
),
|
|
})),
|
|
resetChecklist: () => set({ checklist: defaultChecklist.map(i => ({ ...i })) }),
|
|
|
|
measureMode: false,
|
|
setMeasureMode: (measureMode) => set({ measureMode, measurePoints: [] }),
|
|
measurePoints: [],
|
|
addMeasurePoint: (p) => set((state) => {
|
|
const points = [...state.measurePoints, p];
|
|
if (points.length === 2) {
|
|
const [a, b] = points;
|
|
const dx = (a.x - b.x) * 1000;
|
|
const dy = (a.y - b.y) * 1000;
|
|
const dz = (a.z - b.z) * 1000;
|
|
const distanceMM = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
const measurement: Measurement = {
|
|
id: `m_${Date.now()}`,
|
|
pointA: a,
|
|
pointB: b,
|
|
distanceMM,
|
|
};
|
|
return { measurePoints: [], measurements: [...state.measurements, measurement] };
|
|
}
|
|
return { measurePoints: points };
|
|
}),
|
|
measurements: [],
|
|
clearMeasurements: () => set({ measurements: [], measurePoints: [] }),
|
|
removeMeasurement: (id) => set((state) => ({
|
|
measurements: state.measurements.filter(m => m.id !== id),
|
|
})),
|
|
}));
|