演示效果
threejs版本116
实现过程
1、利用box3获取模型边界
const box3 = new Box3();
box3.setFromObject(this.clipingModel); // 获取模型对象的边界
this.low = box3.min;
this.high = box3.max;
this.low_init.copy(this.low); // 保留一下初始值,好作为限制条件
this.high_init.copy(this.high);
this.group = new Group();
2、初始化剖切盒的 6 个剖切平面
private initPlanes() {
this.planes = [];
this.planes.push(
new Plane(new Vector3(0, -1, 0), this.high.y), // 上
new Plane(new Vector3(0, 1, 0), -this.low.y), // 下
new Plane(new Vector3(1, 0, 0), -this.low.x), // 左
new Plane(new Vector3(-1, 0, 0), this.high.x), // 右
new Plane(new Vector3(0, 0, -1), this.high.z), // 前
new Plane(new Vector3(0, 0, 1), -this.low.z), // 后
);
this.clipingModel.traverse((child: any) => {
if (['Mesh', 'LineSegments'].includes(child.type)) {
child.material.clippingPlanes = this.planes;
}
});
}
3、初始化剖切盒的顶点
this.vertices[0].set(this.low.x, this.high.y, this.low.z);
this.vertices[1].set(this.high.x, this.high.y, this.low.z);
this.vertices[2].set(this.high.x, this.high.y, this.high.z);
this.vertices[3].set(this.low.x, this.high.y, this.high.z);
this.vertices[4].set(this.low.x, this.low.y, this.low.z);
this.vertices[5].set(this.high.x, this.low.y, this.low.z);
this.vertices[6].set(this.high.x, this.low.y, this.high.z);
this.vertices[7].set(this.low.x, this.low.y, this.high.z);
4、定义拖拽面
initFaces() {
this.faces = [
new ClipFace('y2', [0, 1, 2, 3].map(i => ({ dirty: true, position: this.vertices![i] }))),// x+
new ClipFace('y1', [4, 7, 6, 5].map(i => ({ dirty: true, position: this.vertices![i] }))), // x-
new ClipFace('x1', [0, 3, 7, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// y+
new ClipFace('x2', [1, 5, 6, 2].map(i => ({ dirty: true, position: this.vertices![i] }))),// y-
new ClipFace('z2', [2, 6, 7, 3].map(i => ({ dirty: true, position: this.vertices![i] }))), // z-
new ClipFace('z1', [0, 4, 5, 1].map(i => ({ dirty: true, position: this.vertices![i] }))), // z+
]
this.faces.forEach(face => {
this.group.add(face)
})
}
5、定义边线
private initLines() {
this.lines = [
new ClipLine([0, 1].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive left 0
new ClipLine([1, 2].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive top 1
new ClipLine([2, 3].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive right 2
new ClipLine([3, 0].map(i => ({ dirty: true, position: this.vertices![i] }))),// positive bottom 3
new ClipLine([4, 5].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative left 4
new ClipLine([5, 6].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative top 5
new ClipLine([6, 7].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative right 6
new ClipLine([7, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// negative bottom 7
new ClipLine([1, 5].map(i => ({ dirty: true, position: this.vertices![i] }))),// left top 8
new ClipLine([0, 4].map(i => ({ dirty: true, position: this.vertices![i] }))),// left bottom 9
new ClipLine([2, 6].map(i => ({ dirty: true, position: this.vertices![i] }))),// right top 10
new ClipLine([3, 7].map(i => ({ dirty: true, position: this.vertices![i] }))),// right bottom 11
]
this.faces![0].lines = [0, 1, 2, 3].map(d => this.lines![d]) //y2
this.faces![1].lines = [4, 5, 6, 7].map(d => this.lines![d]) //y1
this.faces![2].lines = [3, 7, 9, 11].map(d => this.lines![d]) //x1
this.faces![3].lines = [1, 5, 8, 10].map(d => this.lines![d]) //x2
this.faces![4].lines = [2, 6, 10, 11].map(d => this.lines![d]) //z2
this.faces![5].lines = [0, 4, 8, 9].map(d => this.lines![d]) //z1
this.lines.forEach(line => {
this.group.add(line)
})
}
鼠标操作则为拖拽面后相应修改对应的剖切面,实现手动拖拽剖切
感兴趣的评论留言吧