我正在尝试在 three.js 中计算 3d 对象(.stl 网格对象)的“平面”n
面积。通过单击鼠标选择它。例如这个区域:
我们知道构成“平面”表面的所有“三角形”(因为它是.stl)都以相同的角度连接,如果与最后一个三角形相比角度发生变化,我们知道这个三角形不是“飞机”的一部分了。
所以知道这是我们试图计算的表面的属性,我们可以将它与某种形式的three.js Raycaster结合使用来选择和计算面积(通过将具有正确属性的三角形的所有面积相加) .
目前,我们不需要担心所选曲面的大小(例如,尝试在曲面上找到“平面”是无效的,但我们现在不需要担心)
我将如何尝试在three.js中找到区域和“平面”。或者更具体地说,我如何开始阅读 .stl 格式的“三角形”。
我当前代码的最小工作示例(包括工作 .stl 文件),它可以使用简单的实时服务器运行,例如在 VS Code 中使用Ritwick Dey 的插件,不需要额外的插件/库,因为它是“普通”HTML/ JS。
唯一的要求是我们在three.js中选择我们试图计算的点,并在选择时在three.js中为区域(选定的三角形)赋予不同的颜色。所需的任何其他计算都可以在某种后端(Python、Node.js 或其他任何东西)中完成,但我看不到在程序之间传输如此复杂数据的明显方法。
我的最小复制代码,请参阅我上面提到的 github 链接以获取我图片中使用的 .stl 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stackoverflow Example</title>
<link rel="stylesheet" type="text/css" href="../style/render.css">
</head>
<body>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/build/three.min.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/loaders/STLLoader.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/controls/OrbitControls.js"></script>
<script>
function init() {
// Setup some basic stuff
scene = new THREE.Scene();
scene.background = new THREE.Color(0xdddddd);
// Setup Camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 5000);
// Setup renerer and add to page
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Setup Camera Position
camera.rotation.y = 45 / 180 * Math.PI;
camera.position.x = 800;
camera.position.y = 100;
camera.position.z = 1000;
// Add Camera Control through orbit.js
let controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', renderer);
// Add some basic ambient lighting (Does light all parts equally and does not cast shadows)
hlight = new THREE.AmbientLight(0x404040, 20);
scene.add(hlight);
//Add some point lights to simulate real lights
light = new THREE.PointLight(0xc4c4c4, 1, 10000);
light.position.set(0, 300, 500);
scene.add(light);
light2 = new THREE.PointLight(0xc4c4c4, 1, 10000);
light2.position.set(500, 100, 0);
scene.add(light2);
light3 = new THREE.PointLight(0xc4c4c4, 1, 10000);
light3.position.set(0, 100, -500);
scene.add(light3);
light4 = new THREE.PointLight(0xc4c4c4, 1, 10000);
light4.position.set(-500, 300, 0);
scene.add(light4);
controls.update();
// Animation Script
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
// Setup GLTF Loader and load in obj
let loader = new THREE.STLLoader();
loader.load('example.stl', function (geometry) {
// console.log(gltf);
var material = new THREE.MeshPhongMaterial({
color: 0x171717,
shininess: 200
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.position.set(0, 0, 0);
scene.add(mesh);
renderer.render(scene, camera)
animate();
});
}
// Call method for starting init
init();
</script>
</body>
</html>
编辑:我的预期输出示例,但在 Fusion 360 中而不是 three.js(注意,原始文件是 .stl 但由于three.js 不允许查看部分,因此在后端将其转换为 .stl) .stl 文件中的“三角形”示例