#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include } namespace { enum class Mode { kA6000, kS21 }; enum class RestartBoundary { kNone, kRepresentations, kFeatures, kGeometry }; struct Options { Mode mode{}; bool has_mode{}; bool resume_geometry_existing{}; bool resume_pre_gv_existing{}; bool resume_candidate_existing{}; unsigned int cpu_budget{}; std::filesystem::path project_dir; std::vector roots; size_t limit{LARDON3D_VISUAL_INDEX_CANDIDATE_MAX}; RestartBoundary restart{RestartBoundary::kNone}; }; struct Campaign { std::vector sources; std::vector confirmations; }; struct Runtime { Lardon3DAppState state{}; std::string project_path; std::string database_path; unsigned int cpu_budget{}; }; struct Evidence { size_t selected{}; size_t features{}; size_t pairs{}; size_t matches{}; size_t verified{}; size_t rejected{}; size_t tracks{}; }; void usage(const char *program) { std::fprintf( stderr, "Usage: %s --mode a6000|s21 --project-dir ABSOLUTE_EMPTY_DIR " "--root ABSOLUTE_DIR [--root ABSOLUTE_DIR ...] [--limit 1..4096] " "[--restart-boundary representations|features|geometry]\n" " %s --resume-geometry-existing --project-dir " "ABSOLUTE_EXISTING_DIR\n" " %s --resume-pre-gv-existing --project-dir " "ABSOLUTE_EXISTING_DIR\n" " %s --resume-candidate-existing --project-dir " "ABSOLUTE_EXISTING_DIR [--cpu-budget 1..12]\n", program, program, program, program); } bool parse_size(const char *text, size_t &value) { char *end = nullptr; errno = 0; const unsigned long long parsed = std::strtoull(text, &end, 10); if (errno != 0 || end == text || *end != '\0' || parsed == 0 || parsed > LARDON3D_VISUAL_INDEX_CANDIDATE_MAX) return false; value = static_cast(parsed); return true; } bool parse_cpu_budget(const char *text, unsigned int &value) { size_t parsed = 0; if (!parse_size(text, parsed) || parsed > 12) return false; value = static_cast(parsed); return true; } bool parse_options(int argc, char **argv, Options &options) { for (int index = 1; index < argc; ++index) { const std::string argument(argv[index]); if (argument == "--help") { usage(argv[0]); std::exit(0); } if (argument == "--resume-geometry-existing") { options.resume_geometry_existing = true; continue; } if (argument == "--resume-pre-gv-existing") { options.resume_pre_gv_existing = true; continue; } if (argument == "--resume-candidate-existing") { options.resume_candidate_existing = true; continue; } if ((argument == "--mode" || argument == "--project-dir" || argument == "--root" || argument == "--limit" || argument == "--restart-boundary" || argument == "--cpu-budget") && index + 1 >= argc) return false; if (argument == "--mode") { const std::string value(argv[++index]); if (value == "a6000") options.mode = Mode::kA6000; else if (value == "s21") options.mode = Mode::kS21; else return false; options.has_mode = true; } else if (argument == "--project-dir") { options.project_dir = argv[++index]; } else if (argument == "--root") { options.roots.emplace_back(argv[++index]); } else if (argument == "--limit") { if (!parse_size(argv[++index], options.limit)) return false; } else if (argument == "--restart-boundary") { const std::string value(argv[++index]); if (value == "representations") options.restart = RestartBoundary::kRepresentations; else if (value == "features") options.restart = RestartBoundary::kFeatures; else if (value == "geometry") options.restart = RestartBoundary::kGeometry; else return false; } else if (argument == "--cpu-budget") { if (!parse_cpu_budget(argv[++index], options.cpu_budget)) return false; } else { return false; } } const unsigned int resume_mode_count = options.resume_geometry_existing + options.resume_pre_gv_existing + options.resume_candidate_existing; if (resume_mode_count != 0) return !options.has_mode && !options.project_dir.empty() && options.roots.empty() && options.restart == RestartBoundary::kNone && resume_mode_count == 1 && (options.resume_candidate_existing || options.cpu_budget == 0); if (options.cpu_budget != 0) return false; return options.has_mode && !options.project_dir.empty() && !options.roots.empty() && options.roots.size() <= LARDON3D_ACQUISITION_CAMPAIGN_MAX_ROOTS; } bool prepare_existing_project(const std::filesystem::path &input, Runtime &runtime) { if (!input.is_absolute() || input.lexically_normal() != input) return false; std::error_code error; if (!std::filesystem::is_directory(input, error) || error || !std::filesystem::is_regular_file(input / "project.lardon3d", error) || error || !std::filesystem::is_directory(input / ".lardon3d" / "checkpoints", error) || error) return false; runtime.project_path = input.string(); runtime.database_path = (input / "project.lardon3d").string(); return runtime.project_path.size() < LARDON3D_APP_STATE_PATH_CAPACITY; } bool prepare_empty_project(const std::filesystem::path &input, std::string &path) { if (!input.is_absolute() || input.lexically_normal() != input) return false; std::error_code error; if (std::filesystem::exists(input, error)) { if (error || !std::filesystem::is_directory(input, error) || error || !std::filesystem::is_empty(input, error) || error) return false; } else if (!std::filesystem::create_directories(input, error) || error) { return false; } path = input.string(); if (path.size() >= LARDON3D_APP_STATE_PATH_CAPACITY) return false; return std::filesystem::create_directories(input / ".lardon3d" / "checkpoints", error) && !error; } bool canonical_root(const std::filesystem::path &input, Lardon3DAcquisitionCampaignRoot &root) { if (!input.is_absolute()) return false; std::error_code error; const auto canonical = std::filesystem::canonical(input, error); if (error || !std::filesystem::is_directory(canonical, error) || error) return false; const std::string path = canonical.string(); if (path.size() >= sizeof(root.path)) return false; std::memcpy(root.path, path.c_str(), path.size() + 1u); return true; } std::string source_stem(const char *path) { const char *name = std::strrchr(path, '/'); name = name == nullptr ? path : name + 1; const char *dot = std::strrchr(name, '.'); return std::string(name, dot == nullptr ? std::strlen(name) : static_cast(dot - name)); } bool discover_campaign(const Options &options, Campaign &campaign) { std::vector roots(options.roots.size()); for (size_t index = 0; index < roots.size(); ++index) if (!canonical_root(options.roots[index], roots[index])) { std::fprintf(stderr, "campaign root %zu is not an absolute readable directory: %s\n", index, options.roots[index].c_str()); return false; } auto discovery = std::make_unique(); const auto discovery_result = lardon3d_acquisition_campaign_discover(roots.data(), roots.size(), discovery.get()); if (discovery_result != LARDON3D_ACQUISITION_CAMPAIGN_OK) { std::fprintf(stderr, "campaign discovery failed with result %d\n", static_cast(discovery_result)); return false; } std::vector> groups; if (options.mode == Mode::kS21) { for (size_t index = 0; index < discovery->source_count && groups.size() < options.limit; ++index) { if (discovery->sources[index].source_kind == LARDON3D_ACQUISITION_SOURCE_JPEG) groups.push_back({index}); } } else { struct Pair { size_t raw{SIZE_MAX}; size_t jpeg{SIZE_MAX}; }; std::map pairs; for (size_t index = 0; index < discovery->source_count; ++index) { Pair &pair = pairs[source_stem(discovery->sources[index].path)]; if (discovery->sources[index].source_kind == LARDON3D_ACQUISITION_SOURCE_RAW) { if (pair.raw != SIZE_MAX) { std::fprintf(stderr, "duplicate RAW stem in discovery: %s\n", source_stem(discovery->sources[index].path).c_str()); return false; } pair.raw = index; } else if (discovery->sources[index].source_kind == LARDON3D_ACQUISITION_SOURCE_JPEG) { if (pair.jpeg != SIZE_MAX) { std::fprintf(stderr, "duplicate JPEG stem in discovery: %s\n", source_stem(discovery->sources[index].path).c_str()); return false; } pair.jpeg = index; } } for (const auto &entry : pairs) { if (entry.second.raw == SIZE_MAX || entry.second.jpeg == SIZE_MAX) { std::fprintf(stderr, "unpaired A6000 stem: %s (%s missing)\n", entry.first.c_str(), entry.second.raw == SIZE_MAX ? "RAW" : "JPEG"); return false; } groups.push_back({entry.second.raw, entry.second.jpeg}); if (groups.size() == options.limit) break; } } if (groups.empty()) { std::fprintf(stderr, "campaign discovery found no usable groups among %zu sources\n", discovery->source_count); return false; } std::vector selected_indices; for (const auto &group : groups) selected_indices.insert(selected_indices.end(), group.begin(), group.end()); std::sort(selected_indices.begin(), selected_indices.end()); std::vector compact_index(discovery->source_count, SIZE_MAX); for (const size_t discovery_index : selected_indices) { compact_index[discovery_index] = campaign.sources.size(); campaign.sources.push_back(discovery->sources[discovery_index]); } /* Filename stems are used only to form explicit CALLER_EXPLICIT input before * Captures exist. The compact source array retains discovery's global canonical * path order, while confirmations map each pair independently of that order. * Once S3-E returns, every phase below follows durable group, Capture, Asset and * image IDs and never treats this convenience key as identity. */ for (const auto &group : groups) { Lardon3DAcquisitionCampaignConfirmation confirmation{}; confirmation.source_count = group.size(); for (size_t member = 0; member < group.size(); ++member) confirmation.source_indices[member] = compact_index[group[member]]; campaign.confirmations.push_back(confirmation); } auto plan = std::make_unique(); const auto plan_result = lardon3d_acquisition_campaign_plan( campaign.sources.data(), campaign.sources.size(), campaign.confirmations.data(), campaign.confirmations.size(), plan.get()); if (plan_result != LARDON3D_ACQUISITION_CAMPAIGN_OK || plan->group_count != campaign.confirmations.size()) { std::fprintf(stderr, "explicit campaign plan rejected: result=%d sources=%zu confirmations=%zu " "groups=%zu\n", static_cast(plan_result), campaign.sources.size(), campaign.confirmations.size(), plan->group_count); return false; } return true; } void stop_runtime(Runtime &runtime) { if (runtime.state.task_queue) lardon3d_task_queue_destroy(runtime.state.task_queue); if (runtime.state.resource_governor) lardon3d_resource_governor_destroy(runtime.state.resource_governor); if (runtime.state.project_db) lardon3d_project_db_close(runtime.state.project_db); runtime.state.task_queue = nullptr; runtime.state.resource_governor = nullptr; runtime.state.project_db = nullptr; } bool start_runtime(Runtime &runtime) { char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY]{}; lardon3d_app_state_init(&runtime.state); if (lardon3d_project_db_open(runtime.database_path.c_str(), &runtime.state.project_db, error) != LARDON3D_PROJECT_DB_OK) { std::fprintf(stderr, "project DB open failed: %s\n", error); return false; } char hardware_error[256]{}; Lardon3DResourcePolicy policy{}; if (!lardon3d_hardware_profile_detect(&runtime.state.hardware_profile, hardware_error, sizeof(hardware_error)) || !lardon3d_resource_policy_default(&runtime.state.hardware_profile, &policy)) { std::fprintf(stderr, "hardware policy failed: %s\n", hardware_error); stop_runtime(runtime); return false; } if (runtime.cpu_budget != 0) { if (runtime.cpu_budget > runtime.state.hardware_profile.logical_cpu_count) { std::fprintf(stderr, "requested CPU budget %u exceeds logical CPU count %u\n", runtime.cpu_budget, runtime.state.hardware_profile.logical_cpu_count); stop_runtime(runtime); return false; } // This runner-only override is applied before Governor creation and is never // persisted. The Governor remains the sole admission owner: reserving N // logical CPUs constrains the recovered Candidate Task's execution contract. policy.system_cpu_reserve = runtime.state.hardware_profile.logical_cpu_count - runtime.cpu_budget; } unsigned int feature_threads = runtime.state.hardware_profile.logical_cpu_count - policy.system_cpu_reserve; if (feature_threads > 12) feature_threads = 12; /* Match the production startup contract: OpenCV's process-wide pool is * configured from the same detected profile and Governor policy before any * Queue worker exists. The runner-only CPU override therefore constrains * both admission and nested feature extraction consistently. */ if (!lardon3d_feature_opencv_configure_threads(feature_threads)) { std::fprintf(stderr, "OpenCV thread configuration failed for %u threads\n", feature_threads); stop_runtime(runtime); return false; } runtime.state.resource_governor = lardon3d_resource_governor_create(&runtime.state.hardware_profile, &policy); runtime.state.task_queue = runtime.state.resource_governor ? lardon3d_task_queue_create(runtime.state.resource_governor, 2) : nullptr; if (!runtime.state.task_queue) { stop_runtime(runtime); return false; } runtime.state.project_loaded = true; std::memcpy(runtime.state.project_path, runtime.project_path.c_str(), runtime.project_path.size() + 1u); /* Task owns execution state, Queue owns bounded dispatch/backpressure, and * Governor owns each task's admission reservation. Sequential enqueue/wait * below releases that reservation at the task boundary and never reserves an * entire campaign or creates a parallel worker/scheduler subsystem. */ return true; } bool wait_completed(Runtime &runtime, uint64_t task_id, const char *phase) { for (;;) { Lardon3DTaskSnapshot snapshot{}; if (!lardon3d_task_queue_get(runtime.state.task_queue, task_id, &snapshot)) return false; if (snapshot.state == TASK_COMPLETED || snapshot.state == TASK_FAILED || snapshot.state == TASK_CANCELLED) { Lardon3DProjectDbTask durable{}; if (lardon3d_project_db_load_task(runtime.state.project_db, task_id, &durable) == LARDON3D_PROJECT_DB_OK && durable.saved_state == snapshot.state) { if (snapshot.state != TASK_COMPLETED) { std::fprintf(stderr, "%s task %llu ended in %s: %s\n", phase, static_cast(task_id), lardon3d_task_state_name(snapshot.state), snapshot.message); return false; } return lardon3d_task_queue_remove(runtime.state.task_queue, task_id); } } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } bool restart_runtime(Runtime &runtime, uint64_t execution_id, const char *boundary) { stop_runtime(runtime); if (!start_runtime(runtime)) return false; Lardon3DProjectDbSelectedExecution execution{}; if (lardon3d_project_db_load_selected_execution(runtime.state.project_db, execution_id, &execution) != LARDON3D_PROJECT_DB_OK) { std::fprintf(stderr, "restart at %s lost retained execution %llu\n", boundary, static_cast(execution_id)); return false; } /* This boundary deliberately has no sidecar or durable top-level phase. The * caller retains only execution_id; the next phase reconstructs exact image, * FeatureSet or result IDs from v22 durable records and their cursors. */ std::printf("{\"record\":\"restart\",\"kind\":\"REOPEN_ONLY\"," "\"boundary\":\"%s\",\"execution_id\":%llu}\n", boundary, static_cast(execution_id)); return true; } bool recover_quality_task(Runtime &runtime, uint64_t task_id) { /* Durable Task creation publishes its typed request and initial cursor before * Queue transfer. The original unqueued object has been discarded to model * loss before first dispatch. Recovery must use the existing registry to * reconstruct callback state, then transfer the Task through Queue and * Governor admission; the runner adds no top-level durable state, test hook, * or alternate worker path. */ stop_runtime(runtime); if (!start_runtime(runtime)) return false; Lardon3DProjectRecoverySummary recovery{}; if (lardon3d_project_resume_recoverable_tasks( &runtime.state, lardon3d_task_kind_registry_production(), &recovery) != LARDON3D_PROJECT_DB_OK || recovery.resumed != 1 || recovery.failed != 0) return false; std::printf("{\"record\":\"restart\"," "\"kind\":\"REGISTRY_QUEUE_GOVERNOR_RESTART\"," "\"task_id\":%llu,\"inspected\":%zu,\"resumed\":%zu}\n", static_cast(task_id), recovery.inspected, recovery.resumed); return wait_completed(runtime, task_id, "photo_quality.triage recovered"); } bool run_task_pair(Runtime &runtime, uint64_t scanset_id, const Campaign &campaign, bool prove_restart, uint64_t &quality_task_id, uint64_t &campaign_task_id) { Lardon3DPhotoQualityTaskRequest quality_request{ campaign.sources.data(), campaign.sources.size(), campaign.confirmations.data(), campaign.confirmations.size()}; if (prove_restart) { Lardon3DTask *pending = lardon3d_project_create_photo_quality_task( &runtime.state, scanset_id, &quality_request, &quality_task_id); if (!pending) return false; lardon3d_task_destroy(pending); if (!recover_quality_task(runtime, quality_task_id)) { std::fprintf(stderr, "quality Task could not be restored at its pending boundary\n"); return false; } } else if (!lardon3d_project_enqueue_photo_quality(&runtime.state, scanset_id, &quality_request, &quality_task_id) || !wait_completed(runtime, quality_task_id, "photo_quality.triage")) { return false; } Lardon3DAcquisitionCampaignTaskRequest campaign_request{}; campaign_request.sources = campaign.sources.data(); campaign_request.source_count = campaign.sources.size(); campaign_request.confirmations = campaign.confirmations.data(); campaign_request.confirmation_count = campaign.confirmations.size(); campaign_request.ingest_options.representation = LARDON3D_ACQUISITION_SELECT_JPEG_SOURCE; campaign_request.ingest_options.select_representation = 1; campaign_request.ingest_options.imported_at = std::time(nullptr); campaign_request.ingest_options.max_source_bytes = UINT64_MAX; return lardon3d_project_enqueue_acquisition_campaign( &runtime.state, scanset_id, &campaign_request, &campaign_task_id) && wait_completed(runtime, campaign_task_id, "acquisition_campaign.run"); } bool create_selection(Runtime &runtime, Mode mode, uint64_t quality_task_id, uint64_t campaign_task_id, size_t group_count, Lardon3DProjectDbSelectedExecution &execution) { std::vector items; for (size_t index = 0; index < group_count; ++index) { const uint32_t group_id = static_cast(index + 1u); Lardon3DProjectDbPhotoQualityResult quality{}; Lardon3DProjectDbAcquisitionCampaignCapture campaign{}; if (lardon3d_project_db_load_photo_quality_result(runtime.state.project_db, quality_task_id, group_id, &quality) != LARDON3D_PROJECT_DB_OK || lardon3d_project_db_load_acquisition_campaign_capture( runtime.state.project_db, campaign_task_id, group_id, &campaign) != LARDON3D_PROJECT_DB_OK) return false; if (quality.metrics.recommendation != LARDON3D_PHOTO_QUALITY_GOOD || quality.override_value != LARDON3D_PHOTO_QUALITY_OVERRIDE_NONE) continue; Lardon3DProjectDbSelectedExecutionItem item{}; item.item_index = static_cast(items.size()); item.quality_group_id = group_id; item.campaign_group_id = group_id; item.capture_id = campaign.capture_id; if (mode == Mode::kA6000) { Lardon3DProjectDbCaptureSourceAsset sources[4]{}; size_t source_count = 0; if (lardon3d_project_db_list_capture_source_assets(runtime.state.project_db, campaign.capture_id, 0, sources, 4, &source_count) != LARDON3D_PROJECT_DB_OK) return false; size_t raw_count = 0; for (size_t source = 0; source < source_count; ++source) { if (sources[source].source_kind == LARDON3D_DB_CAPTURE_SOURCE_RAW) { item.source_asset_id = sources[source].asset_id; ++raw_count; } } if (raw_count != 1) return false; item.representation_source = LARDON3D_SELECTED_REPRESENTATION_RAW_ASSET; } else { item.representation_source = LARDON3D_SELECTED_REPRESENTATION_SOURCE_IMAGE; } items.push_back(item); } if (items.empty()) { std::printf("{\"record\":\"selection\",\"selected\":0," "\"reason\":\"no GOOD+NONE groups\"}\n"); return true; } /* These item records are the only bridge between independent quality and * campaign group namespaces. Equal numeric IDs are supplied explicitly and * never used to infer Capture, Asset, or image identity. */ return lardon3d_project_db_create_selected_execution( runtime.state.project_db, quality_task_id, campaign_task_id, items.data(), items.size(), std::time(nullptr), &execution) == LARDON3D_PROJECT_DB_OK; } bool publish_representations(Runtime &runtime, uint64_t execution_id, std::vector &image_ids) { Lardon3DProjectDbSelectedExecution execution{}; if (lardon3d_project_db_load_selected_execution(runtime.state.project_db, execution_id, &execution) != LARDON3D_PROJECT_DB_OK) return false; for (uint32_t index = execution.next_item_index; index < execution.item_count; ++index) { Lardon3DProjectDbSelectedExecutionItem item{}; if (lardon3d_project_db_load_selected_execution_item(runtime.state.project_db, execution_id, index, &item) != LARDON3D_PROJECT_DB_OK) return false; uint64_t image_id = 0; if (item.representation_source == LARDON3D_SELECTED_REPRESENTATION_RAW_ASSET) { uint64_t task_id = 0; if (!lardon3d_project_enqueue_raw_development(&runtime.state, item.capture_id, item.source_asset_id, &task_id) || !wait_completed(runtime, task_id, "raw.develop")) return false; Lardon3DProjectDbRawDevelopmentTask raw{}; if (lardon3d_project_db_load_raw_development_task(runtime.state.project_db, task_id, &raw) != LARDON3D_PROJECT_DB_OK || raw.phase != LARDON3D_RAW_DEVELOPMENT_TASK_PUBLISHED || !raw.has_image || raw.capture_id != item.capture_id || raw.source_asset_id != item.source_asset_id) return false; image_id = raw.image_id; } else { if (lardon3d_project_db_get_selected_capture_image(runtime.state.project_db, item.capture_id, &image_id) != LARDON3D_PROJECT_DB_OK) return false; } if (lardon3d_project_db_record_selected_representation(runtime.state.project_db, execution_id, index, image_id, index + 1u) != LARDON3D_PROJECT_DB_OK) return false; } if (lardon3d_project_db_load_selected_execution(runtime.state.project_db, execution_id, &execution) != LARDON3D_PROJECT_DB_OK || execution.stage != LARDON3D_SELECTED_EXECUTION_CALIBRATION) return false; image_ids.clear(); for (uint32_t index = 0; index < execution.item_count; ++index) { Lardon3DProjectDbSelectedExecutionItem item{}; if (lardon3d_project_db_load_selected_execution_item(runtime.state.project_db, execution_id, index, &item) != LARDON3D_PROJECT_DB_OK || !item.has_image) return false; image_ids.push_back(item.image_id); } return true; } bool extract_features(Runtime &runtime, const std::vector &image_ids, const Lardon3DFeatureExtractorParameters ¶meters, std::vector &feature_sets) { unsigned char fingerprint[32]{}; lardon3d_feature_extractor_parameter_fingerprint(¶meters, fingerprint); feature_sets.clear(); for (const uint64_t image_id : image_ids) { Lardon3DProjectDbFeatureSet feature{}; if (lardon3d_project_db_find_feature_set(runtime.state.project_db, image_id, LARDON3D_FEATURE_EXTRACTOR_KIND, LARDON3D_FEATURE_EXTRACTOR_VERSION, fingerprint, &feature) != LARDON3D_PROJECT_DB_OK) { uint64_t task_id = 0; if (!lardon3d_project_enqueue_feature_extract(&runtime.state, image_id, ¶meters, &task_id) || !wait_completed(runtime, task_id, "features.extract") || lardon3d_project_db_find_feature_set( runtime.state.project_db, image_id, LARDON3D_FEATURE_EXTRACTOR_KIND, LARDON3D_FEATURE_EXTRACTOR_VERSION, fingerprint, &feature) != LARDON3D_PROJECT_DB_OK) return false; } feature_sets.push_back(feature); } return true; } bool collect_verified_ids(Runtime &runtime, const unsigned char verifier_fingerprint[32], std::vector &verified_ids, size_t *applicable = nullptr, size_t *verified = nullptr, size_t *rejected = nullptr) { verified_ids.clear(); if (applicable) *applicable = 0; if (verified) *verified = 0; if (rejected) *rejected = 0; uint64_t match_cursor = 0; for (;;) { Lardon3DProjectDbMatchResult matches[64]{}; size_t match_count = 0; if (lardon3d_project_db_list_match_results(runtime.state.project_db, match_cursor, matches, 64, &match_count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t index = 0; index < match_count; ++index) { match_cursor = matches[index].match_result_id; if (matches[index].result_status != LARDON3D_MATCH_RESULT_STATUS_MATCHED || matches[index].match_count == 0) continue; if (applicable) ++*applicable; Lardon3DProjectDbGeometricVerificationResult result{}; if (lardon3d_project_db_find_geometric_verification_result( runtime.state.project_db, matches[index].match_result_id, LARDON3D_GEOMETRIC_VERIFIER_FUNDAMENTAL, LARDON3D_GEOMETRIC_VERIFIER_VERSION, verifier_fingerprint, &result) != LARDON3D_PROJECT_DB_OK) return false; if (result.status == LARDON3D_GEOMETRIC_VERIFIED) { if (verified) ++*verified; verified_ids.push_back(result.geometric_verification_result_id); } else if (result.status == LARDON3D_GEOMETRIC_REJECTED) { if (rejected) ++*rejected; } else { return false; } } if (match_count < 64) break; } std::sort(verified_ids.begin(), verified_ids.end()); return std::adjacent_find(verified_ids.begin(), verified_ids.end()) == verified_ids.end(); } bool downstream(Runtime &runtime, const std::vector &feature_sets, const Lardon3DFeatureExtractorParameters &orb, uint64_t &geometry_task_id, std::vector &verified_ids) { Lardon3DVisualIndexConfiguration index_configuration{ LARDON3D_VISUAL_INDEX_VERSION, 1024, 256}; uint64_t visual_index_id = 0; if (feature_sets.empty() || lardon3d_visual_index_create(runtime.state.project_db, &feature_sets.front(), &index_configuration, &visual_index_id) != LARDON3D_VISUAL_INDEX_OK) return false; uint64_t task_id = 0; if (!lardon3d_project_enqueue_visual_index_update(&runtime.state, visual_index_id, &task_id) || !wait_completed(runtime, task_id, "visual_index.update")) return false; Lardon3DVisualIndexQueryOptions query{ std::min(64, static_cast(feature_sets.size())), 1, LARDON3D_VISUAL_INDEX_SAME_SCANSET, true}; if (!lardon3d_project_enqueue_candidate_pair_generate(&runtime.state, visual_index_id, &query, &task_id) || !wait_completed(runtime, task_id, "candidate_pair.generate")) return false; Lardon3DMatcherTaskConfiguration matcher{}; std::snprintf(matcher.feature_extractor_kind, sizeof(matcher.feature_extractor_kind), "%s", LARDON3D_FEATURE_EXTRACTOR_KIND); matcher.feature_extractor_version = LARDON3D_FEATURE_EXTRACTOR_VERSION; lardon3d_feature_extractor_parameter_fingerprint(&orb, matcher.feature_parameter_fingerprint); matcher.matcher.kind = LARDON3D_MATCHER_ORB_BF; matcher.matcher.ratio_threshold = lardon3d_matcher_default_ratio(LARDON3D_MATCHER_ORB_BF); if (!lardon3d_project_enqueue_matcher_task(&runtime.state, &matcher, &task_id) || !wait_completed(runtime, task_id, "matcher.run")) return false; Lardon3DGeometricVerifierTaskConfiguration verifier{ lardon3d_geometric_verifier_default_parameters()}; if (!lardon3d_project_enqueue_geometric_verifier_task(&runtime.state, &verifier, &geometry_task_id) || !wait_completed(runtime, geometry_task_id, "geometric_verifier.run")) return false; unsigned char verifier_fingerprint[32]{}; lardon3d_geometric_verifier_fingerprint(&verifier.verifier, verifier_fingerprint); return collect_verified_ids(runtime, verifier_fingerprint, verified_ids); } bool build_tracks(Runtime &runtime, const std::vector &verified_ids, const unsigned char verifier_fingerprint[32], uint64_t *task_id_output = nullptr, Lardon3DProjectDbTrackSet *track_set_output = nullptr) { if (task_id_output) *task_id_output = 0; if (track_set_output) *track_set_output = {}; if (verified_ids.empty()) return true; if (verified_ids.size() > (std::numeric_limits::max() - 8U) / 8U) return false; std::vector scope_bytes(8U + verified_ids.size() * 8U); std::memcpy(scope_bytes.data(), "L3DTSIS1", 8); for (size_t index = 0; index < verified_ids.size(); ++index) { uint64_t value = verified_ids[index]; for (size_t byte = 0; byte < 8; ++byte) { scope_bytes[8U + index * 8U + byte] = static_cast(value & 0xffU); value >>= 8U; } } Lardon3DProjectDbTrackSet exact{}; std::snprintf(exact.builder_kind, sizeof(exact.builder_kind), "track_builder"); exact.builder_version = LARDON3D_TRACK_BUILDER_VERSION; unsigned int digest_size = 0; if (!lardon3d_track_builder_fingerprint(exact.parameter_fingerprint) || EVP_Digest(scope_bytes.data(), scope_bytes.size(), exact.input_scope_hash, &digest_size, EVP_sha256(), nullptr) != 1 || digest_size != 32) return false; exact.verifier_kind = LARDON3D_GEOMETRIC_VERIFIER_FUNDAMENTAL; exact.verifier_version = LARDON3D_GEOMETRIC_VERIFIER_VERSION; std::memcpy(exact.verifier_fingerprint, verifier_fingerprint, 32); exact.gvr_count = verified_ids.size(); Lardon3DProjectDbTrackSet existing{}; const Lardon3DProjectDbResult found = lardon3d_project_db_find_track_set(runtime.state.project_db, &exact, &existing); if (found == LARDON3D_PROJECT_DB_OK) { if (track_set_output) *track_set_output = existing; return true; } if (found != LARDON3D_PROJECT_DB_NOT_FOUND) return false; Lardon3DTrackBuilderTaskConfiguration configuration{ runtime.project_path.c_str(), runtime.state.project_db, LARDON3D_GEOMETRIC_VERIFIER_FUNDAMENTAL, LARDON3D_GEOMETRIC_VERIFIER_VERSION, verifier_fingerprint, verified_ids.data(), verified_ids.size()}; uint64_t task_id = 0; if (!lardon3d_project_enqueue_track_builder_task(&runtime.state, &configuration, &task_id) || !wait_completed(runtime, task_id, "track_builder.run")) return false; Lardon3DProjectDbTrackBuilderTask durable{}; Lardon3DProjectDbTrackSet identity{}; if (lardon3d_project_db_load_track_builder_task(runtime.state.project_db, task_id, &durable) != LARDON3D_PROJECT_DB_OK) return false; std::memcpy(identity.builder_kind, durable.builder_kind, sizeof(identity.builder_kind)); identity.builder_version = durable.builder_version; std::memcpy(identity.parameter_fingerprint, durable.builder_fingerprint, sizeof(identity.parameter_fingerprint)); identity.verifier_kind = durable.verifier_kind; identity.verifier_version = durable.verifier_version; std::memcpy(identity.verifier_fingerprint, durable.verifier_fingerprint, sizeof(identity.verifier_fingerprint)); std::memcpy(identity.input_scope_hash, durable.input_scope_hash, sizeof(identity.input_scope_hash)); identity.gvr_count = durable.gvr_count; Lardon3DProjectDbTrackSet published{}; if (lardon3d_project_db_find_track_set(runtime.state.project_db, &identity, &published) != LARDON3D_PROJECT_DB_OK) return false; if (task_id_output) *task_id_output = task_id; if (track_set_output) *track_set_output = published; return true; } bool collect_evidence(Runtime &runtime, uint64_t execution_id, Evidence &evidence) { Lardon3DProjectDbSelectedExecution execution{}; if (execution_id != 0 && lardon3d_project_db_load_selected_execution(runtime.state.project_db, execution_id, &execution) == LARDON3D_PROJECT_DB_OK) evidence.selected = execution.item_count; uint64_t cursor = 0; for (;;) { Lardon3DProjectDbFeatureSet page[64]{}; size_t count = 0; if (lardon3d_project_db_list_feature_sets(runtime.state.project_db, cursor, page, 64, &count) != LARDON3D_PROJECT_DB_OK) return false; evidence.features += count; if (count) cursor = page[count - 1].feature_set_id; if (count < 64) break; } cursor = 0; for (;;) { Lardon3DProjectDbCandidatePair page[64]{}; size_t count = 0; if (lardon3d_project_db_list_candidate_pairs(runtime.state.project_db, cursor, page, 64, &count) != LARDON3D_PROJECT_DB_OK) return false; evidence.pairs += count; if (count) cursor = page[count - 1].candidate_pair_id; if (count < 64) break; } cursor = 0; for (;;) { Lardon3DProjectDbMatchResult page[64]{}; size_t count = 0; if (lardon3d_project_db_list_match_results(runtime.state.project_db, cursor, page, 64, &count) != LARDON3D_PROJECT_DB_OK) return false; evidence.matches += count; for (size_t index = 0; index < count; ++index) { Lardon3DProjectDbGeometricVerificationResult geometries[4]{}; size_t geometry_count = 0; if (lardon3d_project_db_list_geometric_verification_results( runtime.state.project_db, page[index].match_result_id, 0, geometries, 4, &geometry_count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t geometry = 0; geometry < geometry_count; ++geometry) { if (geometries[geometry].status == LARDON3D_GEOMETRIC_VERIFIED) ++evidence.verified; else ++evidence.rejected; } } if (count) cursor = page[count - 1].match_result_id; if (count < 64) break; } Lardon3DProjectDbTrackSet tracks[8]{}; size_t track_set_count = 0; if (lardon3d_project_db_list_track_sets(runtime.state.project_db, 0, tracks, 8, &track_set_count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t index = 0; index < track_set_count; ++index) evidence.tracks += tracks[index].track_count; return true; } bool count_exact_gvrs(Runtime &runtime, const unsigned char fingerprint[32], size_t &count) { count = 0; uint64_t match_cursor = 0; for (;;) { Lardon3DProjectDbMatchResult matches[64]{}; size_t match_count = 0; if (lardon3d_project_db_list_match_results(runtime.state.project_db, match_cursor, matches, 64, &match_count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t index = 0; index < match_count; ++index) { match_cursor = matches[index].match_result_id; uint64_t geometry_cursor = 0; for (;;) { Lardon3DProjectDbGeometricVerificationResult page[8]{}; size_t geometry_count = 0; if (lardon3d_project_db_list_geometric_verification_results( runtime.state.project_db, matches[index].match_result_id, geometry_cursor, page, 8, &geometry_count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t geometry = 0; geometry < geometry_count; ++geometry) { if (page[geometry].verifier_kind == LARDON3D_GEOMETRIC_VERIFIER_FUNDAMENTAL && page[geometry].verifier_version == LARDON3D_GEOMETRIC_VERIFIER_VERSION && std::memcmp(page[geometry].parameter_fingerprint, fingerprint, 32) == 0) ++count; geometry_cursor = page[geometry].geometric_verification_result_id; } if (geometry_count < 8) break; } } if (match_count < 64) break; } return true; } bool find_pending_pre_gv_task(Runtime &runtime, uint64_t &candidate_task_id, uint64_t &matcher_task_id) { candidate_task_id = 0; matcher_task_id = 0; uint64_t cursor = 0; for (;;) { Lardon3DProjectRecoveryEntry entries[8]{}; size_t count = 0; if (lardon3d_project_list_recoverable( &runtime.state, lardon3d_task_kind_registry_production(), cursor, entries, 8, &count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t index = 0; index < count; ++index) { const auto &entry = entries[index]; cursor = entry.task_id; if ((entry.status != LARDON3D_PROJECT_RECOVERABLE && entry.status != LARDON3D_PROJECT_RECOVERABLE_PUBLISHED_NOT_DURABLE) || entry.snapshot.recovery_state != TASK_PENDING) { std::fprintf(stderr, "pending task %llu is not safely recoverable (status=%d)\n", static_cast(entry.task_id), static_cast(entry.status)); return false; } if (std::strcmp(entry.task_kind, LARDON3D_CANDIDATE_PAIR_GENERATE_TASK_KIND) == 0) { if (candidate_task_id != 0) return false; candidate_task_id = entry.task_id; } else if (std::strcmp(entry.task_kind, LARDON3D_MATCHER_TASK_KIND) == 0) { if (matcher_task_id != 0) return false; matcher_task_id = entry.task_id; } else { // The production recovery API resumes every pending task. Refuse an // unrelated task rather than replaying an earlier pipeline stage. std::fprintf(stderr, "PRE-GV recovery refuses pending task %llu of kind %s\n", static_cast(entry.task_id), entry.task_kind); return false; } } if (count < 8) break; } return !(candidate_task_id != 0 && matcher_task_id != 0); } bool recover_one_pre_gv_task(Runtime &runtime, uint64_t task_id, const char *phase, Lardon3DProjectRecoverySummary &recovery) { recovery = {}; if (lardon3d_project_resume_recoverable_tasks( &runtime.state, lardon3d_task_kind_registry_production(), &recovery) != LARDON3D_PROJECT_DB_OK || recovery.resumed != 1 || recovery.failed != 0 || recovery.queue_full) return false; return wait_completed(runtime, task_id, phase); } bool find_pending_candidate_only_task(Runtime &runtime, uint64_t &candidate_task_id) { candidate_task_id = 0; uint64_t cursor = 0; for (;;) { Lardon3DProjectRecoveryEntry entries[8]{}; size_t count = 0; if (lardon3d_project_list_recoverable( &runtime.state, lardon3d_task_kind_registry_production(), cursor, entries, 8, &count) != LARDON3D_PROJECT_DB_OK) return false; for (size_t index = 0; index < count; ++index) { const auto &entry = entries[index]; cursor = entry.task_id; if ((entry.status != LARDON3D_PROJECT_RECOVERABLE && entry.status != LARDON3D_PROJECT_RECOVERABLE_PUBLISHED_NOT_DURABLE) || entry.snapshot.recovery_state != TASK_PENDING || std::strcmp(entry.task_kind, LARDON3D_CANDIDATE_PAIR_GENERATE_TASK_KIND) != 0 || candidate_task_id != 0) { std::fprintf(stderr, "candidate-only recovery refuses unsafe pending task %llu of kind %s\n", static_cast(entry.task_id), entry.task_kind); return false; } candidate_task_id = entry.task_id; } if (count < 8) break; } // An absent entry is intentionally rejected: it means the requested pending // Candidate boundary is missing or already complete, neither of which this // repair mode may reinterpret or replace. return candidate_task_id != 0; } // This repair route owns exactly one durable Candidate Task. Registry recovery // enqueues through the production Queue and Governor, but the preflight makes // that all-task API safe by admitting no Matcher, GV, Track, SfM, or prior work. bool run_existing_candidate(Runtime &runtime) { if (!start_runtime(runtime)) return false; Evidence before{}; uint64_t candidate_task_id = 0; if (!collect_evidence(runtime, 0, before) || !find_pending_candidate_only_task(runtime, candidate_task_id)) { stop_runtime(runtime); return false; } Lardon3DProjectRecoverySummary recovery{}; const bool recovered = recover_one_pre_gv_task( runtime, candidate_task_id, "candidate_pair.generate recovered", recovery); Evidence after{}; const bool ok = recovered && collect_evidence(runtime, 0, after) && after.features == before.features && after.pairs >= before.pairs && after.matches == before.matches && after.verified == before.verified && after.rejected == before.rejected && after.tracks == before.tracks; std::printf( "{\"record\":\"existing_candidate_summary\",\"ok\":%s," "\"candidate_task_id\":%llu,\"candidate_action\":\"recovered\"," "\"candidate_recovery_inspected\":%zu,\"candidate_recovery_resumed\":%zu," "\"cpu_budget\":%u,\"feature_sets_before\":%zu,\"feature_sets_after\":%zu," "\"candidate_pairs_before\":%zu,\"candidate_pairs_after\":%zu," "\"match_results_before\":%zu,\"match_results_after\":%zu," "\"gvrs_before\":%zu,\"gvrs_after\":%zu,\"tracks_before\":%zu," "\"tracks_after\":%zu,\"prior_stages_replayed\":false," "\"matcher_enqueued\":false,\"gv_enqueued\":false," "\"track_builder_enqueued\":false,\"sparse_sfm_run\":false}\n", ok ? "true" : "false", static_cast(candidate_task_id), recovery.inspected, recovery.resumed, runtime.cpu_budget, before.features, after.features, before.pairs, after.pairs, before.matches, after.matches, before.verified + before.rejected, after.verified + after.rejected, before.tracks, after.tracks); stop_runtime(runtime); return ok; } // This repair route owns only the already-durable Candidate/Matcher boundary. // It may recover those production Tasks or enqueue the missing Matcher, but it // must never reconstruct prior acquisition stages or cross into GV/Tracks/SfM. bool run_existing_pre_gv(Runtime &runtime) { if (!start_runtime(runtime)) return false; Evidence before{}; if (!collect_evidence(runtime, 0, before) || before.verified != 0 || before.rejected != 0 || before.tracks != 0) { std::fprintf(stderr, "PRE-GV mode requires a project with no GV or Track evidence\n"); stop_runtime(runtime); return false; } uint64_t candidate_task_id = 0; uint64_t pending_matcher_task_id = 0; if (!find_pending_pre_gv_task(runtime, candidate_task_id, pending_matcher_task_id)) { stop_runtime(runtime); return false; } Lardon3DProjectRecoverySummary candidate_recovery{}; bool candidate_recovered = false; if (candidate_task_id != 0) { if (!recover_one_pre_gv_task(runtime, candidate_task_id, "candidate_pair.generate recovered", candidate_recovery)) { stop_runtime(runtime); return false; } candidate_recovered = true; } Evidence after_candidate{}; if (!collect_evidence(runtime, 0, after_candidate) || after_candidate.matches > after_candidate.pairs || after_candidate.verified != before.verified || after_candidate.rejected != before.rejected || after_candidate.tracks != before.tracks) { stop_runtime(runtime); return false; } uint64_t newly_pending_candidate = 0; uint64_t matcher_task_id = 0; if (!find_pending_pre_gv_task(runtime, newly_pending_candidate, matcher_task_id) || newly_pending_candidate != 0) { stop_runtime(runtime); return false; } if (pending_matcher_task_id != 0) matcher_task_id = pending_matcher_task_id; Lardon3DProjectRecoverySummary matcher_recovery{}; const char *matcher_action = "already_complete"; if (after_candidate.matches < after_candidate.pairs) { if (matcher_task_id != 0) { if (!recover_one_pre_gv_task(runtime, matcher_task_id, "matcher.run recovered", matcher_recovery)) { stop_runtime(runtime); return false; } matcher_action = "recovered"; } else { const Lardon3DFeatureExtractorParameters orb{8192, 8, 20}; Lardon3DMatcherTaskConfiguration matcher{}; std::snprintf(matcher.feature_extractor_kind, sizeof(matcher.feature_extractor_kind), "%s", LARDON3D_FEATURE_EXTRACTOR_KIND); matcher.feature_extractor_version = LARDON3D_FEATURE_EXTRACTOR_VERSION; lardon3d_feature_extractor_parameter_fingerprint( &orb, matcher.feature_parameter_fingerprint); matcher.matcher.kind = LARDON3D_MATCHER_ORB_BF; matcher.matcher.ratio_threshold = lardon3d_matcher_default_ratio(LARDON3D_MATCHER_ORB_BF); if (!lardon3d_project_enqueue_matcher_task(&runtime.state, &matcher, &matcher_task_id) || !wait_completed(runtime, matcher_task_id, "matcher.run existing")) { stop_runtime(runtime); return false; } matcher_action = "enqueued"; } } else if (matcher_task_id != 0) { std::fprintf(stderr, "complete Match Results coexist with a pending Matcher task\n"); stop_runtime(runtime); return false; } Evidence after{}; const bool ok = collect_evidence(runtime, 0, after) && after.features == before.features && after.pairs >= before.pairs && after.matches == after.pairs && after.verified == before.verified && after.rejected == before.rejected && after.tracks == before.tracks; std::printf( "{\"record\":\"existing_pre_gv_summary\",\"ok\":%s," "\"candidate_task_id\":%llu,\"candidate_action\":\"%s\"," "\"candidate_recovery_inspected\":%zu," "\"candidate_recovery_resumed\":%zu,\"matcher_task_id\":%llu," "\"matcher_action\":\"%s\",\"matcher_recovery_resumed\":%zu," "\"feature_sets_before\":%zu,\"feature_sets_after\":%zu," "\"candidate_pairs_before\":%zu,\"candidate_pairs_after\":%zu," "\"match_results_before\":%zu,\"match_results_after\":%zu," "\"gvrs_before\":%zu,\"gvrs_after\":%zu," "\"tracks_before\":%zu,\"tracks_after\":%zu," "\"prior_stages_replayed\":false,\"gv_enqueued\":false," "\"track_builder_enqueued\":false,\"sparse_sfm_run\":false}\n", ok ? "true" : "false", static_cast(candidate_task_id), candidate_recovered ? "recovered" : "already_complete", candidate_recovery.inspected, candidate_recovery.resumed, static_cast(matcher_task_id), matcher_action, matcher_recovery.resumed, before.features, after.features, before.pairs, after.pairs, before.matches, after.matches, before.verified + before.rejected, after.verified + after.rejected, before.tracks, after.tracks); stop_runtime(runtime); return ok; } bool run_existing_geometry(Runtime &runtime) { if (!start_runtime(runtime)) return false; Lardon3DGeometricVerifierTaskConfiguration configuration{ lardon3d_geometric_verifier_default_parameters()}; unsigned char fingerprint[32]{}; lardon3d_geometric_verifier_fingerprint(&configuration.verifier, fingerprint); size_t exact_before = 0; if (!count_exact_gvrs(runtime, fingerprint, exact_before)) { stop_runtime(runtime); return false; } /* This route deliberately starts at the immutable Match Result boundary. * It enqueues no quality, campaign, representation, feature, index, * candidate, or Matcher work. Task/Queue/Governor retain their production * ownership, and exact current identity reuse makes a full rerun convergent. */ uint64_t geometry_task_id = 0; if (!lardon3d_project_enqueue_geometric_verifier_task( &runtime.state, &configuration, &geometry_task_id) || !wait_completed(runtime, geometry_task_id, "geometric_verifier.run current existing")) { std::printf("{\"record\":\"existing_geometry_summary\",\"ok\":false," "\"stage\":\"geometric_verifier.run\",\"task_errors\":1}\n"); stop_runtime(runtime); return false; } std::vector verified_ids; size_t applicable = 0; size_t verified = 0; size_t rejected = 0; size_t exact_after = 0; if (!collect_verified_ids(runtime, fingerprint, verified_ids, &applicable, &verified, &rejected) || !count_exact_gvrs(runtime, fingerprint, exact_after) || exact_after != applicable) { std::printf("{\"record\":\"existing_geometry_summary\",\"ok\":false," "\"stage\":\"current_evidence_audit\",\"task_errors\":1}\n"); stop_runtime(runtime); return false; } // Track Builder receives only exact current-policy VERIFIED IDs. Historical // v1/v2 evidence is neither replayed nor mixed, and the exact scope identity // reuses an existing Track Set instead of publishing duplicate lineage. uint64_t track_task_id = 0; Lardon3DProjectDbTrackSet track_set{}; if (!build_tracks(runtime, verified_ids, fingerprint, &track_task_id, &track_set)) { std::printf("{\"record\":\"existing_geometry_summary\",\"ok\":false," "\"stage\":\"track_builder.run\",\"task_errors\":1}\n"); stop_runtime(runtime); return false; } const size_t created = exact_after >= exact_before ? exact_after - exact_before : 0; std::printf( "{\"record\":\"existing_geometry_summary\",\"ok\":true," "\"verifier_version\":%u,\"geometry_task_id\":%llu," "\"track_task_id\":%llu,\"applicable_matched_parents\":%zu," "\"verified\":%zu,\"rejected\":%zu,\"gvrs_before\":%zu," "\"gvrs_created\":%zu,\"gvrs_after\":%zu," "\"track_set_id\":%llu,\"track_count\":%llu," "\"track_set_reused\":%s," "\"task_errors\":0,\"upstream_replayed\":false," "\"mixed_verifier_lineage\":false,\"sparse_sfm_run\":false}\n", LARDON3D_GEOMETRIC_VERIFIER_VERSION, static_cast(geometry_task_id), static_cast(track_task_id), applicable, verified, rejected, exact_before, created, exact_after, static_cast(track_set.track_set_id), static_cast(track_set.track_count), track_task_id == 0 && track_set.track_set_id != 0 ? "true" : "false"); stop_runtime(runtime); return true; } } // namespace int main(int argc, char **argv) { Options options; if (!parse_options(argc, argv, options)) { usage(argv[0]); return 2; } Runtime runtime; if (options.resume_geometry_existing || options.resume_pre_gv_existing || options.resume_candidate_existing) { if (!prepare_existing_project(options.project_dir, runtime)) { std::fprintf(stderr, "existing project must be absolute, normalized, and durable\n"); return 2; } runtime.cpu_budget = options.cpu_budget; if (options.resume_candidate_existing) return run_existing_candidate(runtime) ? 0 : 1; return (options.resume_pre_gv_existing ? run_existing_pre_gv(runtime) : run_existing_geometry(runtime)) ? 0 : 1; } if (!prepare_empty_project(options.project_dir, runtime.project_path)) { std::fprintf(stderr, "project directory must be absolute, normalized and empty\n"); return 2; } runtime.database_path = (options.project_dir / "project.lardon3d").string(); Campaign campaign; if (!discover_campaign(options, campaign) || !start_runtime(runtime)) { std::fprintf(stderr, "campaign discovery or runtime setup failed\n"); return 1; } const char *mode_name = options.mode == Mode::kA6000 ? "a6000" : "s21"; Lardon3DProjectDbScanSet scanset{}; if (lardon3d_project_db_create_scanset(runtime.state.project_db, mode_name, &scanset) != LARDON3D_PROJECT_DB_OK) { stop_runtime(runtime); return 1; } uint64_t quality_task_id = 0; uint64_t campaign_task_id = 0; Lardon3DProjectDbSelectedExecution execution{}; bool ok = run_task_pair(runtime, scanset.scanset_id, campaign, options.restart != RestartBoundary::kNone, quality_task_id, campaign_task_id) && create_selection(runtime, options.mode, quality_task_id, campaign_task_id, campaign.confirmations.size(), execution); if (!ok || execution.execution_id == 0) { stop_runtime(runtime); return ok ? 0 : 1; } std::vector image_ids; ok = publish_representations(runtime, execution.execution_id, image_ids); if (ok && options.restart == RestartBoundary::kRepresentations) ok = restart_runtime(runtime, execution.execution_id, "representations") && publish_representations(runtime, execution.execution_id, image_ids); /* ORB is run only for exact images retained by the selected execution. The * 4096 option limit is an operational Visual Index v1 bound, not a scientific * campaign-size rule; callers use one empty project per campaign. */ const Lardon3DFeatureExtractorParameters orb{8192, 8, 20}; std::vector features; if (ok) ok = extract_features(runtime, image_ids, orb, features); if (ok && options.restart == RestartBoundary::kFeatures) { ok = restart_runtime(runtime, execution.execution_id, "features") && publish_representations(runtime, execution.execution_id, image_ids) && extract_features(runtime, image_ids, orb, features); } uint64_t geometry_task_id = 0; std::vector verified_ids; Lardon3DGeometricVerifierParameters verifier = lardon3d_geometric_verifier_default_parameters(); unsigned char verifier_fingerprint[32]{}; lardon3d_geometric_verifier_fingerprint(&verifier, verifier_fingerprint); if (ok) ok = downstream(runtime, features, orb, geometry_task_id, verified_ids); if (ok && options.restart == RestartBoundary::kGeometry) { ok = restart_runtime(runtime, execution.execution_id, "geometry"); if (ok) ok = collect_verified_ids(runtime, verifier_fingerprint, verified_ids); } if (ok) ok = build_tracks(runtime, verified_ids, verifier_fingerprint); if (ok && verified_ids.empty()) std::printf("{\"record\":\"tracks\",\"created\":false," "\"reason\":\"empty verified GVR set\"}\n"); /* Real A6000/S21 calibration is unavailable. The selected execution remains * truthfully at CALIBRATION, and this runner never fabricates a scope or runs * sparse SfM; verified geometry and tracks are the terminal evidence. */ if (ok) { stop_runtime(runtime); ok = start_runtime(runtime); } Evidence evidence{}; if (ok) ok = collect_evidence(runtime, execution.execution_id, evidence); if (ok) { std::printf("{\"record\":\"summary\",\"mode\":\"%s\"," "\"execution_id\":%llu,\"selected\":%zu,\"feature_sets\":%zu," "\"candidate_pairs\":%zu,\"matches\":%zu,\"verified\":%zu," "\"rejected\":%zu,\"tracks\":%zu," "\"orb_max_features_per_set\":8192," "\"visual_index_max_features_per_set\":1024," "\"visual_index_feature_set_limit\":4096," "\"candidate_top_k_limit\":64," "\"calibration_attached\":false,\"sparse_sfm_run\":false}\n", mode_name, static_cast(execution.execution_id), evidence.selected, evidence.features, evidence.pairs, evidence.matches, evidence.verified, evidence.rejected, evidence.tracks); } stop_runtime(runtime); return ok ? 0 : 1; }