当前位置:   article > 正文

blender+Three.js 三维数据可视化_blender threejs

blender threejs

接到了一个需求,一个物联网的电力保障系统实时监控。实施用到了Web 3D技术,以前用过一段时间的Three.js,因为太耗资源,没怎么铺开,现在硬件条件好了,就拿出来试试。

环境:blender-2.93.6-windows-x64+Three.js 0.91.0+Echart2.0

我习惯不用最新版本的软件做开发,一方面新版的稳定性不如旧版,主要是基于js的前端开发,新版大部分对IE都不友好,国内的需求现状就是,问就是随便,验收就拿IE说事,所以多一事不如少一事,就用旧的成熟版本对付了。

首先是3D建模,打开blender,一通XJB操作,做出模型长这样:

然后把工业电区和农用电区分开,按照硬件的分布编好号(部分检测设备在一层并且比较近,就编在一起,报警时候单独处置)。

然后建一个html,按照监控屏的分辨率1920*1080设置一个画布、背景 什么的,建一个对象叫做three,作为我们绘制模型的容器。

#three{width:1920px;height:1080px;position:absolute;z-index:1}

<div id="three"></div>

建一个js文件,加载模型,按照不同的供电方式设置材质:

function init() {

    var container = document.getElementById("three");

    camera = new THREE.PerspectiveCamera( 45, sceneWidth / sceneHeight, 1, 4000 );
    //camera.position.set(900, 400, 900);
    camera.position.set(300, 600, -1400);
    scene = new THREE.Scene();
    //scene.rotation.set(0,Math.PI,0);
    scene.rotation.y = 0.5;
    
    scene.background = new THREE.Color('#394855');
    scene.fog = new THREE.Fog('#394855', 2000, 2500 );
    
    var hemiLight = new THREE.HemisphereLight( 0xFFFFFF, 0x444444);
    hemiLight.position.set( 0, 500, -300 );
    scene.add( hemiLight );

    var dirLight = new THREE.DirectionalLight('#FFFFFF');
    dirLight.position.set( 100, 300, 200 );
    dirLight.castShadow = true;
    dirLight.shadow.camera.top = 1000;
    dirLight.shadow.camera.bottom = - 1000;
    dirLight.shadow.camera.left = - 1000;
    dirLight.shadow.camera.right = 1000;    
    dirLight.shadow.camera.far=1000;
    dirLight.shadow.mapSize.width = 1024;
    dirLight.shadow.mapSize.height = 1024;
    scene.add( dirLight );

    //scene.add(new THREE.CameraHelper( dirLight.shadow.camera ) );

    //地板
    //var textureLoader=new THREE.TextureLoader();
    //var texture = textureLoader.load("../images/ground.png");
    //var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( {map:texture,color: '#2B3745', depthWrite: false } ) );
    var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 8000, 8000 ), new THREE.MeshBasicMaterial( {color: '#394855', depthWrite:false } ) );
    mesh.rotation.set(- Math.PI / 2,0,0);
    mesh.receiveShadow = true;
    scene.add( mesh );

    var grid = new THREE.GridHelper(8000, 200, '#556B80','#556B80');
    grid.material.opacity = 0.2;
    grid.material.transparent = true;
    //grid.rotation.set(0,100,0);
    scene.add(grid);
    
    var loader = new THREE.FBXLoader();                
    loader.load('/object/factory.fbx', function ( object ) {    
        object.traverse( function ( child ) {
            if ( child.isMesh ) {                
                var material =new THREE.MeshPhongMaterial( {color: '#2F3C46' ,opacity:1,transparent:true})
                var material2 =new THREE.MeshStandardMaterial({color: '#394855' ,opacity:0.8,transparent:true})                
                var material1=new THREE.LineBasicMaterial( {
                    color: 0xffffff,
                    linewidth: 1,
                    linecap: 'round',
                    linejoin:  'round'
                } );                                                
                
                child.material =material;                
                child.castShadow = true;
                child.receiveShadow = true;
                
                if(child.name=="ground") //地板
                {
                    child.material=material2;                                        
                }                                
                else if(child.name=="wall") //外墙
                {
                    var textureLoader = new THREE.TextureLoader();    
                    var alphaMap = textureLoader.load( 'images/alphaMap.png' );
                    var wallMaterial=new THREE.MeshBasicMaterial({
                        color: 0x005E9B,
                        side:THREE.DoubleSide,
                        transparent: true,
                        depthWrite: false,
                        alphaMap: alphaMap,
                    });
                    child.material=wallMaterial;
                    child.receiveShadow = false;
                    child.castShadow = false;                                    
                }                        
                else if(child.name.indexOf("HF")==0) //民用电    
                {                    
                    child.material.color.set('#00538A');
                    if(child.name.indexOf("HF18")==0 ) 
                    {                        
                        var fined=false;
                        for(var i=0;i<selectNodes.length;i++)
                        {
                            if(selectNodes[i].name==child.name)
                            {
                                fined=true;
                                break;    
                            }
                        }
                        //if(!fined) selectNodes.push(child);
                    }
                }                            
                else if(child.name.indexOf("TF")==0) //工业电
                {                    
                    child.material.color.set('#917000');
                    //var text=createTitle(child.name);
                    //text.position.set(child.position.x,child.position.y+35,child.position.z);
                    //scene.add(text);
                }                                
                else if(child.name.indexOf("F")==0) //冷凝罐                
                {                    
                    child.material.color.set('#0099FF');
                    //var text=createTitle(child.name);
                    //text.position.set(child.position.x,child.position.y+25,child.position.z);
                    //scene.add(text);
                }                                
                else if(child.name.indexOf("NO")==0) //氮气
                {
                    child.material.color.set('#FF0000');
                    //var text=createTitle(child.name);
                    //text.position.set(child.position.x,child.position.y+25,child.position.z);
                    //scene.add(text);
                }                                
                else if(child.name.indexOf("NH")==0) //氨气
                {                    
                    child.material.color.set('#0000FF');
                    //var text=createTitle(child.name);
                    //text.position.set(child.position.x,child.position.y+25,child.position.z);
                    //scene.add(text);
                }                                
                else if(child.name.indexOf("YH")==0) //液化气
                {                    
                    child.material.color.set('#00FF00');
                    //var text=createTitle(child.name);
                    //text.position.set(child.position.x,child.position.y+25,child.position.z);                    
                    //scene.add(text);
                }
                
                //console.log(child.name);
                
            }
        } );        
        scene.add( object );
    } );                    

    renderer = new THREE.WebGLRenderer( { antialias: true,alpha:true } );
    //renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( sceneWidth, sceneHeight );
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    container.appendChild( renderer.domElement );

    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.target.set( 0, 0, 0 );
    controls.update();

    window.addEventListener( 'resize', onWindowResize );
}

一通操作以后,模型加载进来,页面长这样:

然后上面再加一个效果层,就是一个摄像机一样的东东,禁止它的鼠标响应。把要显示的东西都加上,页面长这样:

数据的刷新分两部分,常规的数据库信息(人员,统计指标什么的)就JQuery加载进来。监控的实时信息,引入MQTT.js和代理服务做个长连接,实时读取显示就行了,数据异常,就弹出个报警框然后发声音什么的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/118810
推荐阅读
  

闽ICP备14008679号