電力佈局三維編輯器功能設計

2023-04-22 15:00:23

楔子

最近和一家公司在談一個專案合作,他們公司主要是做電力相關的。 專案背景大概是這樣的:
國家電網對電網資產需要做到數位化管理,對現有變壓器臺區內的電錶箱電能表做視覺化數位孿生管理。
由於涉及到的臺區非常多,所以客戶希望開發的不是單個專案,而是可以實現專案的3D編輯器,使得電網的臺區經理使用編輯器編輯出所負責的變壓器臺區的裝置關係場景及資料狀態展示。

三維視覺化方面,三維組態,我們經驗還是挺多的,比如資料中心、醫院、學校等三維視覺化專案,還包括智慧園區、智慧城市、智慧小鎮的方向的等三維視覺化。
下面先上幾張三維視覺化的圖瞅瞅:


客戶需要的是一個佈局工具,而不是直接的三維場景,這比直接搭建一個三維的場景要難許多。
但是所謂萬事開頭難,難在不開頭。 天下事有難易乎,幹就是了。由於之前做過油田的三維佈局,雖然內容上不太一樣,但是技術上是類似的,還是相對來說容易很多。
在商務人員和客戶確立合同,正式立項後, 我們的設計小姐姐,開發小哥哥,建模小弟弟,都各司其職,下邊就講一下專案的大概內容。

建立模型庫

模型庫主要包括了園區模型(通用),樓宇模型(通用),臺區模型,電錶箱,電能表等等。

首先是開發同事搭建一個模型庫的功能,主要包括了對於模型的管理。 模型庫功能主要包括,模型的上傳,預覽和分類和列表功能。同時讓建模小夥把相關模型使用3D建模工具 3d max或者c4d 進行模型的建模。建模後,匯出字尾為obj/gltf/fbx格式檔案,建模後的所有模型檔案,最終會上傳到模型庫,模型庫的管理目錄如下圖所示:

三維編輯功能

三維編輯能力是電力佈局三維編輯器的核心功能。

生成模型

三維編輯能力之一是把模型列表的功能拖拽到三維畫布上,生成三維模型。主要的技術實現包括了 DragAndDrop和模型載入:
其中drag and drop 大致如下:

function dragstart_handler(ev) {
  ev.dataTransfer.setData("model","./xxx.gltf");
}

function dragover_handler(ev) {
  ev.preventDefault();
  ev.dataTransfer.dropEffect = "move";
}
function drop_handler(ev) {
  ev.preventDefault();
  var data = ev.dataTransfer.getData("model");
  let model = ModelLoader.load(data);
  ...
}

而模型載入主要使用了GLTFLoader,大致如下

loader.load(modelPath, function (gltf) {
  // todo 
  // add gltf to scene
}

場景編輯

模型拖入場景中後,還可以在場景中二次編輯模型的位置,大小和其他屬性。 可以通過屬性框設定屬性,也可以通過gizmo工具進行平移,旋轉和縮放模型。如下圖所示:

當然還有更多的底層能力,包括undo,redo,批次生產,批次佈局,打組,解散打組,拖拽複製能力,批次移動,旋轉和縮放等等能力,都是用於易用性的開發,此處不在詳細說明。後面將會有文章專門說明編輯器的底層能力。

動態樓層

客戶需要能夠動態生產樓層,樓層模型拉入場景時,手動輸入 地上層數,地下層數,單元數,然後按照輸入的層數自動生成相應樓宇模型。樓層支援動態修改樓層數和單元數量。這樣可以達到的目的就是通用型,不用針對每個臺區進行樓層的建模,減少後期的工作量。

通過對於樓層+ 樓頂進行分開建模,然後把樓層進行組合的能力,來實現上述功能。

連線功能

在臺區和電錶之間要能夠新增連線,表示聯通關係,效果如下所示:

輸入臺區模型編號和電錶模型編號。 然後按照橫平豎直的方法連線連線。其中由於webgl的line寬度只能為1,影響效果,所以我們的連線使用了自己封裝的Line,類似threejs的MeshLine,通過Mesh來模擬Line,可以指定line的寬度。程式碼如下所示:

 const material = new dt.MeshLineMaterial({
    useMap: true,
    map: texture,
    color: new dt.Color("red"),
    transparent: true,
    clipRatio: .1,
    opacity: 1,
    depthTest: false,
    // depthWrite: false,
    resolution: new dt.Vec2(graph.width, graph.height),
    sizeAttenuation: false,
    lineWidth: 100,
    repeat: new dt.Vec2(20, 3),
    offset: new dt.Vec2(0, 0),
    gradientStop: [0, 0.2, random(0.55, 0.65), 1],
    gradientColor: ["blue", "green", "orange", "red"],
    blending: dt.AddtiveBlending,
  });
  var g = new dt.MeshLine();
  g.setGeometry(geo);
  var mesh = new dt.Mesh(g.geometry, material);

特效

通過平臺的腳步能力,可以實現二次開發的能力,二次開發實現的特效如下:

  • 線條的流動效果

    通過uv流動動畫+特定的貼圖,可以實現線條的流動效果,比如demo效果如下:

    有關uv流動動畫的原理,可以參考筆者之前的文章《
    》。

  • 臺區、電能表模型輪廓發光的呼吸燈閃爍效果

    通過引擎的OutlineRenderer,可以實現模型的輪廓效果,並且通過OutlineRenderer的引數的不斷修改,便可以實現呼吸燈的閃爍的效果,程式碼如下所示:

graph.outlineMethod = "glow";
if (graph._outlineRenderer) {
  let pass = graph._outlineRenderer.outlinePass;
  pass.visibleEdgeColor = new Color(controls.visibleEdgeColor);
  pass.hiddenEdgeColor = new Color(controls.visibleEdgeColor);
  pass.edgeGlow = controls.edgeGlow;
  pass.edgeThickness = controls.edgeThickness;
  pass.edgeStrength = controls.edgeStrength;
  pass.downSampleRatio = parseInt(controls.downSampleRatio);
}

最終的效果如下圖所示:

總結

本文主要闡述了電力行業三維佈局的主要功能特點。

最後,關注公號「ITMan彪叔」 可以新增作者微信進行交流,及時收到更多有價值的文章。