# 房间应用(Room)

建筑内拥有房间的概念,它会与分区、空间内设备管理等实际业务问题发生关联,因此本节我们来介绍关于房间的创建及应用。

通过BIMFACE提供的接口,您可以实现:

  1. 在前端创建房间;
  2. 控制房间的显示样式;
  3. 实现房间编辑;
  4. 空间关系计算。

# 基本概念说明

不同于常规通过文件上传转换后得到的构件,BIMFACE中的房间是在引擎中通过接口创建出来的构件,拥有一套独立的创建、修改、过滤方法。

# 房间的几何描述

房间的几何描述,在BIMFACE中,目前以拉伸体的形式表达,需要指定房间边界和高度。

对于边界,需要指定房间的外部边界及内部边界。目前BIMFACE支持三种形式输入边界:

  1. 构造外部边界与内部边界;
  2. 通过模型中轴网的交点来确定边界;
  3. 通过Revit模型中设置的房间信息来确定边界。

对于高度,需要指定房间的高度。目前BIMFACE支持两种形式输入边界:

  1. 输入高度数值;
  2. 指定底标高与顶标高。

将在后文详细介绍房间各条件的输入方法。

# 房间方法架构

BIMFACE在Plugins中构造了Rooms的命名空间,提供了房间相关的接口文档 (opens new window)

该命名空间下,各方法的功能如下:

方法 描述
RoomConfig 房间应用配置项,用于配置房间对象的几何属性、外观、关联viewer对象等。
Room 房间应用,用于房间构造,及针对单个房间的属性获取、修改以及空间关系计算
RoomManager 房间应用管理器,用于房间添加,房间对象获取,显示管理。每个viewer对象拥有默认的RoomManager,通过viewer.getRoomManager()的方式获取。
RoomEditorToolbarConfig 房间编辑器工具条配置项,用于配置房间编辑器工具条
RoomEditorToolbarEvent 房间编辑器监听事件
RoomEditorToolbar 房间编辑器工具条

在前端创建房间时,需遵循如下流程:

  1. 房间接口配置项设置
  2. 房间创建
  3. 将房间添加至房间管理器
  4. 房间应用(空间关系查找、房间编辑...)

# 房间创建

在本节,将展示创建房间的几种方法。

首先,创建一个创建房间的按钮。

<button class="button" id="btnCreateRoom" onclick="createRoom()">创建房间</button>

之后,我们通过接口,获取到房间管理器,后续需要通过房间管理器来添加创建的房间。

let roomManager = viewer3D.getRoomManager();
# 1 创建revit中设置的房间

在本节,我们希望找到一个名称为“活动室 11”的房间对象,并以此来创建BIMFACE内部的房间。

首先,我们需要获取到所有已解析的房间信息。

if (isRoomCreated) {
    return;
}
// 获取解析后的房间边界信息,这里要找到名称为“办公室 11”的对象,并创建房间
viewer3D.getModel().getAreas(function (data) {
    // code here
});

获取房间信息是一个异步过程,它的层级可以简化为“标高”-“房间”-“房间信息”的结构,我们需要在其回调内遍历出我们需要的房间边界。

在找到所需房间边界后,即可创建出房间对象,我们指定房间对象的颜色为红色。

// 获取解析后的房间边界信息,这里要找到名称为“活动室 11”的对象,并创建房间
viewer3D.getModel().getAreas(function (data) {
    if (data) {
        for (let i = 0; i < data.length; i++) {
            if (data[i].rooms) {
                for (let j = 0; j < data[i].rooms.length; j++) {
                    if (data[i].rooms[j].name == "办公室 11") {
                        // 获取房间信息和id
                        let roomInfo = data[i].rooms[j];
                        roomId = 'room-' + roomInfo.id;
                        // 通过房间边界创建一个3350mm高的房间,并自定义房间id
                        let roomConfig = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
                        roomConfig.viewer = viewer3D;
                        roomConfig.roomId = roomId;
                        roomConfig.geometry = {
                            type: "extrusion",
                            boundary: roomInfo.boundary,
                            height: 3350,
                            unit: "mm"
                        };
                        roomConfig.roomColor = new Glodon.Web.Graphics.Color(255, 0, 0, 0.5);
                        roomConfig.frameColor = new Glodon.Web.Graphics.Color(255, 0, 0, 1);
                        let room = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig);
                        roomManager.addRoom(room);
                        viewer3D.render();
                        isRoomCreated = true;
                    }
                }
            }
        }
    }
});
# 2 自定义边界

在本节,我们通过用户指定的房间边界和房间顶部、底部标高来生成房间,并设置为绿色。

用户自定义的房间以外边界和内边界的形式表达,形式如:

// boundary
{
    "outer": [
        { "x": "0", "y": "0", "z": "0" },
        { "x": "30000", "y": "0", "z": "0" },
        { "x": "30000", "y": "30000", "z": "0" },
        { "x": "0", "y": "30000", "z": "0" }
    ],
    "inner": [
        [
            { "x": "10000", "y": "10000", "z": "0" },
            { "x": "20000", "y": "10000", "z": "0" },
            { "x": "20000", "y": "20000", "z": "0" },
            { "x": "10000", "y": "20000", "z": "0" }
        ]
    ]
}

对应代码如下:

// 按用户自定义边界信息和标高生成房间
let roomConfig2 = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
roomConfig2.viewer = viewer3D;
roomConfig2.roomId = 'room2';
roomConfig2.geometry = {
    type: "extrusion",
    boundary: {
        "outer": [
            { "x": "-5500", "y": "0", "z": "0" },
            { "x": "-2300", "y": "0", "z": "0" },
            { "x": "-2300", "y": "-5000", "z": "0" },
            { "x": "-5500", "y": "-5000", "z": "0" }
        ]
    },
    offset: [0, 3500],
    unit: "mm",
    roomConfig.roomColor = new Glodon.Web.Graphics.Color(0, 255, 0, 0.5);
    roomConfig.frameColor = new Glodon.Web.Graphics.Color(0, 255, 0, 1);
};
let room2 = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig2);
roomManager.addRoom(room2);
# 3 按轴网确定边界

首先,需要在模型中加载轴网:

// 加载轴网
viewer3D.getModel().showAxisGridsByFloor("", 311);

其次,通过给定的指定轴网交点,来创建房间,并指定为蓝色:

let roomConfig3 = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
roomConfig3.viewer = viewer3D;
roomConfig3.geometry = {
    type: "extrusion",
    grid: {
        ids: ['A', 'E', '3', '1/5']
    },
    offset: [0, 3500]
};
roomConfig3.roomColor = new Glodon.Web.Graphics.Color(0, 0, 255, 0.5);
roomConfig3.frameColor = new Glodon.Web.Graphics.Color(0, 0, 255, 1);

let room3 = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig3);
roomManager.addRoom(room3);

最终,得到的效果图如下:

# 房间应用

# 1 房间显隐

常规构件可见性的接口并不能控制房间的可见性,需要通过额外的接口来实现,使用方法与常规构件的接口相类似。

我们首先创建一个控制房间可见性的按钮。

<button class="button" id="btnHideRoom" onclick="hideRoom(roomIdList)">隐藏房间</button>

然后我们构造一个函数,用来隐藏或显示已经创建好的房间。这里,隐藏或显示房间的方法需要传入房间的id数组。

isHideRoomActivated = false;
function hideRoom(roomIdList) {
    // 判断是否已经创建房间
    if (!isRoomCreated) {
        window.alert("Please create a room first!");
        return;
    }
    if (!isHideRoomActivated) {
        // 根据id隐藏房间
        roomManager.hideRoomsById(roomIdList);
        viewer3D.render();
        setButtonText("btnHideRoom", "显示房间");
        isHideRoomActivated = true;
    } else {
        // 根据id显示房间
        roomManager.showRoomsById(roomIdList);
        viewer3D.render();
        setButtonText("btnHideRoom", "隐藏房间");
        isHideRoomActivated = false;
    }
}
# 2 属性获取

在创建房间对象后,我们可以通过接口,获取已经创建的房间的属性,对应的方法在room中。

我们首先创建一个获取房间属性的按钮。

<button class="button" id="btnGetProperty" onclick="getProperty(roomId)">获取属性</button>

然后我们构造一个函数,用来获取房间属性。

let roomId = roomIdList[0];
function getProperty(roomId) {
    // 判断是否已经创建房间
    if (!isRoomCreated) {
        window.alert("Please create a room first!");
        return;
    } else {
        // 获取房间对象
        room = roomManager.getRoomById(roomId);

        // 获取面积属性
        area = room.getArea();
        // 获取房间高度
        height = room.getHeight();

        alert("id:" + roomId + "\n" + "面积:" + area.value + "\n" + "高度:" + height);
    }

}

# 扩展

更多关于房间的应用,可参考以下内容:

# 完整代码

<!DOCTYPE html>
<html>

<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%;
        }

        .model {
            flex: 1;
        }

        .buttons {
            font-size: 0;
        }

        .button {
            margin: 5px 0 5px 5px;
            width: 100px;
            height: 30px;
            background: #32D3A6;
            color: #FFFFFF;
            border-radius: 3px;
            border: none;
            cursor: pointer;
            outline: none;
        }
    </style>
    <!-- 引用BIMFACE的JavaScript显示组件库 -->
    <script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js" charset="utf-8">
    </script>
</head>

<body>
    <div class='main'>
        <div class='buttons'>
            <button class="button" id="btnCreateRooms" onclick="createRooms()">创建房间</button>
            <button class="button" id="btnHideRoom" onclick="hideRoom(roomIdList)">隐藏房间</button>
            <button class="button" id="btnGetProperty" onclick="getProperty(roomId)">获取属性</button>
        </div>
        <!-- 定义DOM元素,用于在该DOM元素中显示模型或图纸 -->
        <div class='model' id="domId"></div>
    </div>
    <script type="text/javascript">
        let viewer3D;
        let app;
        let boundary;
        let viewToken = '<yourViewToken>';
        let roomIdList = new Array();
        let roomManager;
        // 初始化显示组件
        let options = new BimfaceSDKLoaderConfig();
        options.viewToken = viewToken;
        BimfaceSDKLoader.load(options, successCallback, failureCallback);

        function successCallback(viewMetaData) {
            if (viewMetaData.viewType == "3DView") {
                // ======== 判断是否为3D模型 ========        
                // 获取DOM元素
                let dom4Show = document.getElementById('domId');
                let webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig();
                webAppConfig.domElement = dom4Show;
                // 设置全局单位
                webAppConfig.globalUnit = Glodon.Bimface.Common.Units.LengthUnits.Millimeter;
                // 创建WebApplication
                app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig);
                // 添加待显示的模型
                app.addView(viewToken);
                // 从WebApplication获取viewer3D对象
                viewer3D = app.getViewer();
                // 监听添加view完成的事件
                viewer3D.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded, function () {
                    //自适应屏幕大小
                    window.onresize = function () {
                        viewer3D.resize(document.documentElement.clientWidth, document.documentElement
                            .clientHeight - 40);
                    }
                    // 渲染3D模型
                    viewer3D.render();
                    roomManager = viewer3D.getRoomManager();
                    // 加载轴网
                    viewer3D.getModel().showAxisGridsByFloor("", 311);
                });
            }
        }


        function failureCallback(error) {
            console.log(error);
        }

        // *********************创建房间***************************
        let isRoomCreated = false;

        function createRooms() {
            if (isRoomCreated) {
                return;
            }
            // 获取解析后的房间边界信息,这里要找到名称为“活动室 11”的对象,并创建房间
            viewer3D.getModel().getAreas(function (data) {
                if (data) {
                    for (let i = 0; i < data.length; i++) {
                        if (data[i].rooms) {
                            for (let j = 0; j < data[i].rooms.length; j++) {
                                if (data[i].rooms[j].name == "活动室 11") {
                                    // 获取房间信息和id
                                    let roomInfo = data[i].rooms[j];
                                    roomId = 'room-' + roomInfo.id;
                                    // 通过房间边界创建一个3350mm高的房间,并自定义房间id
                                    let roomConfig = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
                                    roomConfig.viewer = viewer3D;
                                    roomConfig.roomId = roomId;
                                    roomConfig.geometry = {
                                        type: "extrusion",
                                        boundary: roomInfo.boundary,
                                        height: 3350,
                                        unit: "mm"
                                    };
                                    roomConfig.roomColor = new Glodon.Web.Graphics.Color(255, 0, 0, 0.5);
                                    roomConfig.frameColor = new Glodon.Web.Graphics.Color(255, 0, 0, 1);
                                    let room = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig);
                                    roomManager.addRoom(room);
                                    viewer3D.render();
                                    isRoomCreated = true;
                                    roomIdList.push(roomId);
                                }
                            }
                        }
                    }
                }
            });
            // 按用户自定义边界信息和标高生成房间
            let roomConfig2 = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
            roomConfig2.viewer = viewer3D;
            roomConfig2.roomId = 'room2';
            roomConfig2.geometry = {
                type: "extrusion",
                boundary: {
                    "outer": [
                        { "x": "-5500", "y": "0", "z": "0" },
                        { "x": "-2300", "y": "0", "z": "0" },
                        { "x": "-2300", "y": "-5000", "z": "0" },
                        { "x": "-5500", "y": "-5000", "z": "0" }
                    ]
                },
                offset: [0, 3500],
                unit: "mm"
            };
            roomConfig2.roomColor = new Glodon.Web.Graphics.Color(0, 255, 0, 0.5);
            roomConfig2.frameColor = new Glodon.Web.Graphics.Color(0, 255, 0, 1);
            let room2 = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig2);
            roomManager.addRoom(room2);
            roomIdList.push(roomConfig2.roomId)


            let roomConfig3 = new Glodon.Bimface.Plugins.Rooms.RoomConfig();
            roomConfig3.viewer = viewer3D;
            roomConfig3.roomId = 'room3';
            roomConfig3.geometry = {
                type: "extrusion",
                grid: {
                    ids: ['A', 'E', '3', '1/5']
                },
                offset: [0, 3500]
            };
            roomConfig3.roomColor = new Glodon.Web.Graphics.Color(0, 0, 255, 0.5);
            roomConfig3.frameColor = new Glodon.Web.Graphics.Color(0, 0, 255, 1);

            let room3 = new Glodon.Bimface.Plugins.Rooms.Room(roomConfig3);
            roomManager.addRoom(room3);
            roomIdList.push(roomConfig3.roomId)

        }

        //*********************隐藏房间*************************
        isHideRoomActivated = false;
        function hideRoom(roomIdList) {
            // 判断是否已经创建房间
            if (!isRoomCreated) {
                window.alert("Please create a room first!");
                return;
            }
            if (!isHideRoomActivated) {
                // 根据id隐藏房间
                roomManager.hideRoomsById(roomIdList);
                viewer3D.render();
                setButtonText("btnHideRoom", "显示房间");
                isHideRoomActivated = true;
            } else {
                // 根据id显示房间
                roomManager.showRoomsById(roomIdList);
                viewer3D.render();
                setButtonText("btnHideRoom", "隐藏房间");
                isHideRoomActivated = false;
            }
        }

        //******************获取属性***************************
        let roomId = roomIdList[0];
        function getProperty(roomId) {
            // 判断是否已经创建房间
            if (!isRoomCreated) {
                window.alert("Please create a room first!");
                return;
            } else {
                // 获取房间对象
                room = roomManager.getRoomById(roomId);

                // 获取面积属性
                area = room.getArea();
                // 获取房间高度
                height = room.getHeight();

                alert("id:" + roomId + "\n" + "面积:" + area.value + "\n" + "高度:" + height);

            }

        }



        // ************************** 按钮文字 **************************
        function setButtonText(btnId, text) {
            let dom = document.getElementById(btnId);
            if (dom != null && dom.nodeName == "BUTTON") {
                dom.innerText = text;
            }
        }

    </script>
</body>

</html>