如何用Swift同时生成多个RealityKit模型?
批量生成不同细节等级的RealityKit摄影测量模型
单模型生成基础代码
原本生成单个模型的代码如下,通过指定图片路径、输出路径和细节等级等参数调用HelloPhotogrammetry.main():
HelloPhotogrammetry.main([path_to_folder_of images, path_to_output/model.usdz, "-d", "medium", "-o", "unordered", "-f", "high" ])
批量生成需求
需要同时生成3个仅输出名称和细节等级不同的模型,对应参数如下:
- 输出文件:
modelname_medium.usdz,细节等级参数:-d medium - 输出文件:
modelname_full.usdz,细节等级参数:-d full - 输出文件:
modelname_raw.usdz,细节等级参数:-d raw
你的循环代码可行性分析
你写的循环代码逻辑上是可行的,但存在几个需要修正的细节:
- 字符串换行拼接可能导致Swift语法错误(当前代码里的路径被拆成多行,未正确拼接)
- 你定义的
levelOfDetail数组包含reduced,但需求里是raw,需要保持参数一致 - 硬编码完整路径不利于后续维护和修改
修正后的可运行代码示例:
// 修正细节等级数组,匹配需求 let levelOfDetail = ["medium", "full", "raw"] // 提取固定路径为常量,简化代码 let imageFolderPath = "/Users/paulmmxx/Desktop/Object_Capture_API/dataset/jpeg/all" let outputBasePath = "/Users/paulmmxx/Desktop/Object_Capture_API/output/preiser_" for detail in levelOfDetail { let outputPath = outputBasePath + detail + ".usdz" HelloPhotogrammetry.main([ imageFolderPath, outputPath, "-d", detail, "-o", "unordered", "-f", "high" ]) }
更优实现方案
1. 用元组关联细节等级与输出标识
如果后续需要调整输出文件名后缀或参数,用元组存储对应关系更清晰,便于维护:
// 用元组存储细节等级和对应的输出文件名后缀 let detailConfigs = [ ("medium", "medium"), ("full", "full"), ("raw", "raw") ] let imageFolderPath = "/Users/paulmmxx/Desktop/Object_Capture_API/dataset/jpeg/all" let outputDirPath = "/Users/paulmmxx/Desktop/Object_Capture_API/output/" for (detailLevel, suffix) in detailConfigs { let outputPath = outputDirPath + "preiser_" + suffix + ".usdz" HelloPhotogrammetry.main([ imageFolderPath, outputPath, "-d", detailLevel, "-o", "unordered", "-f", "high" ]) }
这种方式可以灵活调整文件名后缀,比如想把raw对应的文件名改成preiser_highres.usdz,只需要修改元组即可。
2. 增加基础路径的有效性检查
可以提前检查图片输入路径和输出目录是否存在,避免运行时出错:
import Foundation let imageFolderPath = "/Users/paulmmxx/Desktop/Object_Capture_API/dataset/jpeg/all" let outputDirPath = "/Users/paulmmxx/Desktop/Object_Capture_API/output/" // 检查输入路径是否存在 guard FileManager.default.fileExists(atPath: imageFolderPath) else { print("错误:图片文件夹路径不存在") exit(1) } // 检查输出目录是否存在,不存在则创建 if !FileManager.default.fileExists(atPath: outputDirPath) { do { try FileManager.default.createDirectory(atPath: outputDirPath, withIntermediateDirectories: true) } catch { print("创建输出目录失败:\(error.localizedDescription)") exit(1) } } let detailConfigs = [("medium", "medium"), ("full", "full"), ("raw", "raw")] for (detailLevel, suffix) in detailConfigs { let outputPath = outputDirPath + "preiser_" + suffix + ".usdz" HelloPhotogrammetry.main([ imageFolderPath, outputPath, "-d", detailLevel, "-o", "unordered", "-f", "high" ]) }
3. 异步执行(可选)
如果HelloPhotogrammetry.main()是同步阻塞调用,批量生成时会耗时较长。若API支持多线程调用,可以用DispatchQueue并行处理,提升效率:
import Foundation let imageFolderPath = "/Users/paulmmxx/Desktop/Object_Capture_API/dataset/jpeg/all" let outputDirPath = "/Users/paulmmxx/Desktop/Object_Capture_API/output/" // 提前完成路径检查(代码同方案2) guard FileManager.default.fileExists(atPath: imageFolderPath) else { print("错误:图片文件夹路径不存在") exit(1) } if !FileManager.default.fileExists(atPath: outputDirPath) { do { try FileManager.default.createDirectory(atPath: outputDirPath, withIntermediateDirectories: true) } catch { print("创建输出目录失败:\(error.localizedDescription)") exit(1) } } let detailConfigs = [("medium", "medium"), ("full", "full"), ("raw", "raw")] let queue = DispatchQueue(label: "com.example.objectcapture", attributes: .concurrent) let group = DispatchGroup() for (detailLevel, suffix) in detailConfigs { group.enter() queue.async { let outputPath = outputDirPath + "preiser_" + suffix + ".usdz" HelloPhotogrammetry.main([ imageFolderPath, outputPath, "-d", detailLevel, "-o", "unordered", "-f", "high" ]) group.leave() } } // 等待所有任务完成 group.wait() print("所有模型生成完成")
内容的提问来源于stack exchange,提问作者Paul St George
相关产品推荐
相关产品推荐

