如何借助forge-apis ^0.9.2上传多3D文件并在Viewer中合并展示?
实现多文件上传并在Forge Viewer中合并查看的方案
针对你使用forge-apis@0.9.2的需求,分两种场景给出具体实现步骤:
场景1:主文件关联附属资源(如示例中的RVT+CAD/PDF/纹理)
这种场景下主文件(如some-file.rvt)本身已关联其他文件(链接CAD、引用纹理等),只需保证文件结构完整上传,Model Derivative会自动识别依赖并合并转换。
步骤1:初始化Forge API客户端
const { ForgeClient, BucketsApi, ObjectsApi, DerivativesApi } = require('forge-apis'); const fs = require('fs'); const path = require('path'); // 配置客户端 const forgeClient = new ForgeClient({ clientId: '你的Client ID', clientSecret: '你的Client Secret', scopes: ['bucket:create', 'bucket:read', 'data:read', 'data:write', 'data:create'] });
步骤2:创建OSS存储桶(若不存在)
const bucketsApi = new BucketsApi(forgeClient); async function ensureBucketExists(bucketKey) { try { await bucketsApi.getBucketDetails(bucketKey); } catch (err) { if (err.statusCode === 404) { await bucketsApi.createBucket( { bucketKey, policyKey: 'transient' }, // 按需选transient/temporary/persistent {}, {} ); } else { throw err; } } } // 执行创建 await ensureBucketExists('你的桶名称');
步骤3:完整上传目录结构
保持本地文件结构与OSS中的路径一致,确保Model Derivative能识别依赖:
const objectsApi = new ObjectsApi(forgeClient); async function uploadFolderToBucket(bucketKey, localFolderPath, remotePrefix = '') { const entries = fs.readdirSync(localFolderPath, { withFileTypes: true }); for (const entry of entries) { const localPath = path.join(localFolderPath, entry.name); const remotePath = path.join(remotePrefix, entry.name); if (entry.isDirectory()) { await uploadFolderToBucket(bucketKey, localPath, remotePath); } else { const fileStream = fs.createReadStream(localPath); const fileSize = fs.statSync(localPath).size; await objectsApi.uploadObject(bucketKey, remotePath, fileSize, fileStream, {}); } } } // 上传本地MAIN-FOLDER到OSS,远程前缀设为MAIN-FOLDER await uploadFolderToBucket('你的桶名称', './MAIN-FOLDER', 'MAIN-FOLDER');
步骤4:提交模型转换作业
指定主文件URN,Model Derivative会自动加载同目录下的关联文件:
const derivativesApi = new DerivativesApi(forgeClient); async function translateMainModel(bucketKey, mainFileRemotePath) { // 生成主文件的Base64编码URN const objectUrn = Buffer.from(`${bucketKey}/${mainFileRemotePath}`).toString('base64'); const jobPayload = { input: { urn: objectUrn, rootFilename: mainFileRemotePath // 明确主文件路径,帮助识别依赖 }, output: { formats: [{ type: 'svf', views: ['2d', '3d'] }] } }; await derivativesApi.translate(jobPayload, {}, {}); } // 转换主文件MAIN-FOLDER/some-file.rvt await translateMainModel('你的桶名称', 'MAIN-FOLDER/some-file.rvt');
步骤5:在Viewer中加载转换后的模型
转换完成后,用主文件的URN加载Viewer,所有关联资源会自动合并显示。
场景2:多个独立3D文件合并成一个场景
若要合并多个无关联的3D文件(如多个RVT模型),需使用Model Derivative的场景合成功能:
步骤1:分别转换所有独立模型
先将每个3D文件单独转换为SVF格式,记录每个模型的URN:
async function translateSingleModel(bucketKey, fileRemotePath) { const urn = Buffer.from(`${bucketKey}/${fileRemotePath}`).toString('base64'); await derivativesApi.translate({ input: { urn }, output: { formats: [{ type: 'svf', views: ['3d'] }] } }); // 需轮询检查转换状态,确认完成后返回URN return urn; } // 示例:转换两个独立模型 const modelUrns = await Promise.all([ translateSingleModel('你的桶名称', 'MAIN-FOLDER/model1.rvt'), translateSingleModel('你的桶名称', 'MAIN-FOLDER/model2.rvt') ]);
步骤2:创建合成场景作业
将多个模型URN合并为一个新的SVF场景:
async function createCompositeScene(bucketKey, compositeName) { const compositeUrn = Buffer.from(`${bucketKey}/${compositeName}.svf`).toString('base64'); const payload = { input: { composites: modelUrns.map(urn => ({ urn })) }, output: { destination: { region: 'us' }, // 匹配你的桶区域 format: { type: 'svf' } } }; await derivativesApi.createComposite(payload, {}, {}); return compositeUrn; } // 创建名为merged-scene的合成场景 const compositeUrn = await createCompositeScene('你的桶名称', 'merged-scene');
步骤3:在Viewer中加载合成场景
等待合成作业完成后,用返回的compositeUrn加载Viewer,即可查看合并后的效果。
关键注意事项
- 确保所有文件上传到同一个OSS桶,且路径结构完整(场景1)。
- 场景合成需等待所有单个模型转换完成后再执行。
- 转换或合成作业需等待状态变为
success后再加载Viewer(可通过derivativesApi.getManifest(urn)轮询检查)。
内容的提问来源于stack exchange,提问作者nacho
相关产品推荐
相关产品推荐

