• 使用WebGL实现一个Viewer来显示STL文件


    关键字:WebGL,STL,ThreeJS,Chrome,Viewer,Python3.4, HTML5,Canvas。

    OS:Windows 10。

    本文介绍如何使用ThreeJS来实现一个WebGL的Viewer,用来浏览STL文件。

    STL 文件是在计算机图形应用系统中,用于表示三角形网格的一种文件格式。 它的文件格式非常简单, 应用很广泛。
    STL是最多快速原型系统所应用的标准文件类型。STL是用三角网格来表现3D CAD模型。
     
     
    1.新建一个STL.html文件如下:
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>WebViewer - STL</title>
            <meta charset="utf-8">
        </head>
        <body>
            <script src="threejs/three.min.js"></script>
            <script src="threejs/loaders/STLLoader.js"></script>
            <script src="threejs/OrbitControls.js"></script>
    
            <script>
                var container;
    
                var camera, cameraTarget, scene, renderer;
                
                var cameraType = 1;
                var perspectiveAngle = 45;
                var cameraPosX = 200;
                var cameraPosY = 200;
                var cameraPosZ = 200;
                var cameraTargetX = 0;
                var cameraTargetY = 0;
                var cameraTargetZ = 0;
                var upVectorX = 0;
                var upVectorY = 1;
                var upVectorZ = 0;
                var cameralScale = 5;
                
                init();
                animate();
                
                function getQueryStringByName(name){
                     var result = location.search.match(new RegExp("[?&]" + name+ "=([^&]+)","i"));
                    
                     if(result == null || result.length < 1){
                         return "";
                     }
    
                     return result[1];
                }
    
                function init() {
    
                    container = document.createElement( 'div' );
                    document.body.appendChild( container );
                    
                    // set camera
                    var cameraTypeStr = getQueryStringByName('cameraType');
                    cameraType = cameraTypeStr == "" ? cameraType : parseInt(cameraTypeStr);
                    
                    var perspectiveAngleStr = getQueryStringByName('perspectiveAngle');
                    perspectiveAngle = perspectiveAngleStr == "" ? perspectiveAngle : parseFloat(perspectiveAngleStr);
                    
                    var cameraPosXStr = getQueryStringByName('cameraPosX');
                    cameraPosX = cameraPosXStr == "" ? cameraPosX : parseFloat(cameraPosXStr) * cameralScale;
                    
                    var cameraPosYStr = getQueryStringByName('cameraPosY');
                    cameraPosY = cameraPosYStr == "" ? cameraPosY : parseFloat(cameraPosYStr) * cameralScale;
                    
                    var cameraPosZStr = getQueryStringByName('cameraPosZ');
                    cameraPosZ = cameraPosZStr == "" ? cameraPosZ : parseFloat(cameraPosZStr) * cameralScale;
                    
                    var cameraTargetXStr = getQueryStringByName('cameraTargetX');
                    cameraTargetX = cameraTargetXStr == "" ? cameraTargetX : parseFloat(cameraTargetXStr) * cameralScale;
                    
                    var cameraTargetYStr = getQueryStringByName('cameraTargetY');
                    cameraTargetY = cameraTargetYStr == "" ? cameraTargetY : parseFloat(cameraTargetYStr) * cameralScale;
                    
                    var cameraTargetZStr = getQueryStringByName('cameraTargetZ');
                    cameraTargetZ = cameraTargetZStr == "" ? cameraTargetZ : parseFloat(cameraTargetZStr) * cameralScale;
                    
                    var upVectorXStr = getQueryStringByName('upVectorX');
                    upVectorX = upVectorXStr == "" ? upVectorX : parseFloat(upVectorXStr) * cameralScale;
                    
                    var upVectorYStr = getQueryStringByName('upVectorY');
                    upVectorY = upVectorYStr == "" ? upVectorY : parseFloat(upVectorYStr) * cameralScale;
                    
                    var upVectorZStr = getQueryStringByName('upVectorZ');
                    upVectorZ = upVectorZStr == "" ? upVectorZ : parseFloat(upVectorZStr) * cameralScale;
                    
                    if(cameraType == 0) {
                        camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 10000 );
                    }
                    else {
                        camera = new THREE.PerspectiveCamera( perspectiveAngle, window.innerWidth / window.innerHeight, 1, 10000 );
                    }
                
                    camera.position.set( cameraPosX, cameraPosY, cameraPosZ);
                    camera.up.set(upVectorX, upVectorY, upVectorZ);
    
                    cameraTarget = new THREE.Vector3( cameraTargetX, cameraTargetY, cameraTargetZ );
                    camera.lookAt( cameraTarget );
    
                    scene = new THREE.Scene();
                    scene.fog = new THREE.Fog( 0xffffff, 1, 10000 );
    
                    // load file
    
                    var loader = new THREE.STLLoader();
                    
                    var modelName = getQueryStringByName('modelName');
                    loader.load( '../Models/' + modelName, function ( geometry ) {
    
                        var material = new THREE.MeshPhongMaterial( { color: 0x808080, specular: 0x111111, shininess: 200 } );
                        var mesh = new THREE.Mesh( geometry, material );
    
                        mesh.castShadow = true;
                        mesh.receiveShadow = true;
    
                        scene.add( mesh );
    
                    } );
    
                    // lights
    
                    scene.add( new THREE.AmbientLight( 0x333333 ) );
                    
                    addDirectionalLight(-1, 1, 1, 0xFFFFFF, 1.35);
                    addDirectionalLight(1, -1, -1, 0xFFFFFF, 1);
    
                    // renderer
    
                    renderer = new THREE.WebGLRenderer( { antialias: true } );
                    renderer.setClearColor( scene.fog.color );
                    renderer.setSize( window.innerWidth, window.innerHeight );
    
                    renderer.gammaInput = true;
                    renderer.gammaOutput = true;
    
                    renderer.shadowMapEnabled = true;
                    renderer.shadowMapCullFace = THREE.CullFaceBack;
    
                    container.appendChild( renderer.domElement );
                    
                    // orbit control
    
                    control = new THREE.OrbitControls( camera, renderer.domElement );
    
                    // events
    
                    window.addEventListener( 'resize', onWindowResize, false );
                }
                
                function addDirectionalLight( x, y, z, color, intensity ) {
    
                    var directionalLight = new THREE.DirectionalLight( color, intensity );
                    directionalLight.position.set( x, y, z )
                    scene.add( directionalLight );
                }
                
                function onWindowResize() {
    
                    camera.aspect = window.innerWidth / window.innerHeight;
                    camera.updateProjectionMatrix();
    
                    renderer.setSize( window.innerWidth, window.innerHeight );
    
                }
    
                function animate() {
    
                    requestAnimationFrame( animate );
    
                    render();
                }
    
                function render() {
    
    //                var timer = Date.now() * 0.0005;
    //
    //                camera.position.x = Math.cos( timer ) * 3;
    //                camera.position.z = Math.sin( timer ) * 3;
    
                    renderer.render( scene, camera );
                }
    
            </script>
        </body>
    </html>

    2.直接用Chrome打开文件STL.html,将会看到一下错误,那是因为不能打开本地模型文件,需要创建一个http server。

    XMLHttpRequest cannot load file:///D:/L/Dev/WebViewer/Models/. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.THREE.XHRLoader.load @ three.min.js:258
    three.min.js:258 Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'file:///D:/L/Dev/WebViewer/Models/'.

    3.本文使用python来创建一个http server,新建localServer.py文件,内容如下:

    from threading import Thread
    import webbrowser, http.server, socketserver
    import time;
    
    port_number = 8000
    
    server = None
    def startServer(port):
        Handler = http.server.SimpleHTTPRequestHandler
        global server
        server = socketserver.TCPServer(("", port), Handler)
    
        print("Start server at port", port)
        server.serve_forever()
       
    def start(port):
        thread = Thread(target=startServer, args=[port])
        thread.start()
        
        startTime = int(time.time())
        while not server:
            if int(time.time()) > startTime + 60:
                print("Time out")
                break
        return server
    
    def stop():
        if server:
            server.shutdown()
            
    def openUrl():
        url = "http://localhost:" + str(port_number)
        webbrowser.open(url)
        print(url + " is opened in browser")
    
    if __name__ == "__main__":
        start(port_number)
        openUrl()

    4.文件夹结构如下:

    Models - 模型文件夹,放置模型文件,例如bike_frame.stl。

    threejs - threejs文件夹,放置threejs相关的库文件

    5. 双击运行LocalServer.py启动一个http服务器。

    6.在Chrome里面打开http://localhost:8000/WebGLViewer/STL.html?modelName=bike_frame.stl,如下图。

    源代码地址:https://github.com/ldlchina/Sample-of-WebGL-with-STL-loader

    相关链接: http://threejs.org/

  • 相关阅读:
    内联模板 C++快速入门46
    delphi演示程序
    delphi演示程序
    容器和算法 C++快速入门47
    Delphi7_Lite_Fullv7.3优化精简全功能版
    Delphi7_Lite_Fullv7.3优化精简全功能版
    容器和算法 C++快速入门47
    [转载 js]alt美化效果
    “谁动了我的奶酪?”的故事
    谁动了我的奶酪[续] 讨论
  • 原文地址:https://www.cnblogs.com/ldlchina/p/4777356.html
Copyright © 2020-2023  润新知