import * as THREE from "three"; export type AnnotationMode = "navigate" | "freehand" | "geodesic" | "point"; export interface SurfaceHit { point: THREE.Vector3; normal: THREE.Vector3; faceIndex: number; } /** Annotation vertex: position and normal are both in **model local space** (single source of truth, unaffected by camera/placement). */ export interface AnnotationVertex { x: number; y: number; z: number; nx: number; ny: number; nz: number; faceIndex: number; } export interface Annotation { id: string; type: "contour" | "points"; mode: "freehand" | "geodesic" | null; label: string; color: string; closed: boolean; visible: boolean; vertices: AnnotationVertex[]; /** * Geodesic control points (local-space positions) — present only for geodesic contours. Lets a * committed contour be re-opened for editing (drag/delete/insert its anchors). Stored as positions * (not graph indices) so it survives export/import across sessions. */ anchors?: AnnotationVertex[]; object3D: THREE.Object3D | null; } export interface ExportOptions { /** Export coordinate space, defaults to "local" (model space, reproducible and unaffected by camera/placement). */ space?: "local" | "world"; /** Whether to attach a normal to each point [x,y,z,nx,ny,nz]. */ includeNormals?: boolean; } /** World-space hit point → local vertex (position via worldToLocal, normal via inverse transform). */ export declare function worldHitToLocalVertex(h: SurfaceHit, mesh: THREE.Mesh): AnnotationVertex; /** Local vertex → world position + world normal (for rendering). */ export declare function localVertexToWorld(v: AnnotationVertex, mesh: THREE.Mesh): { p: THREE.Vector3; n: THREE.Vector3; };