This commit is contained in:
cjw
2026-02-11 22:40:35 +08:00
parent 96000f3f11
commit 7b09eb3d89
1094 changed files with 242874 additions and 1 deletions
+102
View File
@@ -0,0 +1,102 @@
# src/core/mesh_generator.py
import logging
import numpy as np
from typing import Dict, List, Optional
import pyvista as pv
import trimesh
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
logger = logging.getLogger(__name__)
class MeshGenerator:
"""网格生成器 - 使用PyVista和Trimesh"""
def __init__(self, quality: str = "medium"):
self.quality_settings = {
"low": 0.5,
"medium": 0.1,
"high": 0.01
}
self.quality = self.quality_settings.get(quality, 0.1)
def generate_mesh_from_shape(self, shape, num_points: int = 10000) -> Dict:
"""从形状生成网格数据"""
try:
# 方法1: 使用PythonOCC生成网格
occ_mesh = self._generate_occ_mesh(shape)
# 方法2: 转换为PyVista网格
pv_mesh = self._convert_to_pyvista(occ_mesh)
# 方法3: 转换为Trimesh网格
tri_mesh = self._convert_to_trimesh(pv_mesh)
# 生成点云
pointcloud = self._generate_pointcloud(tri_mesh, num_points)
return {
"pyvista_mesh": pv_mesh,
"trimesh_mesh": tri_mesh,
"pointcloud": pointcloud
}
except Exception as e:
logger.error(f"网格生成失败: {e}")
raise
def _generate_occ_mesh(self, shape) -> any:
"""使用PythonOCC生成网格"""
mesh = BRepMesh_IncrementalMesh(shape, self.quality)
mesh.Perform()
return mesh
def _convert_to_pyvista(self, occ_mesh) -> pv.PolyData:
"""转换为PyVista网格"""
# 这里需要从OCC网格中提取顶点和面数据
# 简化实现 - 实际需要遍历OCC网格数据结构
try:
# 创建示例网格数据
cube = pv.Cube()
return cube
except Exception as e:
logger.warning(f"PyVista转换失败,使用备用方法: {e}")
return self._create_sample_mesh()
def _convert_to_trimesh(self, pv_mesh) -> trimesh.Trimesh:
"""转换为Trimesh网格"""
try:
# 从PyVista转换
vertices = pv_mesh.points
faces = pv_mesh.faces.reshape(-1, 4)[:, 1:4] # 假设三角形网格
return trimesh.Trimesh(vertices=vertices, faces=faces)
except Exception as e:
logger.warning(f"Trimesh转换失败: {e}")
return self._create_sample_trimesh()
def _generate_pointcloud(self, mesh: trimesh.Trimesh, num_points: int) -> Dict:
"""从网格生成点云"""
try:
# 均匀采样点云
points, face_indices = trimesh.sample.sample_surface(mesh, num_points)
# 计算法向量
normals = mesh.face_normals[face_indices]
return {
"points": points.tolist(),
"normals": normals.tolist(),
"count": len(points)
}
except Exception as e:
logger.error(f"点云生成失败: {e}")
raise
def _create_sample_mesh(self) -> pv.PolyData:
"""创建示例网格(备用)"""
return pv.Cube()
def _create_sample_trimesh(self) -> trimesh.Trimesh:
"""创建示例Trimesh(备用)"""
return trimesh.creation.box([100, 80, 50])