three.js计算STL文件网格体积

时间:2018-11-24 14:37:49

标签: javascript three.js

我必须计算一个STL文件的大小,我成功地获得了模型的大小

var box = new THREE.Box3().setFromObject( mesh );
var sizes = box.getSize();

但是我只是无法计算一下计算的概念。我用

加载模型
var loader = new THREE.STLLoader();
loader.load(stlFileURL, function ( geometry ) {});

有人可以帮我指出正确的方向吗?我正在使用javascript。

2 个答案:

答案 0 :(得分:2)

您可以通过我的评论中的算法找到它。

在代码段中,无需缩放即可计算体积。

此外,我还添加了一个简单的检查,即通过找到空心圆柱体的体积来确保算法正确计算。当THREE.STLLoader()返回未索引的几何图形时,我也已将圆柱体的几何图形转换为未索引的几何图形。

Related forum topic

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.setScalar(20);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x404040);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var loader = new THREE.STLLoader();
loader.load('https://threejs.org/examples/models/stl/binary/pr2_head_pan.stl', function(geometry) {

  var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    color: 0xff00ff,
    wireframe: true
  }));
  mesh.rotation.set(-Math.PI / 2, 0, 0);
  mesh.scale.setScalar(100);
  scene.add(mesh);

  console.log("stl volume is " + getVolume(geometry));
});

// check with known volume:
var hollowCylinderGeom = new THREE.LatheBufferGeometry([
  new THREE.Vector2(1, 0),
  new THREE.Vector2(2, 0),
  new THREE.Vector2(2, 2),
  new THREE.Vector2(1, 2),
  new THREE.Vector2(1, 0)
], 90).toNonIndexed();
console.log("pre-computed volume of a hollow cylinder (PI * (R^2 - r^2) * h): " + Math.PI * (Math.pow(2, 2) - Math.pow(1, 2)) * 2);
console.log("computed volume of a hollow cylinder: " + getVolume(hollowCylinderGeom));


function getVolume(geometry) {

  let position = geometry.attributes.position;
  let faces = position.count / 3;
  let sum = 0;
  let p1 = new THREE.Vector3(),
    p2 = new THREE.Vector3(),
    p3 = new THREE.Vector3();
  for (let i = 0; i < faces; i++) {
    p1.fromBufferAttribute(position, i * 3 + 0);
    p2.fromBufferAttribute(position, i * 3 + 1);
    p3.fromBufferAttribute(position, i * 3 + 2);
    sum += signedVolumeOfTriangle(p1, p2, p3);
  }
  return sum;

}

function signedVolumeOfTriangle(p1, p2, p3) {
  return p1.dot(p2.cross(p3)) / 6.0;
}

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
});
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

答案 1 :(得分:-1)

这是一个非常棘手的问题。一种方法是将对象分解为一堆凸多面体,然后将它们的体积求和。

另一种方法是对它进行体素化,然后将其内部的体素相加,以估算其准确性受到体素化分辨率的限制。

编辑:囚犯849有一个可靠的解决方案!