写在前面的话:

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

  前两天跟朋友一次技术对话,对方问了一下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. sqlite3 c++使用以及提高速率(一万条每秒左右)

    参考来源: sqlite3的C语言使用(三):https://www.leavesongs.com/C/sqlite3_3.html sqlite插入和查询效率提高方法及测试结果: http://bl ...

  2. js 判断两个对象是否相等

    最近碰到的一个面试题,不算高频,记录一下 判断两个对象是否相等,大致分为三步 首先判断两个比较对象是不是 Object 如果都是对象 再比较 对象的长度是否相等 如果两个对象的长度相等 再比较对象属性 ...

  3. MySQL灵魂拷问:36题带你面试通关!

    大家好,我是大彬~ 今天给大家分享MySQL常考的面试题,看看你们能答对多少. 本期MySQL面试题的目录如下: 事务的四大特性? 事务隔离级别有哪些? 索引 什么是索引? 索引的优缺点? 索引的作用 ...

  4. [JUC-5]ConcurrentHashMap源码分析JDK8

    在学习之前,最好先了解下如下知识: 1.ReentrantLock的实现和原理. 2.Synchronized的实现和原理. 3.硬件对并发支持的CAS操作及JVM中Unsafe对CAS的实现. 4. ...

  5. Java/JDK/J2SE

    Java8与JDK1.8与JDK8与J2SE8与J2SE1.8的区别是什么? Java是面向对象的编程语言,在我们开发Java应用的程序员的专业术语里,Java这个单词其实指的是Java开发工具,也就 ...

  6. 关于linux下编译的几点知识

    1.-L.-rpath 和 rpath_link的区别 参考博客文章:https://www.cnblogs.com/candl/p/7358384.html (1)-rpath和-rpath-lin ...

  7. 【Golang详解】go语言中并发安全和锁

    go语言中并发安全和锁 首先可以先看看这篇文章,对锁有些了解 [锁]详解区分 互斥锁.⾃旋锁.读写锁.乐观锁.悲观锁 Mutex-互斥锁 Mutex 的实现主要借助了 CAS 指令 + 自旋 + 信号 ...

  8. createContext 你用对了吗?

    目录 前言 性能问题的根源 问题1(整体重复渲染):Provider组件包裹的子组件全部渲染 问题2(局部重复渲染):使用useContext导致组件渲染 解决方案 解决问题1 解决问题2 参考 前言 ...

  9. 『学了就忘』Linux基础 — 10、VMware虚拟机中克隆的使用

    目录 1.什么是克隆 2.克隆的两种类型 (1)完整克隆 (2)链接克隆 3.克隆操作 步骤一:克隆虚拟机 步骤二:进行克隆导向 3.快照与克隆的区别 4.镜像的管理 快照和克隆是VMware中两个非 ...

  10. configure: error: invalid variable name: `'

    今天在交叉编译一个编解码库的时候,出现一个莫名其妙的报错,一直找不到原因,后来无意中删除了一个空格,才发现就是这个空格造成的错误. ./configure --host=arm-linux LDFLA ...