分离模型

This commit is contained in:
Last
2025-05-06 15:58:04 +08:00
parent 5042099121
commit 986fd6f3e8
5 changed files with 216 additions and 17 deletions

102
objects/DEMO.js Normal file
View File

@@ -0,0 +1,102 @@
import * as THREE from 'three';
class HexNutGeometry extends THREE.BufferGeometry {
constructor(radius = 1, height = 0.5, holeRadius = 0.6) {
super();
this.parameters = {
radius: radius,
height: height,
holeRadius: holeRadius
};
this.buildGeometry();
}
buildGeometry() {
const radius = this.parameters.radius;
const height = this.parameters.height;
const holeRadius = this.parameters.holeRadius;
const vertices = [];
const indices = [];
// 1. 定义六边形的顶点 (顶部和底部)
for (let i = 0; i < 6; i++) {
const angle = (Math.PI * 2 / 6) * i;
const x = radius * Math.cos(angle);
const y = radius * Math.sin(angle);
// 顶部顶点
vertices.push(x, y, height / 2);
// 底部顶点
vertices.push(x, y, -height / 2);
}
// 内部孔洞的顶点 (顶部和底部)
for (let i = 0; i < 32; i++) { // 使用更多分段来近似圆形
const angle = (Math.PI * 2 / 32) * i;
const x = holeRadius * Math.cos(angle);
const y = holeRadius * Math.sin(angle);
// 顶部内侧顶点
vertices.push(x, y, height / 2); // 索引从 12 开始
// 底部内侧顶点
vertices.push(x, y, -height / 2); // 索引从 12 + 32 开始
}
// 2. 定义侧面
for (let i = 0; i < 6; i++) {
const currentTop = i * 2;
const nextTop = ((i + 1) % 6) * 2;
const currentBottom = i * 2 + 1;
const nextBottom = ((i + 1) % 6) * 2 + 1;
// 两个三角形组成一个侧面
indices.push(currentTop, nextTop, currentBottom);
indices.push(nextTop, nextBottom, currentBottom);
}
// 3. 定义顶部和底部 (六边形扇面 - 注意避开中心孔洞)
// 顶部
for (let i = 0; i < 6; i++) {
const current = i * 2;
const next = ((i + 1) % 6) * 2;
// 使用孔洞边缘的顶点来创建顶部面
const holeIndex1 = 12 + i * 2;
const holeIndex2 = 12 + ((i + 1) % 32) * 2; // 注意孔洞分段数
indices.push(current, next, holeIndex1);
indices.push(next, holeIndex2, holeIndex1);
}
// 底部
for (let i = 0; i < 6; i++) {
const current = i * 2 + 1;
const next = ((i + 1) % 6) * 2 + 1;
// 使用孔洞边缘的顶点来创建底面
const holeIndex1 = 12 + 64 + i * 2;
const holeIndex2 = 12 + 64 + ((i + 1) % 32) * 2; // 注意孔洞分段数
indices.push(current, holeIndex1, next);
indices.push(holeIndex1, holeIndex2, next);
}
// 4. 定义内部孔洞的侧面
for (let i = 0; i < 32; i++) {
const currentTop = 12 + i * 2;
const nextTop = 12 + ((i + 1) % 32) * 2;
const currentBottom = 12 + 64 + i * 2;
const nextBottom = 12 + 64 + ((i + 1) % 32) * 2;
indices.push(currentTop, nextTop, currentBottom);
indices.push(nextTop, nextBottom, currentBottom);
}
this.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
this.setIndex(indices);
this.computeVertexNormals();
}
}
export { HexNutGeometry };

47
objects/育苗盘.js Normal file
View File

@@ -0,0 +1,47 @@
import * as THREE from 'three';
import { SUBTRACTION, Brush, Evaluator } from 'three-bvh-csg';
class CSGHexNutGeometry extends THREE.BufferGeometry {
constructor(radius = 1, height = 0.5, holeRadius = 0.6) {
super();
this.parameters = {
radius: radius,
height: height,
holeRadius: holeRadius
};
this.buildGeometry();
}
buildGeometry() {
const radius = this.parameters.radius;
const height = this.parameters.height;
const holeRadius = this.parameters.holeRadius;
// 创建螺丝帽主体 (六棱柱)
const hexagonGeometry = new THREE.CylinderGeometry(radius, radius, height, 6, 1, false);
const hexagonMesh = new THREE.Mesh(hexagonGeometry); // 注意这里没有材质
const hexagonBrush = new Brush(hexagonMesh.geometry); // 使用 Brush 构造函数
// 创建内部的孔洞 (圆柱体)
const holeHeight = height + 0.1;
const holeGeometry = new THREE.CylinderGeometry(holeRadius, holeRadius, holeHeight, 32);
const holeMesh = new THREE.Mesh(holeGeometry); // 注意这里没有材质
const holeBrush = new Brush(holeMesh.geometry); // 使用 Brush 构造函数
// 执行布尔运算 (差集)
const evaluator = new Evaluator();
const resultBrush = evaluator.evaluate(hexagonBrush, holeBrush, SUBTRACTION);
// 将布尔运算结果转换为 BufferGeometry
const finalGeometry = resultBrush.geometry;
// 将结果的属性复制到当前的 BufferGeometry 实例
this.setAttribute('position', finalGeometry.getAttribute('position'));
this.setIndex(finalGeometry.getIndex());
this.computeVertexNormals(); // 计算法线
}
}
export { CSGHexNutGeometry };

35
objects/螺丝帽.js Normal file
View File

@@ -0,0 +1,35 @@
import * as THREE from 'three';
import { SUBTRACTION, Brush, Evaluator } from 'three-bvh-csg';
export class 六角螺丝帽 extends THREE.BufferGeometry {
constructor(radius = 1, height = 0.5, holeRadius = 0.6) {
super();
this.parameters = {
radius: radius,
height: height,
holeRadius: holeRadius
};
this.buildGeometry();
}
buildGeometry() {
const { radius, height, holeRadius } = this.parameters;
// 创建螺丝帽主体 (六棱柱)
const hexagonBrush = new Brush(new THREE.CylinderGeometry(radius, radius, height, 6));
// 创建内部的孔洞 (圆柱体)
const holeBrush = new Brush(new THREE.CylinderGeometry(holeRadius, holeRadius, height + 0.1, 128));
// 执行布尔运算 (差集)
const resultBrush = new Evaluator().evaluate(hexagonBrush, holeBrush, SUBTRACTION);
// 将布尔运算结果应用到当前 BufferGeometry
this.copy(resultBrush.geometry);
this.computeVertexNormals(); // 计算法线
}
}
export default { 六角螺丝帽 };