核心改动: - 在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>
1313 lines
48 KiB
C++
1313 lines
48 KiB
C++
#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;
|
||
} |