惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
U
Unit 42
F
Fortinet All Blogs
雷峰网
雷峰网
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
Y
Y Combinator Blog
罗磊的独立博客
V
Visual Studio Blog
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
爱范儿
爱范儿
B
Blog RSS Feed
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
I
InfoQ
博客园 - 叶小钗
博客园 - 聂微东
Last Week in AI
Last Week in AI

博客园 - ITman彪叔

赋能UE运行态编辑平台: 网络图片下载的插件改造与复盘 召回率暴涨!“层级化分片”与“降噪”拯救 RAG 系统 基于FastMCP打通业务系统与AI:构建智能协作新范式 在 Dify 中通过 MCP 集成本地 FastMCP 服务避坑指南 从分形到森林——使用 Three.js 创建逼真的 3D 树木 Threejs 视频融合 UE5 小部件 组合框(键)ComboBox (Key) Tesseract OCR 页面分割模式解析 Java MQTT 主流开发方案对比 Java Modbus主流开发方案对比 Java OPC UA 开发方案全对比:开源、商业、集成与官方标准 Nodejs打包 Webpack 中 __dirname 的正确配置与行为解析 强制 pnpm 使用 IPv4 而不是 IPv6 的终极解决方案指南 uniapp 微信小程序 调试 UE Websocket 通信 UE Geometry_Script 程序化建模 UE MultiLineTraceByChannel函数返回只有一个对象的问题 UE Spline 样条网格体组件添加碰撞 Three光源Target位置改变光照方向不变的问题及解决方法 UE5 射线检测排除隐藏的Actor UE5打包SDK未正确安装的问题 判断两个矩形是否相交(Rect Intersection) UE4 WebUI使用指南2-通信
电力布局三维编辑器功能设计
ITman彪叔 · 2023-04-22 · via 博客园 - ITman彪叔

楔子

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

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

创建模型库

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

三维编辑功能

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

生成模型

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

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

动态楼层

客户需要能够动态生产楼层,楼层模型拉入场景时,手动输入 地上层数,地下层数,单元数,然后按照输入的层数自动生成相应楼宇模型。楼层支持动态修改楼层数和单元数量。这样可以达到的目的就是通用型,不用针对每个台区进行楼层的建模,减少后期的工作量。
626f7e815295ff07f66ffd42d372f79.pngbab51f8ed71f808ac8cdecc9bcb3b57.pngf2f0dc2ac1ed0ba4bdad9a7f771f84a.png

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

连线功能

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

最终的效果如下图所示:
image.png

总结

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

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