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 {
            width: 100%;
            height: 80%;
            cursor: pointer;
            position: relative;
            /*background-image:url(img/bg.png);*/
        }
        .box{
            height: 20%;
            background: #EDEDED;
            display: flex;
        }
        .box div{
            width: 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;width:100%;height:20px;margin-top:200px;text-align: center;">请上传模型</div>
</div>
<div class="box">
    <div class="left">
        <p> 上传模型:</p>
        <div class="model_box" style="width: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="width: 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="width: 100%;display: none;">
            <div style="border-bottom: 2px solid #ccc;width: 100%;height: 86px;display: flex;">
                <div class="model_text" style="width: 100px;text-align: center;line-height: 86px;"></div>
                <div id="model_text2" style="flex: 1">
                    <div style="width: 100%;height:45px;">
                        <div style="width: 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="width: 100%;height: 45px;">
                        <div style="width: 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

如果错误,请指出。谢谢

猜你喜欢

转载自www.cnblogs.com/yuerdong/p/9588499.html