You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在three.js中实现墙体开窗布尔运算并提取3D模型轮廓点?

Three.js 墙体布尔切割窗户的实现方案

核心思路验证:挤出窗户模型+CSG减运算完全可行

你提出的思路完全成立——先基于窗户外侧2D轮廓生成带厚度的3D窗户模型,再通过CSG(构造实体几何)减运算从墙体模型中减去窗户区域,这是Three.js生态里实现这类布尔切割最成熟的方案之一。

具体实现步骤

1. 创建2D窗户外轮廓并挤出为3D模型

  • 用THREE.Shape定义窗户的2D轮廓路径,示例为带圆角的矩形:
    const windowShape = new THREE.Shape();
    const width = 2;
    const height = 3;
    const radius = 0.2;
    // 绘制带圆角的矩形轮廓
    windowShape.moveTo(radius, 0);
    windowShape.lineTo(width - radius, 0);
    windowShape.quadraticCurveTo(width, 0, width, radius);
    windowShape.lineTo(width, height - radius);
    windowShape.quadraticCurveTo(width, height, width - radius, height);
    windowShape.lineTo(radius, height);
    windowShape.quadraticCurveTo(0, height, 0, height - radius);
    windowShape.lineTo(0, radius);
    windowShape.quadraticCurveTo(0, 0, radius, 0);
    
  • 用THREE.ExtrudeGeometry将2D轮廓挤出为3D模型,厚度需大于等于墙体厚度,确保能完全切穿:
    const extrudeSettings = {
      depth: 0.3, // 匹配墙体厚度
      bevelEnabled: false // 不需要倒角时关闭
    };
    const windowGeometry = new THREE.ExtrudeGeometry(windowShape, extrudeSettings);
    const windowMesh = new THREE.Mesh(windowGeometry);
    // 调整位置,让窗户模型对齐墙体待切割区域
    windowMesh.position.set(1, 1, 0);
    

2. 执行CSG布尔减运算

Three.js原生不支持CSG,需使用社区成熟库(如three-csg-ts,纯TS实现无额外依赖):

  • 将墙体和窗户模型转换为CSG对象:
    import { CSG } from 'three-csg-ts';
    
    const wallCSG = CSG.fromMesh(wallMesh);
    const windowCSG = CSG.fromMesh(windowMesh);
    
  • 执行减运算并转回Mesh:
    const subtractedCSG = wallCSG.subtract(windowCSG);
    const finalWallMesh = CSG.toMesh(subtractedCSG, wallMesh.matrix);
    finalWallMesh.material = wallMesh.material;
    

3. 提取2D/3D通用的轮廓面片与轮廓点

提取3D模型轮廓点

  • 可以直接从初始的windowShape提取2D顶点,再结合挤出方向扩展为3D轮廓点:
    // 获取2D轮廓原始顶点
    const shapePoints = windowShape.getPoints();
    // 转换为3D轮廓点(假设挤出方向为Z轴)
    const contour3DPoints = shapePoints.map(point => 
      new THREE.Vector3(point.x, point.y, 0).add(windowMesh.position)
    ).concat(shapePoints.map(point => 
      new THREE.Vector3(point.x, point.y, extrudeSettings.depth).add(windowMesh.position)
    ));
    

获取2D/3D通用轮廓面片

  • 2D场景直接用windowShape生成THREE.ShapeGeometry:
    const window2DGeometry = new THREE.ShapeGeometry(windowShape);
    const window2DMesh = new THREE.Mesh(window2DGeometry, new THREE.MeshBasicMaterial({ color: 0xff0000 }));
    
  • 3D轮廓面片可通过THREE.EdgesGeometry生成轮廓线框,或从挤出模型中提取侧面面:
    // 基于边缘生成3D轮廓线框
    const edgesGeometry = new THREE.EdgesGeometry(windowGeometry);
    const contourMesh = new THREE.LineSegments(edgesGeometry, new THREE.LineBasicMaterial({ color: 0x00ff00 }));
    

注意事项

  • 确保墙体和窗户模型的几何体已三角化,否则CSG运算可能出错,可提前用THREE.TriangulationUtils处理,或在模型导出时开启三角化选项;
  • 复杂轮廓会增加运算负担,尽量简化顶点数量;
  • 若仅需轮廓数据,也可跳过完整CSG运算,手动修改墙体几何体的顶点和面,但这种方法复杂度高,通用性远不如CSG方案。

内容的提问来源于stack exchange,提问作者drPapus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:33:15