# utils/html_generator.py
from pathlib import Path
from typing import Dict, Any, Optional
import json
from datetime import datetime
from utils.logger import get_logger
logger = get_logger(__name__)
class HTMLGenerator:
"""HTML文件生成器"""
def __init__(self, output_dir: str = "./html_output"):
self.output_dir = Path(output_dir)
self.output_dir.mkdir(exist_ok=True)
def generate_3d_viewer_html(
self,
geometry_data: Dict[str, Any],
stp_filename: str,
cavity_data: Optional[Dict[str, Any]] = None,
pointcloud_data: Optional[Dict[str, Any]] = None
) -> str:
"""生成3D可视化HTML页面"""
# 提取几何数据
bounding_box = geometry_data.get("bounding_box", {})
volume = geometry_data.get("volume", 0) or 0
surface_area = geometry_data.get("surface_area", 0) or 0
topology = geometry_data.get("topology", {})
center_of_mass = geometry_data.get("center_of_mass", [0, 0, 0])
cavity_html = ""
# 强制测试:无论cavity_data如何,都显示面板
if True:
# 安全获取嵌套数据
metadata = cavity_data.get("metadata", {}) if cavity_data else {}
manufacturing_info = cavity_data.get("manufacturing_info", {}) if cavity_data else {}
mold_cavities = cavity_data.get("mold_cavities", {}) if cavity_data else {}
cavity_key_info = mold_cavities.get("cavity_key_info", {})
geo_chars = cavity_key_info.get("geometric_characteristics", {})
logger.info(f"生成HTML - 收缩率: {metadata.get('shrinkage_rate')}")
logger.info(f"生成HTML - 型腔材料: {manufacturing_info.get('mold_material')}")
logger.info(f"生成HTML - 产品体积: {geo_chars.get('product_volume')}")
cavity_html = f"""
🔧 关键工艺参数
模具参数
收缩率:
{metadata.get("shrinkage_rate", "N/A")}
拔模角:
{metadata.get("draft_angle", "N/A")}°
分型线长度:
{manufacturing_info.get("parting_line_length", "N/A")}
几何特性
产品体积:
{geo_chars.get("product_volume", "N/A")}
产品重量:
{geo_chars.get("product_weight", "N/A")}
壁厚范围:
{geo_chars.get("wall_thickness_range", "N/A")}
制造要求
模仁材料:
{manufacturing_info.get("mold_material", "N/A")}
硬度:
{manufacturing_info.get("mold_hardness", "N/A")}
表面光洁度:
{manufacturing_info.get("surface_finish", "N/A")}
预估周期:
{manufacturing_info.get("estimated_cycle_time", "N/A")}
"""
else:
logger.warning(f"cavity_data 为空,无法显示工艺参数 - 文件: {stp_filename}")
cavity_html = ""
html_content = f"""
3D模具几何可视化 - {stp_filename}
{cavity_html}
模具几何信息
文件名:
{stp_filename}
体积:
{volume:.2f} mm³
表面积:
{surface_area:.2f} mm²
边界框:
{bounding_box.get('dimensions', [0, 0, 0])[0]:.1f} × {bounding_box.get('dimensions', [0, 0, 0])[1]:.1f} × {bounding_box.get('dimensions', [0, 0, 0])[2]:.1f} mm
面数:
{topology.get('faces', 0)}
边数:
{topology.get('edges', 0)}
顶点数:
{topology.get('vertices', 0)}
"""
return html_content
def save_html_file(self, html_content: str, filename: str) -> str:
"""保存HTML文件到磁盘"""
try:
file_path = self.output_dir / filename
with open(file_path, 'w', encoding='utf-8') as f:
f.write(html_content)
logger.info(f"HTML文件保存成功: {file_path}")
return str(file_path)
except Exception as e:
logger.error(f"保存HTML文件失败: {e}")
raise
def generate_and_save_visualization(
self,
geometry_data: Dict[str, Any],
stp_filename: str,
cavity_data: Optional[Dict[str, Any]] = None,
pointcloud_data: Optional[Dict[str, Any]] = None
) -> str:
"""生成并保存可视化HTML文件"""
try:
# 生成HTML内容
html_content = self.generate_3d_viewer_html(
geometry_data,
stp_filename,
cavity_data=cavity_data,
pointcloud_data=pointcloud_data
)
# 创建文件名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
safe_filename = stp_filename.replace('.', '_').replace(' ', '_')
html_filename = f"{safe_filename}_{timestamp}.html"
# 保存文件
file_path = self.save_html_file(html_content, html_filename)
return file_path
except Exception as e:
logger.error(f"生成可视化文件失败: {e}")
raise