模型大多是不规则的物体,无法用传统数学公式去计算,这里采用Three.js(针对3D模型展示技术)。
本文的例子是一个3D模型展示的例子,在此基础上二次开发计算体积与尺寸。
当前three.js 版本为92。
Title
html, body {
margin: 0;
height: 100%;
}
canvas {
display: block;
}
//console.log(THREE.REVISION);
var div_canvas = document.getElementById(“div_canvas”);
var w = 400;
var h = 396;
var renderer;
function initRender() {
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(w, h);
//告诉渲染器需要阴影效果
renderer.setClearColor(0xffffff);
div_canvas.appendChild(renderer.domElement);
}
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45, w/h, 0.1, 1000);
camera.position.set(0, 40, 50);
camera.lookAt(new THREE.Vector3(0,0,0));
}
var scene;
function initScene() {
scene = new THREE.Scene();
}
//初始化dat.GUI简化试验流程
var gui;
function initGui() {
//声明一个保存需求修改的相关数据的对象
gui = {
};
var datGui = new dat.GUI();
//将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
}
var light;
function initLight() {
scene.add(new THREE.AmbientLight(0x444444));
light = new THREE.PointLight(0xffffff);
light.position.set(0,50,50);
//告诉平行光需要开启阴影投射
light.castShadow = true;
scene.add(light);
}
function initModel() {
//辅助工具
var helper = new THREE.AxesHelper(50);
scene.add(helper);
var loader = new THREE.STLLoader();
loader.load(“stl/xsldq.stl”, function (geometry) {
// loader.load(“stl/bar+1.stl”, function (geometry) {
//loader.load(“stl/4.9.stl”, function (geometry) {
// loader.load(“stl/Complete_Assembly.STL”, function (geometry) {
if (geometry instanceof THREE.BufferGeometry) {
geometry = new THREE.Geometry().fromBufferGeometry(geometry);
}
//尺寸
geometry.computeBoundingBox();
var volume = 0;
for (var f = 0, fl = geometry.faces.length; f < fl; f++) {
var face = geometry.faces[f];
var vA = geometry.vertices[face.a];
var vB = geometry.vertices[face.b];
var vC = geometry.vertices[face.c];
var x1 = vA.x,
x2 = vB.x,
x3 = vC.x;
var y1 = vA.y,
y2 = vB.y,
y3 = vC.y;
var z1 = vA.z,
z2 = vB.z,
z3 = vC.z;
V = (-x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 – x1 * y3 * z2 – x2 * y1 * z3 + x1 * y2 * z3) / 6;
volume += V;
}
console.log(‘体积:’,volume.toFixed(2)+’mm3′);
//创建纹理
var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
var mesh = new THREE.Mesh(geometry, mat);
//console.log(mesh);
mesh.rotation.x = -0.5 * Math.PI; //将模型摆正
mesh.scale.set(0.5, 0.5, 0.5); //缩放
geometry.center(); //居中显示
scene.add(mesh);
var boundingBox = geometry.boundingBox;
console.log(‘x_y_z:’, boundingBox.max);//实际长宽高,取2x,2y,2z。
});
}
//初始化性能插件
var stats;
function initStats() {
stats = new Stats();
div_canvas.appendChild(stats.dom);
}
//用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
// 如果使用animate方法时,将此函数删除
//controls.addEventListener( ‘change’, render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
controls.enableZoom = true;
//是否自动旋转
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
//设置相机距离原点的最远距离
controls.minDistance = 1;
//设置相机距离原点的最远距离
controls.maxDistance = 200;
//是否开启右键拖拽
controls.enablePan = true;
}
function render() {
renderer.render( scene, camera );
}
//窗口变动触发的函数
function onWindowResize() {
camera.aspect = w / h;
camera.updateProjectionMatrix();
render();
renderer.setSize( w, h );
}
function animate() {
//更新控制器
render();
//更新性能插件
stats.update();
controls.update();
requestAnimationFrame(animate);
}
function draw() {
initGui();
initRender();
initScene();
initCamera();
initLight();
initModel();
initControls();
initStats();
animate();
window.onresize = onWindowResize;
}
体积与尺寸console.log出来了。实际尺寸取2x,2y,2z,对比信息可参照魔猴网打印页面 魔猴网。
源码链接: https://pan.baidu.com/s/1DLFvabggHcBXnV5dgqjhdw 密码: vtee