(
paths: Iterable<string>,
options: ResolveColmapPathsOptions = {}
)
| 101 | * when no complete model is present. |
| 102 | */ |
| 103 | export function resolveColmapPaths( |
| 104 | paths: Iterable<string>, |
| 105 | options: ResolveColmapPathsOptions = {} |
| 106 | ): ColmapPathSelection | null { |
| 107 | const requirePoints3D = options.requirePoints3D ?? true; |
| 108 | const directories = new Map<string, ColmapDirectory>(); |
| 109 | |
| 110 | for (const rawPath of paths) { |
| 111 | const role = getColmapRole(getBasename(rawPath)); |
| 112 | if (!role) { |
| 113 | continue; |
| 114 | } |
| 115 | const dir = getParentDir(rawPath); |
| 116 | const entry = directories.get(dir) ?? {}; |
| 117 | entry[role] = role === 'database' |
| 118 | ? (entry[role] ?? rawPath) |
| 119 | : choosePreferredPath(entry[role], rawPath); |
| 120 | directories.set(dir, entry); |
| 121 | } |
| 122 | |
| 123 | const candidates: { dir: string; entry: ColmapDirectory }[] = []; |
| 124 | for (const [dir, entry] of directories) { |
| 125 | if (entry.cameras && entry.images && (entry.points3D || !requirePoints3D)) { |
| 126 | candidates.push({ dir, entry }); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | if (candidates.length === 0) { |
| 131 | return null; |
| 132 | } |
| 133 | |
| 134 | candidates.sort((a, b) => { |
| 135 | const scoreDelta = getColmapDirectoryScore(a.dir) - getColmapDirectoryScore(b.dir); |
| 136 | return scoreDelta !== 0 ? scoreDelta : a.dir.localeCompare(b.dir); |
| 137 | }); |
| 138 | |
| 139 | const best = candidates[0]; |
| 140 | return { |
| 141 | dir: best.dir, |
| 142 | cameras: best.entry.cameras, |
| 143 | images: best.entry.images, |
| 144 | points3D: best.entry.points3D, |
| 145 | database: best.entry.database, |
| 146 | rigs: best.entry.rigs, |
| 147 | frames: best.entry.frames, |
| 148 | }; |
| 149 | } |
| 150 | |
| 151 | const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.tif']; |
| 152 |
no test coverage detected