# 管网分析教程

为实现模型的管网分析,需要进行的步骤是:

  1. 上传文件并完成转换/集成;
  2. 发起元素信息抽提并完成;
  3. 调用接口实现数据的查询与分析。

基于该流程,本文给出了一个管网拓扑分析的元素信息使用教程,实现如下功能:

  1. 管道系统属性的获取;
  2. 管道系统与管道构件控制关系的获取;
  3. 管道构件之间的拓扑关系获取;
  4. rvm格式的流向动画绘制。

在进行动手操作前,推荐先阅读基本概念中的管网拓扑分析 (opens new window),以了解基本概念和基本功能。

# 前期准备

BIMFACE提供了一个含属性信息的rvm文件 (opens new window),用于元素信息分析使用示例。

可下载该文件,并在您自己的控制台完成模型的上传与转换。当然,您也可以通过后端接口的形式进行文件的上传与转换,但在此之前需要进行accessToken的获取。

# 元素信息抽提

在完成模型的上传与转换后,对准备好的数据进行元素信息抽提:

PUT https://api.bimface.com/feature-management/v1/domain/extraction

对于管道系统的业务场景,指定抽提类型为pipeSystem,故在body里指定相关信息:

{
    "fileId":#your fileId#,
    "extractType":"pipeSystem"
}

发起元素信息抽提后,可通过接口批量查询元素信息抽提的状态:

POST https://api.bimface.com/feature-management/v1/domain/extraction-states

当status=99时,说明抽提任务已经完成:

{
    "code": "bimfaceservice-0000",
    "message": null,
    "data": {
        "list": [
            {
                "appKey": "abcdefg",
                "cost": 1047,
                "createTime": "2022-08-24T11:28:32.000Z",
                "databagId": "abcdefg",
                "errorCode": null,
                "errorMessage": null,
                "extractId": 1234567,
                "fileId": 1234567,
                "integrateId": null,
                "projectId": 1234567,
                "status": 99
            }
        ],
        "page": {
            "nextPage": 1,
            "pageNo": 1,
            "pageSize": 20,
            "prePage": 1,
            "startIndex": 0,
            "totalCount": 1,
            "totalPages": 1
        }
    }
}

需注意:该接口为批量查询状态接口。若不在body参数中传入projectId,默认会查询默认项目下的元素信息抽提结果。

详细接口文档可参考:查询BIM元素信息抽提状态及列表 (opens new window) 详细开发指南可参考:元素信息抽提与管理 (opens new window)

# 前端应用

# 模型加载

首先,需设置html的头部用于页面布局:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>管网分析</title>
    <style media="screen">
        * {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            height: 100%;

        }

        .main {
            display: flex;
            flex-direction: column;
            overflow: hidden;
            height: 100%;
            width: 100%;
        }

        .input {
            margin-left: 5px;
            padding: 0 8px;
            height: 30px;
            border: 1px solid #32D3A6;
            box-sizing: border-box;
            width: 160px;
        }

        .model {
            flex: 1;
        }

        .buttons {
            font-size: 0;
        }

        .button {
            margin: 5px 0 5px 5px;
            width: 160px;
            height: 30px;
            background: #32D3A6;
            color: #FFFFFF;
            border-radius: 3px;
            border: none;
            cursor: pointer;
        }
        /* 其它你需要的css样式 */
    </style>


其次,需要引用BIMFACE的显示组件库(必须):

<script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js"></script>

完成后,可在body中编写javascript,实现模型加载显示。

需注意,在使用时需要将viewToken替换为自己的viewToken。 viewToken的获取可参考:https://bimface.com/docs/model-viewer/v1/developers-guide/view-token.html

<body>

    <div class='main'>
        <!-- 按钮 -->
        <div class='buttons'>
            <!-- 设置自定义按钮 -->
        </div>
        <!-- 设置其它需要的div -->

        <!-- 定义DOM元素,用于在该DOM元素中显示模型或图纸 -->
        <div class='model' id="view"></div>
    </div>

    <script type="text/javascript">

        // 定义初始化参数
        let viewer;
        let app;
        let viewAdded = false;

        // 设置viewToken
        let viewToken = 'yourViewToken';

        // 初始化显示组件
        let options = new BimfaceSDKLoaderConfig();
        options.viewToken = viewToken;
        BimfaceSDKLoader.load(options, successCallback, failureCallback);

        function successCallback(viewMetaData) {
            if (viewMetaData.viewType == "3DView") {
                //模型加载
                let view = document.getElementById('view')
                let config = new Glodon.Bimface.Application.WebApplication3DConfig();
                config.domElement = view;
                app = new Glodon.Bimface.Application.WebApplication3D(config);
                viewer = app.getViewer();
                viewer.addModel(viewMetaData);

                //加载完成监听事件
                viewer.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded, function () {
                    //自适应屏幕大小
                    window.onresize = function () {
                        viewer.resize(document.documentElement.clientWidth, document.documentElement.clientHeight - 40);
                    }
                    viewer.render();
                    // 添加自定义功能
                });

            };
        };

        function failureCallback(error) {
            console.log("Failed to load SDK!");
        };

    </script>
</body>

完成该步骤并运行后,即可看见如下加载页面: 浏览

后续如有需要使用BIMFACE其它的前端接口功能,可参考Model Viewer (opens new window)


# 管网分析功能

在构建好前端页面后,可以使用管网分析相关功能。前端参考文档见PipeSystem (opens new window)


管网系统对象加载

在使用相关功能之前,需要先在bimModel中加载元素信息对象

pipe = viewer.getModel().getFeatureData("pipeSystem");

注意:代码需写在模型加载完成监听事件addEventListener的callback中。


获取管道系统信息

可调用前端接口,获取管道系统信息,并打印在控制台:

pipe.getSystems().then(
    function (data) {
        console.log(data)
        // 其它操作
        }
);

最终可以获取到返回结果,后续用于其它分析。返回结构示例如下。

// 返回结果示例
// 对于管道系统,通用属性为name、parentId、systemId、systemType
[
    {
        "flowFrom": ['54', '1317'],
        "flowInto": ['962', '951'],
        "name": "/100-B-8",
        "parentId": "995",
        "systemId": "1287",
        "systemType": "PIPE",
        "terminals": []
    }
]

获取管道系统内构件

在获取到模型内的系统信息后,可以通过系统id来获取指定系统包含的构件。以本模型为例,选择系统id为1147,调用前端接口,将信息打印在控制台:

pipe.getComponentsBySystemId({"systemId":1147},[]).then(
    function (data){
        console.log(data);
    }
    // 获取构件id列表,用于其它分析
);

最终可以获取到返回结果,后续用于其它分析。

// 返回结果示例
// 返回某管道系统下包含的管道构件
['1154', '1153', '1152', '1151', '1149', '1148', '1157', '1156', '1155'];

例如,可以对获取到的管道系统构件进行隔离与定位操作:

viewer.getModel().setSelectedComponentsById(data);
viewer.getModel().zoomToSelectedComponents();
viewer.getModel().isolateComponentsById(data, Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent);

返回效果如下: 获取系统构件 当然,也可以增加筛选条件,如,获取该系统内type=圆管的构件:

condition = [{"type":"圆管"}];
pipe.getComponentsBySystemId({"systemId":1147},condition).then(
    function (data){
        console.log(data);
    }
    // 获取构件id列表,用于其它分析
);

返回结果如下:

// 返回结果示例
// 返回管道系统下type=圆管包含的管道构件
['1149', '1148'];

获取管道构件属性

可以通过接口,通过指定的管道构件id,获取对应构件的拓扑属性。以本模型为例,选择构件id=1148的构件:

let component = {"componentId": 1148};
pipe.getTopologyPropertiesById(component).then(
    function(data){
        console.log(data);
        }
    )

最终可以获取到返回结果,后续用于其它分析。返回结果如下:

// 返回结果示例
{
    "flowFrom": ['1154'],
    "flowInto": ['1155'],
    "id": "1149",
    "in": [],
    "name": "圆柱[1149]",
    "out": [],
    "systemId": ['1147'],
    "type": "圆柱",
    "uvDirection": 1,
}

获取上游/下游构件

可以获取管道构件的上游构件和下游构件,示例代码如下。可以将获得的信息打印在控制台,也可对获取的构件进行隔离定位操作:

let component = {
    // 设置需要获取下游构件的构件id,如1295
    "componentId": "1295"
    };
pipe.getDownstreamComponentsById(component).then(
    function (data) {
        console.log(data);
        viewer.getModel().setSelectedComponentsById(data);
        viewer.getModel().zoomToSelectedComponents();
        viewer.getModel().isolateComponentsById(data, Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent);
        }
        )

可以获得返回结果如下图:


构件流向动画

管网分析还支持流向动画的生成,步骤如下:

  1. 获取需要设置流向动画的构件id列表;
  2. 前端接口设置构件水流贴图材质;
  3. 设置水流动画。

需注意:目前贴图暂时支持PDMS模型的圆管、圆管弯头和方管,其它格式正在开发中。

示例代码如下。对本模型,设置系统id为1147的管道系统的流向动画:

// 流向动画设置
function setFlowAnimation(data) {
    // 动画
    flowEffectConfig1 = new Glodon.Bimface.Plugins.Animation.FlowEffectConfig();
    // 构造水流动画对象 flowEffect1
    flowEffectConfig1.material = data;
    flowEffectConfig1.speed = [0.03, 0];
    flowEffectConfig1.viewer = viewer;
    flowEffect1 = new Glodon.Bimface.Plugins.Animation.FlowEffect(flowEffectConfig1);
    flowEffect1.play();
    }
// 设置贴图材质,设置水流动画
system = {"systemId": 1147};
pipe.getComponentsBySystemId(system, []).then(
    function (data) {
        pipe.setFlowEffectMaterialByIds({ "componentIds": data }).then(
            function (data) {
                for (i = 0; i < data.length; i++) {
                    setFlowAnimation(data[i])};
                });
            viewer.getModel().zoomToSelectedComponents();
            viewer.getModel().isolateComponentsById(data, Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent);
            }
)

得到返回结果如下图:


获取管道路径

在实际业务场景中,我们可能还需要知道两根管道构件之间的流动路径。BIMFACE也提供了相应接口。

以构件1449和构件1453为例,寻找对应的路径:

示例代码如下:

let component = {
    "startComponentId": 1449,
    "endComponentId": 1453,
    "limit": "3"
    };
pipe.getFlowPathByIds(component).then(
    function (data) {
        console.log(data);
        }
)

最终得到的结果如下:

[
    {
        "end":'1453',
        "path":['1449', '1462', '1450', '1463', '1496', '1498', '1499', '1501', '1503', '1497', '1482', '1452', '1484', '1453'],
        "start":'1449'
    },
    {
        "end":'1453',
        "path":['1449', '1462', '1450', '1463', '1464', '1466', '1468', '1469', '1470', '1472', '1474', '1475', '1476', '1451', '1477', '1479', '1481', '1482', '1452', '1484', '1453'],
        "start":'1449'
    }
]

寻找上下游最近的管道构件

在实际场景中,我们需要去寻找某管道上/下游各流动路径中,最近的某种类型的构件,如下游各路径最近的开关,BIMFACE提供了相应接口。

以示例模型为例,我们去寻找构件id=1156的上游的,类型为FLAN的最近的构件,示例代码如下:

function getAdjacentComponent() {
    let component = {
        "componentId": 1156
    };
    let condition = {
        "type": "upstream",
        "filter": [{ "type": "FLAN" }]
    }
    pipe.getAdjacentComponentsByConditions(component, condition).then(
        // 设置展示效果
        viewer.getModel().setSelectedComponentsById(data);
        viewer.getModel().isolateComponentsById(data, Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent)
        viewer.getModel().zoomToSelectedComponents();
        viewer.render();
    )
}

最终寻找到构件后,展示效果如下:

寻找最近构件