许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  Node.js基于Autodesk Forge转换和展示BIM(RVT格式)教程

Node.js基于Autodesk Forge转换和展示BIM(RVT格式)教程

阅读数 3
点赞 0
article_banner
本人对于 BIM 一无所知,笔记中都是搜索引擎查找+猜测+总结的成果,一些结论和断言会有不准确和不专业之处,请多多见谅。

背景

工作的项目中需要在页面中展示 BIM。

BIM 有很多解释,这里指的是 Building Information Model - 建筑信息模型,简单说就是为建筑工程绘制的 2D/3D 模型。

功能需求是:将提供的 .rvt 文件的模型展示在 web 页面中。

经过一番研究:

  1. BIM 模型文件有多种格式,.rvt 格式是 Autodesk Revit 开发的项目文件。
  2. 前端无法直接使用 .rvt 文件,three.js 可以通过加载 .rvt 文件转化的 .json 文件展示模型内容。
  3. 要将 .rvt 转化成 .json(实际上是一堆 .json 和其他资源文件),要用 revit 软件,例如,付费软件 Autodesk Revit,试用版 16GB
  4. Revit 支持二次开发,其中包括转化文件的 API,似乎用 ASP.NET 开发的,但是也不是一键转化,似乎需要一些操作和知识(不懂)。
  5. 一些平台实现了二次开发,并提供包括上传、转化、展示等一条龙服务,当然这都是收费的,例如广联达的 BIMFACE、Autodesk 官方团队的 Autodesk Forge(本人主要研究的后者)。
  6. .rvt 测试文件不好找,转换完的 .json 文件也不好找,本人没找到,测试用的文件是客户给的,所以不方便提供。Autodesk Forge 官方提供了一些示例文件,不过我没下载成功,你可以试试: Revit 示例项目文件

Forge

指引

Autodesk Forge 提供了很多 API 用于开发和管理模型数据,还可以使用 Autodesk Forge Viewer 在页面上加载展示模型。

Autodesk Forge 的工作人员提供了一个 《Autodesk Forge中文帮助中心》,里面包括教程文档、Forge 进阶、常见问题、在线工具等很多内容,阅读它们是最快掌握 Forge 的途径,建议至少阅读完 《Autodesk Forge 学习简谈系列》

系列中有称为 learnforge 的新手案例教程,包括视频教程《Forge Viewer案例从搭建到部署》和视频中的《参考文档》,具体的搭建和演示本人就不重复了,建议自己搭一遍,熟悉简单的流程。

流程

我跟着 Nodejs 案例搭建了一遍,一直到成功展示到页面,至此我的需求就基本满足了,所以就没有继续看后面的扩展。

案例的大致流程是:

1、注册登录

官方注册账号并登录,开启试用

2、身份验证

创建 App,主要用来获取开发用的 Client ID 和 Client Secret,基于它们生成具体访问指定范围权限的 token,调用 API 时需将 token 传递过去。

3、数据管理

Forge 将数据存储在云端的名叫 bucket 的容器(抽象)中。

  1. 首先创建一个 bucket
  2. 然后上传支持格式的模型文件,例如 .rvt
  3. 然后执行转换操作,将模型文件转换成 Forge Viewer 可以加载的数据格式。

4、页面展示

Forge 可以任意支持的模型文件转化成 SVF 格式(.svf ),.svf 文件记录了模型中使用到了哪些资源,通过它可以得知需要加载哪些文件,包括 .json、图片、.gz.bin 等。

案例中通过 Viewer 加载远程的 svf 文件进而加载相关资源文件,最终渲染整个模型。

svf 包提取器

关于 SVF

SVF 不是单一文件,是一个数据包,包括了构建集合信息,属性包,有一个 .svf 的清单文件(二维模型时.f2d)。而 Forge Viewer 的 JavaScript 库对此数据进行解析和渲染。 目前 SVF 数据格式并没有文档说明,也无官方端口直接下载数据包。不过可以按清单文件下载到这些文件。 注意:SVF2 暂时还不支持下载数据包。

Forge Viewer 支持 SVF 格式是内部格式,作为入口的 .svf 文件实际上就是个压缩包,可以通过压缩软件解压。其中包含的 manifest.json 文件记录了模型所需的相关资源的文件地址,例如 .json、图片、.gz.bin 等。

下图是 {3D}.svf 文件解压结果:

在这里插入图片描述

功能

通过搭建案例已经实现基本的展示需求,但实际上,转化的数据都存储在 Forge 云端 服务器  ,这样对于数据管理和网络请求都是不友好的,所以还需要将其下载到自己的私有服务器进行存储。

可是 Forge 并没有提供傻瓜式的一键下载 SVF 包的功能。

好在官方开发人员提出了可行的方案,就是根据获取到的文件清单,批量进行手动下载打包,见《Autodesk Forge 学习简谈 - 4》

团队中也有人(PHILIPPE LEEFSMA)从已废弃的官方在线工具中解耦了 “下载离线 SVF 包” 的功能:《Forge SVF Extractor in Node.js》

官方还开发了支持一键下载的 vscode 插件,也可以参考源码开发自己的下载功能。

方案

.svf 文件和其记录的相关资源统称为 SVF,Forge 称呼这些转化后的结果为 Derivatives - SVF 衍生(或派生)文件。

通过 DerivativesApi 和 URN 可以提取模型的 manifest   数据,其中存储了这个模型的 Derivatives 信息,再通过 Derivatives 信息中的路径手动拼接官方地址就是 Viewer 加载的文件地址。

将这些衍生文件的路径全部整合好,进行批量下载并存储到本地就实现了 SVF 包的下载。

URN:Uniform Resource Name(统一资源名称)不同与 URL(统一资源定位符)的标准格式的URI,以唯一名称的方式指向资源,而不是资源的所在地。更多请参考《HTTP 权威指南》中 URN 的介绍。

代码

本人使用的 PHILIPPE 的解耦代码,并对代码进行了一些调整以使其可以直接使用:

  • 删除代码中保留的一些 PHILIPPE 自己项目中的模块
  • 一些 API 的过时使用方式,导致调用报错
  • 一些路径分隔符不一致导致的报错
  • 本人将代码放在了 Nodejs 环境运行,所以改用 CommonJS 方式加载模块
  • 环境搭建和 token 生成沿用 Learn Forge 案例

最终结果:

// ExtractorSvc.js
const archiver = require('archiver')
const {
   
    DerivativesApi } = require('forge-apis')
const request = require('request')
const mkdirp = require('mkdirp')
const Zip = require('node-zip')
const Zlib = require('zlib')
const path = require('path')
const fs = require('fs')
const _ = require('lodash')

// 转化路径中的分隔符
// path 会将路径中的路径分隔符全部转化为当前环境的默认格式,可能会是 `\`,在拼接其它路径时可能会有问题,这里进行了统一替换
function formatSep(str, sep = path.sep) {
   
   
  const reg = new RegExp(sep === '/' ? '\\\\' : '/', 'g')
  return str.replace(reg, sep)
}

// Extractor Service 类
class ExtractorSvc {
   
   
  // 构造函数
  constructor() {
   
   
    // 初始化 API 实例
    this.derivativesAPI = new DerivativesApi()
  }

  // 实例名成
  name() {
   
   
    return 'ExtractorSvc'
  }

  /**
   * 【对外提供的 API】
   * 将 SVF 文件全部下载到服务器,并返回所有文件的路径
   * @param {AuthClient} oauth2Client 案例中定义的 getClient 方法生成的 token
   * @param {AuthToken} credentials 案例中定义的 getInternalToken 方法生成的 token
   * @param {string} urn 案例中 new ObjectsApi().getObjects API获取的 objectId
   * @param {string} directory 存储资源的目标绝对路径
   * @returns
   */
  download(oauth2Client, credentials, urn, directory) {
   
   
    return new Promise(async (resolve, reject) => {
   
   
      // mkdirp:mkdir 的 promise 分装
      // 创建目标目录,确保目录确实存在
      await mkdirp(directory)

      // 根据 URL 获取顶层的 manifest
      const manifest = await this.derivativesAPI.getManifest(urn, {
   
   }, oauth2Client, credentials)

      // 整合要获取的全部资源
      const derivatives = await this.getDerivatives(oauth2Client, credentials, manifest.body)

      // 格式化资源信息,提取必要字段
      const nestedDerivatives = derivatives.map(item => {
   
   
        return item.files.map(file => {
   
   
          const localPath = formatSep(path.resolve(directory, item.localPath))

          return {
   
   
            basePath: item.basePath,
            guid: item.guid,
            mime: item
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空