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

已知闭合曲面网格的单元边界点,如何提取子网格并计算单元面积?

基于边界点分割闭合心脏曲面网格并计算单元面积

核心思路

闭合曲面被闭合边界环分割为两个拓扑独立的区域,直接删除边界点会破坏网格拓扑导致面积计算失真,标准方案是通过边界环构建闭合切割体,利用布尔分割得到两个子网格,再提取目标单元。以下是Trimesh和Open3D的具体实现:


Trimesh 实现方案

import trimesh

# 加载闭合心脏网格(支持stl/obj等格式)
mesh = trimesh.load("heart_mesh.stl")

# 已知的闭合边界点索引列表(需保证首尾点相连,无交叉)
boundary_indices = [10, 25, 42, 67, 10]  # 替换为实际索引
boundary_points = mesh.vertices[boundary_indices]

# 生成闭合多边形路径
polygon = trimesh.load_path(boundary_points)

# 拉伸多边形生成薄闭合切割体(厚度需足够穿透原网格)
cutting_mesh = polygon.extrude(height=0.2, cap=True)

# 预处理原网格,修复拓扑问题
mesh.remove_duplicate_faces()
mesh.fill_holes()
cutting_mesh.remove_duplicate_faces()

# 执行网格分割
split_result = mesh.split(cutting_mesh)
sub_meshes = list(split_result)

# 提取目标单元(示例选面积较小的,可按需调整)
target_mesh = min(sub_meshes, key=lambda m: m.area)

# 计算单元面积
unit_area = target_mesh.area
print(f"目标单元面积: {unit_area}")

注意事项

  • 若边界点不共面,先通过trimesh.projection.project_to_plane将点投影到主成分平面,再生成切割多边形
  • 布尔分割失败时,用mesh.is_watertight验证闭合性,mesh.remove_non_manifold_edges()修复非流形边

Open3D 实现方案

import open3d as o3d
import numpy as np
from scipy.spatial import Delaunay

# 加载闭合心脏网格
mesh = o3d.io.read_triangle_mesh("heart_mesh.stl")

# 已知闭合边界点索引
boundary_indices = [10, 25, 42, 67, 10]  # 替换为实际索引
boundary_points = np.asarray(mesh.vertices)[boundary_indices]

# 计算边界点所在平面的法向量与原点
plane_vec1 = boundary_points[1] - boundary_points[0]
plane_vec2 = boundary_points[2] - boundary_points[0]
plane_normal = np.cross(plane_vec1, plane_vec2)
plane_normal /= np.linalg.norm(plane_normal)
plane_origin = boundary_points[0]

# 投影边界点到平面,保证共面
projected_points = []
for p in boundary_points:
    dist = np.dot(p - plane_origin, plane_normal)
    projected_points.append(p - dist * plane_normal)
projected_points = np.array(projected_points)

# 对投影点做Delaunay三角化,生成切割面网格
tri = Delaunay(projected_points)
cutting_mesh = o3d.geometry.TriangleMesh()
cutting_mesh.vertices = o3d.utility.Vector3dVector(projected_points)
cutting_mesh.triangles = o3d.utility.Vector3iVector(tri.simplices)

# 拉伸切割面为闭合体
cutting_mesh = cutting_mesh.extrude((0, 0, 0.2))

# 网格预处理,修复拓扑问题
mesh.remove_duplicated_vertices()
mesh.remove_duplicated_triangles()
mesh.remove_non_manifold_edges()
cutting_mesh.remove_duplicated_vertices()
cutting_mesh.remove_duplicated_triangles()
cutting_mesh.remove_non_manifold_edges()

# 执行布尔切割
split_result = mesh.boolean_cut(cutting_mesh)

# 提取目标单元并计算面积
target_mesh = min(split_result, key=lambda m: m.get_surface_area())
unit_area = target_mesh.get_surface_area()
print(f"目标单元面积: {unit_area}")

注意事项

  • 若边界环复杂,用o3d.geometry.LineSet可视化边界,验证闭合性与连续性
  • 布尔运算依赖网格的watertight属性,mesh.is_watertight()可检查,不满足则用mesh.fill_holes()修复

关键验证步骤

  1. 边界环验证:确保边界索引构成单一闭合环,无分支或交叉,可通过绘制边界线确认
  2. 网格质量验证:修复所有非流形拓扑、重复元素,保证网格是watertight的闭合曲面
  3. 分割结果验证:可视化两个子网格,确认目标单元与预期区域一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:15:36