暑期项目实训:基于webgl(three.js)的牙科数据可视化展示

本文详述了一组学生在暑期项目中使用WebGL和three.js进行牙科数据可视化的过程。他们从数据处理到前端平台搭建,实现了三维数据呈现、动画效果、光照跟随等功能。在数据可视化部分,他们处理了CBCT和X光全景图数据,通过WebGL和three.js简化了开发流程。目前面临的问题包括模型材质效果、2D图像质量、点云到面片的三维重建等。
摘要由CSDN通过智能技术生成

第一天:

本组的选题是“牙科数据的分割与分类及可视化展示平台”。工作主要划分成三块:前端平台页面搭建、算法与数据可视化、后端及数据库。我和另一个同学一起负责算法与数据可视化。
根据学长给的demo视频。我们将组内任务分为如下:

一、牙科数据可视化

(1)CBCT数据、口扫数据可视化(三维数据)
其中细分由分为如下功能:三维数据呈现、改变观测视角、光照效果、材质、颜色透明度变换,形成渲染器中的GUI。
(2)X光全景图可视化(二维数据)
细分功能如下:二维数据呈现、切换深度、基本的图像处理。

二、牙科数据处理

(1)牙齿分割任务
(2)牙齿分类任务
注:模型已经由学长给出,我们要导入数据以及输出结果。、

细分好工作后,我们先决定实现数据可视化。考虑到和Web端适配,我们决定使用WebGL开发,一开始使用原生的WebGL的开发是痛苦的。WebGL和OpenGL是类似的,而渲染管线又是流水线的工作,必须按照流程。于是我们寻找到更高效的开发工具three.js简化开发的流程。我们建立了一个建立的html页面,并成功载入三维CBCT数据,并渲染出来。

这是载入stl文件函数

这是我们需要加载的外部文件

我们需要创建场景、设置光源、设置相机、创建渲染器、执行渲染

第二天:

我们开始给3D模型添加动画效果
一是添加旋转,让鼠标和场景完成交互。在网上搜索资料,有封装好的API可以调用,类似于JQuery,创建控件对象,然后监听鼠标、键盘事件,将render()函数做为参数。这样可以做出“相加跟随的效果”。

var controls = new THREE.OrbitControls(camera, renderer.domElement);//创建控件对象
controls.addEventListener('change', render);//监听鼠标、键盘事件

效果如下:

二是加入光照跟随的效果,起初环境光与点光源都是固定的,所以我们从不同的视角观测,模型的亮暗部分都是固定的。所以有的角度直面的是暗的部分,观测不清楚。我们定义好了render()函数,用来专门渲染物体。在这个render()函数中,我们先获取了相机的位置,然后新建一个点光源,把相机位置传入。这样,无论我们在何处观测,都有点光源会照在正对相机的表面上。极大地方便了用户观测三维模型。

function render() {
    var vector = camera.position.clone();
    //console.log(vector.x);
    point.position.set(vector.x, vector.y, vector.z); //点光源位置
    renderer.render(scene, camera);//执行渲染操作
    //console.log(vector.x);
}

问题:
我们在添加监控对象的时候遇到了一个麻烦:即加入监听事件的对象后,程序保持着监听状态,但是刚点开网页的时候,却无法渲染出物体。只有通过移动鼠标,运动相机后才能渲染出。我们判断,是因为渲染的逻辑顺序的问题,“监听”的机制我们其实并不了解。但是我们可以在载入STL文件后,立即执行渲染,这样可以保证刚打开时,就能有模型显示。

三:

为了进一步增加交互,提高用户友好性。我们尝试增加一些按钮。首先增加“Reset”按钮,即还原相机位置,让屏幕显示出从模型的正面观测。

   <button type="button" onclick="reset()">重置方向</button>

我们按照html语法写了一个button,添加了onclick,一旦点击此按钮,便会执行“reset()”函数。

function reset() {
   
    var v = camera.position.clone();

    camera.position.set(0, 0, 200);
    camera.lookAt(scene.position);
    scene.position.set(0,0,0);
    //var controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
    //controls.addEventListener('change', render);//监听鼠标、键盘事件
    render();
}

Reset()函数是先把相机的位置归回最初的(0,0,200),把保存模型的场景位置归回(0,0,0),再把相机的目标点放到“场景”上,最后渲染出。就能实现“reset”。
同样的,添加了坐标轴的显示

坐标轴显示/消失

由于坐标轴显示与否是一个状态值,所以添加了简单的逻辑判断。

function axis() {
   
    if (a == 0) {
   
        //axesHelper.position.set(0,100,0);
        scene.add(axesHelper);
        a = 1;
        //console.log(a);
    }
    else if (a == 1) {
   
        scene.remove(axesHelper);
        a = 0;
        //console.log(a);
    }
    render();
}

如下图所示

为了保证画面的美观,看起来更灵活。我们加入了“自动旋转”,即当浏览器开启时,其实显示的模型就已经开始缓慢运动。这样看起来使得场景更具“高级感”。代码如下;

     <button type="button" onclick="spin()">自动旋转</button>
        <button type="button" onclick="speedup()">旋转加速</button>
        <button type="button" onclick="speedown()">旋转减速</button>

function speedup() {
   
    speed = speed + 0.002;
}

function speedown() {
   
    if (speed - 0.002 >= 0.001) {
   
        speed = speed - 0.002;
    } else {
   
        speed = 0.001;
    }
}
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值