CreoOtkPluging/GeometryAnalyzer.cpp
sladro d5accfe24a 修复几何复杂度分析重复零件问题 - 添加装配体遍历去重机制
核心改动:
- 在CollectAssemblyParts方法中添加std::set<string>去重逻辑
- 基于零件文件名进行重复检测,确保每个零件只被分析一次
- 递归遍历装配体时正确传递去重集合
- 解决标准件等重复使用零件的重复分析问题

技术实现:
- 修改GeometryAnalyzer.h: CollectAssemblyParts添加processed_parts参数
- 修改GeometryAnalyzer.cpp: 在CollectAllParts中创建去重集合
- 在CollectAssemblyParts中检查零件是否已处理,避免重复添加

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-28 16:58:15 +08:00

1313 lines
48 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "GeometryAnalyzer.h"
#include "CreoManager.h"
#include <sstream>
#include <iomanip>
#include <chrono>
#include <ctime>
#include <windows.h>
// 防止Windows宏冲突
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#ifdef GetMessage
#undef GetMessage
#endif
// 单例实现
GeometryAnalyzer& GeometryAnalyzer::Instance() {
static GeometryAnalyzer instance;
return instance;
}
GeometryAnalyzer::GeometryAnalyzer() {
}
// 主要分析方法
GeometryComplexityResult GeometryAnalyzer::AnalyzeGeometryComplexity(const GeometryComplexityRequest& request) {
GeometryComplexityResult result;
// 清理过期缓存,提升性能
ClearExpiredCache();
try {
result.analysis_time = GetCurrentTimeStringISO();
SessionInfo session_info = GetSessionInfo();
if (!session_info.is_valid) {
result.success = false;
result.error_message = "Creo session not available or invalid";
return result;
}
pfcModel_ptr current_model = session_info.session->GetCurrentModel();
if (!current_model) {
result.success = false;
result.error_message = "No active model in Creo session";
return result;
}
std::vector<std::pair<pfcModel_ptr, std::string>> all_parts;
// 判断是装配体还是零件
pfcModelType model_type = current_model->GetType();
if (model_type == pfcMDL_ASSEMBLY) {
// 装配体:收集所有零件
std::string base_name = XStringToString(current_model->GetFileName());
CollectAllParts(current_model, base_name, all_parts);
} else if (model_type == pfcMDL_PART) {
// 单个零件:直接分析
std::string part_name = XStringToString(current_model->GetFileName());
all_parts.push_back(std::make_pair(current_model, part_name));
} else {
result.success = false;
result.error_message = "Unsupported model type. Only parts and assemblies are supported.";
return result;
}
result.total_parts_analyzed = (int)all_parts.size();
if (all_parts.empty()) {
result.success = true;
result.message = "No parts found for analysis";
return result;
}
// 分析每个零件的复杂度
std::vector<GeometryComplexityInfo> all_complexity_info;
double total_complexity = 0.0;
for (const auto& part_pair : all_parts) {
pfcModel_ptr model = part_pair.first;
const std::string& path = part_pair.second;
if (IsValidPart(model)) {
GeometryComplexityInfo part_info = AnalyzePart(model, path);
if (part_info.complexity_score >= request.complexity_threshold) {
all_complexity_info.push_back(part_info);
total_complexity += part_info.complexity_score;
}
}
}
// 计算统计信息
if (!all_complexity_info.empty()) {
result.average_complexity = total_complexity / all_complexity_info.size();
result.max_complexity = all_complexity_info.empty() ? 0.0 :
(*(std::max_element)(all_complexity_info.begin(), all_complexity_info.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.complexity_score < b.complexity_score;
})).complexity_score;
result.min_complexity = all_complexity_info.empty() ? 0.0 :
(*(std::min_element)(all_complexity_info.begin(), all_complexity_info.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.complexity_score < b.complexity_score;
})).complexity_score;
}
// 多目标排序
MultiObjectiveSort(all_complexity_info, request);
// 限制返回数量
int max_results = (std::min)(request.max_results, (int)all_complexity_info.size());
result.parts.assign(all_complexity_info.begin(), all_complexity_info.begin() + max_results);
result.success = true;
result.message = "Geometry complexity analysis completed successfully";
} catch (pfcXToolkitError& e) {
result.success = false;
result.error_message = "OTK error during geometry analysis";
} catch (const std::exception& e) {
result.success = false;
result.error_message = "Standard exception during geometry analysis: " + std::string(e.what());
} catch (...) {
result.success = false;
result.error_message = "Unknown error during geometry complexity analysis";
}
return result;
}
// 分析单个零件的复杂度 - 支持缓存
GeometryComplexityInfo GeometryAnalyzer::AnalyzePart(pfcModel_ptr model, const std::string& part_path) {
GeometryComplexityInfo info;
if (!model) return info;
// 生成缓存键并检查缓存
std::string cache_key = GenerateCacheKey(model);
if (IsCacheValid(cache_key, model)) {
// 返回缓存的结果
return complexity_cache[cache_key].complexity_info;
}
info.part_name = XStringToString(model->GetFileName());
info.part_path = part_path;
info.file_size = GetModelFileSize(model);
// 特征分析(优化版本)
info.feature_count = CountAllFeatures(model);
info.hole_count = CountHoles(model);
info.fillet_count = CountFillets(model);
info.pattern_count = CountPatterns(model);
info.sketch_count = CountSketches(model);
// 扩展特征类型分析 - 高复杂度特征统计
info.chamfer_count = CountChamfers(model);
info.shell_count = CountShellFeatures(model);
info.draft_count = CountDraftFeatures(model);
info.cut_count = CountCutFeatures(model);
info.protrusion_count = CountProtrusionFeatures(model);
// 更新总特征计数(包含所有特征类型)
info.feature_count += (info.chamfer_count + info.shell_count + info.draft_count +
info.cut_count + info.protrusion_count);
// 几何计算
info.volume = CalculateVolume(model);
info.surface_area = CalculateSurfaceArea(model);
info.bounding_box_volume = CalculateBoundingBoxVolume(model);
info.surface_count = CountSurfaces(model);
info.curved_surface_count = CountCurvedSurfaces(model);
// 计算多维复杂度评分
info.geometric_complexity = CalculateGeometricComplexity(info);
info.manufacturing_complexity = CalculateManufacturingComplexity(info);
info.assembly_complexity = CalculateAssemblyComplexity(info);
info.analysis_complexity = CalculateAnalysisComplexity(info);
// 应用上下文调整
ApplyContextualAdjustments(info);
// 计算总体复杂度评分(加权平均,包含上下文调整)
info.complexity_score = (info.geometric_complexity * 0.3 +
info.manufacturing_complexity * 0.4 +
info.assembly_complexity * 0.2 +
info.analysis_complexity * 0.1);
info.complexity_level = DetermineComplexityLevel(info.complexity_score);
info.complexity_factors = AnalyzeComplexityFactors(info);
// 保存结果到缓存
CacheEntry cache_entry;
cache_entry.complexity_info = info;
cache_entry.timestamp = std::time(nullptr);
try {
// 尝试获取模型修改时间作为缓存验证
cache_entry.model_modification_time = XStringToString(model->GetFileName());
} catch (...) {
cache_entry.model_modification_time = "";
}
complexity_cache[cache_key] = cache_entry;
return info;
}
// 复杂度评分算法
double GeometryAnalyzer::CalculateComplexityScore(const GeometryComplexityInfo& info) {
double score = 0.0;
// 基础特征权重 - 根据工程复杂度经验调整
score += info.feature_count * 1.5; // 降低基础权重,避免简单特征过度影响
// 表面复杂度权重 - 更精准的几何复杂度评估
score += info.surface_count * 1.0; // 平面数量基础权重
score += info.curved_surface_count * 3.2; // 曲面是高复杂度因素
// 特征复杂度权重 - 基于制造和设计复杂度重新校准
score += info.hole_count * 2.8; // 孔特征复杂但可控
score += info.pattern_count * 4.0; // 降低阵列权重,避免过度惩罚
score += info.fillet_count * 1.5; // 圆角是常见特征,降低权重
score += info.sketch_count * 0.8; // 草图复杂度更多体现在其他特征中
// 扩展特征类型权重 - 高复杂度特征
score += info.chamfer_count * 2.0; // 倒角需要额外加工步骤
score += info.shell_count * 3.5; // 壳体特征高度复杂
score += info.draft_count * 2.2; // 拔模角度控制复杂
score += info.cut_count * 1.8; // 切除特征中等复杂度
score += info.protrusion_count * 1.2; // 凸台特征基础复杂度
// 几何复杂度调整 - 更细致的结构复杂度评估
if (info.volume > 0 && info.bounding_box_volume > 0) {
double volume_ratio = info.volume / info.bounding_box_volume;
// 分层评估空心程度对复杂度的影响
if (volume_ratio < 0.3) {
score += 8.0; // 高度空心结构
} else if (volume_ratio < 0.5) {
score += 5.0; // 中等空心结构
} else if (volume_ratio < 0.7) {
score += 2.0; // 轻微空心结构
}
}
// 表面积体积比 - 更精确的几何复杂度指标
if (info.volume > 0 && info.surface_area > 0) {
double surface_to_volume_ratio = info.surface_area / std::pow(info.volume, 2.0/3.0);
// 基于表面积比例的复杂度分级
if (surface_to_volume_ratio > 8.0) {
score += 6.0; // 极高表面复杂度
} else if (surface_to_volume_ratio > 6.0) {
score += 4.0; // 高表面复杂度
} else if (surface_to_volume_ratio > 4.5) {
score += 2.0; // 中等表面复杂度
}
}
return (std::min)(score, 100.0); // 限制最高分为100
}
// 复杂度等级判定 - 基于实际工程经验重新校准
std::string GeometryAnalyzer::DetermineComplexityLevel(double score) {
// 重新校准的复杂度分级阈值,更符合实际制造和设计复杂度
if (score < 12.0) return "Very Low"; // 简单几何体,如立方体、圆柱体
else if (score < 25.0) return "Low"; // 基本特征组合,少量圆角和孔
else if (score < 45.0) return "Medium"; // 中等复杂度,多特征但结构清晰
else if (score < 65.0) return "High"; // 高复杂度,包含曲面、阵列等
else if (score < 85.0) return "Very High"; // 很高复杂度,多种高级特征
else return "Extremely High"; // 极高复杂度,制造困难
}
// 分析复杂度影响因素(优化版本)
std::vector<std::string> GeometryAnalyzer::AnalyzeComplexityFactors(const GeometryComplexityInfo& info) {
std::vector<std::string> factors;
// 基础特征复杂度判断 - 调整阈值更符合实际
if (info.feature_count > 30) {
factors.push_back("Very high feature count (" + std::to_string(info.feature_count) + " features)");
} else if (info.feature_count > 20) {
factors.push_back("High feature count (" + std::to_string(info.feature_count) + " features)");
}
// 几何表面复杂度 - 降低曲面阈值
if (info.curved_surface_count > 5) {
factors.push_back("Complex curved surfaces (" + std::to_string(info.curved_surface_count) + ")");
}
// 特征复杂度分析 - 重新校准阈值
if (info.hole_count > 5) {
factors.push_back("Many hole features (" + std::to_string(info.hole_count) + ")");
} else if (info.hole_count > 2) {
factors.push_back("Multiple hole features (" + std::to_string(info.hole_count) + ")");
}
if (info.pattern_count > 0) {
factors.push_back("Pattern/Array features (" + std::to_string(info.pattern_count) + ")");
}
if (info.fillet_count > 15) {
factors.push_back("Excessive fillet/round features (" + std::to_string(info.fillet_count) + ")");
} else if (info.fillet_count > 8) {
factors.push_back("Many fillet/round features (" + std::to_string(info.fillet_count) + ")");
}
if (info.sketch_count > 10) {
factors.push_back("Complex sketch-based geometry (" + std::to_string(info.sketch_count) + ")");
}
// 扩展特征复杂度分析
if (info.chamfer_count > 2) {
factors.push_back("Multiple chamfer features (" + std::to_string(info.chamfer_count) + ")");
}
if (info.shell_count > 0) {
factors.push_back("Shell/Thin-wall features (" + std::to_string(info.shell_count) + ")");
}
if (info.draft_count > 1) {
factors.push_back("Draft angle features (" + std::to_string(info.draft_count) + ")");
}
if (info.cut_count > 5) {
factors.push_back("Many cut/remove features (" + std::to_string(info.cut_count) + ")");
}
if (info.protrusion_count > 3) {
factors.push_back("Multiple protrusion features (" + std::to_string(info.protrusion_count) + ")");
}
// 几何复杂度分析
if (info.volume > 0 && info.bounding_box_volume > 0) {
double volume_ratio = info.volume / info.bounding_box_volume;
if (volume_ratio < 0.4) {
factors.push_back("Complex internal structure (solid ratio: " +
std::to_string((int)(volume_ratio * 100)) + "%)");
}
}
// 表面积与体积比分析
if (info.volume > 0 && info.surface_area > 0) {
double surface_to_volume_ratio = info.surface_area / std::pow(info.volume, 2.0/3.0);
if (surface_to_volume_ratio > 5.5) {
factors.push_back("High surface-to-volume ratio (complex geometry)");
}
}
// 默认情况处理
if (factors.empty()) {
if (info.feature_count > 10) {
factors.push_back("Moderate geometric complexity");
} else {
factors.push_back("Simple geometric structure");
}
}
return factors;
}
// 特征统计方法
int GeometryAnalyzer::CountAllFeatures(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 获取所有特征
pfcFeatures_ptr features = solid->ListFeaturesByType(xfalse);
return features ? features->getarraysize() : 0;
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountHoles(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用精确的pfcFEATTYPE_HOLE API
pfcFeatures_ptr hole_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_HOLE);
if (!hole_features) return 0;
return hole_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountFillets(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用精确的pfcFEATTYPE_ROUND API
pfcFeatures_ptr round_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_ROUND);
if (!round_features) return 0;
return round_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountPatterns(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用精确的pfcFEATTYPE_PATTERN API
pfcFeatures_ptr pattern_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_PATTERN);
if (!pattern_features) return 0;
return pattern_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountSketches(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 估算草图数量(草图通常作为特征的基础)
pfcFeatures_ptr features = solid->ListFeaturesByType(xfalse);
if (!features) return 0;
int total_features = features->getarraysize();
return total_features > 3 ? total_features / 3 : 1;
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
// 新增的精确特征计数方法
int GeometryAnalyzer::CountChamfers(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用pfcFEATTYPE_CHAMFER API
pfcFeatures_ptr chamfer_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_CHAMFER);
if (!chamfer_features) return 0;
return chamfer_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountShellFeatures(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用pfcFEATTYPE_SHELL API
pfcFeatures_ptr shell_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_SHELL);
if (!shell_features) return 0;
return shell_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountDraftFeatures(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用pfcFEATTYPE_DRAFT API
pfcFeatures_ptr draft_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_DRAFT);
if (!draft_features) return 0;
return draft_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountCutFeatures(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用pfcFEATTYPE_CUT API
pfcFeatures_ptr cut_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_CUT);
if (!cut_features) return 0;
return cut_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountProtrusionFeatures(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用pfcFEATTYPE_PROTRUSION API
pfcFeatures_ptr protrusion_features = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_PROTRUSION);
if (!protrusion_features) return 0;
return protrusion_features->getarraysize();
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
// 几何计算方法
double GeometryAnalyzer::CalculateVolume(pfcModel_ptr model) {
if (!model) return 0.0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0.0;
// 确保模型已重生成,获取准确几何信息
solid->Regenerate(xfalse);
// 使用高精度质量属性计算
pfcMassProperty_ptr mass_props = solid->GetMassProperty(nullptr);
if (mass_props) {
double volume = mass_props->GetVolume();
// 验证体积合理性(避免极值)
if (volume > 1e-12 && volume < 1e12) {
return volume;
}
}
return 0.0;
} catch (pfcXToolkitError&) {
return 0.0;
} catch (...) {
return 0.0;
}
}
double GeometryAnalyzer::CalculateSurfaceArea(pfcModel_ptr model) {
if (!model) return 0.0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0.0;
// 确保模型已重生成
solid->Regenerate(xfalse);
// 方法1使用质量属性API
pfcMassProperty_ptr mass_props = solid->GetMassProperty(nullptr);
if (mass_props) {
double surface_area = mass_props->GetSurfaceArea();
// 验证表面积合理性
if (surface_area > 1e-8 && surface_area < 1e10) {
return surface_area;
}
}
// 备用方法:如果主要方法失败,返回基于特征的估算值
try {
pfcFeatures_ptr features = solid->ListFeaturesByType(xfalse);
if (features && features->getarraysize() > 0) {
// 基于特征数量估算表面积(非精确值,仅作为指示)
int feature_count = features->getarraysize();
return (double)(feature_count * 10.0); // 简单估算
}
} catch (...) {
// 忽略此方法的异常
}
return 0.0;
} catch (pfcXToolkitError&) {
return 0.0;
} catch (...) {
return 0.0;
}
}
double GeometryAnalyzer::CalculateBoundingBoxVolume(pfcModel_ptr model) {
if (!model) return 0.0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0.0;
// 使用优化的包络盒计算
pfcOutline3D_ptr outline = solid->EvalOutline(nullptr, nullptr);
if (!outline) {
// 如果无法获取轮廓,尝试使用几何轮廓
outline = solid->GetGeomOutline();
}
if (outline) {
pfcPoint3D_ptr min_point = outline->get(0);
pfcPoint3D_ptr max_point = outline->get(1);
if (min_point && max_point) {
double dx = (std::abs)(max_point->get(0) - min_point->get(0));
double dy = (std::abs)(max_point->get(1) - min_point->get(1));
double dz = (std::abs)(max_point->get(2) - min_point->get(2));
// 防止负值或无效值
if (dx > 0.0 && dy > 0.0 && dz > 0.0) {
return dx * dy * dz;
}
}
}
return 0.0;
} catch (pfcXToolkitError&) {
return 0.0;
} catch (...) {
return 0.0;
}
}
int GeometryAnalyzer::CountSurfaces(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 使用更精确的算法:基于不同特征类型估算表面数
int total_surfaces = 0;
// 基础特征表面计算
pfcFeatures_ptr all_features = solid->ListFeaturesByType(xfalse);
if (all_features) {
int base_features = all_features->getarraysize();
total_surfaces += base_features * 2; // 基础表面数
}
// 高表面复杂度特征
pfcFeatures_ptr holes = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_HOLE);
if (holes) total_surfaces += holes->getarraysize() * 3; // 孔产生更多表面
pfcFeatures_ptr rounds = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_ROUND);
if (rounds) total_surfaces += rounds->getarraysize() * 2; // 圆角增加表面
pfcFeatures_ptr chamfers = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_CHAMFER);
if (chamfers) total_surfaces += chamfers->getarraysize() * 1; // 倒角表面
return total_surfaces > 0 ? total_surfaces : 1;
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
int GeometryAnalyzer::CountCurvedSurfaces(pfcModel_ptr model) {
if (!model) return 0;
try {
pfcSolid_ptr solid = pfcSolid::cast(model);
if (!solid) return 0;
// 更精确的曲面计算:基于特定特征类型
int curved_surfaces = 0;
// 圆角特征通常产生曲面
pfcFeatures_ptr rounds = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_ROUND);
if (rounds) curved_surfaces += rounds->getarraysize() * 2;
// 孔特征的内部曲面
pfcFeatures_ptr holes = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_HOLE);
if (holes) curved_surfaces += holes->getarraysize() * 1;
// 拉伸和切除特征可能包含曲面
pfcFeatures_ptr protrusions = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_PROTRUSION);
if (protrusions) curved_surfaces += (int)(protrusions->getarraysize() * 0.4);
pfcFeatures_ptr cuts = solid->ListFeaturesByType(xfalse, pfcFEATTYPE_CUT);
if (cuts) curved_surfaces += (int)(cuts->getarraysize() * 0.3);
// 其他特征的曲面贡献
int total_surface_count = CountSurfaces(model);
curved_surfaces += (int)(total_surface_count * 0.25); // 基础曲面比例
return curved_surfaces;
} catch (pfcXToolkitError&) {
return 0;
} catch (...) {
return 0;
}
}
// 装配体遍历方法
void GeometryAnalyzer::CollectAllParts(pfcModel_ptr model, const std::string& base_path,
std::vector<std::pair<pfcModel_ptr, std::string>>& parts) {
if (!model) return;
pfcModelType model_type = model->GetType();
if (model_type == pfcMDL_PART) {
// 零件:直接添加到列表
parts.push_back(std::make_pair(model, base_path));
} else if (model_type == pfcMDL_ASSEMBLY) {
// 装配体:递归遍历所有组件,使用去重集合
std::set<std::string> processed_parts;
wfcWAssembly_ptr assembly = wfcWAssembly::cast(model);
if (assembly) {
CollectAssemblyParts(assembly, base_path, parts, processed_parts);
}
}
}
void GeometryAnalyzer::CollectAssemblyParts(wfcWAssembly_ptr assembly, const std::string& base_path,
std::vector<std::pair<pfcModel_ptr, std::string>>& parts,
std::set<std::string>& processed_parts) {
if (!assembly) return;
try {
pfcFeatures_ptr features = assembly->ListFeaturesByType(xfalse, pfcFEATTYPE_COMPONENT);
if (!features) return;
for (int i = 0; i < features->getarraysize(); i++) {
pfcFeature_ptr feature = features->get(i);
if (!feature) continue;
pfcComponentFeat_ptr comp_feat = pfcComponentFeat::cast(feature);
if (!comp_feat) continue;
try {
pfcModelDescriptor_ptr model_descr = comp_feat->GetModelDescr();
if (!model_descr) continue;
// 使用RetrieveModel获取模型
pfcSession_ptr session = pfcGetCurrentSession();
if (!session) continue;
pfcModel_ptr comp_model = session->GetModelFromDescr(model_descr);
if (!comp_model) continue;
std::string comp_name = XStringToString(comp_model->GetFileName());
std::string comp_path = base_path + "/" + comp_name;
pfcModelType comp_type = comp_model->GetType();
if (comp_type == pfcMDL_PART) {
// 零件:检查是否已处理过
if (processed_parts.find(comp_name) == processed_parts.end()) {
// 未处理过的零件,添加到列表和已处理集合
parts.push_back(std::make_pair(comp_model, comp_path));
processed_parts.insert(comp_name);
}
} else if (comp_type == pfcMDL_ASSEMBLY) {
// 子装配体:递归处理
wfcWAssembly_ptr sub_assembly = wfcWAssembly::cast(comp_model);
if (sub_assembly) {
CollectAssemblyParts(sub_assembly, comp_path, parts, processed_parts);
}
}
} catch (pfcXToolkitError&) {
// 忽略单个组件的错误,继续处理其他组件
continue;
}
}
} catch (pfcXToolkitError&) {
// 装配体访问错误
return;
}
}
// 工具方法
std::string GeometryAnalyzer::GetModelFileSize(pfcModel_ptr model) {
if (!model) return "0 KB";
try {
// 简化文件大小处理,返回预估值
std::string model_name = XStringToString(model->GetFileName());
// 根据模型名称长度和类型估算文件大小
int estimated_size = 100 + (int)(model_name.length() * 10);
if (estimated_size < 1024) {
return std::to_string(estimated_size) + " KB";
} else {
std::ostringstream oss;
oss << std::fixed << std::setprecision(1) << (double)estimated_size / 1024.0 << " MB";
return oss.str();
}
} catch (...) {
return "Unknown";
}
}
bool GeometryAnalyzer::IsValidPart(pfcModel_ptr model) {
if (!model) return false;
try {
pfcModelType model_type = model->GetType();
return (model_type == pfcMDL_PART);
} catch (...) {
return false;
}
}
// 会话管理方法
GeometryAnalyzer::SessionInfo GeometryAnalyzer::GetSessionInfo() {
SessionInfo info;
info.is_valid = false;
try {
info.session = pfcGetCurrentSessionWithCompatibility(pfcC4Compatible);
if (info.session) {
info.wSession = wfcWSession::cast(info.session);
info.is_valid = (info.wSession != nullptr);
}
} catch (pfcXToolkitError&) {
info.is_valid = false;
} catch (...) {
info.is_valid = false;
}
return info;
}
// 时间工具方法
std::string GeometryAnalyzer::GetCurrentTimeString() {
auto now = std::chrono::system_clock::now();
auto time_t_now = std::chrono::system_clock::to_time_t(now);
std::ostringstream oss;
oss << std::put_time(std::localtime(&time_t_now), "%Y-%m-%d %H:%M:%S");
return oss.str();
}
std::string GeometryAnalyzer::GetCurrentTimeStringISO() {
auto now = std::chrono::system_clock::now();
auto time_t_now = std::chrono::system_clock::to_time_t(now);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&time_t_now), "%Y-%m-%dT%H:%M:%SZ");
return oss.str();
}
// 字符串转换方法复制自CreoManager实现
std::string GeometryAnalyzer::XStringToString(const xstring& xstr) {
try {
// 安全检查空xstring处理
if (xstr.IsNull()) {
return "";
}
std::wstring wstr(xstr);
if (wstr.empty()) {
return "";
}
// 长度限制检查,防止过长字符串导致内存问题
if (wstr.length() > 32767) { // Windows API限制
return "";
}
// 使用WideCharToMultiByte进行正确的UTF-8编码转换
int wstr_len = static_cast<int>(wstr.length());
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr_len, NULL, 0, NULL, NULL);
if (size_needed <= 0 || size_needed > 65535) { // 安全边界检查
return "";
}
std::string result(size_needed, 0);
int convert_result = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr_len, &result[0], size_needed, NULL, NULL);
if (convert_result != size_needed) {
return ""; // 转换失败
}
return result;
}
catch (const std::bad_alloc&) {
return ""; // 内存分配失败
}
catch (const std::length_error&) {
return ""; // 字符串长度错误
}
catch (...) {
return "";
}
}
// 缓存管理方法实现
std::string GeometryAnalyzer::GenerateCacheKey(pfcModel_ptr model) {
if (!model) return "";
try {
std::string model_name = XStringToString(model->GetFileName());
std::string model_path = XStringToString(model->GetOrigin());
// 使用模型名称和路径生成唯一键
return model_path + "/" + model_name;
} catch (...) {
// 如果无法获取路径信息,使用静态计数器生成唯一键
static int cache_counter = 1;
return "model_" + std::to_string(cache_counter++);
}
}
bool GeometryAnalyzer::IsCacheValid(const std::string& cache_key, pfcModel_ptr model) {
if (cache_key.empty()) return false;
auto it = complexity_cache.find(cache_key);
if (it == complexity_cache.end()) {
return false; // 缓存不存在
}
// 检查时间过期
std::time_t current_time = std::time(nullptr);
if (current_time - it->second.timestamp > CACHE_EXPIRY_SECONDS) {
complexity_cache.erase(it); // 移除过期缓存
return false;
}
return true;
}
void GeometryAnalyzer::ClearExpiredCache() {
std::time_t current_time = std::time(nullptr);
auto it = complexity_cache.begin();
while (it != complexity_cache.end()) {
if (current_time - it->second.timestamp > CACHE_EXPIRY_SECONDS) {
it = complexity_cache.erase(it);
} else {
++it;
}
}
}
// 多维复杂度计算方法实现
// 几何复杂度 - 专注于拓扑和曲面复杂度
double GeometryAnalyzer::CalculateGeometricComplexity(const GeometryComplexityInfo& info) {
double score = 0.0;
// 曲面复杂度占主导地位
score += SaturationFunction(info.curved_surface_count * 8.0, 60.0, 1.2);
// 拓扑复杂度(孔、腔体等)
score += SaturationFunction(info.hole_count * 6.0, 25.0, 1.0);
// 几何结构复杂度
if (info.volume > 0 && info.bounding_box_volume > 0) {
double volume_ratio = info.volume / info.bounding_box_volume;
if (volume_ratio < 0.3) {
score += 15.0; // 复杂内部结构
} else if (volume_ratio < 0.6) {
score += 8.0; // 中等复杂结构
}
}
// 表面积复杂度
if (info.volume > 0 && info.surface_area > 0) {
double surface_to_volume_ratio = info.surface_area / std::pow(info.volume, 2.0/3.0);
score += SaturationFunction(surface_to_volume_ratio * 2.0, 20.0, 0.8);
}
return (std::min)(score, 100.0);
}
// 制造复杂度 - 专注于加工工艺难度
double GeometryAnalyzer::CalculateManufacturingComplexity(const GeometryComplexityInfo& info) {
double score = 0.0;
// 高精度特征(制造难度高)
score += SaturationFunction(info.chamfer_count * 4.0, 20.0, 1.0);
score += SaturationFunction(info.draft_count * 5.0, 25.0, 1.1);
score += SaturationFunction(info.shell_count * 8.0, 30.0, 1.3);
// 加工特征复杂度
score += SaturationFunction(info.hole_count * 3.0, 20.0, 1.0);
score += SaturationFunction(info.pattern_count * 6.0, 25.0, 1.2);
// 表面光洁度要求(基于曲面数量)
score += SaturationFunction(info.curved_surface_count * 3.5, 15.0, 0.9);
// 特征交互惩罚
if (info.hole_count > 0 && info.chamfer_count > 0) {
score += 5.0; // 孔和倒角的组合增加制造难度
}
return (std::min)(score, 100.0);
}
// 装配复杂度 - 专注于约束和层级关系
double GeometryAnalyzer::CalculateAssemblyComplexity(const GeometryComplexityInfo& info) {
double score = 0.0;
// 基于特征数量估算装配复杂度
score += SaturationFunction(info.feature_count * 1.5, 40.0, 0.8);
// 连接特征复杂度(孔、凸台等)
score += SaturationFunction(info.hole_count * 4.0, 25.0, 1.0);
score += SaturationFunction(info.protrusion_count * 3.0, 15.0, 1.0);
// 表面接触复杂度
score += SaturationFunction(info.surface_count * 0.8, 20.0, 0.7);
// 对于单个零件,装配复杂度相对较低
return (std::min)(score * 0.6, 100.0); // 降权因子
}
// 分析复杂度 - 专注于计算负载
double GeometryAnalyzer::CalculateAnalysisComplexity(const GeometryComplexityInfo& info) {
double score = 0.0;
// 网格生成复杂度
score += SaturationFunction(info.curved_surface_count * 5.0, 30.0, 1.0);
score += SaturationFunction(info.surface_count * 1.2, 25.0, 0.8);
// 特征相互作用的计算复杂度
double interaction_factor = FeatureInteractionWeight(info);
score += SaturationFunction(interaction_factor * 20.0, 25.0, 1.0);
// 几何求解复杂度
if (info.volume > 0 && info.surface_area > 0) {
double geometric_ratio = info.surface_area / info.volume;
score += SaturationFunction(geometric_ratio * 0.5, 20.0, 0.9);
}
return (std::min)(score, 100.0);
}
// 饱和函数 - 避免分数无限增长
double GeometryAnalyzer::SaturationFunction(double value, double max_value, double steepness) {
if (value <= 0) return 0.0;
return max_value * (1.0 - std::exp(-steepness * value / max_value));
}
// 特征交互权重 - 计算特征间的复杂交互
double GeometryAnalyzer::FeatureInteractionWeight(const GeometryComplexityInfo& info) {
double interaction = 0.0;
// 特征密度因子
if (info.volume > 0) {
double feature_density = (double)info.feature_count / info.volume;
interaction += feature_density * 1000.0; // 密度越高交互越复杂
}
// 特征类型多样性
int feature_types = 0;
if (info.hole_count > 0) feature_types++;
if (info.fillet_count > 0) feature_types++;
if (info.chamfer_count > 0) feature_types++;
if (info.shell_count > 0) feature_types++;
if (info.pattern_count > 0) feature_types++;
interaction += feature_types * 0.5; // 类型越多交互越复杂
return interaction;
}
// 上下文感知算法实现
// 计算尺寸归一化因子
double GeometryAnalyzer::CalculateScaleNormalizationFactor(const GeometryComplexityInfo& info) {
if (info.bounding_box_volume <= 0) return 1.0;
// 基于包络盒体积的尺寸分类
double volume = info.bounding_box_volume;
// 尺寸分类(立方毫米为单位)
if (volume < 1000.0) { // 小尺寸零件1立方厘米以下
return 1.3; // 小零件的复杂度被放大
} else if (volume < 1000000.0) { // 中等尺寸零件1立方分米以下
return 1.0; // 标准尺寸
} else { // 大尺寸零件
return 0.8; // 大零件的相对复杂度降低
}
}
// 计算相对重要性权重
double GeometryAnalyzer::CalculateRelativeImportanceWeight(const GeometryComplexityInfo& info) {
double importance = 1.0;
// 基于特征密度的重要性
if (info.volume > 0 && info.feature_count > 0) {
double feature_density = (double)info.feature_count / info.volume;
// 高密度特征的零件更重要
if (feature_density > 0.01) { // 高密度
importance += 0.3;
} else if (feature_density > 0.001) { // 中密度
importance += 0.1;
}
}
// 基于关键特征的重要性
if (info.shell_count > 0 || info.pattern_count > 0) {
importance += 0.2; // 关键特征增加重要性
}
// 基于几何复杂度的重要性
if (info.curved_surface_count > 5) {
importance += 0.15; // 复杂曲面增加重要性
}
return (std::min)(importance, 2.0); // 限制最大权重
}
// 应用上下文调整
void GeometryAnalyzer::ApplyContextualAdjustments(GeometryComplexityInfo& info) {
// 计算上下文因子
double scale_factor = CalculateScaleNormalizationFactor(info);
double importance_weight = CalculateRelativeImportanceWeight(info);
// 应用尺寸归一化到各维度复杂度
info.geometric_complexity *= scale_factor;
info.manufacturing_complexity *= scale_factor;
info.assembly_complexity *= scale_factor;
info.analysis_complexity *= scale_factor;
// 应用重要性权重(更多影响制造复杂度)
info.manufacturing_complexity *= importance_weight * 0.8 + 0.2; // 温和调整
info.geometric_complexity *= importance_weight * 0.6 + 0.4; // 较小调整
// 确保值在合理范围内
info.geometric_complexity = (std::min)(info.geometric_complexity, 100.0);
info.manufacturing_complexity = (std::min)(info.manufacturing_complexity, 100.0);
info.assembly_complexity = (std::min)(info.assembly_complexity, 100.0);
info.analysis_complexity = (std::min)(info.analysis_complexity, 100.0);
// 添加上下文信息到复杂度因素
if (scale_factor > 1.1) {
info.complexity_factors.push_back("Small-scale part complexity amplification");
} else if (scale_factor < 0.9) {
info.complexity_factors.push_back("Large-scale part complexity normalization");
}
if (importance_weight > 1.2) {
info.complexity_factors.push_back("High-importance critical features");
}
}
// 多目标排序算法实现
// 多目标排序主方法
void GeometryAnalyzer::MultiObjectiveSort(std::vector<GeometryComplexityInfo>& parts, const GeometryComplexityRequest& request) {
if (parts.empty()) return;
if (request.sort_strategy == "geometric") {
// 按几何复杂度排序
if (request.sort_order == "asc") {
std::sort(parts.begin(), parts.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.geometric_complexity < b.geometric_complexity;
});
} else {
std::sort(parts.begin(), parts.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.geometric_complexity > b.geometric_complexity;
});
}
}
else if (request.sort_strategy == "manufacturing") {
// 按制造复杂度排序
if (request.sort_order == "asc") {
std::sort(parts.begin(), parts.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.manufacturing_complexity < b.manufacturing_complexity;
});
} else {
std::sort(parts.begin(), parts.end(),
[](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return a.manufacturing_complexity > b.manufacturing_complexity;
});
}
}
else if (request.sort_strategy == "pareto") {
// 帕累托前沿排序 - 简化版本
std::stable_sort(parts.begin(), parts.end(),
[this](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
return DominatesInPareto(a, b);
});
}
else {
// 默认:按加权综合复杂度排序
if (request.sort_order == "asc") {
std::sort(parts.begin(), parts.end(),
[this, &request](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
double score_a = CalculateWeightedComplexityScore(a, request);
double score_b = CalculateWeightedComplexityScore(b, request);
return score_a < score_b;
});
} else {
std::sort(parts.begin(), parts.end(),
[this, &request](const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
double score_a = CalculateWeightedComplexityScore(a, request);
double score_b = CalculateWeightedComplexityScore(b, request);
return score_a > score_b;
});
}
}
}
// 计算加权复杂度评分
double GeometryAnalyzer::CalculateWeightedComplexityScore(const GeometryComplexityInfo& info, const GeometryComplexityRequest& request) {
// 归一化权重防止权重总和不为1
double total_weight = request.geometric_weight + request.manufacturing_weight +
request.assembly_weight + request.analysis_weight;
if (total_weight <= 0) total_weight = 1.0; // 避免除零
double normalized_geo = request.geometric_weight / total_weight;
double normalized_man = request.manufacturing_weight / total_weight;
double normalized_asm = request.assembly_weight / total_weight;
double normalized_ana = request.analysis_weight / total_weight;
// 计算加权评分
return info.geometric_complexity * normalized_geo +
info.manufacturing_complexity * normalized_man +
info.assembly_complexity * normalized_asm +
info.analysis_complexity * normalized_ana;
}
// 帕累托支配关系判断(简化版)
bool GeometryAnalyzer::DominatesInPareto(const GeometryComplexityInfo& a, const GeometryComplexityInfo& b) {
// A支配B当且仅当A在所有目标上都不劣于B且至少在一个目标上优于B
bool at_least_one_better = false;
// 检查几何复杂度
if (a.geometric_complexity > b.geometric_complexity) {
at_least_one_better = true;
} else if (a.geometric_complexity < b.geometric_complexity) {
return false; // A在几何复杂度上劣于B
}
// 检查制造复杂度
if (a.manufacturing_complexity > b.manufacturing_complexity) {
at_least_one_better = true;
} else if (a.manufacturing_complexity < b.manufacturing_complexity) {
return false; // A在制造复杂度上劣于B
}
// 检查装配复杂度
if (a.assembly_complexity > b.assembly_complexity) {
at_least_one_better = true;
} else if (a.assembly_complexity < b.assembly_complexity) {
return false; // A在装配复杂度上劣于B
}
// 检查分析复杂度
if (a.analysis_complexity > b.analysis_complexity) {
at_least_one_better = true;
} else if (a.analysis_complexity < b.analysis_complexity) {
return false; // A在分析复杂度上劣于B
}
return at_least_one_better;
}