楔子

最近和一家公司在谈一个项目合作,他们公司主要是做电力相关的。 项目背景大概是这样的:
国家电网对电网资产需要做到数字化管理,对现有变压器台区内的电表箱电能表做可视化数字孪生管理。
由于涉及到的台区非常多,所以客户希望开发的不是单个项目,而是可以实现项目的3D编辑器,使得电网的台区经理使用编辑器编辑出所负责的变压器台区的设备关系场景及数据状态展示。

三维可视化方面,三维组态,我们经验还是挺多的,比如数据中心、医院、学校等三维可视化项目,还包括智慧园区、智慧城市、智慧小镇的方向的等三维可视化。
下面先上几张三维可视化的图瞅瞅:
电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP
电力布局三维编辑器功能设计-LMLPHP
客户需要的是一个布局工具,而不是直接的三维场景,这比直接搭建一个三维的场景要难许多。
但是所谓万事开头难,难在不开头。 天下事有难易乎,干就是了。由于之前做过油田的三维布局,虽然内容上不太一样,但是技术上是类似的,还是相对来说容易很多。
在商务人员和客户确立合同,正式立项后, 我们的设计小姐姐,开发小哥哥,建模小弟弟,都各司其职,下边就讲一下项目的大概内容。

创建模型库

模型库主要包括了园区模型(通用),楼宇模型(通用),台区模型,电表箱,电能表等等。
电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP
首先是开发同事搭建一个模型库的功能,主要包括了对于模型的管理。 模型库功能主要包括,模型的上传,预览和分类和列表功能。同时让建模小伙把相关模型使用3D建模工具 3d max或者c4d 进行模型的建模。建模后,导出后缀为obj/gltf/fbx格式文件,建模后的所有模型文件,最终会上传到模型库,模型库的管理目录如下图所示:
电力布局三维编辑器功能设计-LMLPHP

三维编辑功能

三维编辑能力是电力布局三维编辑器的核心功能。

生成模型

三维编辑能力之一是把模型列表的功能拖拽到三维画布上,生成三维模型。主要的技术实现包括了 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工具进行平移,旋转和缩放模型。如下图所示:
电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP

当然还有更多的底层能力,包括undo,redo,批量生产,批量布局,打组,解散打组,拖拽复制能力,批量移动,旋转和缩放等等能力,都是用于易用性的开发,此处不在详细说明。后面将会有文章专门说明编辑器的底层能力。

动态楼层

客户需要能够动态生产楼层,楼层模型拉入场景时,手动输入 地上层数,地下层数,单元数,然后按照输入的层数自动生成相应楼宇模型。楼层支持动态修改楼层数和单元数量。这样可以达到的目的就是通用型,不用针对每个台区进行楼层的建模,减少后期的工作量。
电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP电力布局三维编辑器功能设计-LMLPHP

通过对于楼层+ 楼顶进行分开建模,然后把楼层进行组合的能力,来实现上述功能。

连线功能

在台区和电表之间要能够添加连线,表示联通关系,效果如下所示:
电力布局三维编辑器功能设计-LMLPHP
输入台区模型编号和电表模型编号。 然后按照横平竖直的方法连接连线。其中由于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效果如下:
    电力布局三维编辑器功能设计-LMLPHP
    有关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);
}

最终的效果如下图所示:
电力布局三维编辑器功能设计-LMLPHP

总结

本文主要阐述了电力行业三维布局的主要功能特点。

最后,关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。

04-22 14:27