自动摘要: 背景:场景中加载的模型是用obj格式文件和mtl格式文件,mtl文件中包含材质文件需求:创建按钮,点击将显示结果的渲染模型导出PLY格式;分析:用threejs中的PLYExporter ```jav ……..
背景:场景中加载的模型是用obj格式文件和mtl格式文件,mtl文件中包含材质文件需求:创建按钮,点击将显示结果的渲染模型导出PLY格式;分析:用threejs中的PLYExporter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| MTLLoader.load("http://" + severAddress + '/download/mtl', function (materials) { materials.preload(); console.log(materials); OBJLoader.setMaterials(materials); var materialsDetail = materials.materials; for (var item in materialsDetail) { materialsDetail[item].transparent = false; materialsDetail[item].opacity = 1; } OBJLoader.load("http://" + severAddress + '/download/obj', function (obj) { console.log("模型信息:"+obj); obj.rotateY(-0.3 * Math.PI); obj.rotateX(-0.1 * Math.PI); obj.rotateZ(0.05); obj.scale.set(0.3, 0.3, 0.3); scene2.add(obj); mesh = obj; }, onProgress, onError) })
var exporter = new THREE.PLYExporter(); function exports(){ exportBinaryLittleEndian(); }
function exportBinaryLittleEndian() {
exporter.parse( mesh, function ( result ) {
saveArrayBuffer( result, 'box.ply' );
}, { binary: true, littleEndian: true } );
}
const link = document.createElement( 'a' ); link.style.display = 'none'; document.body.appendChild( link );
function save( blob, filename ) {
link.href = URL.createObjectURL( blob ); link.download = filename; link.click();
}
function saveArrayBuffer( buffer, filename ) {
save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
}
|
遇到问题:导出的模型没有颜色渲染,只是一个没有材质的模型。原因可能是mesh对应的obj只包含几何信息;并没有导出材质;如何导出材质信息?尝试解决:
- 分析如何导出材质,材质几何放在PLY格式中?(无法下手)
- 直接进行服务器文件下载是否可以?
- 服务器中获取的是两个文件,一个是obj格式文件,一个是mtl格式文件
- 需要下载两个文件
- 方法一:通过window.open()可以直接下载
- 方法二:也可以通过a链接下载
- 遇到问题:
- 成功下载两个文件后打开obj格式模型,模型的颜色渲染有问题
- 分析:查看两个文件的内容,是否是mtl文件本身问题
- 结果:通过对比发现,每个模型的mtl文件不一致,但是obj文件中mtllib的文件名都为./mesh.obj.mtl。所以打开obj文件时,材质只导入名为mesh.obj.mtl的材质信息,重点是文件下载时,文件名重复,文件名变为mesh.obj(2).mtl,以此类推。
- 所以obj文件和mtl文件无法一一对应导致最后模型的渲染有问题
- 尝试解决:
- 重命名从服务器中下载的文件(已解决)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| var i = 0; var filename; function openFile(){ filename = "mesh"+i; handleDownload("http://" + severAddress + "/download/obj",filename+".obj"); handleDownload("http://" + severAddress + "/download/mtl","mesh.obj.mtl"); i++; } function handleDownload(url,fileName) { this.getBlob(url, (blob) => { this.saveAs(blob, fileName) }) }
function getBlob(url, cb) { var xhr = new XMLHttpRequest() xhr.open('GET', url, true) xhr.responseType = 'blob' xhr.onload = function () { if (xhr.status === 200) { cb(xhr.response) } } xhr.send() }
function saveAs(blob, filename) { if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, filename) } else { var link = document.createElement('a') var body = document.querySelector('body')
link.href = window.URL.createObjectURL(blob) link.download = filename
link.style.display = 'none' body.appendChild(link)
link.click() body.removeChild(link)
window.URL.revokeObjectURL(link.href) } }
|
1. 修改obj中的mtllib的文件名(未解决)
背景:需要点击选择文件按钮在本地文件中选择文件进行上传,本地文件中不一定有牙颌模型需求:创建两个按钮,点击时直接上传模型分析:修改获取的文件对象信息,直接获取文件地址问题:出现跨域问题以及一些其他问题(目前没有办法实现不选择文件直接获取默认的本地文件地址上传)解决方法:点击按钮,进行模型下载至本地,再点击选择文件上传按钮,从本地选择下载好的文件上传缺点:操作步骤繁琐
问题:threejs加载PLY格式模型,无法正确加载材质(目前只能加载obj格式的模型然后加载mtl材质文件,才能正确渲染)
需求:将html中的元素全屏显示分析:
需求:设置一个drawSpline功能绘制牙颌颈缘线,并成功导出颈缘线的json文件具体实现:
- start按钮:进入画线功能
- 点击鼠标左键:在点击位置上创建圆点,每次点击都创建圆点,圆点超过三个时绘制曲线
- 点击鼠标右键:闭合样条曲线
- ctrl+d:绘制错误退回上一步骤(未完成)
- 鼠标选择圆点,可以进行移动,避免(未完成)
- save按钮:保存绘制的颈缘线,并导出json文件
分析:使用threejs自带的json保存和加载方式解决方法:
- 通过THREE.Raycaster()进行射线投射确定鼠标点击位置
- 将屏幕坐标转换为webgl坐标系
- 通过raycaster.setFromCamera()确定点击物体的3d空间位置
- raycaster.intersectObjects(scene.children)获取点击位置上的物体数量
- 判断点击位置是否有物体,有则选取第一个物体
需求:点击按钮,用户不进行文件选择,直接上传默认文件至服务器分析:方法1:将需要上传的文件对象进行浏览器缓存,然后获取文件缓存地址,直接上传
需求:制作AI聊天窗口分析:
需求:特征点识别功能描述:用户选择上传模型至服务器,成功上传返回一个特征点json格式文件,里面包含的是点的坐标,按显示结果按钮,在场景中显示牙颌模型以及显示模型上的特征点(红色小球表示)分析:
- 上传模型至服务器,上传文件对象,input type=file
- 缓存服务器返回的文件至浏览器,用sessionStorage.setItem缓存
- 通过Ajax读取缓存文件信息,for循环创建圆点