三維組態可視化解決方案


HTML5 WebGL 在三維中的應用,已經發展的如火如荼,使其在三維組態(工業控制)方面也變得簡單易行! 三維組態軟件提高了工業控制的管理效率,讓工業控制的資源管理、風險管控得到很大的改善。

傳統的三維組態一般都是本地應用, 該案例使用的是基於瀏覽器B/S架構下的三維組態的應用。

該案例模擬的是一個油田簡單的工業控制場景, 模型大致包括
油井、分離器、 加熱爐、天然氣、外輸泵。
還包括管路流動、流動方向。 描述了采油、加工、 輸出的全過程。

制作模型

第一步要做的就是建模,設計組使用3D建模工具 3d max或者c4d 進行油田設備模型的建模。建模后導出后綴為obj或者gltf格式文件,這兩種格式是我們三維渲染引擎支持最好的文件格式。

建模后的所有模型文件,最終會放到后端的模型庫,模型庫的管理目錄,如下圖所示:
模型列表

需要制作的模型包括油井、分離器、加熱爐、天然氣、外輸泵,如下圖所示,

模型

加載模型

加載模型可使用引擎模型的加載函數,進行模型加載,如obj模型加載,如下代碼所示:

new mono.OBJMTLLoader().load( 'youjing.obj', 'youjing.mtl', '',  (node)=> {
    node.type = 'obj';
    box.addByDescendant(node);
  },
);

如加載一個油井模型,因為加載模型是一個異步的過程,所以會有一個回調函數,加載完成之后,在回調函數中,把模型文件生成的三維對象,加入到場景容器box之中,加入之后場景中就會顯示我們的三維對象,如下圖所示:

油井

三維場景搭建

創建Network3D對象,即可以創建三維場景對象,如下代碼所示:

const box = new mono.DataBox();
    const network = new TopoNetwork(box, null, 'monoCanvas');
    network.mode = 'editor';
    window.network = network; // todo
    this.network = network;
    network.bindApp(this);
    network.setRenderSelectFunction(() => false);
    make.Default.path = './static/myModellib/';

    network.setClearColor(0, 0, 0);
    network.setClearAlpha(0);

    const directionalLight = new mono.DirectionalLight(0x333333, 0.3);
    directionalLight.setDirection(new mono.Vec3(0, 1, 1));
    box.add(directionalLight);
    let pointLight = new mono.PointLight(0xeae5e1, 0.3);
    pointLight.setPosition(2000, 2000, 2000);
    box.add(pointLight);
    pointLight = new mono.PointLight(0xeae5e1, 0.4);
    pointLight.setPosition(-2000, 2000, 2000);
    box.add(pointLight);
    pointLight = new mono.PointLight(0xeae5e1, 0.3);
    pointLight.setPosition(2000, 2000, -2000);
    box.add(pointLight);
    pointLight = new mono.PointLight(0xeae5e1, 0.4);
    pointLight.setPosition(-2000, 2000, -2000);
    box.add(pointLight);
    box.add(new mono.AmbientLight(0x888888));

    mono.Utils.autoAdjustNetworkBounds(
      network,
      document.querySelector('.app'),
      'clientWidth',
      'clientHeight',
    );

拖拽模型生成場景

從模型列表,把模型拖拽到三維場景對象上,即可以創建模型對象,如下圖所示:
拖拽生成場景

在模型按鈕上,需要監聽drag 或者dragstart事件,這個被封裝到一個獨立的類Dragger.js里面,在該類中專門處理了dragstart事件:

 addDragger(parent, subClass, option) {
    parent.addEventListener('dragstart', (e) => {
      let target = null;
      //  拿到冒泡的所有元素
      const path = eventPath(e);
      for (let i = 0; i < path.length; i += 1) {
        if (path[i].classList && path[i].classList.contains(subClass)) {
          target = path[i];
          break;
        }
      }
...
}

創建管路

在三維場景中,可以直接通過打點的方式創建三維管道,如下代碼所示:

 let path = new mono.Path(pipePoints);
    path = mono.PathNode.prototype.adjustPath(path, 2, 2);
    const node = new mono.PathNode(path, 10, 3, 20);
    node.s({
      'm.type': 'phong',
      'm.side': 'both',
      'm.normalType': mono.NormalTypeSmooth,
      'm.color': '#E35944',
      'm.ambient': '#E35944',
    });
    this.network.getDataBox().addByDescendant(node);

其中pipePoints是打點記錄下的三維頂點。

管路動畫

管路動畫是通過管路貼圖的offset屬性,不斷變化形成的動態流動效果,如下代碼所示:

 node.animate = new mono.Animate({
      from: pipeDirection === 'forward' ? 0 : 1,
      to: pipeDirection === 'forward' ? 1 : 0,
      dur: 1000,
      reverse: false,
      repeat: Number.POSITIVE_INFINITY,
      onUpdate(value) {
        node.setStyle('m.texture.offset', new mono.Vec2(value, 0));
      },
    });

最終效果如下圖:
pipe_animate.gif

整體效果

通過研發編輯,最終的顯示效果大致如下:

all.gif

還有更多效果本文並沒有凸顯出來, 有興趣獲取demo的,請發郵件到:
terry.tan@servasoft.com

歡迎關注公眾號“ITman彪叔”。彪叔,擁有10多年開發經驗,現任公司系統架構師、技術總監、技術培訓師、職業規划師。在計算機圖形學、WebGL、前端可視化方面有深入研究。對程序員思維能力訓練和培訓、程序員職業規划有濃厚興趣。
ITman彪叔公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM