CreoOtkPluging/MFCCreoDll.cpp
sladro 99c6d17795 feat: 为shell-analysis接口添加投票数量字段
- 在FeatureDeletion结构体中添加vote_count字段,记录多方向投影分析中的投票数量
- 在AnalyzeShellFeaturesEnhanced函数中填充投票数据,利用visibilityVotes映射
- 更新JSON响应,为safeDeletions、suggestedDeletions、preserveList添加voteCount字段
- 提供模型外表面可见性程度的量化指标,增强分析结果的透明度

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-19 16:40:23 +08:00

1709 lines
71 KiB
C++
Raw 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.

// MFCCreoDll.cpp: 定义 DLL 的初始化例程。
//
#include "pch.h"
#include "framework.h"
#include "MFCCreoDll.h"
#include "HttpServer.h"
#include "CreoManager.h"
#include "ShellExportHandler.h"
#include "PathDeleteManager.h"
#include "GeometryAnalyzer.h"
#include "ModelSearchHandler.h"
#include "HierarchyStatisticsAnalyzer.h"
#include <wfcSession.h>
#include <wfcGlobal.h>
#include <string>
#include <sstream>
#include <regex>
#include <atomic>
#include <memory>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// --- 全局变量 ---
static std::unique_ptr<HttpServer> g_http_server;
static UINT_PTR timer_id = 0;
// 无锁消息队列项
struct MessageItem {
std::string type; // "SHOW_MESSAGE", "OPEN_MODEL_REQUEST", 或 "SHRINKWRAP_SHELL_REQUEST"
std::string data; // 消息内容或文件路径或JSON数据
std::string extra; // 额外参数如open_mode
volatile bool completed; // 完成标志
void* result_ptr; // 结果指针
MessageItem() : completed(false), result_ptr(nullptr) {}
};
// 无锁同步机制
static volatile MessageItem* pending_message_item = nullptr;
static std::atomic<bool> has_pending_item{false};
// --- 辅助函数:将 std::string 转换为 xstring ---
xstring ConvertStringToXstring(const std::string& str)
{
std::wstring wstr(str.begin(), str.end());
return xstring(wstr.c_str());
}
// 定时器回调函数,使用无锁消息机制处理消息
VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
// 使用无锁机制检查待处理消息
if (has_pending_item.load() && pending_message_item) {
MessageItem* item = const_cast<MessageItem*>(pending_message_item);
try {
if (item->type == "OPEN_MODEL_REQUEST") {
OpenResult result = CreoManager::Instance().OpenModel(item->data, item->extra);
// 如果模式是active且模型成功打开激活窗口
if (result.success && item->extra == "active") {
try {
pfcSession_ptr session = pfcGetCurrentSession();
if (session) {
// 获取刚刚打开的模型
xstring filename_xstr = ConvertStringToXstring(result.model_name);
pfcModelDescriptor_ptr desc = pfcModelDescriptor::CreateFromFileName(filename_xstr);
pfcModel_ptr model = session->GetModelFromDescr(desc);
if (model) {
// 创建或激活模型窗口
pfcWindow_ptr modelWindow = session->CreateModelWindow(model);
if (modelWindow) {
try {
modelWindow->Activate();
model->Display();
modelWindow->Refresh();
}
catch (...) {
// 激活失败,尝试设置为当前窗口
try {
session->SetCurrentWindow(modelWindow);
}
catch (...) {
}
}
// 尝试刷新窗口
try {
modelWindow->Refresh();
}
catch (...) {
// 刷新失败不影响主要功能
}
}
}
}
}
catch (...) {
}
}
item->result_ptr = new OpenResult(result);
item->completed = true;
}
else if (item->type == "SHRINKWRAP_SHELL_REQUEST") {
// Shrinkwrap外壳导出处理
// 将JSON数据转换为HttpRequest格式
HttpRequest shrinkwrap_request;
shrinkwrap_request.method = "POST";
shrinkwrap_request.path = "/api/creo/shrinkwrap/shell";
shrinkwrap_request.body = item->data;
// 执行Shrinkwrap处理
HttpResponse response = ShellExportHandler::HandleShrinkwrapShellRequest(shrinkwrap_request);
// 保存结果
item->result_ptr = new HttpResponse(response);
item->completed = true;
}
else if (item->type == "SHOW_MESSAGE") {
// 消息显示处理
CreoManager::Instance().ShowMessage(item->data);
item->completed = true;
}
// 清理状态
pending_message_item = nullptr;
has_pending_item = false;
}
catch (...) {
// 异常处理
if (item->type == "OPEN_MODEL_REQUEST") {
OpenResult* error_result = new OpenResult();
error_result->success = false;
error_result->error_message = "Unexpected error during operation execution";
item->result_ptr = error_result;
}
else if (item->type == "SHRINKWRAP_SHELL_REQUEST") {
HttpResponse* error_response = new HttpResponse();
error_response->status_code = 500;
error_response->body = "{\"success\": false, \"error\": \"Unexpected error during shrinkwrap operation\"}";
item->result_ptr = error_response;
}
item->completed = true;
pending_message_item = nullptr;
has_pending_item = false;
}
}
}
// 测试路由处理器
HttpResponse TestHandler(const HttpRequest& request) {
bool creo_connected = false;
try {
pfcSession_ptr session = pfcGetCurrentSessionWithCompatibility(pfcC4Compatible);
creo_connected = (session != nullptr);
}
catch (...) {
creo_connected = false;
}
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"running\": " << (creo_connected ? "true" : "false") << ","
<< "\"message\": \"" << (creo_connected ? "CREOSON 与 Creo 均已启动" : "Creo 未连接") << "\""
<< "},"
<< "\"error\": null"
<< "}";
HttpResponse response;
response.body = json.str();
return response;
}
// 显示消息路由处理器
HttpResponse ShowMessageHandler(const HttpRequest& request) {
// 从查询参数获取消息
std::string message = "Default message";
size_t text_pos = request.query.find("text=");
if (text_pos != std::string::npos) {
text_pos += 5; // 跳过"text="
size_t end_pos = request.query.find("&", text_pos);
if (end_pos == std::string::npos) {
end_pos = request.query.length();
}
message = request.query.substr(text_pos, end_pos - text_pos);
}
// 使用无锁消息机制
MessageItem message_item;
message_item.type = "SHOW_MESSAGE";
message_item.data = message;
// 原子设置(无锁)
pending_message_item = &message_item;
has_pending_item = true;
// 等待主线程处理完成
while (!message_item.completed) {
Sleep(10);
}
HttpResponse response;
response.body = "{\"status\":\"ok\",\"message\":\"Message sent to Creo\"}";
return response;
}
// Creo状态检测路由处理器
HttpResponse CreoStatusHandler(const HttpRequest& request) {
CreoStatus status = CreoManager::Instance().GetCreoStatus();
std::ostringstream json;
json << "{"
<< "\"is_connected\":" << (status.is_connected ? "true" : "false") << ","
<< "\"version\":\"" << status.version << "\","
<< "\"build\":\"" << status.build << "\","
<< "\"working_directory\":\"" << status.working_directory << "\","
<< "\"session_id\":" << status.session_id
<< "}";
HttpResponse response;
response.body = json.str();
return response;
}
// 模型状态检测路由处理器
HttpResponse ModelStatusHandler(const HttpRequest& request) {
ModelStatus status = CreoManager::Instance().GetModelStatus();
std::ostringstream json;
if (status.has_model) {
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"name\": \"" << status.name << "\","
<< "\"filename\": \"" << status.filename << "\","
<< "\"type\": \"" << status.type << "\","
<< "\"software\": \"" << status.software << "\","
<< "\"version\": \"" << status.version << "\","
<< "\"connectionTime\": \"" << status.connection_time << "\","
<< "\"isAssembly\": " << (status.is_assembly ? "true" : "false") << ",";
if (status.is_assembly) {
json << "\"basicStats\": {"
<< "\"totalParts\": " << status.total_parts << ","
<< "\"assemblyLevels\": " << status.assembly_levels << ","
<< "\"fileSize\": \"" << status.file_size << "\""
<< "},";
}
json << "\"fileName\": \"" << status.filename << "\","
<< "\"sourceSoftware\": \"" << status.software << "\","
<< "\"partCount\": " << status.total_parts << ","
<< "\"assemblyLevel\": " << status.assembly_levels << ","
<< "\"connectionStatus\": \"" << status.connection_status << "\","
<< "\"openTime\": \"" << status.open_time << "\""
<< "},"
<< "\"error\": null"
<< "}";
} else {
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"No model is currently open\""
<< "}";
}
HttpResponse response;
response.body = json.str();
return response;
}
// 简单的JSON解析函数
std::string ExtractJsonValue(const std::string& json, const std::string& key) {
// 查找键值对 "key": "value"
std::string key_pattern = "\"" + key + "\"";
size_t key_pos = json.find(key_pattern);
if (key_pos != std::string::npos) {
// 找到冒号
size_t colon_pos = json.find(":", key_pos);
if (colon_pos != std::string::npos) {
// 跳过空格找到值的开始
size_t value_start = colon_pos + 1;
while (value_start < json.length() && (json[value_start] == ' ' || json[value_start] == '\t' || json[value_start] == '\n' || json[value_start] == '\r')) {
value_start++;
}
// 检查是否是字符串值(以双引号开始)
if (value_start < json.length() && json[value_start] == '"') {
size_t value_end = json.find('"', value_start + 1);
if (value_end != std::string::npos) {
return json.substr(value_start + 1, value_end - value_start - 1);
}
}
// 处理数字值(不以双引号开始)
else if (value_start < json.length()) {
size_t value_end = value_start;
while (value_end < json.length() &&
json[value_end] != ',' &&
json[value_end] != '}' &&
json[value_end] != ']' &&
json[value_end] != ' ' &&
json[value_end] != '\t' &&
json[value_end] != '\n' &&
json[value_end] != '\r') {
value_end++;
}
if (value_end > value_start) {
return json.substr(value_start, value_end - value_start);
}
}
}
}
return "";
}
bool ExtractJsonBool(const std::string& json, const std::string& key) {
std::regex pattern("\"" + key + "\"\s*:\s*(true|false)");
std::smatch match;
if (std::regex_search(json, match, pattern)) {
return match[1].str() == "true";
}
return false;
}
// JSON字符串转义函数
std::string EscapeJsonString(const std::string& str) {
std::string escaped = str;
// Replace backslashes
size_t pos = 0;
while ((pos = escaped.find("\\", pos)) != std::string::npos) {
escaped.replace(pos, 1, "\\\\");
pos += 2;
}
// Replace double quotes
pos = 0;
while ((pos = escaped.find("\"", pos)) != std::string::npos) {
escaped.replace(pos, 1, "\\\"");
pos += 2;
}
// Replace newlines
pos = 0;
while ((pos = escaped.find("\n", pos)) != std::string::npos) {
escaped.replace(pos, 1, "\\n");
pos += 2;
}
// Replace tabs
pos = 0;
while ((pos = escaped.find("\t", pos)) != std::string::npos) {
escaped.replace(pos, 1, "\\t");
pos += 2;
}
return escaped;
}
// 模型导出路由处理器
HttpResponse ExportModelHandler(const HttpRequest& request) {
if (request.method != "POST") {
HttpResponse response;
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
// 解析JSON请求体
std::string software_type = ExtractJsonValue(request.body, "software_type");
std::string format_type = ExtractJsonValue(request.body, "format_type");
std::string export_path = ExtractJsonValue(request.body, "export_path");
// 提取options中的geom_flags - 简化处理,避免正则表达式崩溃
std::string geom_flags = "solids"; // 默认值
// 简单的字符串查找方式,避免正则表达式
size_t options_pos = request.body.find("\"options\"");
if (options_pos != std::string::npos) {
size_t start_brace = request.body.find("{", options_pos);
if (start_brace != std::string::npos) {
size_t end_brace = request.body.find("}", start_brace);
if (end_brace != std::string::npos) {
std::string options_content = request.body.substr(start_brace + 1, end_brace - start_brace - 1);
std::string extracted_geom_flags = ExtractJsonValue(options_content, "geom_flags");
if (!extracted_geom_flags.empty()) {
geom_flags = extracted_geom_flags;
}
}
}
}
// 验证参数
if (software_type != "creo" || format_type != "step" || export_path.empty()) {
HttpResponse response;
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid parameters\"}";
return response;
}
// 执行导出
ExportResult result = CreoManager::Instance().ExportModelToSTEP(export_path, geom_flags);
HttpResponse response;
if (result.success) {
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"exportPath\": \"" << EscapeJsonString(result.export_path) << "\","
<< "\"fileSize\": \"" << result.file_size << "\","
<< "\"format\": \"" << result.format << "\","
<< "\"exportTime\": \"" << result.export_time << "\","
<< "\"software\": \"" << result.software << "\","
<< "\"originalFile\": \"" << EscapeJsonString(result.original_file) << "\","
<< "\"details\": {"
<< "\"dirname\": \"" << EscapeJsonString(result.dirname) << "\","
<< "\"filename\": \"" << EscapeJsonString(result.filename) << "\","
<< "\"creoson_response\": {"
<< "\"dirname\": \"" << EscapeJsonString(result.dirname) << "\","
<< "\"filename\": \"" << EscapeJsonString(result.filename) << "\","
<< "\"full_path\": \"" << EscapeJsonString(result.export_path) << "\""
<< "}"
<< "}"
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.body = json.str();
response.status_code = 500;
}
return response;
}
// JSON数组解析函数
std::vector<std::string> ExtractJsonArray(const std::string& json, const std::string& key) {
std::vector<std::string> result;
try {
// 查找键值对 "key": [...]
std::string key_pattern = "\"" + key + "\"";
size_t key_pos = json.find(key_pattern);
if (key_pos != std::string::npos) {
// 找到冒号
size_t colon_pos = json.find(":", key_pos);
if (colon_pos != std::string::npos) {
// 跳过空格找到数组开始
size_t array_start = colon_pos + 1;
while (array_start < json.length() && (json[array_start] == ' ' || json[array_start] == '\t' || json[array_start] == '\n' || json[array_start] == '\r')) {
array_start++;
}
// 检查是否是数组(以方括号开始)
if (array_start < json.length() && json[array_start] == '[') {
size_t array_end = json.find(']', array_start);
if (array_end != std::string::npos) {
std::string array_content = json.substr(array_start + 1, array_end - array_start - 1);
// 解析数组中的字符串元素
size_t pos = 0;
while (pos < array_content.length()) {
// 跳过空格和逗号
while (pos < array_content.length() && (array_content[pos] == ' ' || array_content[pos] == '\t' || array_content[pos] == '\n' || array_content[pos] == '\r' || array_content[pos] == ',')) {
pos++;
}
// 查找字符串开始
if (pos < array_content.length() && array_content[pos] == '"') {
size_t str_start = pos + 1;
size_t str_end = array_content.find('"', str_start);
if (str_end != std::string::npos) {
std::string element = array_content.substr(str_start, str_end - str_start);
if (!element.empty()) {
result.push_back(element);
}
pos = str_end + 1;
} else {
break;
}
} else {
break;
}
}
}
}
}
}
} catch (...) {
// 解析失败,返回空数组
}
return result;
}
// 按路径删除组件处理器
HttpResponse PathDeleteHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
PathDeleteManager::PathDeleteRequest delete_request;
delete_request.software_type = ExtractJsonValue(request.body, "software_type");
delete_request.component_paths = ExtractJsonArray(request.body, "component_paths");
std::string force_delete_str = ExtractJsonValue(request.body, "force_delete");
delete_request.force_delete = (force_delete_str == "true");
// 参数验证
if (delete_request.software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
if (delete_request.software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
if (delete_request.component_paths.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: component_paths\"}";
return response;
}
// 执行按路径删除
PathDeleteManager::PathDeleteResult result = PathDeleteManager::Instance().DeleteComponentsByPaths(delete_request);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"successfully_deleted\": [";
// 构建成功删除列表
for (size_t i = 0; i < result.successfully_deleted.size(); i++) {
if (i > 0) json << ",";
json << "\"" << EscapeJsonString(result.successfully_deleted[i]) << "\"";
}
json << "],"
<< "\"failed_to_delete\": [";
// 构建失败删除列表
for (size_t i = 0; i < result.failed_to_delete.size(); i++) {
if (i > 0) json << ",";
json << "\"" << EscapeJsonString(result.failed_to_delete[i]) << "\"";
}
json << "],"
<< "\"deletion_summary\": {"
<< "\"total_requested\": " << result.total_requested << ","
<< "\"successful\": " << result.successful << ","
<< "\"failed\": " << result.failed
<< "},"
<< "\"deletion_reasons\": {";
// 构建删除原因映射
bool first_reason = true;
for (const auto& reason_pair : result.deletion_reasons) {
if (!first_reason) json << ",";
first_reason = false;
json << "\"" << EscapeJsonString(reason_pair.first) << "\": \""
<< EscapeJsonString(reason_pair.second) << "\"";
}
json << "}"
<< "},"
<< "\"error\": null"
<< "}";
response.status_code = 200;
response.body = json.str();
} else {
// 构建失败响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": {"
<< "\"successfully_deleted\": [],"
<< "\"failed_to_delete\": [";
// 构建失败删除列表
for (size_t i = 0; i < result.failed_to_delete.size(); i++) {
if (i > 0) json << ",";
json << "\"" << EscapeJsonString(result.failed_to_delete[i]) << "\"";
}
json << "],"
<< "\"deletion_summary\": {"
<< "\"total_requested\": " << result.total_requested << ","
<< "\"successful\": " << result.successful << ","
<< "\"failed\": " << result.failed
<< "},"
<< "\"deletion_reasons\": {";
// 构建删除原因映射
bool first_reason = true;
for (const auto& reason_pair : result.deletion_reasons) {
if (!first_reason) json << ",";
first_reason = false;
json << "\"" << EscapeJsonString(reason_pair.first) << "\": \""
<< EscapeJsonString(reason_pair.second) << "\"";
}
json << "}"
<< "},"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Request processing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Unknown error during path deletion\"}";
}
return response;
}
// 层级分析路由处理器
HttpResponse HierarchyAnalysisHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求
HierarchyAnalysisRequest analysis_request;
// 简单的JSON解析参考现有的ExtractJsonValue方法
analysis_request.software_type = ExtractJsonValue(request.body, "software_type");
analysis_request.project_name = ExtractJsonValue(request.body, "project_name");
analysis_request.include_geometry = ExtractJsonValue(request.body, "include_geometry") == "true";
// 解析max_depth参数保持兼容性但不实际使用
std::string max_depth_str = ExtractJsonValue(request.body, "max_depth");
if (!max_depth_str.empty()) {
try {
analysis_request.max_depth = std::stoi(max_depth_str);
} catch (...) {
analysis_request.max_depth = 0; // 0表示无限制
}
} else {
analysis_request.max_depth = 0; // 0表示无限制
}
// 解析target_level参数指定返回的层级
std::string target_level_str = ExtractJsonValue(request.body, "target_level");
if (!target_level_str.empty()) {
try {
analysis_request.target_level = std::stoi(target_level_str);
} catch (...) {
analysis_request.target_level = -1; // -1表示返回所有层级
}
} else {
analysis_request.target_level = -1; // -1表示返回所有层级
}
// 执行层级分析
HierarchyAnalysisResult result = CreoManager::Instance().AnalyzeModelHierarchy(analysis_request);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"message\": \"" << result.message << "\","
<< "\"data\": {"
<< "\"project_name\": \"" << EscapeJsonString(result.project_name) << "\","
<< "\"total_levels\": " << result.total_levels << ","
<< "\"total_components\": " << result.total_components << ","
<< "\"hierarchy\": [";
// 构建层级数据
for (size_t level = 0; level < result.hierarchy.size(); level++) {
if (level > 0) json << ",";
json << "{"
<< "\"level\": " << level << ","
<< "\"name\": \"" << (level == 0 ? "Main Assembly" :
level == 1 ? "Sub Assembly" :
level == 2 ? "Parts" :
"Level " + std::to_string(level + 1) + " Components") << "\","
<< "\"components\": [";
for (size_t comp = 0; comp < result.hierarchy[level].size(); comp++) {
if (comp > 0) json << ",";
const ComponentInfo& component = result.hierarchy[level][comp];
json << "{"
<< "\"id\": \"" << EscapeJsonString(component.id) << "\","
<< "\"name\": \"" << EscapeJsonString(component.name) << "\","
<< "\"type\": \"" << EscapeJsonString(component.type) << "\","
<< "\"level\": " << component.level << ","
<< "\"children_count\": " << component.children_count << ","
<< "\"path\": \"" << EscapeJsonString(component.full_path) << "\","
<< "\"file_size\": \"" << EscapeJsonString(component.file_size) << "\","
<< "\"deletion_safety\": \"" << EscapeJsonString(component.deletion_safety) << "\""
<< "}";
}
json << "]}";
}
json << "],"
<< "\"deletion_recommendations\": {"
<< "\"safe_deletions\": [],"
<< "\"risky_deletions\": [";
// 构建删除建议
for (size_t i = 0; i < result.risky_deletions.size(); i++) {
if (i > 0) json << ",";
const DeletionRecommendation& rec = result.risky_deletions[i];
json << "{"
<< "\"component_id\": \"" << EscapeJsonString(rec.component_id) << "\","
<< "\"component_name\": \"" << EscapeJsonString(rec.component_name) << "\","
<< "\"level\": " << rec.level << ","
<< "\"reason\": \"" << EscapeJsonString(rec.reason) << "\","
<< "\"risk_factors\": [";
for (size_t j = 0; j < rec.risk_factors.size(); j++) {
if (j > 0) json << ",";
json << "\"" << EscapeJsonString(rec.risk_factors[j]) << "\"";
}
json << "],"
<< "\"confidence\": " << rec.confidence
<< "}";
}
json << "]"
<< "}"
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建失败响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << result.error_message << "\""
<< "}";
response.body = json.str();
response.status_code = 500;
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Unknown error during hierarchy analysis\"}";
}
return response;
}
// 层级删除路由处理器
HttpResponse HierarchyDeleteHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求
std::string software_type = ExtractJsonValue(request.body, "software_type");
std::string project_name = ExtractJsonValue(request.body, "project_name");
std::string target_level_str = ExtractJsonValue(request.body, "target_level");
if (software_type.empty() || project_name.empty() || target_level_str.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameters: software_type, project_name, target_level\"}";
return response;
}
int target_level;
try {
target_level = std::stoi(target_level_str);
} catch (...) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid target_level parameter\"}";
return response;
}
// 执行层级删除
CreoManager::HierarchyDeleteResult result = CreoManager::Instance().DeleteHierarchyComponents(project_name, target_level);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"message\": \"" << EscapeJsonString(result.message) << "\","
<< "\"data\": {"
<< "\"original_levels\": " << result.original_levels << ","
<< "\"target_level\": " << result.target_level << ","
<< "\"final_levels\": " << result.final_levels << ","
<< "\"deleted_components\": {";
// 构建删除组件数据
bool first_level = true;
for (const auto& level_pair : result.deleted_components) {
if (!first_level) json << ",";
first_level = false;
json << "\"level_" << level_pair.first << "\": [";
bool first_component = true;
for (const auto& component : level_pair.second) {
if (!first_component) json << ",";
first_component = false;
json << "\"" << EscapeJsonString(component) << "\"";
}
json << "]";
}
json << "},"
<< "\"deletion_summary\": {"
<< "\"total_deleted\": " << result.total_deleted << ","
<< "\"successful\": " << result.successful << ","
<< "\"failed\": " << result.failed
<< "}"
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"message\": \"" << EscapeJsonString(result.message) << "\","
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Unknown error during hierarchy deletion\"}";
}
return response;
}
// 薄壳化分析处理器
HttpResponse ShellAnalysisHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
CreoManager::ShellAnalysisRequest analysis_request;
// 必填参数
analysis_request.software_type = ExtractJsonValue(request.body, "software_type");
if (analysis_request.software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
if (analysis_request.software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 可选参数解析
std::string project_name = ExtractJsonValue(request.body, "projectName");
if (!project_name.empty()) {
analysis_request.project_name = project_name;
}
std::string analysis_type = ExtractJsonValue(request.body, "analysisType");
if (!analysis_type.empty()) {
analysis_request.analysis_type = analysis_type;
}
std::string preserve_external = ExtractJsonValue(request.body, "preserveExternalSurfaces");
if (!preserve_external.empty()) {
analysis_request.preserve_external_surfaces = (preserve_external == "true");
}
std::string min_thickness = ExtractJsonValue(request.body, "minWallThickness");
if (!min_thickness.empty()) {
try {
analysis_request.min_wall_thickness = std::stod(min_thickness);
} catch (...) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid minWallThickness parameter\"}";
return response;
}
}
std::string confidence = ExtractJsonValue(request.body, "confidenceThreshold");
if (!confidence.empty()) {
try {
analysis_request.confidence_threshold = std::stod(confidence);
if (analysis_request.confidence_threshold < 0.0 || analysis_request.confidence_threshold > 1.0) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"confidenceThreshold must be between 0.0 and 1.0\"}";
return response;
}
} catch (...) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid confidenceThreshold parameter\"}";
return response;
}
}
// Execute enhanced shell analysis (uses new algorithm with real geometry APIs)
CreoManager::ShellAnalysisResult result = CreoManager::Instance().AnalyzeShellFeaturesEnhanced(analysis_request);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"safeDeletions\": [";
// 构建安全删除列表
bool first_item = true;
for (const auto& deletion : result.safe_deletions) {
if (!first_item) json << ",";
first_item = false;
json << "{"
<< "\"id\": " << deletion.id << ","
<< "\"name\": \"" << EscapeJsonString(deletion.name) << "\","
<< "\"type\": \"" << EscapeJsonString(deletion.type) << "\","
<< "\"reason\": \"" << EscapeJsonString(deletion.reason) << "\","
<< "\"confidence\": " << deletion.confidence << ","
<< "\"volumeReduction\": " << deletion.volume_reduction << ","
<< "\"partFile\": \"" << EscapeJsonString(deletion.part_file) << "\","
<< "\"partPath\": \"" << EscapeJsonString(deletion.part_path) << "\","
<< "\"componentType\": \"" << EscapeJsonString(deletion.component_type) << "\","
<< "\"voteCount\": " << deletion.vote_count
<< "}";
}
json << "],"
<< "\"suggestedDeletions\": [";
// 构建建议删除列表
first_item = true;
for (const auto& deletion : result.suggested_deletions) {
if (!first_item) json << ",";
first_item = false;
json << "{"
<< "\"id\": " << deletion.id << ","
<< "\"name\": \"" << EscapeJsonString(deletion.name) << "\","
<< "\"type\": \"" << EscapeJsonString(deletion.type) << "\","
<< "\"reason\": \"" << EscapeJsonString(deletion.reason) << "\","
<< "\"confidence\": " << deletion.confidence << ","
<< "\"volumeReduction\": " << deletion.volume_reduction << ","
<< "\"partFile\": \"" << EscapeJsonString(deletion.part_file) << "\","
<< "\"partPath\": \"" << EscapeJsonString(deletion.part_path) << "\","
<< "\"componentType\": \"" << EscapeJsonString(deletion.component_type) << "\","
<< "\"voteCount\": " << deletion.vote_count
<< "}";
}
json << "],"
<< "\"preserveList\": [";
// 构建保留列表
first_item = true;
for (const auto& preserve : result.preserve_list) {
if (!first_item) json << ",";
first_item = false;
json << "{"
<< "\"id\": " << preserve.id << ","
<< "\"name\": \"" << EscapeJsonString(preserve.name) << "\","
<< "\"type\": \"" << EscapeJsonString(preserve.type) << "\","
<< "\"reason\": \"" << EscapeJsonString(preserve.reason) << "\","
<< "\"confidence\": " << preserve.confidence << ","
<< "\"volumeReduction\": " << preserve.volume_reduction << ","
<< "\"partFile\": \"" << EscapeJsonString(preserve.part_file) << "\","
<< "\"partPath\": \"" << EscapeJsonString(preserve.part_path) << "\","
<< "\"componentType\": \"" << EscapeJsonString(preserve.component_type) << "\","
<< "\"voteCount\": " << preserve.vote_count
<< "}";
}
json << "],"
<< "\"estimatedReduction\": {"
<< "\"volumeReduction\": \"" << EscapeJsonString(result.estimated_reduction.volume_reduction) << "\","
<< "\"fileSizeReduction\": \"" << EscapeJsonString(result.estimated_reduction.file_size_reduction) << "\","
<< "\"performanceImprovement\": \"" << EscapeJsonString(result.estimated_reduction.performance_improvement) << "\""
<< "},"
<< "\"analysisParameters\": {"
<< "\"preserveExternalSurfaces\": " << (result.analysis_parameters.preserve_external_surfaces ? "true" : "false") << ","
<< "\"minWallThickness\": " << result.analysis_parameters.min_wall_thickness << ","
<< "\"confidenceThreshold\": " << result.analysis_parameters.confidence_threshold << ","
<< "\"totalFeatures\": " << result.analysis_parameters.total_features << ","
<< "\"deletableFeatures\": " << result.analysis_parameters.deletable_features << ","
<< "\"preservedFeatures\": " << result.analysis_parameters.preserved_features << ","
<< "\"assemblyAnalysis\": " << (result.analysis_parameters.assembly_analysis ? "true" : "false") << ","
<< "\"analysisStrategy\": \"" << EscapeJsonString(result.analysis_parameters.analysis_strategy) << "\","
<< "\"surfaceCount\": " << result.analysis_parameters.surface_count << ","
<< "\"shellSurfaces\": " << result.analysis_parameters.shell_surfaces << ","
<< "\"internalSurfaces\": " << result.analysis_parameters.internal_surfaces << ","
<< "\"shellFeatureWhitelist\": " << result.analysis_parameters.shell_feature_whitelist;
// 添加层次分析信息
if (result.analysis_parameters.hierarchy_analysis.enabled) {
json << ","
<< "\"hierarchyAnalysis\": {"
<< "\"enabled\": true,"
<< "\"totalParts\": " << result.analysis_parameters.hierarchy_analysis.total_parts << ","
<< "\"outerParts\": " << result.analysis_parameters.hierarchy_analysis.outer_parts << ","
<< "\"internalParts\": " << result.analysis_parameters.hierarchy_analysis.internal_parts << ","
<< "\"containmentRelationships\": " << result.analysis_parameters.hierarchy_analysis.containment_relationships << ","
<< "\"performanceStats\": {";
bool first_stat = true;
for (const auto& stat : result.analysis_parameters.hierarchy_analysis.performance_stats) {
if (!first_stat) json << ",";
first_stat = false;
json << "\"" << EscapeJsonString(stat.first) << "\": \"" << EscapeJsonString(stat.second) << "\"";
}
json << "}"
<< "}";
}
json << "}" // 结束 analysisParameters (不加逗号)
<< "}," // 结束 data (加逗号)
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during shell analysis\"}";
}
return response;
}
// 保存模型路由处理器
HttpResponse SaveModelHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
std::string software_type = ExtractJsonValue(request.body, "software_type");
// 参数验证
if (software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
if (software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 执行保存操作
SaveResult result = CreoManager::Instance().SaveModel();
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"file_size\": \"" << EscapeJsonString(result.file_size) << "\","
<< "\"save_time\": \"" << EscapeJsonString(result.save_time) << "\","
<< "\"software\": \"" << EscapeJsonString(result.software) << "\","
<< "\"original_file\": \"" << EscapeJsonString(result.original_file) << "\""
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during save operation\"}";
}
return response;
}
// 关闭模型路由处理器
HttpResponse CloseModelHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
std::string software_type = ExtractJsonValue(request.body, "software_type");
std::string force_close_str = ExtractJsonValue(request.body, "force_close");
// 参数验证
if (software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
if (software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 解析force_close参数
bool force_close = (force_close_str == "true");
// 执行关闭操作
CloseResult result = CreoManager::Instance().CloseModel(force_close);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"model_name\": \"" << EscapeJsonString(result.model_name) << "\","
<< "\"was_modified\": " << (result.was_modified ? "true" : "false") << ","
<< "\"close_time\": \"" << EscapeJsonString(result.close_time) << "\""
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during close operation\"}";
}
return response;
}
// 打开模型路由处理器
HttpResponse OpenModelHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
std::string software_type = ExtractJsonValue(request.body, "software_type");
std::string file_path = ExtractJsonValue(request.body, "file_path");
std::string dirname = ExtractJsonValue(request.body, "dirname");
std::string filename = ExtractJsonValue(request.body, "filename");
std::string open_mode = ExtractJsonValue(request.body, "open_mode");
// 参数验证
if (software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
// 支持两种路径格式完整路径或分离的dirname+filename
if (file_path.empty()) {
if (dirname.empty() || filename.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameters: either 'file_path' or both 'dirname' and 'filename'\"}";
return response;
}
// 组合dirname和filename为完整路径creoson风格
file_path = dirname + "/" + filename;
}
if (software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 设置默认打开模式
if (open_mode.empty()) {
open_mode = "active";
}
// 使用无锁消息机制
MessageItem open_message_item;
open_message_item.type = "OPEN_MODEL_REQUEST";
open_message_item.data = file_path;
open_message_item.extra = open_mode;
// 原子设置(无锁)
pending_message_item = &open_message_item;
has_pending_item = true;
// 等待主线程完成操作(带超时)
int timeout_ms = 10000; // 10秒超时
while (!open_message_item.completed && timeout_ms > 0) {
Sleep(50);
timeout_ms -= 50;
}
OpenResult result;
if (open_message_item.completed && open_message_item.result_ptr) {
result = *static_cast<OpenResult*>(open_message_item.result_ptr);
delete static_cast<OpenResult*>(open_message_item.result_ptr); // 清理内存
} else {
// 超时处理
result.success = false;
result.error_message = "Operation timeout: OpenModel took too long to complete";
}
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"model_name\": \"" << EscapeJsonString(result.model_name) << "\","
<< "\"model_type\": \"" << EscapeJsonString(result.model_type) << "\","
<< "\"file_path\": \"" << EscapeJsonString(result.file_path) << "\","
<< "\"file_size\": \"" << EscapeJsonString(result.file_size) << "\","
<< "\"open_time\": \"" << EscapeJsonString(result.open_time) << "\","
<< "\"is_assembly\": " << (result.is_assembly ? "true" : "false") << ","
<< "\"total_parts\": " << result.total_parts << ","
<< "\"model_in_session\": " << (result.model_in_session ? "true" : "false") << ","
<< "\"window_model_match\": " << (result.window_model_match ? "true" : "false")
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during open operation\"}";
}
return response;
}
// 几何复杂度分析路由处理器
HttpResponse GeometryComplexityHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析请求参数
GeometryComplexityRequest complexity_request;
// 提取JSON参数
complexity_request.software_type = ExtractJsonValue(request.body, "software_type");
complexity_request.project_name = ExtractJsonValue(request.body, "project_name");
std::string max_results_str = ExtractJsonValue(request.body, "max_results");
if (!max_results_str.empty()) {
complexity_request.max_results = std::stoi(max_results_str);
}
std::string include_details_str = ExtractJsonValue(request.body, "include_details");
if (!include_details_str.empty()) {
complexity_request.include_details = (include_details_str == "true");
}
complexity_request.sort_order = ExtractJsonValue(request.body, "sort_order");
if (complexity_request.sort_order.empty()) {
complexity_request.sort_order = "desc";
}
std::string threshold_str = ExtractJsonValue(request.body, "complexity_threshold");
if (!threshold_str.empty()) {
complexity_request.complexity_threshold = std::stod(threshold_str);
}
// 参数验证
if (complexity_request.software_type.empty()) {
complexity_request.software_type = "creo";
}
if (complexity_request.project_name.empty()) {
complexity_request.project_name = "Geometry Complexity Analysis";
}
if (complexity_request.software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 执行几何复杂度分析
GeometryComplexityResult result = GeometryAnalyzer::Instance().AnalyzeGeometryComplexity(complexity_request);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"message\": \"" << EscapeJsonString(result.message) << "\","
<< "\"data\": {"
<< "\"parts\": [";
for (size_t i = 0; i < result.parts.size(); ++i) {
const GeometryComplexityInfo& part = result.parts[i];
if (i > 0) json << ",";
json << "{"
<< "\"part_name\": \"" << EscapeJsonString(part.part_name) << "\","
<< "\"part_path\": \"" << EscapeJsonString(part.part_path) << "\","
<< "\"file_size\": \"" << EscapeJsonString(part.file_size) << "\","
<< "\"complexity_score\": " << part.complexity_score << ","
<< "\"complexity_level\": \"" << EscapeJsonString(part.complexity_level) << "\","
<< "\"feature_count\": " << part.feature_count << ","
<< "\"surface_count\": " << part.surface_count << ","
<< "\"curved_surface_count\": " << part.curved_surface_count << ","
<< "\"hole_count\": " << part.hole_count << ","
<< "\"fillet_count\": " << part.fillet_count << ","
<< "\"pattern_count\": " << part.pattern_count << ","
<< "\"sketch_count\": " << part.sketch_count << ","
<< "\"volume\": " << part.volume << ","
<< "\"surface_area\": " << part.surface_area << ","
<< "\"bounding_box_volume\": " << part.bounding_box_volume << ","
<< "\"complexity_factors\": [";
for (size_t j = 0; j < part.complexity_factors.size(); ++j) {
if (j > 0) json << ",";
json << "\"" << EscapeJsonString(part.complexity_factors[j]) << "\"";
}
json << "]"
<< "}";
}
json << "],"
<< "\"total_parts_analyzed\": " << result.total_parts_analyzed << ","
<< "\"analysis_time\": \"" << EscapeJsonString(result.analysis_time) << "\","
<< "\"average_complexity\": " << result.average_complexity << ","
<< "\"max_complexity\": " << result.max_complexity << ","
<< "\"min_complexity\": " << result.min_complexity
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Exception during geometry complexity analysis: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during geometry complexity analysis\"}";
}
return response;
}
// Shrinkwrap外壳导出路由处理器
HttpResponse ShrinkwrapShellHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析请求获取超时参数
int timeout_seconds = 30; // 默认值
try {
// 简单解析JSON获取timeout_seconds
std::string json_body = request.body;
std::string search_pattern = "\"timeout_seconds\"\\s*:\\s*(\\d+)";
std::regex timeout_regex(search_pattern);
std::smatch match;
if (std::regex_search(json_body, match, timeout_regex)) {
int parsed_timeout = std::stoi(match[1].str());
if (parsed_timeout >= 10 && parsed_timeout <= 300) {
timeout_seconds = parsed_timeout;
}
}
} catch (...) {
// 解析失败,使用默认值
timeout_seconds = 30;
}
// 使用无锁消息机制
MessageItem shrinkwrap_message_item;
shrinkwrap_message_item.type = "SHRINKWRAP_SHELL_REQUEST";
shrinkwrap_message_item.data = request.body;
// 原子设置(无锁)
pending_message_item = &shrinkwrap_message_item;
has_pending_item = true;
// 等待主线程完成操作(带动态超时)
int timeout_ms = timeout_seconds * 1000; // 转换为毫秒
while (!shrinkwrap_message_item.completed && timeout_ms > 0) {
Sleep(100); // 稍长的间隔因为Shrinkwrap是重操作
timeout_ms -= 100;
}
if (shrinkwrap_message_item.completed && shrinkwrap_message_item.result_ptr) {
HttpResponse result = *static_cast<HttpResponse*>(shrinkwrap_message_item.result_ptr);
delete static_cast<HttpResponse*>(shrinkwrap_message_item.result_ptr); // 清理内存
return result;
} else {
// 超时处理
response.status_code = 504;
response.body = "{\"success\": false, \"error\": \"Operation timeout: Shrinkwrap export exceeded " + std::to_string(timeout_seconds) + " seconds limit\"}";
return response;
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Request processing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Unknown error during shrinkwrap shell export\"}";
}
return response;
}
// 层级统计分析路由处理器
HttpResponse HierarchyStatisticsHandler(const HttpRequest& request) {
HttpResponse response;
response.headers["Content-Type"] = "application/json";
// 只支持POST请求
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed. Use POST.\"}";
return response;
}
try {
// 解析请求参数
HierarchyStatisticsRequest stats_request;
// 提取project_name参数可选
std::string project_name_str = ExtractJsonValue(request.body, "project_name");
if (!project_name_str.empty()) {
stats_request.project_name = project_name_str;
}
// 执行层级统计分析
HierarchyStatisticsResult result = HierarchyStatisticsAnalyzer::Instance().AnalyzeHierarchyStatistics(stats_request);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"message\": \"" << result.message << "\","
<< "\"data\": {"
<< "\"model_name\": \"" << EscapeJsonString(result.model_name) << "\","
<< "\"model_type\": \"" << result.model_type << "\","
<< "\"total_levels\": " << result.total_levels << ","
<< "\"analysis_time\": \"" << result.analysis_time << "\","
<< "\"statistics\": {";
// 构建层级统计数据
bool first = true;
for (const auto& stat : result.level_statistics) {
if (!first) json << ",";
json << "\"" << stat.first << "\": " << stat.second;
first = false;
}
json << "}"
<< "}"
<< "}";
response.body = json.str();
} else {
// 构建失败响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.body = json.str();
response.status_code = 500;
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Exception: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"error\": \"Unknown error during hierarchy statistics analysis\"}";
}
return response;
}
extern "C" int user_initialize(
int argc,
char* argv[],
char* version,
char* build,
wchar_t errbuf[80])
{
pfcSession_ptr Session = pfcGetCurrentSessionWithCompatibility(pfcC4Compatible);
wfcWSession_ptr wSession = wfcWSession::cast(Session);
xstring info = L"New HTTP Server Starting on port 12345";
wSession->UIShowMessageDialog(info, NULL);
// 启动定时器处理消息
timer_id = SetTimer(NULL, 0, 100, TimerProc);
// 创建并启动HTTP服务器
g_http_server = std::make_unique<HttpServer>();
// 设置路由
g_http_server->SetRouteHandler("/test", TestHandler);
g_http_server->SetRouteHandler("/show_message", ShowMessageHandler);
g_http_server->SetRouteHandler("/api/status/creo", CreoStatusHandler);
g_http_server->SetRouteHandler("/api/status/model", ModelStatusHandler);
g_http_server->SetRouteHandler("/api/export/model", ExportModelHandler);
g_http_server->SetRouteHandler("/api/creo/analysis/hierarchy", HierarchyAnalysisHandler);
g_http_server->SetRouteHandler("/api/creo/hierarchy/delete", HierarchyDeleteHandler);
g_http_server->SetRouteHandler("/api/analysis/shell-analysis", ShellAnalysisHandler);
g_http_server->SetRouteHandler("/api/model/save", SaveModelHandler);
g_http_server->SetRouteHandler("/api/model/close", CloseModelHandler);
g_http_server->SetRouteHandler("/api/model/open", OpenModelHandler);
g_http_server->SetRouteHandler("/api/analysis/geometry-complexity", GeometryComplexityHandler);
g_http_server->SetRouteHandler("/api/creo/shrinkwrap/shell", ShrinkwrapShellHandler);
g_http_server->SetRouteHandler("/api/creo/component/delete-by-path", PathDeleteHandler);
g_http_server->SetRouteHandler("/api/search/models", ModelSearchHandler::HandleModelSearchRequest);
g_http_server->SetRouteHandler("/api/analysis/hierarchy-statistics", HierarchyStatisticsHandler);
if (g_http_server->Start()) {
return 0;
} else {
g_http_server.reset();
return 1;
}
}
// --- OTK 出口函数 ---
// 这个函数在卸载插件或关闭 Creo 时被调用,非常重要!
extern "C" void user_terminate()
{
if (g_http_server) {
g_http_server->Stop();
g_http_server.reset();
}
if (timer_id != 0) {
KillTimer(NULL, timer_id);
timer_id = 0;
}
}