• three.js 运行3D模型


    HTML 
    <!DOCTYPE html>
    <html style="height: 100%;">
    <head>
        <title>model_load</title>
        <meta charset="utf-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <style>
            *{
                margin:0;
                padding:0;
            }
            #canvas_view {
                 100%;
                height: 80%;
                cursor: pointer;
                position: relative;
                /*background-image:url(img/bg.png);*/
            }
            .box{
                height: 20%;
                background: #EDEDED;
                display: flex;
            }
            .box div{
                 50%;
                height: 100%;
            }
            .box>.left>p{
                margin:15px auto;
            }
            .box>.left{
                border-right:1px solid #4D4D4D;
            }
            .box>.left>input{
                display:block;margin:15px auto;
            }
        </style>
    // 运行模型所需要的第三方 js 文件   
        <script src="js/threejs/three.js"></script>  
        <script src="js/threejs/Detector.js"></script>
        <script src="js/threejs/stats.min.js"></script>
        <script src="js/threejs/ColladaLoader.js"></script><!--3D模型加载器-->
        <script src="js/threejs/DDSLoader.js"></script>
        <script src="js/threejs/OrbitControls.js"></script>
        <script src="js/threejs/VTKloader.js"></script>
        <script src="js/threejs/TrackballControls.js"></script>
        <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
    </head>
    <body style="height: 100%;">
    // 初始化 canvas
    <div id="canvas_view">
        <div id="text_title" style="position: absolute;100%;height:20px;margin-top:200px;text-align: center;">请上传模型</div>
    </div>
    <div class="box">
        <div class="left">
            <p> 上传模型:</p>
            <div class="model_box" style="90%;padding: 10px 20px;height: auto;">
                <button class="model" style="display: none;"></button>
            </div>
        </div>
        <div class="right" style="overflow: scroll">
            <div class="bg_color_box" style=" 100%;height:50px;background:lightcoral;display: flex;">
                <div style="text-align: center;line-height: 50px;">设置背景颜色:</div>
                <div style="line-height: 50px;text-align: left;">
                    <input type="color" class="bg_color" value="#c0c0c0">
                </div>
            </div>
            <!--循环-->
            <div class="show_element" style=" 100%;display: none;">
                <div style="border-bottom: 2px solid #ccc; 100%;height: 86px;display: flex;">
                    <div class="model_text" style=" 100px;text-align: center;line-height: 86px;"></div>
                    <div id="model_text2" style="flex: 1">
                        <div style=" 100%;height:45px;">
                            <div style=" 100%;height:auto;padding:10px 0;display: flex;">
                                <span>  设置颜色: </span>
                                <input type="color" class="color" value="#400000" style="display: block;margin:0;">
                            </div>
                        </div>
                        <div style=" 100%;height: 45px;">
                            <div style=" 100%;height:auto;padding:10px 0;display: flex;">
                                <span> 设置透明度: </span>
                                <input type="range" class="range" value="80" style="background: red;">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    //加载模型 构造函数的方法
    <script src="resources/model.js"></script>
    //初始化 调用 函数
    <script src="resources/controller.js"></script>
    </body>
    </html>
    View Code

    model.js   实例指向的原型方法

    /**
     * -------------- on 2018/8/7.
     */
    
    
    function init() {
        //创建渲染器
        width = document.getElementById("canvas_view").width=document.documentElement.clientWidth;
        height = document.getElementById("canvas_view").height=document.documentElement.clientHeight*0.8;
        renderer = new THREE.WebGLRenderer({
            antialias : true//抗锯齿属性
        });
        renderer.setPixelRatio( window.devicePixelRatio );
        //设置渲染器宽高
        renderer.setSize(width, height);
        //add到页面中
        document.getElementById('canvas_view').appendChild(renderer.domElement);
        //设置渲染器背景颜色和透明度
        renderer.setClearColor('#c0c0c0', 1);
    
        //更改背景颜色=============================
        $(".bg_color_box .bg_color").change(function () {
            var color = this.value;
            renderer.setClearColor(color, 1);
        });
    
        //创建相机
        camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 2000);
        //定义相机的位置
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 3;
        //设置相机的方向
        camera.up.x = 0;
        camera.up.y = 1;
        camera.up.z = 0;
        camera.lookAt({
            x : 0,
            y : 0,
            z : 0
        });
        //控制器
        controls = new THREE.TrackballControls( camera ,renderer.domElement );
        this.screen.left = 0;
        this.screen.top = 0;
        this.screen.width = document.documentElement.clientWidth;
        this.screen.height = document.documentElement.clientHeight*0.8;
    
        //创建场景
        scene = new THREE.Scene();
        scene.add( camera );
        //添加三维辅助线
        var axisHelper = new THREE.AxisHelper(500);
        scene.add(axisHelper);
    }
    
    
    //创建光源,AmbientLight,
    function light_fn() {
        //环境光
        light = new THREE.AmbientLight(0xFF0000);
        //定义光源位置
        light.position.set(100, 100, 200);
        //添加到场景
        scene.add(light);
    
        //方向光
        var dirLight = new THREE.DirectionalLight( 0xffffff );
        dirLight.position.set( 200, 200, 1000 ).normalize();
        camera.add( dirLight );
        camera.add( dirLight.target );
    }
    
    
    //创建实物
    function initObject() {
        //统一文件路径
        var str = "../model/",
            //后缀名
            suffix = ".vtk",
            //表示加载每个文件的按钮【tumors:非文件名,仅仅代表按钮,很多小肿瘤的按钮集合】
            arr_link = ["liver-1","couinaud-1","couinaud-2","couinaud-3","couinaud-4", "couinaud-5",
            "couinaud-6","couinaud-7","couinaud-8","tumor-3","tumors"],
    
            //肿瘤文件名
            tumors = ["tumor-1","tumor-2","tumor-4","tumor-5","tumor-6",
                "tumor-7","tumor-8","tumor-9","tumor-10","tumor-11"];
    
        //克隆按钮
        for(var a in arr_link){
            $(".left div .model").css("display","inline");
            if(a>="1"){$(".left div .model:eq(0)").clone(true).appendTo('.model_box')}
            $(".left div .model:eq(-1)").text(arr_link[a]);
        }
    
        var model_arr = [];
        var idx;
        var url;
        var urls;
        $(".model").click(function () {
            idx = model_arr.indexOf($(this).index());
            if(idx<0){
                model_arr.push($(this).index());
                if(arr_link[$(this).index()] == "tumors"){
                    for(var d in tumors){
                        urls = str + tumors[d] + suffix;
                        loader_model(urls,$(this).index(),d);//加载单个模型
                    }
                    arr_fn($(this).index(),model_arr);//加一个设置盘
                }else{
                    url = str + arr_link[$(this).index()] + suffix;//拼接字符串
                    loader_model(url,$(this).index());//加载单个模型
                    arr_fn($(this).index(),model_arr);//加一个设置盘
                }
            }else{alert("不可重复上传");}
        });
        //克隆节点
        function arr_fn(idx,arr) {
            var text_title = document.getElementById("text_title");
            if(text_title) text_title.parentNode.removeChild(text_title);//删除"请上传模型"文本;
            //true 深度克隆事件
            $(".show_element").css("display","inline");
            if(arr.length>1){$(".show_element:eq(0)").clone(true).appendTo('.right');}
            var text = $(".left div .model:eq("+idx+")").text();
            $(".show_element:eq(-1) .model_text").text(text);//给text赋值【eq(-1)获取最后一个元素】
            $(".show_element:eq(-1) .color").val("#400000");//初始化颜色
            $(".show_element:eq(-1) .range").val("80");//初始化透明度
        }
    
    
    
        //颜色设置
        $(".show_element .color").change(function () {
            var str = "请先上传模型";
            var idx;
            var model_idx = $(this).parents("#model_text2").siblings(".model_text").html();
            for(var b in arr_link){
                if(model_idx==arr_link[b]){
                    idx=b;
                }
            }
            if(arr_link[Number(idx)] == "tumors"){
                for(var e in tumors){
                    var num_t = Number(e)+1;
                    var vars_name_t = "tumor"+num_t;
                    if(eval(vars_name_t)){eval(vars_name_t).color.set( this.value );}else{alert(str)}
                }
            }else{
                var num = Number(idx)+1;
                var vars_name = "material"+num;
                if(eval(vars_name)){eval(vars_name).color.set( this.value );}else{alert(str)}
            }
        });
    
    
        //透明度设置
        $(".show_element .range").change(function () {
            var range = Number($(this).val())/100;
            var str = "请先上传模型";
            var idx;
            var model_idx = $(this).parents("#model_text2").siblings(".model_text").html();
            for(var c in arr_link){
                if(model_idx==arr_link[c]){
                    idx=c;
                }
            }
            if(arr_link[Number(idx)] == "tumors"){
                for(var e in tumors){
                    var num_t = Number(e)+1;
                    var vars_name_t = "tumor"+num_t;
                    if(eval(vars_name_t)){eval(vars_name_t).opacity = range;}else{alert(str)}
                }
            }else{
                var num = Number(idx)+1;
                var vars_name = "material"+num;
                if(eval(vars_name)){eval(vars_name).opacity = range;}else{alert(str)}
            }
        });
    
    
        //加载模型函数
        function loader_model(url,idx,tumors_idx) {
            var loader = new THREE.VTKLoader();
            loader.load( url, function ( geometry ) {
                geometry.computeVertexNormals();
                var mesh;
                var material = new THREE.MeshPhongMaterial( {
                        color: "#400000",//模型颜色
                        opacity: 0.8,//模型透明度
                        depthWrite: false,
                        transparent: true,
                        polygonOffset: true,
                        polygonOffsetFactor: 1, // positive value pushes polygon further away
                        polygonOffsetUnits: 1
                } );
    
                if(tumors_idx){
                    //变量拼接
                    // var num_t = Number(tumors_idx)+1;
                    // var vars_name_t = "tumor"+num_t;
                    // var vars_name1_t = eval(vars_name_t);
                    // eval(vars_name_t) = material;mesh = new THREE.Mesh( geometry, vars_name1_t );
    
                    switch (Number(tumors_idx)+1){
                        case 1:tumor1=material;mesh = new THREE.Mesh( geometry, tumor1 );break;
                        case 2:tumor2=material;mesh = new THREE.Mesh( geometry, tumor2 );break;
                        case 3:tumor3=material;mesh = new THREE.Mesh( geometry, tumor3 );break;
                        case 4:tumor4=material;mesh = new THREE.Mesh( geometry, tumor4 );break;
                        case 5:tumor5=material;mesh = new THREE.Mesh( geometry, tumor5 );break;
                        case 6:tumor6=material;mesh = new THREE.Mesh( geometry, tumor6 );break;
                        case 7:tumor7=material;mesh = new THREE.Mesh( geometry, tumor7 );break;
                        case 8:tumor8=material;mesh = new THREE.Mesh( geometry, tumor8 );break;
                        case 9:tumor9=material;mesh = new THREE.Mesh( geometry, tumor9 );break;
                        case 10:tumor10=material;mesh = new THREE.Mesh( geometry, tumor10 );break;
                    }
                }else{
                    //变量拼接
                    // var num = Number(idx)+1;
                    // var vars_name = "material"+num;
                    // var vars_name1 = eval(vars_name);
                    // eval(vars_name) = material;mesh = new THREE.Mesh( geometry, vars_name1 );
    
                    switch (Number(idx)+1){
                        case 1:material1=material;mesh = new THREE.Mesh( geometry, material1 );break;
                        case 2:material2=material;mesh = new THREE.Mesh( geometry, material2 );break;
                        case 3:material3=material;mesh = new THREE.Mesh( geometry, material3 );break;
                        case 4:material4=material;mesh = new THREE.Mesh( geometry, material4 );break;
                        case 5:material5=material;mesh = new THREE.Mesh( geometry, material5 );break;
                        case 6:material6=material;mesh = new THREE.Mesh( geometry, material6 );break;
                        case 7:material7=material;mesh = new THREE.Mesh( geometry, material7 );break;
                        case 8:material8=material;mesh = new THREE.Mesh( geometry, material8 );break;
                        case 9:material9=material;mesh = new THREE.Mesh( geometry, material9 );break;
                        case 10:material10=material;mesh = new THREE.Mesh( geometry, material10 );break;
                        case 11:material11=material;mesh = new THREE.Mesh( geometry, material11 );break;
                    }
                }
                mesh.position.set( -1, -1, -0.5 );
                mesh.scale.multiplyScalar( 0.01 );
                scene.add( mesh );
            } );
            //事件("事件名",事件处理函数,useCapture)
            window.addEventListener( 'resize', onWindowResize, false );
        }
    
        //点击事件的处理函数
        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight*0.8;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight*0.8 );
            controls.handleResize();
        }
    }
    
    //每帧都渲染一次场景与相机到渲染器中
    function animation() {
        renderer.render(scene, camera);
        controls.update();
        //循环执行animation函数
        requestAnimationFrame(animation);
    }
    View Code

    contorler.js  初始化函数

    /**
     * -------------- on 2018/8/7.
     */
    
    //全局变量
    var renderer,width,height,camera,scene,light,controls,stats,
        //材质/变量【器官】
        material1,material2,material3,material4,material5,material6,material7,material8,
        material9,material10,material11,
        //材质/变量【肿瘤】
        tumor1,tumor2,tumor3,tumor4,tumor5,tumor6,tumor7,tumor8,tumor9,tumor10;
    
        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
    //初始化
    init();
    
    //创建光源
    light_fn();
    
    //创建实物
    initObject();
    
    //每帧渲染一次
    animation();
    View Code

    如果错误,请指出。谢谢

  • 相关阅读:
    C语言数据结构(二)
    面向对象
    Java集合类汇总
    C语言运算符优先级和结合性
    c语言数据结构(一)
    浏览器间bug
    HTTP协议中的1xx,2xx,3xx,4xx,5xx状态码分别表示什么,列举常见错误码及含义
    SSL是啥?
    {转}大公司里怎样开发和部署前端代码?
    浏览器 HTTP 缓存原理分析
  • 原文地址:https://www.cnblogs.com/yuerdong/p/9588499.html
Copyright © 2020-2023  润新知