关键字: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/

使用WebGL实现一个Viewer来显示STL文件的更多相关文章

  1. 与STL文件相关的各类学习地址

    几个网址: 1.STL :https://en.wikipedia.org/wiki/STL_(file_format)#ASCII_STL 2.一个博客的文章地址: 三维图形数据格式 STL的 读取 ...

  2. 打开本地STL文件并创建webgl使用的geometry

    需求 打开本地STL文件 一个独立基于webgl的viewer,会被别的网站重用 将打开文件的数据传输给viewer,并且在文件加载的时候显示进度条 解决方案 #1可以使用传统的html5 api来打 ...

  3. VTK中导入并显示STL、3DS文件

    VTK(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学.图像处理和科学计算可视化.VTK是在三维函数库OpenGL 的基础上采用面向对象的设计方法发展起 ...

  4. 使一个div始终显示在页面中间

    使一个div始终显示在页面中间 假设我们有一个div层:<div id=”myDiv”></div> 首先,我们用css来控制它在水平上始终居中,那么我们的css代码应该是这样 ...

  5. 关于一个隐藏和显示物品列表的demo

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  6. Keil MDK 5.14 仿真时System Viewer菜单显示空白和Peripherals菜单无外设寄存器

    keil mdk5.14新建工程进行仿真时,进入Debug环境发现System Viewer菜单显示空白,Peripherals菜单没有外设寄存器.如图1和图2所示.打开Oprons for Targ ...

  7. Sublime Text 如何一个代码双屏显示代码上下部分?

    Sublime Text 如何一个代码双屏显示代码上下部分? sublime text如何一个代码双屏显示代码上下部分 先显示2行实图 把想要分屏显示的文件,打开新窗口,然后再拖过去就可以了. 快捷操 ...

  8. SharePoint server 2016中文版导出list template,在另外一个环境不能显示

    SharePoint server 2016中文版导出list template,在另外一个环境不能显示,解决方案: $web = Get-SPWeb <url of web> $web. ...

  9. Qt for Android (三) 打开Android相册并选一个图片进行显示

    Qt for Android (三) 这两天弄了一下android相册的相关功能.还是花了挺长时间的,这里总结一下,避免以后再踩坑.同时也在这篇文章里面补齐一些android开发的基础支持 打开And ...

随机推荐

  1. Ios插件开发

    Ios插件开发 http://www.exmobi.cn/course/course_26.html Android插件开发 http://www.exmobi.cn/course/course_25 ...

  2. TIANKENG’s rice shop

    Problem Description TIANKENG managers a pan fried rice shop. There are n kinds of fried rice numbere ...

  3. Simple Membership 学习笔记

    第一步:新建项目后添加对WebMartix.Data 和 WebMatrix.WebData的引用第二步:在web.config中添加membership配置节第三步:修改Global.asax文件 ...

  4. [改善Java代码]自由选择字符串拼接方法

    对一个字符串拼接有三种方法:加号,contact方法,StringBuffer或者StringBuilder的append方法,其中加号是最常用的.其他两种方式偶尔会出现在一些开源项目中,那么这三者有 ...

  5. django 学习-11 Django模型数据模板呈现

    1.for author in Author.objects.all(): for book in author.book_set.all(): print   book 2.vim blog/vie ...

  6. C#算法基础之堆排序

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. Android环境搭建的步骤

    Android 环境搭建步骤 这里简单介绍一下学习Android之后如何搭建环境的问题 一.    在搭建环境之前,首先你要先下载Java JDK(根据系统位数选择下载是64位或32位的),Eclip ...

  8. SQL创建函数及应用

    用户自定义函数在SQL Server中,用户不仅可以使用标准的内置函数,也可以使用自己定义的函数来实现一些特殊的功能.用户自定义函数可以在企业管理器中创建,也可以使用CREATE FUNCTION 语 ...

  9. Contoso 大学 - 4 - 创建更加复杂的数据模型

    原文 Contoso 大学 - 4 - 创建更加复杂的数据模型 原文地址:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using- ...

  10. 大数据技术 —— MapReduce 简介

    本文为senlie原创,转载请保留此地址:http://www.cnblogs.com/senlie/ 1.概要很多计算在概念上很直观,但由于输入数据很大,为了能在合理的时间内完成,这些计算必须分布在 ...