写在前面的话:

说点啥好呢?就讲讲前两天的小故事吧,让我确实好好反省了一下。

  前两天跟朋友一次技术对话,对方问了一下Geometry与BufferGeometry的具体不同,我一下子脑袋短路,没点到重点定义,被朋友嘲笑一番,亏还搞了three.js 这么久,这么简单的基础知识尽然不能对答如流,原来都是假把式。着实尴尬至极,尴尬至极....

  朋友间的调侃,本是玩笑,但认真思考,不无道理。正所谓温故而知新,也是我们程序员的必须课程,不仅仅是学习利用新技术,对自己常用的老技术也要时长翻看一下,加强记忆,加深理解。

  后来我还真好好的整理总结了一下Geometry与BufferGeometry,查漏补缺,也算为时未晚也。

  一句话,这两个对象的主要区别:主要在数据结构上,BufferGeometry非常高效,主要是因为数据直接放在一个连续的GPU内存空间中,有效减少向 GPU 传输上述数据所需的开销,而three.js后期版本中的geometry最终都转化为bufferGeometry,但始终是比bufferGeomerty多了一步,而且还是从CPU的geometry对象传输到GPU的bufferGeometry对象的一个夸硬件传递过程,所以后期也不建议用geometry了。

序:

在三维机房管理系统中,我们已经可以看到很多实现3d机房的可视化管理方案,常见的功能有动力环境管理、安防监控、资产管理与运维,包括我的前面的文章也有过常规3D机房方案的介绍,可以看我前面的文章(使用webgl(three.js)创建科技版3D机房,3D机房微模块详细介绍(升级版三)—— 1)。

再很多3D机房方案中,管线管理.一直是无法切实解决的痛点。主要原因有如下几个:

1、种类繁杂,机房管线线路繁杂,光是线路类型就包括了强电,弱电走线、光纤网线、消防管线、甚至包括国防线(政策上是规避展示的)

2、施工图纸整理繁杂,涉及到各种类型的线路,施工图都来源一大堆,着实无法入手

3、建模工作量大,线路的建模,是最繁杂的,除了线路多,走势还错综复杂

那么针对上面的痛点,我们又该如何解决。

首先是素材来源问题,记得高中学过,唯物主义辨证方法论的思想,牵牛我们要牵牛鼻子,既然线路繁杂,何不挑重点先解决,数据中心这个行业,管线最关心的还是光纤网络线路,而且是只正对数据服务器的网络线路,其它什么强电弱电,甚至是机房内部的动环系统传感器走线,都不是那么重要。所以我们先提出主要矛盾。重点解决机房数据业务的网络走线即可。

然后是技术实现方面:

有三种方案选择:

  1、全程建模,通过建模的方式实现走线展示,这虽然准确,但哪有那么多的人力物力去建模,还有建模过程中,也不能确保没有遗漏与错搭。

  2、数据节点驱动:只保存每条线路的关键节点,使用代码生成的线路方式。这很大程度上减少了工作量,但是整理的工作量也不小。

  3、逻辑线路:只记住起点与经过的设备节点以及终点,自动智能化生成线路。线路不按照实际走向,只记录描述线路上设备的逻辑点位。

我们的解决方案是采用后面两种,虚实结合。

好了 闲话少叙,归入正题:

一、定义:

管道:顾名思义,就知道是指放线缆的固定建筑,有时候是铁管道,有时候是水泥管道

井:每隔一段管道就会有一个便于施工人员维护的井出现

线缆:通常情况下,是放在管道里面的粗黑粗黑的电缆。

电路:是指在线缆里面的一根一根的电线,通常一根电缆里面有几根或者十几根电路

光纤:在电路里面的光纤

二、效果与代码实现:

1、整体园区效果,我们还是采用深色科技蓝风格(科技的主流风)。模型我们还是采用代码创建的方式,楼宇标号采用精灵模型。这里的井盖采用黄色标亮,便于识别。

全场景实现主要代码如下:

function threeStart(_height) { // dataFunc 获取机柜,空调,墙等设备的json对象
WT3DModel = new WT3D(); // 实例化 3D 核心对象,见 WT3D.core.js 文件。
var initOption = {
antialias: true, // 启用平滑、抗锯齿效果
loadSyn: false, // 是否启用异步加载
showHelpGrid: false, // 是否显示网格线
clearCoolr: 0x4068b0, // 背景色
clearColorOp: 0, // 透明度
};
//初始化模型
var models = [];
httpGetSyn("../models/build.json", function (res) {
models=res;
});
//q {x: -1886.6067471471795, y: 4391.583740697971, z: -5331.98996721255}
//WT3DObj.controls.target
//q {x: 66.88861133235778, y: 755.2546885005784, z: 750.5239600058044}
//加载效果
showLoadingNoLine(
models.length,//模型个数
null,
roomConfig.cameraPostion,
roomConfig.cameraTarget,
function () {//加载完成后回调
modelBussiness = new ModelBussiness();
modelBussiness.init();
pageindex = new Page();
pageindex.initPage();
//旋转注册
WT3DObj.mouseMoveRotateEvent = function (v) {
pageindex.transLeftBall(v);
}
//拓展功能
WT3DObj.commonFunc.transToScreenCoord = function (point) {
var _this = WT3DObj; var screenCoord = {};
var vector = new THREE.Vector3(point.x, point.y, point.z);
vector.project(WT3DObj.camera);
screenCoord.x = (0.5 + vector.x / 2) * _this.width; screenCoord.y = (0.5 - vector.y / 2) * _this.height; return screenCoord;
};
WT3DObj.commonFunc.transToThreeCoord = function (x, y) { var _this = WT3DObj; var pX = (x / _this.width) * 2 - 1; var pY = -(y / _this.height) * 2 + 1; var p = new THREE.Vector3(pX, pY, -1).unproject(WT3DObj.camera); return p; }; });
console.log(models);
var Aobjects = { // 给3D对象绑定事件
objects: models,
Animation: [
{
obj_name: "",
obj_animation: function (_obj) { },
animationType: 0, // 动画类型 -1永久循环执行 0触发执行 >=1执行多少次
aniInterval: 1000, // 执行时间间隔 毫秒
}],
events: {
dbclick: [
{
obj_name: "ALL",
obj_event: function (_obj, face,c,d) { // 被选中的对象 被选中的面
// 此处设置双击聚焦
{
modelBussiness.dbClickSelect(_obj, face);
if (_obj.name.indexOf("build") == 0 || _obj.name.indexOf("ecn") == 0) {
return;
}
modelBussiness.commonFunc.ZoomINShow(_obj, face, c);
}
}
},
],
mouseDown: [
{
obj_name: "ALL",
obj_event: function (_obj, face, objs) { // 被选中的对象 被选中的面
if (window.location.href.indexOf("index.html") >= 0) {
} else if (window.location.href.indexOf("floor.html") >= 0) {
showFloorDetail(_obj);
}
}
},
],
mouseMove: [
{
obj_name: "ALL",
obj_event: function (_obj) {
console.log(_obj.name);
return true;//返回true表示移动
}
},
]
},
//WT3DModel.viewState;表示0编辑状态 1表示运行状态
btns: []
} if (parent != null && parent.Aobjects_objects != null) {
Aobjects.objects = parent.Aobjects_objects;
}
//修改btns //优化Aobjects 此处用于优化 可以先异步加载图片 Aobjects.imageList = [];
imageUUIDList = [];
//遍历获取图片资源
function getImageList(obj) {
if (obj && typeof (obj) == "object") {
$.each(obj, function (_index, _obj) {
if (_obj && _obj.imgurl) {
var imgObj = {};
imgObj.uuid = _obj.imgurl;
imgObj.imgurl = _obj.imgurl;
if ($.inArray(imgObj.uuid, imageUUIDList) < 0) {
imageUUIDList.push(imgObj.uuid);
Aobjects.imageList.push(imgObj);
}
}
getImageList(_obj);
});
}
}
getImageList(Aobjects.objects);
if (_height != null && typeof (_height) != 'undefined' && _height == 0) {
$("#canvas-frame").height($(document).height());
}
//检查是否存在动态资源需要加载
var dynamicSource = [];
$.each(Aobjects.objects, function (_index, _obj) {
/*
动态资源结构
{
name: '',
objType: 'dynamicSource',
file:"";
loadedCallBackFuncName:""
}
*/
if (_obj && _obj.objType && _obj.objType == "dynamicSource") {
dynamicSource.push(_obj);
}
});
if (dynamicSource.length > 0) {
WT3DModel.additionModels = {};
var loadednub = 0;
$.each(dynamicSource, function (_index, _obj) {
$.getScript(_obj.file).done(function () {
/* 耶,没有问题,这里可以干点什么 */
loadednub++;
if (loadednub == dynamicSource.length) {
$.each(dynamicSource, function (_dindex, _dobj) {
if (_dobj.loadedCallBackFuncName && _dobj.loadedCallBackFuncName != "") {
eval(_dobj.loadedCallBackFuncName + "()");
}
});
}
})
.fail(function () {
/* 靠,马上执行挽救操作 */
console.log("文件加载失败");
});
});
}
}

2、显示地下所有管道,实现方式也比较简单,只需要隐藏上方的建筑与园区地面,把管道显现出来即可。这里可以看到一个园区渐变隐藏的效果。

代码实现:

//隐藏园区模型
ModelBussiness.prototype.hideYuanquModel = function (cb) {
if (!this.helpBuildModels) {
this.helpBuildModels = WT3DObj.commonFunc.findObjectsByNames(this.helpBuildNames);
}
// WT3DObj.commonFunc.changeObjsOpacity(this.helpBuildModels, 0,0.5, 1000, function () {});
WT3DObj.commonFunc.changeObjsOpacity(this.m_yuanquModels, 1,0.2, 1000, function () {
modelBussiness.hideDistance()
WT3DObj.commonFunc.findObject("backGround").visible = false;
cb&&cb()
});
}
ModelBussiness.prototype.showYuanquModel = function (cb) {
if (!this.helpBuildModels) {
this.helpBuildModels = WT3DObj.commonFunc.findObjectsByNames(this.helpBuildNames);
}
WT3DObj.commonFunc.changeObjsOpacity(this.helpBuildModels, 0.5, 0, 1000, function () {});
WT3DObj.commonFunc.changeObjsOpacity(this.m_yuanquModels, 0.2, 1, 1000, function () {
cb&&cb()
});
}

3、井下走线方式展现,可以查看井下每条线路的信息,便于运维人员运维查看管理

主要代码逻辑:

//双击线缆
ModelBussiness.prototype.dbClickSelect = function (_obj, _face, formRoute, searchParam) {
var _this = this;
if(_obj.name.indexOf('jing_line_')>-1){//线缆
$("#guangLan").hide()
_this.inVisibleJing(function () {
$(".cableImg").css("transform", "scale(1)");
})
}
}
var jingNameArr = ['jing_jing', 'jing_guandao', 'jing_line_4', 'jing_line_6', 'jing_line_7', 'jing_line_8', 'DirectionalLight_29'];
// 显示井
ModelBussiness.prototype.visibleJing = function (cb) {
WT3DModel.commonFunc.changeObjsOpacityByName(jingNameArr, 0, 1, 1000, function () {
cb && cb()
})
}
// 隐藏井
ModelBussiness.prototype.inVisibleJing = function (cb) {
WT3DModel.commonFunc.changeObjsOpacityByName(jingNameArr, 1, 0, 1000, function () {
cb && cb()
})
}
//绑定悬停事件
ModelBussiness.prototype.bindHoverEvent = function () {
//悬停回调
WT3DObj.mouseOverCallBack = this.mouseOverCallBack;
//进入回调
WT3DObj.mouseOverInCallBack = this.mouseOverInCallBack;
//离开回调
WT3DObj.mouseOverLeaveCallBack = this.mouseOverLeaveCallBack;
//悬停触发时间长度
WT3DObj.mouseOverTimeLong = 1000;
window.onresize = function () {
modelBussiness.mouseEvent();
};
}
//悬停
ModelBussiness.prototype.mouseOverCallBack = function (_obj, face) {}
//鼠标滑入回调
ModelBussiness.prototype.mouseOverInCallBack = function (_obj, face, _objs) {
console.log(_obj)
var obj=_obj.name.indexOf("_OBJCREN_")>-1?_obj.parent:_obj;
if(_obj.name.indexOf("jing_line_")>-1){
showLightLineData(obj.name);
}
}
//鼠标滑出回调
ModelBussiness.prototype.mouseOverLeaveCallBack = function (_obj, face, nowobj) {
var obj=_obj.name.indexOf("_OBJCREN_")>-1?_obj.parent:_obj;
if(_obj.name.indexOf("jing_line_")>-1){
$("#guangLan").hide()
}
}

4、双击管线,查看管线内部光纤信息,快速掌握光纤走向与状态。

  var _this = this;
if(_obj.name.indexOf('jing_line_')>-1){//显示详细线缆
$("#guangLan").hide()
_this.inVisibleJing(function () {
$(".cableImg").css("transform", "scale(1)");
})

5、展现所有线缆信息,标注线缆,以及点击查看线缆信息。

这里主要用精灵模型,精灵贴图的方式。

function createPicModel(param) {
var models = [{ "objType": "envMaps", "envMaps": [{ "name": "skybox", "imgs": ["../img/3dImg/skyboxs/1/UP.jpg", "../img/3dImg/skyboxs/1/UP.jpg", "../img/3dImg/skyboxs/1/UP.jpg", "../img/3dImg/skyboxs/1/UP.jpg", "../img/3dImg/skyboxs/1/UP.jpg", "../img/3dImg/skyboxs/1/UP.jpg"] }, { "name": "skybox2", "imgs": ["../img/3dImg/water.jpg", "../img/3dImg/water.jpg", "../img/3dImg/water.jpg", "../img/3dImg/water.jpg", "../img/3dImg/water.jpg", "../img/3dImg/water.jpg"] }] }, { "show": true, "showHelper": true, "uuid": "", "name": "DirectionalLight_8", "objType": "DirectionalLight", "shadowCameraNear": 1, "shadowCameraFar": 1, "shadowCameraLeft": 0, "shadowCameraRight": 0, "shadowCameraTop": 0, "shadowCameraBottom": 0, "shadowMapWidth": 1024, "shadowMapHeight": 1024, "distance": 5000, "targetName": "floor", "intensity": 1, "color": 16775651, "castShadow": true, "position": { "x": 4222.947, "y": 4379.619, "z": 2859.101 }, "showSortNub": 8, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "shadowCameraFov": null, "decay": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }]; if (param.showBack) {
models.push({ "show": true, "uuid": "", "name": "back", "objType": "cube2", "length": 100000, "width": 100000, "height": 1, "x": param.centerx, "y": -100, "z": param.centerz, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 2851238, "side": 1, "opacity": 1, "imgurl": (param.showBackImg ? param.showBackImg : "../../img/3dImg/bg201.png"), "repeatx": true, "width": 200, "repeaty": true, "height": 200 }, "skin_down": { "skinColor": 1259338, "side": 1, "opacity": 1, "imgurl": (param.showBackImg ? param.showBackImg : "../../img/3dImg/bg201.png"), "repeatx": true, "width": 200, "repeaty": true, "height": 200 }, "skin_fore": { "skinColor": 1259338, "side": 1, "opacity": 1 }, "skin_behind": { "skinColor": 1259338, "side": 1, "opacity": 1 }, "skin_left": { "skinColor": 1259338, "side": 1, "opacity": 1 }, "skin_right": { "skinColor": 1259338, "side": 1, "opacity": 1 } } }, "showSortNub": 10, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null });
}
if (param.width && param.length) {
models.push({ "show": true, "uuid": "", "name": "floor", "objType": "cube2", "length": param.width, "width": param.length, "height": 1, "x": param.centerx, "y": 0, "z": param.centerz, "style": { "skinColor": 16777215, "skin": { "skin_up": { "skinColor": 2440013, "materialType": "Phong", "side": 1, "opacity": 0.8, "envMap": { "name": "skybox", "reflectivity": 0.1, "refractionRatio": "", "combine": "" } }, "skin_down": { "skinColor": 4243455, "side": 1, "opacity": 0.5 }, "skin_fore": { "skinColor": 4243455, "side": 1, "opacity": 1 }, "skin_behind": { "skinColor": 4243455, "side": 1, "opacity": 1 }, "skin_left": { "skinColor": 4243455, "side": 1, "opacity": 1 }, "skin_right": { "skinColor": 4243455, "side": 1, "opacity": 1 } } }, "showSortNub": 100, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": 0 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "thick": null, "scale": { "x": 1, "y": 1, "z": 1 }, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null })
}
if (param.builds && param.builds.length > 0) {
$.each(param.builds, function (_index, _obj) {
for (var i = 1; i <= _obj.floors; i++) {
var points = [];
if (_obj.shape && _obj.shape.length > 0) {
$.each(_obj.shape, function (_sindex, _sobj) {
_sobj.type = "nomal";
points.push(_sobj);
});
} else {
points = [{ "x": (0 - _obj.width / 2), "y": (0 - _obj.length / 2), "type": "nomal" }, { "x": (0 - _obj.width / 2), "y": (_obj.length / 2), "type": "nomal" }, { "x": (_obj.width / 2), "y": (_obj.length / 2), "type": "nomal" }, { "x": (_obj.width / 2), "y": (0 - _obj.length / 2), "type": "nomal" }]
}
console.log(points);
if (i == _obj.floors) {
models.push({ "show": true, "uuid": "", "name": "parkbuild_" + _obj.name + "_f_" + i, "objType": "ExtrudeGeometry", "position": { "x": _obj.x, "y": 151 * (i - 1), "z": _obj.y }, "style": { "skinColor": 16711680, "skin": { "skin_up": { "skinColor": 6992593, "materialType": "Phong", "side": 2, "opacity": 0.8, "imgurl": "../../img/3dImg/wall/top3.jpg", "repeatx": true, "width": 0.01, "repeaty": true, "height": 0.01, "envMap": { "name": "skybox", "reflectivity": 0.4, "refractionRatio": 0.8, "combine": "" } }, "skin_down": { "skinColor": 16711680, "materialType": "Phong", "side": 1, "opacity": 1 }, "skin_side": { "skinColor": 13099775, "side": 2, "materialType": "Phong", "opacity": 0.65, "imgurl": "../../img/3dImg/wall/inner-wall11.jpg", "repeatx": true, "width": 0.01, "repeaty": true, "height": 0.004, "envMap": { "name": "skybox", "reflectivity": 0.8, "refractionRatio": 0.8, "combine": "" } } } }, "scale": { "x": 1, "y": 1, "z": 1 }, "shapeParm": { "points": points, "holes": [] }, "extrudeSettings": { "amount": 150, "curveSegments": 2, "steps": 2, "bevelEnabled": true, "bevelThickness": 1, "bevelSize": 1, "bevelSegments": 2, "extrudePathPoints": [] }, "showSortNub": 800 + i, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": -1.5707963267948966 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null })
} else {
models.push({ "show": true, "uuid": "", "name": "parkbuild_" + _obj.name + "_f_" + i, "objType": "ExtrudeGeometry", "position": { "x": _obj.x, "y": 151 * (i - 1), "z": _obj.y }, "style": { "skinColor": 16711680, "skin": { "skin_up": { "skinColor": 6543871, "materialType": "Phong", "side": 1, "opacity": 0.6 }, "skin_down": { "skinColor": 16711680, "materialType": "Phong", "side": 1, "opacity": 1 }, "skin_side": { "skinColor": 13099775, "side": 2, "materialType": "Phong", "opacity": 0.65, "imgurl": "../../img/3dImg/wall/inner-wall11.jpg", "repeatx": true, "width": 0.01, "repeaty": true, "height": 0.004, "envMap": { "name": "skybox", "reflectivity": 0.8, "refractionRatio": 0.8, "combine": "" } } } }, "scale": { "x": 1, "y": 1, "z": 1 }, "shapeParm": { "points": points, "holes": [] }, "extrudeSettings": { "amount": 150, "curveSegments": 2, "steps": 2, "bevelEnabled": true, "bevelThickness": 1, "bevelSize": 1, "bevelSegments": 2, "extrudePathPoints": [] }, "showSortNub": 800 + i, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "rotation": [{ "direction": "x", "degree": -1.5707963267948966 }, { "direction": "y", "degree": 0 }, { "direction": "z", "degree": 0 }], "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null })
}
}
});
}
return models;
}

6、双击线缆,查看线缆内的光纤数据信息。

7、标注井深与管深。便于施工与土建规避。知道深度,能有效辅助运维人员下井准备,而且再土建施工时,能有效规避风险,不会有挖断线缆情况发生。

代码实现:

//显示管道
ModelBussiness.prototype.showGD = function (cb) {
this.hideDistance()
var guandao = WT3DObj.commonFunc.findObject("yqgx_guandao");
guandao.position.y =0;
guandao.visible = true;
WT3DObj.commonFunc.changeObjsOpacity([guandao], 0.1, 1, 500, function () {
cb&&cb()
});
}
//隐藏管道
ModelBussiness.prototype.hideGD = function (cb) {
var guandao = WT3DObj.commonFunc.findObject("yqgx_guandao");
WT3DObj.commonFunc.changeObjsOpacity([guandao], 1, 0.1, 500, function () {
guandao.position.y = -100000;
guandao.visible = false;
cb&&cb()
});
} // 显示深度
ModelBussiness.prototype.showDeep=function(cb){
modelBussiness.showDistance()
// 缓存相机位置
this.cameraPostion_cache=JSON.parse(JSON.stringify(WT3DObj.getCameraPosition()));
this.cameraTarget_cache=JSON.parse(JSON.stringify(WT3DObj.getCameraTarget()));
var position={x: -520.4091455366863, y: 144.35504820242926, z: 627.9302907417292};
var positionTarget={x: -263.56663925875796, y: -150.20066997406482, z: 240.69791289652335};
WT3DObj.commonFunc.changeCameraPosition(position,positionTarget,1000,function(){cb&&cb()})
}
//隐藏深度
ModelBussiness.prototype.hideDeep = function (cb) {
var yuanqu=WT3DObj.commonFunc.findObject(["zysjzx_yuanqu_7"]);
WT3DObj.commonFunc.changeObjsOpacity([yuanqu],0.1,1,500,function(){
modelBussiness.hideDistance()
WT3DObj.commonFunc.findObject(["backGround"]).visible=true;
WT3DObj.commonFunc.changeCameraPosition(roomConfig.cameraPostion,roomConfig.cameraTarget,1000)
cb&&cb()
})
}
// 显示井深、管道深尺寸标注
ModelBussiness.prototype.showDistance=function(){
var that=this;
WT3DObj.commonFunc.findObject("backGround").visible=false;
WT3DObj.commonFunc.findObject("zysjzx_yuanqu_7").visible=false;
WT3DObj.commonFunc.changeObjsOpacity(this.m_shenduModels,0.2,1,1000,function(){
for(var i=0;i<that.m_shenduModels.length;i++){
that.m_shenduModels[i].visible=true;
}
})
}
// 隐藏井深、管道深尺寸标注
ModelBussiness.prototype.hideDistance=function(){
WT3DObj.commonFunc.findObject("backGround").visible=true;
WT3DObj.commonFunc.findObject("zysjzx_yuanqu_7").visible=true;
for(var i=0;i<this.m_shenduModels.length;i++){
this.m_shenduModels[i].visible=false;
}
}

8、线缆检索。能够根据线缆属性,快熟定位查看线缆走势与信息。

ModelBussiness.prototype.showAllFloorLinesModel = function (callBack) {
var _this = this;
this.openFloors(function () {
if (!_this.FloorLines) {
var linesname = []; for (var i = 1; i <= 3; i++) {
linesname.push("zb_f" + i + "_H1xi");
linesname.push("zb_f" + i + "_H2xi");
linesname.push("zb_f" + i + "_Ixi");
linesname.push("zb_f" + i + "_H1cu");
linesname.push("zb_f" + i + "_H2cu");
linesname.push("zb_f" + i + "_Icu");
}
_this.FloorLines = WT3DObj.commonFunc.findObjectsByNames(linesname);
}
var outlines = [];
if (_this.FloorLines.length > 0) {
$.each(_this.FloorLines, function (_index, _obj) {
_obj.visible = true;
if (_obj.name.indexOf("cu") >= 0) {
outlines.push(_obj);
}
});
}
var vmodes = [];
$.each(WT3DObj.scene.children, function (_index, _obj) {
if (_obj.name.indexOf("r1_11_1") >= 0 || _obj.name.indexOf("r1_11_2") >= 0 ) {
vmodes.push(_obj);
}
});
vmodes = vmodes.concat(_this.FloorLines);
_this.VitureAllFloors(function () {
WT3DObj.commonFunc.changeObjsOpacity(vmodes, 0.1, 1, 100, function () {
WT3DObj.commonFunc.changeObjsOpacity(outlines, 1, 0.1, 500, function () {
if (callBack) {
callBack();
}
});
});
});
})
} ModelBussiness.prototype.showAllFloorOutLinesModel = function (callBack) {
var _this = this;
this.openFloors(function () { if (!_this.FloorLines) {
var linesname = []; for (var i = 1; i <= 3; i++) {
linesname.push("zb_f" + i + "_H1xi");
linesname.push("zb_f" + i + "_H2xi");
linesname.push("zb_f" + i + "_Ixi");
linesname.push("zb_f" + i + "_H1cu");
linesname.push("zb_f" + i + "_H2cu");
linesname.push("zb_f" + i + "_Icu");
}
_this.FloorLines = WT3DObj.commonFunc.findObjectsByNames(linesname);
}
var outlines = [];
if (_this.FloorLines.length > 0) {
$.each(_this.FloorLines, function (_index, _obj) { if (_obj.name.indexOf("cu") >= 0) {
_obj.visible = true;
outlines.push(_obj);
}
});
}
var vmodes = [];
$.each(WT3DObj.scene.children, function (_index, _obj) {
if (_obj.name.indexOf("r1_11_1") >= 0 || _obj.name.indexOf("r1_11_2") >= 0 || _obj.name.indexOf("zb_f1_jigui") >= 0) {
vmodes.push(_obj);
}
});
vmodes = vmodes.concat(_this.FloorLines);
_this.VitureAllFloors(function () {
WT3DObj.commonFunc.changeObjsOpacity(vmodes, 0.1, 1, 100, function () {
WT3DObj.commonFunc.changeObjsOpacity(outlines, 0.1, 1, 500, function () {
if (callBack) {
callBack();
}
});
});
});
})
}

9、设备检索,端口检索,能快速定位到具体设备。查看设备信息状态,位置信息等。

主要思路:

//搜索
ModelBussiness.prototype.showPostionState = false;
ModelBussiness.prototype.showPosition = function (cabid, serverid, portId) {
var _this = this;
if (window.location.href.indexOf("index.html") >= 0) {
var serchParam = cabid + "_search_" + serverid;
if (portId) {
serchParam += "_search_" + portId;
}
_this.dbClickSelect(WT3DObj.commonFunc.findObject("build_1"),null, null, serchParam);
}
if (window.location.href.indexOf("floor.html")>=0) {
WT3DObj.commonFunc.flashObjsGradualByName(["zb_3f1_546", "zb_3f2_1320"], "floor3_flash1", "000000", "0000ff", 7, 1000, 10, 0);
setTimeout(function () {
var serchParam = cabid + "_search_" + serverid;
if (portId) {
serchParam += "_search_" + portId;
}
_this.dbClickSelect(WT3DObj.commonFunc.findObject("zb_3f1_546"),null, null, serchParam);
}, 2000);
}
}
// 隐藏所有模型
ModelBussiness.prototype.cacheAllModels = function(cb){
this.m_allNames=[].concat(this.m_yuanquNames,this.m_guandaoNames,this.m_xianlanNames,this.m_shenduNames,this.m_buildInfoNames)
if(!this.m_allModels.length){
var models=WT3DObj.scene.children
for(var i=0;i<models.length;i++){
var item=models[i];
if(this.m_yuanquNames.indexOf(item.name)>-1){this.m_yuanquModels.push(item)}
if(this.m_guandaoNames.indexOf(item.name)>-1){this.m_guandaoModels.push(item)}
if(this.m_xianlanNames.indexOf(item.name)>-1){this.m_xianlanModels.push(item)}
if(this.m_shenduNames.indexOf(item.name)>-1){this.m_shenduModels.push(item)}
if(this.m_buildInfoNames.indexOf(item.name)>-1){this.m_buildInfoModels.push(item)}
}
this.m_allModels=[].concat(this.m_yuanquModels,this.m_guandaoModels,this.m_xianlanModels,this.m_shenduModels,this.m_buildInfoModels)
}
}

10、电路检索,线缆中包含很多电路,支持电路检索,能快速定位相应的电路。

主要代码:

//隐藏显示线
ModelBussiness.prototype.Lines = null;
ModelBussiness.prototype.hideAllLinesModels = function (cb) {
var _this = this;
WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 1, 0.1, 500, function () {
$.each(_this.m_xianlanModels, function (_index, _obj) {
_obj.visible = false;
_obj.position.y=-1000000;
});
cb&&cb()
});
}
ModelBussiness.prototype.showAllLineModels = function (cb) {
var line = [];
$.each(this.m_xianlanModels, function (_index, _obj) {
_obj.visible = true;
_obj.position.y=0;
if (_obj.name.indexOf("cuxian")>0) {
line.push(_obj);
}
})
WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 0.1, 1, 500, function () {
// WT3DObj.commonFunc.changeObjsOpacity(line, 1, 1, 500, function () {
cb&&cb()
// });
});
}
ModelBussiness.prototype.showLines = function(callback){
var guandao=WT3DObj.commonFunc.findObject('yqgx_guandao');
var backGround=WT3DObj.commonFunc.findObject('backGround');
guandao.position.y=-1000000;
backGround.position.y=-1000000;
$.each(this.m_xianlanModels, function (_index, _obj) {
_obj.visible = true;
if (_obj.name.indexOf("cuxian")>0) {
_obj.position.y=0;
// if(_obj.resourcePosition){
// _obj.position.y=_obj.resourcePosition.y;
// }
}
})
WT3DObj.commonFunc.changeObjsOpacity(this.m_xianlanModels, 0.1, 1, 500, function () {
});
}
//虚化某一根线
ModelBussiness.prototype.visLine = function (name, callBack) {
if (!this.Lines) {
this.Lines = WT3DObj.commonFunc.findObjectsByNames(
["yqgx_cuxian1_11", "yqgx_cuxian2_15", "yqgx_cuxian3_19", "yqgx_cuxian4_23", "yqgx_cuxian5_27", "yqgx_cuxian6_31", "yqgx_cuxian7_35", "yqgx_cuxian8_39", "yqgx_cuxian9_46", "yqgx_cuxian10_50", "yqgx_xixian1_54", "yqgx_xixian2_54", "yqgx_xixian3_62", "yqgx_xixian4_66", "yqgx_xixian5_70", "yqgx_xixian6_72", "yqgx_xixian7_76", "yqgx_xixian8_80", "yqgx_xixian9_86", "yqgx_xixian10_92"]);
}
var line = [];
$.each(this.Lines, function (_index, _obj) {
if (_obj.name == name) {
line.push(_obj);
}
})
WT3DObj.commonFunc.changeObjsOpacity(line,1, 0.5, 500, function () {
if (callBack) {
callBack();
}
});
}
//显示单根线
ModelBussiness.prototype.showSingleLines = function (name,callBack) {
if (!this.Lines) {
this.Lines = WT3DObj.commonFunc.findObjectsByNames(
["yqgx_cuxian1_11", "yqgx_cuxian2_15", "yqgx_cuxian3_19", "yqgx_cuxian4_23", "yqgx_cuxian5_27", "yqgx_cuxian6_31", "yqgx_cuxian7_35", "yqgx_cuxian8_39", "yqgx_cuxian9_46", "yqgx_cuxian10_50", "yqgx_xixian1_54", "yqgx_xixian2_54", "yqgx_xixian3_62", "yqgx_xixian4_66", "yqgx_xixian5_70", "yqgx_xixian6_72", "yqgx_xixian7_76", "yqgx_xixian8_80", "yqgx_xixian9_86", "yqgx_xixian10_92"]);
}
var line = [];
$.each(this.Lines, function (_index, _obj) {
_obj.position.y=-1000000;
if (_obj.name == name) {
line.push(_obj);
_obj.visible = true;
_obj.position.y=0;
}
})
WT3DObj.commonFunc.changeObjsOpacity(line, 0.3, 1, 500, function () {
if (callBack) {
callBack();
}
});
}

由于篇幅过长,我们下节课详细描述楼层内部以及机房内部的线路方案。

技术交流 1203193731@qq.com

交流微信:

    

如果你有什么要交流的心得 可邮件我

其它相关文章:

使用webgl(three.js)创建3D机房,3D机房微模块详细介绍(升级版二)

如何用webgl(three.js)搭建一个3D库房-第一课

如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课

使用webgl(three.js)搭建一个3D建筑,3D消防模拟——第三课

使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课

如何用webgl(three.js)搭建不规则建筑模型,客流量热力图模拟

使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课(炫酷版一)

使用webgl(three.js)搭建3D智慧园区、3D大屏,3D楼宇,智慧灯杆三维展示,3D灯杆,web版3D,bim管理系统——第六课

如何用webgl(three.js)搭建处理3D园区、3D楼层、3D机房管线问题(机房升级版)-第九课(一)的更多相关文章

  1. 如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室(升级版)

    很长一段时间没有写3D库房,3D密集架相关的效果文章了,刚好最近有相关项目落地,索性总结一下 与之前我写的3D库房密集架文章<如何用webgl(three.js)搭建一个3D库房,3D密集架,3 ...

  2. 如何用webgl(three.js)搭建处理3D隧道、3D桥梁、3D物联网设备、3D高速公路、三维隧道桥梁设备监控-第十一课

    开篇废话: 跟之前的文章一样,开篇之前,总要写几句废话,大抵也是没啥人看仔细文字,索性我也想到啥就聊啥吧. 这次聊聊疫情,这次全国多地的疫情挺严重的,本人身处深圳,深圳这几日报导都是几十几十的新增病例 ...

  3. 如何用webgl(three.js)搭建一个3D库房,3D仓库,3D码头,3D集装箱可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

  4. 如何用webgl(three.js)搭建一个3D库房,3D仓库3D码头,3D集装箱,车辆定位,叉车定位可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

  5. 如何用webgl(three.js)搭建不规则建筑模型,客流量热力图模拟

    本节课主要讲解如何用webgl(three.js)搭建一个建筑模型,客流量热力图模拟 使用技术说明: 这里主要用到了three.js,echart.js以及一些其它的js 与css技术,利用webso ...

  6. 如何用webgl(three.js)搭建一个3D库房-第二课

    闲话少叙,我们接着第一课继续讲(http://www.cnblogs.com/yeyunfei/p/7899613.html),很久没有做技术分享了.很多人问第二课有没有,我也是抽空写一下第二课. 第 ...

  7. 如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课

    闲话少叙,我们接着第一课继续讲(http://www.cnblogs.com/yeyunfei/p/7899613.html),很久没有做技术分享了.很多人问第二课有没有,我也是抽空写一下第二课. 第 ...

  8. 如何用webgl(three.js)搭建一个3D库房-第一课

    今天我们来讨论一下如何使用当前流行的WebGL技术搭建一个库房并且实现实时有效交互 第一步.搭建一个3D库房首先你得知道库房长啥样,我们先来瞅瞅库房长啥样(这是我在网上找的一个库房图片,百度了“库房” ...

  9. 使用webgl(three.js)搭建3D智慧园区、3D大屏,3D楼宇,智慧灯杆三维展示,3D灯杆,web版3D,bim管理系统——第六课

    前言: 今年是建国70周年,爱国热情异常的高涨,为自己身在如此安全.蓬勃发展的国家深感自豪. 我们公司楼下为庆祝国庆,拉了这样的标语,每个人做好一件事,就组成了我们强大的祖国. 看到这句话,深有感触, ...

随机推荐

  1. Django序列化页和过滤页规范

    序列化类:serializers.py from rest_framework import serializers from goods.models import Goods, GoodsCate ...

  2. UE4蓝图AI角色制作(六)之行为树

    13.行为树原理 AI最重要的环节就是行为树.我们将解释什么是行为树.为何它如此重要,以及构建行为树需要哪些元素. 借助行为树,我们可以轻松控制并显示AI的决策制定过程.行为树是一种将AI在场景中的决 ...

  3. 解决Mybatis 报错Invalid bound statement (not found)

    解决Mybatis 报错Invalid bound statement (not found) 出现此错误的原因 1.xml文件不存在 2.xml文件和mapper没有映射上 namespace指定映 ...

  4. PyCharm中目录directory与包package的区别及相关import详解

    一.概念介绍 在介绍目录directory与包package的区别之前,先理解一个概念---模块 模块的定义:本质就是以.py结尾的python文件,模块的目的是为了其他程序进行引用. 目录(Dire ...

  5. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  6. [软工顶级理解组] Beta阶段测试报告

    在测试过程中发现了多少Bug? 测试阶段发现并已修复的bug: 尚且存在,但是难以解决或者不影响使用的bug: 计算重修课程的时候,如果重修课程的课程号和原课程号不同,则GPA计算会出现误差.但我们无 ...

  7. UltraSoft - Alpha - Scrum Meeting 4

    Date: Apr 18th, 2020. 会议内容为 例行汇报. Scrum 情况汇报 进度情况 组员 负责 前两日进度 后两日任务 CookieLau PM 完成前后端交互规格的约定,了解前后端进 ...

  8. 2021.7.17 NKOJ周赛总结

    发现自己简直是个智障:T1模数写成1e9+9:T2居然没有考虑刚好一个周期的情况:T4用"%lld"读入"unsigned long long".~qwq~ T ...

  9. pyqgis环境配置

    配置pyqgis开发环境时,很多网上教程写的非常繁琐,这里仅仅找了一个最简单的配置方法,使用pycharm的IDE,安装QGIS软件后,在pycharm的ProjectInterpreter里面填写Q ...

  10. 广域网(ppp协议、HDLC协议)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105028759 学习课程:<2019王道考研计算机网络> 学习目的 ...