CreoOtkPluging/HierarchyStatisticsAnalyzer.cpp
sladro 623bfe6728 修复文件统计错误并优化薄壳化分析
主要修复:
- 修复CalculateAssemblyTotalSize中文件计数逻辑
- 解决"from X files"数量不正确的问题
- 无条件计数所有有效组件,不管文件大小是否为0

薄壳化分析优化:
- 使用命名常量替代硬编码置信度值
- 实现真实几何计算和缓存机制
- 添加大模型采样优化策略
- 改进体积影响计算算法

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 14:52:05 +08:00

186 lines
6.6 KiB
C++

#include "pch.h"
#include "HierarchyStatisticsAnalyzer.h"
#include <pfcGlobal.h>
#include <pfcSession.h>
#include <wfcSession.h>
#include <pfcModel.h>
#include <pfcFeature.h>
#include <pfcComponentFeat.h>
#include <wfcAssembly.h>
#include <ctime>
#include <sstream>
#include <iomanip>
HierarchyStatisticsAnalyzer& HierarchyStatisticsAnalyzer::Instance() {
static HierarchyStatisticsAnalyzer instance;
return instance;
}
std::string HierarchyStatisticsAnalyzer::GetCurrentTimeString() {
auto now = std::time(nullptr);
std::tm* localTime = std::localtime(&now);
std::ostringstream oss;
oss << std::put_time(localTime, "%Y-%m-%d %H:%M:%S");
return oss.str();
}
HierarchyStatisticsResult HierarchyStatisticsAnalyzer::AnalyzeHierarchyStatistics(const HierarchyStatisticsRequest& request) {
HierarchyStatisticsResult result;
auto& creoManager = CreoManager::Instance();
CreoManager::SessionInfo sessionInfo = creoManager.GetSessionInfo();
if (!sessionInfo.is_valid) {
result.error_message = "Creo session not available";
return result;
}
try {
pfcModel_ptr current_model = sessionInfo.session->GetCurrentModel();
if (!current_model) {
result.error_message = "No current model loaded";
return result;
}
try {
xstring filename_xstr = current_model->GetFileName();
result.model_name = creoManager.XStringToString(filename_xstr);
} catch (...) {
result.model_name = "unknown_model";
}
if (!request.project_name.empty()) {
result.model_name = request.project_name;
}
pfcModelType model_type = current_model->GetType();
if (model_type == pfcMDL_PART) {
result.model_type = "part";
result.total_levels = 1;
result.level_statistics[0] = 1; // Part itself counts as 1
result.success = true;
result.message = "Part model has no hierarchy";
result.analysis_time = GetCurrentTimeString();
return result;
} else if (model_type == pfcMDL_ASSEMBLY) {
result.model_type = "assembly";
} else {
result.error_message = "Current model is neither a part nor an assembly";
return result;
}
wfcWAssembly_ptr assembly = wfcWAssembly::cast(current_model);
if (!assembly) {
result.error_message = "Failed to cast model to assembly";
return result;
}
result.level_statistics.clear();
result.total_levels = 0;
// Level 0: root assembly itself, always 1
result.level_statistics[0] = 1;
result.total_levels = 1;
// Analyze components starting from level 1
AnalyzeAssemblyLevel(assembly, 1, result.level_statistics, result.total_levels);
// Clean results: remove levels with 0 components
std::map<int, int> cleaned_statistics;
for (const auto& stat : result.level_statistics) {
if (stat.second > 0) {
cleaned_statistics[stat.first] = stat.second;
}
}
result.level_statistics = cleaned_statistics;
// Update total levels (max non-zero level + 1)
if (!cleaned_statistics.empty()) {
result.total_levels = cleaned_statistics.rbegin()->first + 1;
}
result.success = true;
result.message = "Hierarchy statistics analysis completed";
result.analysis_time = GetCurrentTimeString();
} catch (const std::exception& e) {
result.error_message = "Exception during analysis: " + std::string(e.what());
} catch (...) {
result.error_message = "Unknown exception during hierarchy statistics analysis";
}
return result;
}
void HierarchyStatisticsAnalyzer::AnalyzeAssemblyLevel(wfcWAssembly_ptr assembly, int level, std::map<int, int>& statistics, int& maxLevel) {
if (!assembly) return;
try {
pfcFeatures_ptr features = assembly->ListFeaturesByType(xfalse, pfcFEATTYPE_COMPONENT);
if (!features) return;
int features_count = features->getarraysize();
if (features_count <= 0) return;
// Initialize statistics for current level if not exists
if (statistics.find(level) == statistics.end()) {
statistics[level] = 0;
}
// Count components at current level
statistics[level] += features_count;
// Update max level
if (level > maxLevel) {
maxLevel = level;
}
// Traverse all components, recurse for sub-assemblies
for (int i = 0; i < features_count; i++) {
try {
pfcFeature_ptr feature = features->get(i);
if (!feature) continue;
pfcComponentFeat_ptr compFeat = pfcComponentFeat::cast(feature);
if (!compFeat) continue;
pfcModel_ptr childModel = nullptr;
try {
auto modelDescr = compFeat->GetModelDescr();
if (modelDescr) {
auto& creoManager2 = CreoManager::Instance();
CreoManager::SessionInfo sessionInfo = creoManager2.GetSessionInfo();
if (sessionInfo.is_valid && sessionInfo.session) {
childModel = sessionInfo.session->GetModelFromDescr(modelDescr);
if (!childModel) {
try {
childModel = sessionInfo.session->RetrieveModelWithOpts(modelDescr, nullptr);
} catch (...) {
}
}
}
}
} catch (...) {
}
if (childModel) {
// Only recurse for sub-assemblies
if (childModel->GetType() == pfcMDL_ASSEMBLY) {
wfcWAssembly_ptr childAssembly = wfcWAssembly::cast(childModel);
if (childAssembly) {
// Recurse to analyze next level
AnalyzeAssemblyLevel(childAssembly, level + 1, statistics, maxLevel);
}
}
}
} catch (...) {
continue;
}
}
} catch (...) {
}
}