diff --git a/HierarchyStatisticsAnalyzer.cpp b/HierarchyStatisticsAnalyzer.cpp index 18db5f4..34f7683 100644 --- a/HierarchyStatisticsAnalyzer.cpp +++ b/HierarchyStatisticsAnalyzer.cpp @@ -10,6 +10,7 @@ #include #include #include +#include HierarchyStatisticsAnalyzer& HierarchyStatisticsAnalyzer::Instance() { static HierarchyStatisticsAnalyzer instance; @@ -42,51 +43,81 @@ HierarchyStatisticsResult HierarchyStatisticsAnalyzer::AnalyzeHierarchyStatistic return result; } + std::string current_model_name; try { xstring filename_xstr = current_model->GetFileName(); - result.model_name = creoManager.XStringToString(filename_xstr); + current_model_name = creoManager.XStringToString(filename_xstr); } catch (...) { - result.model_name = "unknown_model"; + current_model_name = "unknown_model"; } + result.model_name = current_model_name; if (!request.project_name.empty()) { result.model_name = request.project_name; } pfcModelType model_type = current_model->GetType(); + wfcWAssembly_ptr target_assembly = nullptr; - 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"; + if (request.subassembly_path.empty()) { + // 没有指定子装配体路径,使用当前模型 + if (model_type == pfcMDL_PART) { + result.model_type = "part"; + result.total_levels = 1; + result.level_statistics[0] = 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"; + target_assembly = wfcWAssembly::cast(current_model); + } else { + result.error_message = "Current model is neither a part nor an assembly"; + return result; + } } else { - result.error_message = "Current model is neither a part nor an assembly"; - return result; + // 指定了子装配体路径 + if (model_type != pfcMDL_ASSEMBLY) { + result.error_message = "Current model is not an assembly"; + return result; + } + + wfcWAssembly_ptr root_assembly = wfcWAssembly::cast(current_model); + if (!root_assembly) { + result.error_message = "Failed to cast model to assembly"; + return result; + } + + target_assembly = FindSubassemblyByPath(root_assembly, request.subassembly_path, current_model_name); + if (!target_assembly) { + result.error_message = "Subassembly not found at path: " + request.subassembly_path; + return result; + } + + // 更新模型名称为子装配体名称 + try { + pfcModel_ptr target_model = pfcModel::cast(target_assembly); + if (target_model) { + xstring filename_xstr = target_model->GetFileName(); + result.model_name = creoManager.XStringToString(filename_xstr); + } + } catch (...) {} + result.model_type = "assembly"; } - wfcWAssembly_ptr assembly = wfcWAssembly::cast(current_model); - if (!assembly) { - result.error_message = "Failed to cast model to assembly"; + if (!target_assembly) { + result.error_message = "Failed to get target 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); + AnalyzeAssemblyLevel(target_assembly, 1, result.level_statistics, result.total_levels); - // Clean results: remove levels with 0 components std::map cleaned_statistics; for (const auto& stat : result.level_statistics) { if (stat.second > 0) { @@ -95,7 +126,6 @@ HierarchyStatisticsResult HierarchyStatisticsAnalyzer::AnalyzeHierarchyStatistic } 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; } @@ -113,6 +143,113 @@ HierarchyStatisticsResult HierarchyStatisticsAnalyzer::AnalyzeHierarchyStatistic return result; } +wfcWAssembly_ptr HierarchyStatisticsAnalyzer::FindSubassemblyByPath(wfcWAssembly_ptr root_assembly, + const std::string& subassembly_path, + const std::string& current_model_name) { + if (!root_assembly || subassembly_path.empty()) { + return nullptr; + } + + auto& creoManager = CreoManager::Instance(); + + try { + // 解析路径 + std::vector path_segments; + std::string path = subassembly_path; + std::replace(path.begin(), path.end(), '\\', '/'); + + std::istringstream iss(path); + std::string segment; + while (std::getline(iss, segment, '/')) { + if (!segment.empty()) { + path_segments.push_back(segment); + } + } + + if (path_segments.empty()) { + return nullptr; + } + + // 如果第一段是当前模型名,跳过它 + size_t start_index = 0; + if (!current_model_name.empty() && !path_segments.empty()) { + std::string first_seg = path_segments[0]; + std::string model_name = current_model_name; + std::transform(first_seg.begin(), first_seg.end(), first_seg.begin(), ::tolower); + std::transform(model_name.begin(), model_name.end(), model_name.begin(), ::tolower); + if (first_seg == model_name) { + start_index = 1; + } + } + + if (start_index >= path_segments.size()) { + return root_assembly; + } + + wfcWAssembly_ptr current_assembly = root_assembly; + + for (size_t i = start_index; i < path_segments.size(); ++i) { + std::string target = path_segments[i]; + std::string target_lower = target; + std::transform(target_lower.begin(), target_lower.end(), target_lower.begin(), ::tolower); + + pfcFeatures_ptr features = current_assembly->ListFeaturesByType(xfalse, pfcFEATTYPE_COMPONENT); + if (!features) return nullptr; + + int count = features->getarraysize(); + bool found = false; + + for (int j = 0; j < count; ++j) { + try { + pfcFeature_ptr feature = features->get(j); + if (!feature) continue; + + pfcComponentFeat_ptr compFeat = pfcComponentFeat::cast(feature); + if (!compFeat) continue; + + auto modelDescr = compFeat->GetModelDescr(); + if (!modelDescr) continue; + + xstring filename_xstr = modelDescr->GetFileName(); + std::string comp_name = creoManager.XStringToString(filename_xstr); + std::string comp_lower = comp_name; + std::transform(comp_lower.begin(), comp_lower.end(), comp_lower.begin(), ::tolower); + + if (comp_lower == target_lower) { + pfcModel_ptr child_model = nullptr; + CreoManager::SessionInfo sessionInfo = creoManager.GetSessionInfo(); + if (sessionInfo.is_valid && sessionInfo.session) { + child_model = sessionInfo.session->GetModelFromDescr(modelDescr); + if (!child_model) { + try { + child_model = sessionInfo.session->RetrieveModelWithOpts(modelDescr, nullptr); + } catch (...) {} + } + } + + if (child_model && child_model->GetType() == pfcMDL_ASSEMBLY) { + current_assembly = wfcWAssembly::cast(child_model); + found = true; + break; + } else if (i == path_segments.size() - 1) { + return nullptr; // 最后一段但不是装配体 + } + } + } catch (...) { + continue; + } + } + + if (!found) return nullptr; + } + + return current_assembly; + + } catch (...) { + return nullptr; + } +} + void HierarchyStatisticsAnalyzer::AnalyzeAssemblyLevel(wfcWAssembly_ptr assembly, int level, std::map& statistics, int& maxLevel) { if (!assembly) return; diff --git a/HierarchyStatisticsAnalyzer.h b/HierarchyStatisticsAnalyzer.h index 69bb62f..8369f7f 100644 --- a/HierarchyStatisticsAnalyzer.h +++ b/HierarchyStatisticsAnalyzer.h @@ -3,12 +3,14 @@ #include #include #include +#include #include #include "CreoManager.h" // 层级统计请求结构 struct HierarchyStatisticsRequest { - std::string project_name; // 可选的项目名称,默认使用当前模型名 + std::string project_name; // 可选的项目名称,默认使用当前模型名 + std::string subassembly_path; // 可选的子装配体路径,如 "top.asm/sub.asm" }; // 层级统计结果结构 @@ -42,6 +44,9 @@ private: // 递归分析装配体层级 void AnalyzeAssemblyLevel(wfcWAssembly_ptr assembly, int level, std::map& statistics, int& maxLevel); + // 根据路径查找子装配体 + wfcWAssembly_ptr FindSubassemblyByPath(wfcWAssembly_ptr root_assembly, const std::string& path, const std::string& model_name); + // 获取当前时间字符串 std::string GetCurrentTimeString(); }; diff --git a/MFCCreoDll.cpp b/MFCCreoDll.cpp index 4f3d0fa..5ee4eab 100644 --- a/MFCCreoDll.cpp +++ b/MFCCreoDll.cpp @@ -1702,6 +1702,12 @@ HttpResponse HierarchyStatisticsHandler(const HttpRequest& request) { stats_request.project_name = project_name_str; } + // 提取subassembly_path参数(可选) + std::string subassembly_path_str = ExtractJsonValue(request.body, "subassembly_path"); + if (!subassembly_path_str.empty()) { + stats_request.subassembly_path = subassembly_path_str; + } + // 执行层级统计分析 HierarchyStatisticsResult result = HierarchyStatisticsAnalyzer::Instance().AnalyzeHierarchyStatistics(stats_request); diff --git a/MFCCreoDll/x64/Debug/AuthManager.obj b/MFCCreoDll/x64/Debug/AuthManager.obj index e75b11d..c61f49a 100644 Binary files a/MFCCreoDll/x64/Debug/AuthManager.obj and b/MFCCreoDll/x64/Debug/AuthManager.obj differ diff --git a/MFCCreoDll/x64/Debug/BatchOperationManager.obj b/MFCCreoDll/x64/Debug/BatchOperationManager.obj index 3f4555d..8b787ae 100644 Binary files a/MFCCreoDll/x64/Debug/BatchOperationManager.obj and b/MFCCreoDll/x64/Debug/BatchOperationManager.obj differ diff --git a/MFCCreoDll/x64/Debug/ComponentChildrenManager.obj b/MFCCreoDll/x64/Debug/ComponentChildrenManager.obj index 8ed5720..6e43620 100644 Binary files a/MFCCreoDll/x64/Debug/ComponentChildrenManager.obj and b/MFCCreoDll/x64/Debug/ComponentChildrenManager.obj differ diff --git a/MFCCreoDll/x64/Debug/CreoManager.obj b/MFCCreoDll/x64/Debug/CreoManager.obj index 8347365..6beeb92 100644 Binary files a/MFCCreoDll/x64/Debug/CreoManager.obj and b/MFCCreoDll/x64/Debug/CreoManager.obj differ diff --git a/MFCCreoDll/x64/Debug/CreoUtilities.obj b/MFCCreoDll/x64/Debug/CreoUtilities.obj index 2bc8627..a1ac9c9 100644 Binary files a/MFCCreoDll/x64/Debug/CreoUtilities.obj and b/MFCCreoDll/x64/Debug/CreoUtilities.obj differ diff --git a/MFCCreoDll/x64/Debug/GeometryAnalyzer.obj b/MFCCreoDll/x64/Debug/GeometryAnalyzer.obj index a88481c..8347005 100644 Binary files a/MFCCreoDll/x64/Debug/GeometryAnalyzer.obj and b/MFCCreoDll/x64/Debug/GeometryAnalyzer.obj differ diff --git a/MFCCreoDll/x64/Debug/HierarchyStatisticsAnalyzer.obj b/MFCCreoDll/x64/Debug/HierarchyStatisticsAnalyzer.obj index 35226f9..8cc1e21 100644 Binary files a/MFCCreoDll/x64/Debug/HierarchyStatisticsAnalyzer.obj and b/MFCCreoDll/x64/Debug/HierarchyStatisticsAnalyzer.obj differ diff --git a/MFCCreoDll/x64/Debug/HttpRouter.obj b/MFCCreoDll/x64/Debug/HttpRouter.obj index adfd90e..11f78e9 100644 Binary files a/MFCCreoDll/x64/Debug/HttpRouter.obj and b/MFCCreoDll/x64/Debug/HttpRouter.obj differ diff --git a/MFCCreoDll/x64/Debug/HttpServer.obj b/MFCCreoDll/x64/Debug/HttpServer.obj index 21e584d..068a9b4 100644 Binary files a/MFCCreoDll/x64/Debug/HttpServer.obj and b/MFCCreoDll/x64/Debug/HttpServer.obj differ diff --git a/MFCCreoDll/x64/Debug/JsonHelper.obj b/MFCCreoDll/x64/Debug/JsonHelper.obj index daecdf5..f23c8e6 100644 Binary files a/MFCCreoDll/x64/Debug/JsonHelper.obj and b/MFCCreoDll/x64/Debug/JsonHelper.obj differ diff --git a/MFCCreoDll/x64/Debug/Logger.obj b/MFCCreoDll/x64/Debug/Logger.obj index a96b51e..c1d123d 100644 Binary files a/MFCCreoDll/x64/Debug/Logger.obj and b/MFCCreoDll/x64/Debug/Logger.obj differ diff --git a/MFCCreoDll/x64/Debug/MFCCreoDll.obj b/MFCCreoDll/x64/Debug/MFCCreoDll.obj index b43a29c..53d331e 100644 Binary files a/MFCCreoDll/x64/Debug/MFCCreoDll.obj and b/MFCCreoDll/x64/Debug/MFCCreoDll.obj differ diff --git a/MFCCreoDll/x64/Debug/MFCCreoDll.pch b/MFCCreoDll/x64/Debug/MFCCreoDll.pch index 4d3917e..3aa20b8 100644 Binary files a/MFCCreoDll/x64/Debug/MFCCreoDll.pch and b/MFCCreoDll/x64/Debug/MFCCreoDll.pch differ diff --git a/MFCCreoDll/x64/Debug/MFCCreoDll.tlog/CL.read.1.tlog b/MFCCreoDll/x64/Debug/MFCCreoDll.tlog/CL.read.1.tlog index fca3649..27d7215 100644 Binary files a/MFCCreoDll/x64/Debug/MFCCreoDll.tlog/CL.read.1.tlog and b/MFCCreoDll/x64/Debug/MFCCreoDll.tlog/CL.read.1.tlog differ diff --git a/MFCCreoDll/x64/Debug/ModelAnalyzer.obj b/MFCCreoDll/x64/Debug/ModelAnalyzer.obj index 7271fdc..65a68f2 100644 Binary files a/MFCCreoDll/x64/Debug/ModelAnalyzer.obj and b/MFCCreoDll/x64/Debug/ModelAnalyzer.obj differ diff --git a/MFCCreoDll/x64/Debug/ModelSearchEngine.obj b/MFCCreoDll/x64/Debug/ModelSearchEngine.obj index c483fdd..17f0611 100644 Binary files a/MFCCreoDll/x64/Debug/ModelSearchEngine.obj and b/MFCCreoDll/x64/Debug/ModelSearchEngine.obj differ diff --git a/MFCCreoDll/x64/Debug/ModelSearchHandler.obj b/MFCCreoDll/x64/Debug/ModelSearchHandler.obj index 2e7ef64..d343120 100644 Binary files a/MFCCreoDll/x64/Debug/ModelSearchHandler.obj and b/MFCCreoDll/x64/Debug/ModelSearchHandler.obj differ diff --git a/MFCCreoDll/x64/Debug/PathDeleteManager.obj b/MFCCreoDll/x64/Debug/PathDeleteManager.obj index 08f49cc..63a626c 100644 Binary files a/MFCCreoDll/x64/Debug/PathDeleteManager.obj and b/MFCCreoDll/x64/Debug/PathDeleteManager.obj differ diff --git a/MFCCreoDll/x64/Debug/ServerManager.obj b/MFCCreoDll/x64/Debug/ServerManager.obj index 8a43a5c..8219189 100644 Binary files a/MFCCreoDll/x64/Debug/ServerManager.obj and b/MFCCreoDll/x64/Debug/ServerManager.obj differ diff --git a/MFCCreoDll/x64/Debug/ShellExportHandler.obj b/MFCCreoDll/x64/Debug/ShellExportHandler.obj index 6eb0d91..71bdc0e 100644 Binary files a/MFCCreoDll/x64/Debug/ShellExportHandler.obj and b/MFCCreoDll/x64/Debug/ShellExportHandler.obj differ diff --git a/MFCCreoDll/x64/Debug/ShrinkwrapManager.obj b/MFCCreoDll/x64/Debug/ShrinkwrapManager.obj index 855a80e..29c7ae2 100644 Binary files a/MFCCreoDll/x64/Debug/ShrinkwrapManager.obj and b/MFCCreoDll/x64/Debug/ShrinkwrapManager.obj differ diff --git a/MFCCreoDll/x64/Debug/WebSocketServer.obj b/MFCCreoDll/x64/Debug/WebSocketServer.obj index fef38ff..f10c1d2 100644 Binary files a/MFCCreoDll/x64/Debug/WebSocketServer.obj and b/MFCCreoDll/x64/Debug/WebSocketServer.obj differ diff --git a/MFCCreoDll/x64/Debug/pch.obj b/MFCCreoDll/x64/Debug/pch.obj index fe6dbae..dfab2dd 100644 Binary files a/MFCCreoDll/x64/Debug/pch.obj and b/MFCCreoDll/x64/Debug/pch.obj differ diff --git a/MFCCreoDll/x64/Debug/vc143.idb b/MFCCreoDll/x64/Debug/vc143.idb index adf6a88..b35be2f 100644 Binary files a/MFCCreoDll/x64/Debug/vc143.idb and b/MFCCreoDll/x64/Debug/vc143.idb differ diff --git a/MFCCreoDll/x64/Debug/vc143.pdb b/MFCCreoDll/x64/Debug/vc143.pdb index 38c7fea..b16c86c 100644 Binary files a/MFCCreoDll/x64/Debug/vc143.pdb and b/MFCCreoDll/x64/Debug/vc143.pdb differ diff --git a/x64/Debug/MFCCreoDll.dll b/x64/Debug/MFCCreoDll.dll index 964fb5f..bd06d44 100644 Binary files a/x64/Debug/MFCCreoDll.dll and b/x64/Debug/MFCCreoDll.dll differ diff --git a/x64/Debug/MFCCreoDll.pdb b/x64/Debug/MFCCreoDll.pdb index 29e85db..d62e4d5 100644 Binary files a/x64/Debug/MFCCreoDll.pdb and b/x64/Debug/MFCCreoDll.pdb differ