简体   繁体   English

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

[英]three.js calculate STL file mesh volume

I have to calculate the volume of an STL file, I successfully got the sizes of the model with我必须计算 STL 文件的体积,我成功地得到了 model 的大小

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

but I just can't wrap my head around the concept of calculating it.但我就是无法理解计算它的概念。 I load the model with我用 model 加载

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

Can someone help me out and point me in the right direction?有人可以帮助我并指出正确的方向吗? I'm doing it with javascript.我用 javascript 来做。

You can find it with the algorithm from my comment.您可以使用我的评论中的算法找到它。

In the code snippet, the volume is computed without scaling.在代码片段中,体积是在没有缩放的情况下计算的。

Also, I've added a simple check that the algorithm calculates correctly by finding the volume of a hollow cylinder.此外,我添加了一个简单的检查,该算法通过查找空心圆柱体的体积来正确计算。 As THREE.STLLoader() returns a non-indexed geometry, I've casted the geometry of the cylinder to non-indexed too.由于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>

I'm also looking for a solution to this, And didn't have any implementation so far.我也在寻找解决方案,到目前为止还没有任何实现。

But extending from the voxelization idea like @manthrax mentioned.但是从@manthrax 提到的体素化想法延伸而来。

I think we can voxelized into the octree structure.我认为我们可以体素化成八叉树结构。

If the cube still intersects with multiple triangles then voxelized deeper octree.如果立方体仍然与多个三角形相交,则体素化更深的八叉树。

Until we reached the level of a single triangle cut through,直到我们达到一个三角形的水平,
Then we calculate the volume of the cube using this method:然后我们使用这种方法计算立方体的体积:

https://math.stackexchange.com/questions/454583/volume-of-cube-section-above-intersection-with-plane https://math.stackexchange.com/questions/454583/volume-of-cube-section-above-intersection-with-plane


After understood prisoner849's solution, This idea is no more valid compared to his solution.在了解了priner849的解决方案后,这个想法与他的解决方案相比已经不再有效。

This is a pretty tricky problem.这是一个相当棘手的问题。 One way is to decompose the object into a bunch of convex polyhedra and sum the volumes of those...一种方法是将对象分解成一堆凸多面体,然后将这些多面体的体积相加......

Another way is to voxelize it, and add up the voxels on the inside to get an estimate whos accuracy is limited by the resolution of your voxelization.另一种方法是对其进行体素化,并将内部的体素相加,以得到其准确性受体素化分辨率限制的估计值。

Edit: prisoner849 has a rad solution!编辑:囚犯849 有一个 rad 解决方案!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM