美文网首页
2022-01-05 点云.ply在网页中可视化

2022-01-05 点云.ply在网页中可视化

作者: L6511 | 来源:发表于2022-01-06 15:29 被阅读0次

http://www.yanhuangxueyuan.com/
https://blog.csdn.net/weixin_43954810/article/details/118512825基于此,意识到用html和three.js,怎么用看基础教程即可。

但是遇到问题,示例网页(或者就把一个网页的源码复制,修改一下路径)打开也是空白的,而且不论mac还是windows都是这样的。

如何发现bug,
command option u可以看这个网页的源码进行学习
command shift c 可以看开发者调试工具,也就是知道error在哪里。

发现都是fail to load resource:net::ERR_FAILED等问题,就是仅仅把位置路径改成自己的文件夹下是不够的
然后谷歌这些bug即可
https://blog.csdn.net/qq_37909508/article/details/83109577
https://threejs.org/docs/index.html#manual/en/introduction/How-to-run-things-locally How to run things locally

搜索mac电脑如何配置网页为localhost并打开
https://shannonchenchn.github.io/2018/10/22/How-do-you-set-up-a-local-web-server-on-Mac/即要配置一个本地web服务器

我们为什么需要服务器?

1. 本地文件 VS. 远程文件

通常情况下,你可以通过在浏览器中直接打开或者通过一个 URL 来访问一个文件。

使用浏览器访问本地文件时,一般地址是 file:// 开头的本地文件地址。
而访问远程文件时,一般地址是 http:// 或者 https:// 开头的地址,表示这个文件通过 http 协议访问的。

2. 直接访问本地文件时存在的问题

在有些情况下,你打开一个本地的 html 文件时,会出现运行错误。

导致这些错误的原因主要有以下两个:
(1) 其中包含了异步请求。 如果你直接打开本地文件运行,一些浏览器(包括 Chrome)将不会运行其中的异步请求(请参阅 从服务器获取数据)。 这是因为安全限制而导致的(更多关于 Web 安全的信息,请参阅Website security)。

比如,你直接在浏览器中打开含有如下内容的文件:

<html>
<head>
   <script>
       var request = new XMLHttpRequest(); 

       request.onreadystatechange = function () { 
           console.log(request);
       }

       // 发送请求:
       request.open('GET', './data.json');
       request.send();
   </script>
   <title>HTML 测试页面</title>
</head>

<body>
   <p>测试页面</p>
</body>

</html>

然后,你会在 console 中看到这样的错误:

index.html:12 Failed to load file:///Users/ShannonChen/Desktop/Playground/nodejs_example/data.json: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
(2) 执行文件中的代码时需要通过执行一些附加逻辑(如 PHP 或 Python)才能获得结果,而不仅仅是直接访问一个文件。

比如,我登录了京东网站后,查看购物车页面时,需要服务器返回的是包含我的购物车数据的页面,这个时候,就需要服务端在接收到请求后,跟我的用户信息(一般是 cookie)来返回匹配的数据。

利用方法一:启动 Mac 自带的 Apache 服务器
1.运行 Apache $ sudo apachectl start
2.退出 Apache $ sudo apachectl stop
3.把工程文件夹放到以下位置中 /Library/WebServer/Documents
4.在浏览器中访问:在地址栏中输入地址 http://localhost/工程文件夹名称/,回车。

注意: 不再需要使用后一定要记得退出,否则会消耗电脑性能。

搞来搞去就是要把工程文件夹放在这个位置下
修改后的源代码是这样的

|  | <!DOCTYPE html> |
|  | <html lang="en"> |
|  | <head> |
|  | <title>three.js webgl - PLY</title> |
|  | <meta charset="utf-8"> |
|  | <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|  | <link type="text/css" rel="stylesheet" href="[main.css](http://localhost/main.css)"> |
|  | </head> |
|  | <body> |
|  | <div id="info"> |
|  | <a href="[https://threejs.org](https://threejs.org/)" target="_blank" rel="noopener">three.js</a> - |
|  | PLY loader test by <a href="[https://github.com/menway](https://github.com/menway)" target="_blank" rel="noopener">Wei Meng</a>.<br/> |
|  | Image from <a href="[http://people.sc.fsu.edu/~jburkardt/data/ply/ply.html](http://people.sc.fsu.edu/~jburkardt/data/ply/ply.html)">John Burkardt</a> |
|  | </div> |
|  | 
 |
|  | <script type="module"> |
|  | 
 |
|  | import * as THREE from './assets/three.js-master/build/three.module.js'; |
|  | 
 |
|  | import Stats from './assets/three.js-master/examples/jsm/libs/stats.module.js'; |
|  | 
 |
|  | import { PLYLoader } from './assets/three.js-master/examples/jsm/loaders/PLYLoader.js'; |
|  | 
 |
|  | let container, stats; |
|  | 
 |
|  | let camera, cameraTarget, scene, renderer; |
|  | 
 |
|  | init(); |
|  | animate(); |
|  | 
 |
|  | function init() { |
|  | 
 |
|  | container = document.createElement( 'div' ); |
|  | document.body.appendChild( container ); |
|  | 
 |
|  | camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 ); |
|  | camera.position.set( 3, 0.15, 3 ); |
|  | 
 |
|  | cameraTarget = new THREE.Vector3( 0, - 0.1, 0 ); |
|  | 
 |
|  | scene = new THREE.Scene(); |
|  | scene.background = new THREE.Color( 0x72645b ); |
|  | scene.fog = new THREE.Fog( 0x72645b, 2, 15 ); |
|  | 
 |
|  | 
 |
|  | // Ground |
|  | 
 |
|  | const plane = new THREE.Mesh( |
|  | new THREE.PlaneGeometry( 40, 40 ), |
|  | new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } ) |
|  | ); |
|  | plane.rotation.x = - Math.PI / 2; |
|  | plane.position.y = - 0.5; |
|  | scene.add( plane ); |
|  | 
 |
|  | plane.receiveShadow = true; |
|  | 
 |
|  | 
 |
|  | // PLY file |
|  | 
 |
|  | const loader = new PLYLoader(); |
|  | loader.load( './assets/three.js-master/examples/models/ply/ascii/dolphins.ply', function ( geometry ) { |
|  | 
 |
|  | geometry.computeVertexNormals(); |
|  | 
 |
|  | const material = new THREE.MeshStandardMaterial( { color: 0x0055ff, flatShading: true } ); |
|  | const mesh = new THREE.Mesh( geometry, material ); |
|  | 
 |
|  | mesh.position.y = - 0.2; |
|  | mesh.position.z = 0.3; |
|  | mesh.rotation.x = - Math.PI / 2; |
|  | mesh.scale.multiplyScalar( 0.001 ); |
|  | 
 |
|  | mesh.castShadow = true; |
|  | mesh.receiveShadow = true; |
|  | 
 |
|  | scene.add( mesh ); |
|  | 
 |
|  | } ); |
|  | 
 |
|  | loader.load( './assets/three.js-master/examples/models/ply/binary/Lucy100k.ply', function ( geometry ) { |
|  | 
 |
|  | geometry.computeVertexNormals(); |
|  | 
 |
|  | const material = new THREE.MeshStandardMaterial( { color: 0x0055ff, flatShading: true } ); |
|  | const mesh = new THREE.Mesh( geometry, material ); |
|  | 
 |
|  | mesh.position.x = - 0.2; |
|  | mesh.position.y = - 0.02; |
|  | mesh.position.z = - 0.2; |
|  | mesh.scale.multiplyScalar( 0.0006 ); |
|  | 
 |
|  | mesh.castShadow = true; |
|  | mesh.receiveShadow = true; |
|  | 
 |
|  | scene.add( mesh ); |
|  | 
 |
|  | } ); |
|  | 
 |
|  | // Lights |
|  | 
 |
|  | scene.add( new THREE.HemisphereLight( 0x443333, 0x111122 ) ); |
|  | 
 |
|  | addShadowedLight( 1, 1, 1, 0xffffff, 1.35 ); |
|  | addShadowedLight( 0.5, 1, - 1, 0xffaa00, 1 ); |
|  | 
 |
|  | // renderer |
|  | 
 |
|  | renderer = new THREE.WebGLRenderer( { antialias: true } ); |
|  | renderer.setPixelRatio( window.devicePixelRatio ); |
|  | renderer.setSize( window.innerWidth, window.innerHeight ); |
|  | renderer.outputEncoding = THREE.sRGBEncoding; |
|  | 
 |
|  | renderer.shadowMap.enabled = true; |
|  | 
 |
|  | container.appendChild( renderer.domElement ); |
|  | 
 |
|  | // stats |
|  | 
 |
|  | stats = new Stats(); |
|  | container.appendChild( stats.dom ); |
|  | 
 |
|  | // resize |
|  | 
 |
|  | window.addEventListener( 'resize', onWindowResize ); |
|  | 
 |
|  | } |
|  | 
 |
|  | function addShadowedLight( x, y, z, color, intensity ) { |
|  | 
 |
|  | const directionalLight = new THREE.DirectionalLight( color, intensity ); |
|  | directionalLight.position.set( x, y, z ); |
|  | scene.add( directionalLight ); |
|  | 
 |
|  | directionalLight.castShadow = true; |
|  | 
 |
|  | const d = 1; |
|  | directionalLight.shadow.camera.left = - d; |
|  | directionalLight.shadow.camera.right = d; |
|  | directionalLight.shadow.camera.top = d; |
|  | directionalLight.shadow.camera.bottom = - d; |
|  | 
 |
|  | directionalLight.shadow.camera.near = 1; |
|  | directionalLight.shadow.camera.far = 4; |
|  | 
 |
|  | directionalLight.shadow.mapSize.width = 1024; |
|  | directionalLight.shadow.mapSize.height = 1024; |
|  | 
 |
|  | directionalLight.shadow.bias = - 0.001; |
|  | 
 |
|  | } |
|  | 
 |
|  | function onWindowResize() { |
|  | 
 |
|  | camera.aspect = window.innerWidth / window.innerHeight; |
|  | camera.updateProjectionMatrix(); |
|  | 
 |
|  | renderer.setSize( window.innerWidth, window.innerHeight ); |
|  | 
 |
|  | } |
|  | 
 |
|  | function animate() { |
|  | 
 |
|  | requestAnimationFrame( animate ); |
|  | 
 |
|  | render(); |
|  | stats.update(); |
|  | 
 |
|  | } |
|  | 
 |
|  | function render() { |
|  | 
 |
|  | const timer = Date.now() * 0.0005; |
|  | 
 |
|  | camera.position.x = Math.sin( timer ) * 2.5; |
|  | camera.position.z = Math.cos( timer ) * 2.5; |
|  | 
 |
|  | camera.lookAt( cameraTarget ); |
|  | 
 |
|  | renderer.render( scene, camera ); |
|  | 
 |
|  | } |
|  | 
 |
|  | </script> |
|  | </body> |
|  | </html> |

就是把自己写的那个文件打开(那个文件必须在工程文件夹下,而且得默认名字叫index.html,然后里面按要求写好配置路径,然后在地址上写localhost就行了,主要是必须在/Library/WebServer/Documents下,而且得是index.html,然后改的话就在terminal里用sudo vim

得把那个“照片”复制在工程文件夹下,然后给那个“照片”也得赋予权限才可以
xxx@xxx Documents % su root
Password:
sh-3.2# chmod +x pcloud_tobacco.ply

记得

sudo apachectl stop
sudo apachectl start

如果我用老头.ply去插入我的代码是可以实现我要的目的


image.png

但我偏偏就是用自己的烟草实现不了,即使这个老头文件更大
FPS (每秒传输帧数(Frames Per Second))


image.png
|  | <!DOCTYPE html> |
|  | <html lang="en"> |
|  | <head> |
|  | <title>three.js webgl - PLY</title> |
|  | <meta charset="utf-8"> |
|  | <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|  | <link type="text/css" rel="stylesheet" href="[main.css](http://localhost/main.css)"> |
|  | </head> |
|  | <body> |
|  | <div id="info"> |
|  | <a href="[https://threejs.org](https://threejs.org/)" target="_blank" rel="noopener">three.js</a> - |
|  | PLY loader test by <a href="[https://github.com/menway](https://github.com/menway)" target="_blank" rel="noopener">Wei Meng</a>.<br/> |
|  | Image from <a href="[http://people.sc.fsu.edu/~jburkardt/data/ply/ply.html](http://people.sc.fsu.edu/~jburkardt/data/ply/ply.html)">John Burkardt</a> |
|  | </div> |
|  | 
 |
|  | <script type="module"> |
|  | 
 |
|  | import * as THREE from './assets/three.js-master/build/three.module.js'; |
|  | 
 |
|  | import Stats from './assets/three.js-master/examples/jsm/libs/stats.module.js'; |
|  | 
 |
|  | import { PLYLoader } from './assets/three.js-master/examples/jsm/loaders/PLYLoader.js'; |
|  | 
 |
|  | let container, stats; |
|  | 
 |
|  | let camera, cameraTarget, scene, renderer; |
|  | 
 |
|  | init(); |
|  | animate(); |
|  | 
 |
|  | function init() { |
|  | 
 |
|  | container = document.createElement( 'div' ); |
|  | document.body.appendChild( container ); |
|  | 
 |
|  | camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 ); |
|  | camera.position.set( 3, 0.15, 3 ); |
|  | 
 |
|  | cameraTarget = new THREE.Vector3( 0, - 0.1, 0 ); |
|  | 
 |
|  | scene = new THREE.Scene(); |
|  | scene.background = new THREE.Color( 0x72645b ); |
|  | scene.fog = new THREE.Fog( 0x72645b, 2, 15 ); |
|  | 
 |
|  | 
 |
|  | // Ground |
|  | 
 |
|  | const plane = new THREE.Mesh( |
|  | new THREE.PlaneGeometry( 40, 40 ), |
|  | new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } ) |
|  | ); |
|  | plane.rotation.x = - Math.PI / 2; |
|  | plane.position.y = - 0.5; |
|  | scene.add( plane ); |
|  | 
 |
|  | plane.receiveShadow = true; |
|  | 
 |
|  | 
 |
|  | // PLY file |
|  | 
 |
|  | const loader = new PLYLoader(); |
|  |  |
|  | loader.load( './Bearded_guy.ply', function ( geometry ) { |
|  | 
 |
|  | geometry.computeVertexNormals(); |
|  | 
 |
|  | const material = new THREE.MeshStandardMaterial( { color: 0x0055ff, flatShading: true } ); |
|  | const mesh = new THREE.Mesh( geometry, material ); |
|  | 
 |
|  | mesh.position.y = - 0.2; |
|  | mesh.position.z = 0.3; |
|  | mesh.rotation.x = - Math.PI / 2; |
|  | mesh.scale.multiplyScalar( 0.001 ); |
|  | 
 |
|  | mesh.castShadow = true; |
|  | mesh.receiveShadow = true; |
|  | 
 |
|  | scene.add( mesh ); |
|  | 
 |
|  | } ); |
|  |  |
|  | // Lights |
|  | 
 |
|  | scene.add( new THREE.HemisphereLight( 0x443333, 0x111122 ) ); |
|  | 
 |
|  | addShadowedLight( 1, 1, 1, 0xffffff, 1.35 ); |
|  | addShadowedLight( 0.5, 1, - 1, 0xffaa00, 1 ); |
|  | 
 |
|  | // renderer |
|  | 
 |
|  | renderer = new THREE.WebGLRenderer( { antialias: true } ); |
|  | renderer.setPixelRatio( window.devicePixelRatio ); |
|  | renderer.setSize( window.innerWidth, window.innerHeight ); |
|  | renderer.outputEncoding = THREE.sRGBEncoding; |
|  | 
 |
|  | renderer.shadowMap.enabled = true; |
|  | 
 |
|  | container.appendChild( renderer.domElement ); |
|  | 
 |
|  | // stats |
|  | 
 |
|  | stats = new Stats(); |
|  | container.appendChild( stats.dom ); |
|  | 
 |
|  | // resize |
|  | 
 |
|  | window.addEventListener( 'resize', onWindowResize ); |
|  | 
 |
|  | } |
|  | 
 |
|  | function addShadowedLight( x, y, z, color, intensity ) { |
|  | 
 |
|  | const directionalLight = new THREE.DirectionalLight( color, intensity ); |
|  | directionalLight.position.set( x, y, z ); |
|  | scene.add( directionalLight ); |
|  | 
 |
|  | directionalLight.castShadow = true; |
|  | 
 |
|  | const d = 1; |
|  | directionalLight.shadow.camera.left = - d; |
|  | directionalLight.shadow.camera.right = d; |
|  | directionalLight.shadow.camera.top = d; |
|  | directionalLight.shadow.camera.bottom = - d; |
|  | 
 |
|  | directionalLight.shadow.camera.near = 1; |
|  | directionalLight.shadow.camera.far = 4; |
|  | 
 |
|  | directionalLight.shadow.mapSize.width = 1024; |
|  | directionalLight.shadow.mapSize.height = 1024; |
|  | 
 |
|  | directionalLight.shadow.bias = - 0.001; |
|  | 
 |
|  | } |
|  | 
 |
|  | function onWindowResize() { |
|  | 
 |
|  | camera.aspect = window.innerWidth / window.innerHeight; |
|  | camera.updateProjectionMatrix(); |
|  | 
 |
|  | renderer.setSize( window.innerWidth, window.innerHeight ); |
|  | 
 |
|  | } |
|  | 
 |
|  | function animate() { |
|  | 
 |
|  | requestAnimationFrame( animate ); |
|  | 
 |
|  | render(); |
|  | stats.update(); |
|  | 
 |
|  | } |
|  | 
 |
|  | function render() { |
|  | 
 |
|  | const timer = Date.now() * 0.0005; |
|  | 
 |
|  | camera.position.x = Math.sin( timer ) * 2.5; |
|  | camera.position.z = Math.cos( timer ) * 2.5; |
|  | 
 |
|  | camera.lookAt( cameraTarget ); |
|  | 
 |
|  | renderer.render( scene, camera ); |
|  | 
 |
|  | } |
|  | 
 |
|  | </script> |
|  | </body> |
|  | </html> |
|  |  |

image.png
这里的错误至少没有去说我输入的东西有问题,可以重新看一下我的烟草出了什么问题
image.png
就是输入的问题
image.png
这里的每秒传输帧数也是正常的,就是输入有问题
如果用大的那个文件,就不会有这个问题但依然不显示
image.png
用小的就会这样
image.png
然后想要看看是不是针对点云.ply有什么不同
https://stackoverflow.com/questions/68329448/colored-point-cloud-ply-does-not-display-in-three-js
这个人和我遇到的问题很像呐,可惜就是没有答案,下载他的点云数据可以当作尝试
https://www.coder.work/article/5306359用了这里的方法也没用

决定转换思路
https://ibrahimsaricicek.medium.com/visualizing-point-cloud-3d-data-on-web-8f9792385e68

Visualizing Point Cloud & 3D Data On Web

最终指向————potree

相关文章

网友评论

      本文标题:2022-01-05 点云.ply在网页中可视化

      本文链接:https://www.haomeiwen.com/subject/wvdhcrtx.html