( text: string, options?: ParseCamerasTextOptions )
| 81 | * still load); each skip is logged and reported through `options.onSkip`. |
| 82 | */ |
| 83 | export function parseCamerasText( |
| 84 | text: string, |
| 85 | options?: ParseCamerasTextOptions |
| 86 | ): Map<number, Camera> { |
| 87 | const cameras = new Map<number, Camera>(); |
| 88 | const lines = text.split('\n'); |
| 89 | |
| 90 | for (const [lineIndex, line] of lines.entries()) { |
| 91 | // Skip comments and empty lines |
| 92 | if (line.startsWith('#') || line.trim() === '') continue; |
| 93 | |
| 94 | const parts = line.trim().split(/\s+/); |
| 95 | if (parts.length < 4) continue; |
| 96 | |
| 97 | const cameraId = parseColmapIntegerToken(parts[0], { min: 0 }); |
| 98 | if (cameraId === null) continue; |
| 99 | |
| 100 | const modelName = parts[1]; |
| 101 | const modelId = colmapNameToModelId(modelName); |
| 102 | |
| 103 | if (modelId === undefined) { |
| 104 | appLogger.warn(`Unknown camera model: ${modelName}`); |
| 105 | options?.onSkip?.({ line: lineIndex + 1, modelName }); |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | const width = parseColmapIntegerToken(parts[2], { min: 0 }); |
| 110 | const height = parseColmapIntegerToken(parts[3], { min: 0 }); |
| 111 | const params = parseColmapNumberTokens(parts.slice(4)); |
| 112 | |
| 113 | if (width === null || height === null || params === null) continue; |
| 114 | |
| 115 | cameras.set(cameraId, { |
| 116 | cameraId, |
| 117 | modelId, |
| 118 | width, |
| 119 | height, |
| 120 | params, |
| 121 | }); |
| 122 | } |
| 123 | |
| 124 | return cameras; |
| 125 | } |
no test coverage detected