1179 lines
46 KiB
C++
1179 lines
46 KiB
C++
#include "pch.h"
|
|
#include "BatchOperationManager.h"
|
|
#include "CreoManager.h"
|
|
#include "PathDeleteManager.h"
|
|
#include "ShrinkwrapManager.h"
|
|
#include <sstream>
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
|
|
// Helper: Get current time as string
|
|
std::string BatchOperationManager::GetCurrentTimeString() {
|
|
auto now = std::chrono::system_clock::now();
|
|
auto now_time = std::chrono::system_clock::to_time_t(now);
|
|
std::tm local_time;
|
|
localtime_s(&local_time, &now_time);
|
|
|
|
std::ostringstream oss;
|
|
oss << std::put_time(&local_time, "%Y-%m-%d %H:%M:%S");
|
|
return oss.str();
|
|
}
|
|
|
|
// Helper: Escape JSON string
|
|
std::string BatchOperationManager::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;
|
|
}
|
|
|
|
// Build JSON result for SaveModel
|
|
std::string BatchOperationManager::BuildSaveResultJson(const SaveResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"file_size\":\"" << EscapeJsonString(result.file_size) << "\","
|
|
<< "\"save_time\":\"" << EscapeJsonString(result.save_time) << "\","
|
|
<< "\"software\":\"" << EscapeJsonString(result.software) << "\","
|
|
<< "\"original_file\":\"" << EscapeJsonString(result.original_file) << "\""
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for ExportModel
|
|
std::string BatchOperationManager::BuildExportResultJson(const ExportResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"export_path\":\"" << EscapeJsonString(result.export_path) << "\","
|
|
<< "\"file_size\":\"" << EscapeJsonString(result.file_size) << "\","
|
|
<< "\"format\":\"" << EscapeJsonString(result.format) << "\","
|
|
<< "\"export_time\":\"" << EscapeJsonString(result.export_time) << "\","
|
|
<< "\"software\":\"" << EscapeJsonString(result.software) << "\","
|
|
<< "\"original_file\":\"" << EscapeJsonString(result.original_file) << "\","
|
|
<< "\"dirname\":\"" << EscapeJsonString(result.dirname) << "\","
|
|
<< "\"filename\":\"" << EscapeJsonString(result.filename) << "\""
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for DeleteByPath
|
|
std::string BatchOperationManager::BuildDeleteByPathResultJson(const PathDeleteManager::PathDeleteResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"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 << "],\"total_requested\":" << result.total_requested
|
|
<< ",\"successful\":" << result.successful
|
|
<< ",\"failed\":" << result.failed
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for HierarchyDelete
|
|
std::string BatchOperationManager::BuildHierarchyDeleteResultJson(const CreoManager::HierarchyDeleteResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"message\":\"" << EscapeJsonString(result.message) << "\","
|
|
<< "\"original_levels\":" << result.original_levels << ","
|
|
<< "\"target_level\":" << result.target_level << ","
|
|
<< "\"final_levels\":" << result.final_levels << ","
|
|
<< "\"total_deleted\":" << result.total_deleted << ","
|
|
<< "\"successful\":" << result.successful << ","
|
|
<< "\"failed\":" << result.failed
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for Shrinkwrap
|
|
std::string BatchOperationManager::BuildShrinkwrapResultJson(const ShrinkwrapShellResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"message\":\"" << EscapeJsonString(result.message) << "\","
|
|
<< "\"output_file_path\":\"" << EscapeJsonString(result.parameters.output_file_path) << "\","
|
|
<< "\"output_file_size\":\"" << EscapeJsonString(result.parameters.output_file_size) << "\","
|
|
<< "\"shrinkwrap_time\":\"" << EscapeJsonString(result.parameters.shrinkwrap_time) << "\","
|
|
<< "\"quality\":" << result.parameters.quality << ","
|
|
<< "\"chord_height\":" << result.parameters.chord_height
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for CloseModel
|
|
std::string BatchOperationManager::BuildCloseResultJson(const CloseResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"model_name\":\"" << EscapeJsonString(result.model_name) << "\","
|
|
<< "\"was_modified\":" << (result.was_modified ? "true" : "false") << ","
|
|
<< "\"close_time\":\"" << EscapeJsonString(result.close_time) << "\""
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON result for OpenModel
|
|
std::string BatchOperationManager::BuildOpenResultJson(const OpenResult& result) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"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
|
|
<< "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Build JSON for workflow step
|
|
std::string BatchOperationManager::BuildWorkflowStepJson(const std::string& step_name,
|
|
bool success,
|
|
const std::string& time,
|
|
const std::string& error) {
|
|
std::ostringstream json;
|
|
json << "{"
|
|
<< "\"step\":\"" << EscapeJsonString(step_name) << "\","
|
|
<< "\"success\":" << (success ? "true" : "false") << ","
|
|
<< "\"time\":\"" << EscapeJsonString(time) << "\"";
|
|
|
|
if (!error.empty()) {
|
|
json << ",\"error\":\"" << EscapeJsonString(error) << "\"";
|
|
}
|
|
|
|
json << "}";
|
|
return json.str();
|
|
}
|
|
|
|
// Execute save_model operation
|
|
BatchOperationResult BatchOperationManager::ExecuteSaveModel(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "save_model";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
SaveResult save_result = CreoManager::Instance().SaveModel();
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = save_result.success;
|
|
if (save_result.success) {
|
|
result.result_json = BuildSaveResultJson(save_result);
|
|
} else {
|
|
result.error_message = save_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during save operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute export_model operation
|
|
BatchOperationResult BatchOperationManager::ExecuteExportModel(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "export_model";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
// Extract parameters
|
|
std::string export_path;
|
|
std::string geom_flags = "solids";
|
|
|
|
auto it = operation.parameters.find("export_path");
|
|
if (it != operation.parameters.end()) {
|
|
export_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("geom_flags");
|
|
if (it != operation.parameters.end()) {
|
|
geom_flags = it->second;
|
|
}
|
|
|
|
if (export_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: export_path";
|
|
return result;
|
|
}
|
|
|
|
ExportResult export_result = CreoManager::Instance().ExportModelToSTEP(export_path, geom_flags);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = export_result.success;
|
|
if (export_result.success) {
|
|
result.result_json = BuildExportResultJson(export_result);
|
|
} else {
|
|
result.error_message = export_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during export operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute delete_by_path operation
|
|
BatchOperationResult BatchOperationManager::ExecuteDeleteByPath(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "delete_by_path";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
PathDeleteManager::PathDeleteRequest delete_request;
|
|
delete_request.software_type = "creo";
|
|
delete_request.component_paths = operation.array_parameters;
|
|
|
|
auto it = operation.parameters.find("force_delete");
|
|
if (it != operation.parameters.end()) {
|
|
delete_request.force_delete = (it->second == "true");
|
|
}
|
|
|
|
if (delete_request.component_paths.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: component_paths";
|
|
return result;
|
|
}
|
|
|
|
PathDeleteManager::PathDeleteResult delete_result =
|
|
PathDeleteManager::Instance().DeleteComponentsByPaths(delete_request);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = delete_result.success;
|
|
if (delete_result.success) {
|
|
result.result_json = BuildDeleteByPathResultJson(delete_result);
|
|
} else {
|
|
result.error_message = delete_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during delete by path operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute hierarchy_delete operation
|
|
BatchOperationResult BatchOperationManager::ExecuteHierarchyDelete(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "hierarchy_delete";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
std::string project_name;
|
|
int target_level = 0;
|
|
|
|
auto it = operation.parameters.find("project_name");
|
|
if (it != operation.parameters.end()) {
|
|
project_name = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("target_level");
|
|
if (it != operation.parameters.end()) {
|
|
try {
|
|
target_level = std::stoi(it->second);
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Invalid target_level parameter";
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if (project_name.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: project_name";
|
|
return result;
|
|
}
|
|
|
|
CreoManager::HierarchyDeleteResult delete_result =
|
|
CreoManager::Instance().DeleteHierarchyComponents(project_name, target_level);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = delete_result.success;
|
|
if (delete_result.success) {
|
|
result.result_json = BuildHierarchyDeleteResultJson(delete_result);
|
|
} else {
|
|
result.error_message = delete_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during hierarchy delete operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute shrinkwrap_shell operation
|
|
BatchOperationResult BatchOperationManager::ExecuteShrinkwrapShell(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "shrinkwrap_shell";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
ShrinkwrapShellRequest shrink_request;
|
|
|
|
// Extract parameters
|
|
auto it = operation.parameters.find("output_file_path");
|
|
if (it != operation.parameters.end()) {
|
|
shrink_request.output_file_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("quality");
|
|
if (it != operation.parameters.end()) {
|
|
try {
|
|
shrink_request.quality = std::stoi(it->second);
|
|
} catch (...) {}
|
|
}
|
|
|
|
it = operation.parameters.find("chord_height");
|
|
if (it != operation.parameters.end()) {
|
|
try {
|
|
shrink_request.chord_height = std::stod(it->second);
|
|
} catch (...) {}
|
|
}
|
|
|
|
if (shrink_request.output_file_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: output_file_path";
|
|
return result;
|
|
}
|
|
|
|
ShrinkwrapShellResult shrink_result =
|
|
ShrinkwrapManager::Instance().ExecuteShrinkwrapShell(shrink_request);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = shrink_result.success;
|
|
if (shrink_result.success) {
|
|
result.result_json = BuildShrinkwrapResultJson(shrink_result);
|
|
} else {
|
|
result.error_message = shrink_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during shrinkwrap operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute close_model operation
|
|
BatchOperationResult BatchOperationManager::ExecuteCloseModel(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "close_model";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
bool force_close = false;
|
|
|
|
auto it = operation.parameters.find("force_close");
|
|
if (it != operation.parameters.end()) {
|
|
force_close = (it->second == "true");
|
|
}
|
|
|
|
CloseResult close_result = CreoManager::Instance().CloseModel(force_close);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = close_result.success;
|
|
if (close_result.success) {
|
|
result.result_json = BuildCloseResultJson(close_result);
|
|
} else {
|
|
result.error_message = close_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during close operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute open_model operation
|
|
BatchOperationResult BatchOperationManager::ExecuteOpenModel(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "open_model";
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
std::string file_path;
|
|
std::string open_mode = "active";
|
|
|
|
auto it = operation.parameters.find("file_path");
|
|
if (it != operation.parameters.end()) {
|
|
file_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("open_mode");
|
|
if (it != operation.parameters.end()) {
|
|
open_mode = it->second;
|
|
}
|
|
|
|
if (file_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: file_path";
|
|
return result;
|
|
}
|
|
|
|
OpenResult open_result = CreoManager::Instance().OpenModel(file_path, open_mode);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
result.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
result.success = open_result.success;
|
|
if (open_result.success) {
|
|
result.result_json = BuildOpenResultJson(open_result);
|
|
} else {
|
|
result.error_message = open_result.error_message;
|
|
}
|
|
} catch (const std::exception& e) {
|
|
result.success = false;
|
|
result.error_message = "Exception: " + std::string(e.what());
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Unknown error during open operation";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute workflow_hierarchy_delete operation
|
|
BatchOperationResult BatchOperationManager::ExecuteHierarchyDeleteWorkflow(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "workflow_hierarchy_delete";
|
|
|
|
auto workflow_start = std::chrono::high_resolution_clock::now();
|
|
std::vector<std::string> steps_json;
|
|
|
|
try {
|
|
// Extract parameters
|
|
std::string working_directory;
|
|
std::string input_file_path;
|
|
std::string open_mode = "active";
|
|
std::string project_name;
|
|
std::string target_level_str;
|
|
std::string export_path;
|
|
std::string geom_flags = "solids";
|
|
|
|
auto it = operation.parameters.find("working_directory");
|
|
if (it != operation.parameters.end()) {
|
|
working_directory = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("input_file_path");
|
|
if (it != operation.parameters.end()) {
|
|
input_file_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("open_mode");
|
|
if (it != operation.parameters.end()) {
|
|
open_mode = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("project_name");
|
|
if (it != operation.parameters.end()) {
|
|
project_name = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("target_level");
|
|
if (it != operation.parameters.end()) {
|
|
target_level_str = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("export_path");
|
|
if (it != operation.parameters.end()) {
|
|
export_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("geom_flags");
|
|
if (it != operation.parameters.end()) {
|
|
geom_flags = it->second;
|
|
}
|
|
|
|
// Validate required parameters
|
|
if (input_file_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: input_file_path";
|
|
return result;
|
|
}
|
|
|
|
if (project_name.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: project_name";
|
|
return result;
|
|
}
|
|
|
|
if (target_level_str.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: target_level";
|
|
return result;
|
|
}
|
|
|
|
if (export_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: export_path";
|
|
return result;
|
|
}
|
|
|
|
int target_level = 0;
|
|
try {
|
|
target_level = std::stoi(target_level_str);
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Invalid target_level value";
|
|
return result;
|
|
}
|
|
|
|
// Step 1: Set working directory (if provided)
|
|
if (!working_directory.empty()) {
|
|
auto step_start = std::chrono::high_resolution_clock::now();
|
|
ChangeDirectoryResult dir_result = CreoUtilities::SetWorkingDirectory(working_directory);
|
|
auto step_end = std::chrono::high_resolution_clock::now();
|
|
auto step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("set_directory", dir_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
dir_result.success ? "" : dir_result.error_message));
|
|
|
|
if (!dir_result.success) {
|
|
result.success = false;
|
|
result.error_message = "Failed to set working directory: " + dir_result.error_message;
|
|
result.result_json = "{\"steps\":[" + steps_json[0] + "]}";
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// Step 2: Open model
|
|
auto step_start = std::chrono::high_resolution_clock::now();
|
|
OpenResult open_result = CreoManager::Instance().OpenModel(input_file_path, open_mode);
|
|
auto step_end = std::chrono::high_resolution_clock::now();
|
|
auto step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("open_model", open_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
open_result.success ? "" : open_result.error_message));
|
|
|
|
if (!open_result.success) {
|
|
result.success = false;
|
|
result.error_message = "Failed to open model: " + open_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 3: Hierarchy delete
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
CreoManager::HierarchyDeleteResult delete_result =
|
|
CreoManager::Instance().DeleteHierarchyComponents(project_name, target_level);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("hierarchy_delete", delete_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
delete_result.success ? "" : delete_result.error_message));
|
|
|
|
if (!delete_result.success) {
|
|
// Try to close model before returning error
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Failed to delete hierarchy: " + delete_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 4: Export STEP
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
ExportResult export_result = CreoManager::Instance().ExportModelToSTEP(export_path, geom_flags);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("export_step", export_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
export_result.success ? "" : export_result.error_message));
|
|
|
|
if (!export_result.success) {
|
|
// Try to close model before returning error
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Failed to export STEP: " + export_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 5: Close model
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
CloseResult close_result = CreoManager::Instance().CloseModel(false);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("close_model", close_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
close_result.success ? "" : close_result.error_message));
|
|
|
|
// Build final result
|
|
auto workflow_end = std::chrono::high_resolution_clock::now();
|
|
auto workflow_duration = std::chrono::duration_cast<std::chrono::milliseconds>(workflow_end - workflow_start);
|
|
result.execution_time = std::to_string(workflow_duration.count()) + "ms";
|
|
|
|
std::ostringstream final_json;
|
|
final_json << "{"
|
|
<< "\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) final_json << ",";
|
|
final_json << steps_json[i];
|
|
}
|
|
final_json << "],"
|
|
<< "\"final_output\":\"" << EscapeJsonString(export_path) << "\","
|
|
<< "\"final_size\":\"" << EscapeJsonString(export_result.file_size) << "\""
|
|
<< "}";
|
|
|
|
result.success = true;
|
|
result.result_json = final_json.str();
|
|
|
|
} catch (const std::exception& e) {
|
|
// Try to close model on exception
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Exception in workflow: " + std::string(e.what());
|
|
|
|
if (!steps_json.empty()) {
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
}
|
|
} catch (...) {
|
|
// Try to close model on exception
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Unknown error in workflow";
|
|
|
|
if (!steps_json.empty()) {
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Execute workflow_shrinkwrap operation
|
|
BatchOperationResult BatchOperationManager::ExecuteShrinkwrapWorkflow(int index, const BatchOperation& operation) {
|
|
BatchOperationResult result;
|
|
result.operation_index = index;
|
|
result.operation_type = "workflow_shrinkwrap";
|
|
|
|
auto workflow_start = std::chrono::high_resolution_clock::now();
|
|
std::vector<std::string> steps_json;
|
|
|
|
try {
|
|
// Extract parameters
|
|
std::string working_directory;
|
|
std::string input_file_path;
|
|
std::string shrinkwrap_output_path;
|
|
std::string quality_str = "5";
|
|
std::string chord_height_str = "0.5";
|
|
std::string step_export_path;
|
|
std::string geom_flags = "solids";
|
|
|
|
auto it = operation.parameters.find("working_directory");
|
|
if (it != operation.parameters.end()) {
|
|
working_directory = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("input_file_path");
|
|
if (it != operation.parameters.end()) {
|
|
input_file_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("shrinkwrap_output_path");
|
|
if (it != operation.parameters.end()) {
|
|
shrinkwrap_output_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("quality");
|
|
if (it != operation.parameters.end() && !it->second.empty()) {
|
|
quality_str = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("chord_height");
|
|
if (it != operation.parameters.end() && !it->second.empty()) {
|
|
chord_height_str = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("step_export_path");
|
|
if (it != operation.parameters.end()) {
|
|
step_export_path = it->second;
|
|
}
|
|
|
|
it = operation.parameters.find("geom_flags");
|
|
if (it != operation.parameters.end()) {
|
|
geom_flags = it->second;
|
|
}
|
|
|
|
// Validate required parameters
|
|
if (input_file_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: input_file_path";
|
|
return result;
|
|
}
|
|
|
|
if (shrinkwrap_output_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: shrinkwrap_output_path";
|
|
return result;
|
|
}
|
|
|
|
if (step_export_path.empty()) {
|
|
result.success = false;
|
|
result.error_message = "Missing required parameter: step_export_path";
|
|
return result;
|
|
}
|
|
|
|
int quality = 5;
|
|
double chord_height = 0.5;
|
|
|
|
try {
|
|
quality = std::stoi(quality_str);
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Invalid quality value";
|
|
return result;
|
|
}
|
|
|
|
try {
|
|
chord_height = std::stod(chord_height_str);
|
|
} catch (...) {
|
|
result.success = false;
|
|
result.error_message = "Invalid chord_height value";
|
|
return result;
|
|
}
|
|
|
|
// Step 1: Set working directory (if provided)
|
|
if (!working_directory.empty()) {
|
|
auto step_start = std::chrono::high_resolution_clock::now();
|
|
ChangeDirectoryResult dir_result = CreoUtilities::SetWorkingDirectory(working_directory);
|
|
auto step_end = std::chrono::high_resolution_clock::now();
|
|
auto step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("set_directory", dir_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
dir_result.success ? "" : dir_result.error_message));
|
|
|
|
if (!dir_result.success) {
|
|
result.success = false;
|
|
result.error_message = "Failed to set working directory: " + dir_result.error_message;
|
|
result.result_json = "{\"steps\":[" + steps_json[0] + "]}";
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// Step 2: Open original model
|
|
auto step_start = std::chrono::high_resolution_clock::now();
|
|
OpenResult open_result = CreoManager::Instance().OpenModel(input_file_path, "active");
|
|
auto step_end = std::chrono::high_resolution_clock::now();
|
|
auto step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("open_model", open_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
open_result.success ? "" : open_result.error_message));
|
|
|
|
if (!open_result.success) {
|
|
result.success = false;
|
|
result.error_message = "Failed to open model: " + open_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 3: Execute Shrinkwrap
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
ShrinkwrapShellRequest shrink_request;
|
|
shrink_request.output_file_path = shrinkwrap_output_path;
|
|
shrink_request.quality = quality;
|
|
shrink_request.chord_height = chord_height;
|
|
|
|
ShrinkwrapShellResult shrink_result =
|
|
ShrinkwrapManager::Instance().ExecuteShrinkwrapShell(shrink_request);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("shrinkwrap", shrink_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
shrink_result.success ? "" : shrink_result.error_message));
|
|
|
|
if (!shrink_result.success) {
|
|
// Try to close model before returning error
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Failed to execute shrinkwrap: " + shrink_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 4: Close original model
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
CloseResult close_original = CreoManager::Instance().CloseModel(true);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("close_original", close_original.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
close_original.success ? "" : close_original.error_message));
|
|
|
|
// Step 5: Open Shrinkwrap model
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
OpenResult open_shrink = CreoManager::Instance().OpenModel(shrinkwrap_output_path, "active");
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("open_shrinkwrap_model", open_shrink.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
open_shrink.success ? "" : open_shrink.error_message));
|
|
|
|
if (!open_shrink.success) {
|
|
result.success = false;
|
|
result.error_message = "Failed to open shrinkwrap model: " + open_shrink.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 6: Export STEP
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
ExportResult export_result = CreoManager::Instance().ExportModelToSTEP(step_export_path, geom_flags);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("export_step", export_result.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
export_result.success ? "" : export_result.error_message));
|
|
|
|
if (!export_result.success) {
|
|
// Try to close model before returning error
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Failed to export STEP: " + export_result.error_message;
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
return result;
|
|
}
|
|
|
|
// Step 7: Close shrinkwrap model
|
|
step_start = std::chrono::high_resolution_clock::now();
|
|
CloseResult close_shrink = CreoManager::Instance().CloseModel(true);
|
|
step_end = std::chrono::high_resolution_clock::now();
|
|
step_duration = std::chrono::duration_cast<std::chrono::milliseconds>(step_end - step_start);
|
|
|
|
steps_json.push_back(BuildWorkflowStepJson("close_shrinkwrap", close_shrink.success,
|
|
std::to_string(step_duration.count()) + "ms",
|
|
close_shrink.success ? "" : close_shrink.error_message));
|
|
|
|
// Build final result
|
|
auto workflow_end = std::chrono::high_resolution_clock::now();
|
|
auto workflow_duration = std::chrono::duration_cast<std::chrono::milliseconds>(workflow_end - workflow_start);
|
|
result.execution_time = std::to_string(workflow_duration.count()) + "ms";
|
|
|
|
std::ostringstream final_json;
|
|
final_json << "{"
|
|
<< "\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) final_json << ",";
|
|
final_json << steps_json[i];
|
|
}
|
|
final_json << "],"
|
|
<< "\"final_output\":\"" << EscapeJsonString(step_export_path) << "\","
|
|
<< "\"final_size\":\"" << EscapeJsonString(export_result.file_size) << "\""
|
|
<< "}";
|
|
|
|
result.success = true;
|
|
result.result_json = final_json.str();
|
|
|
|
} catch (const std::exception& e) {
|
|
// Try to close model on exception
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Exception in workflow: " + std::string(e.what());
|
|
|
|
if (!steps_json.empty()) {
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
}
|
|
} catch (...) {
|
|
// Try to close model on exception
|
|
try {
|
|
CreoManager::Instance().CloseModel(true);
|
|
} catch (...) {}
|
|
|
|
result.success = false;
|
|
result.error_message = "Unknown error in workflow";
|
|
|
|
if (!steps_json.empty()) {
|
|
std::ostringstream steps_array;
|
|
steps_array << "{\"steps\":[";
|
|
for (size_t i = 0; i < steps_json.size(); i++) {
|
|
if (i > 0) steps_array << ",";
|
|
steps_array << steps_json[i];
|
|
}
|
|
steps_array << "]}";
|
|
result.result_json = steps_array.str();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Main entry point: Execute batch operations
|
|
BatchOperationsResponse BatchOperationManager::ExecuteBatchOperations(const BatchOperationsRequest& request) {
|
|
BatchOperationsResponse response;
|
|
response.total_operations = static_cast<int>(request.operations.size());
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
try {
|
|
// Validate request
|
|
if (request.software_type != "creo") {
|
|
response.success = false;
|
|
response.error_message = "Invalid software_type, must be 'creo'";
|
|
return response;
|
|
}
|
|
|
|
if (request.operations.empty()) {
|
|
response.success = false;
|
|
response.error_message = "No operations specified";
|
|
return response;
|
|
}
|
|
|
|
// Execute each operation sequentially
|
|
for (size_t i = 0; i < request.operations.size(); i++) {
|
|
const BatchOperation& operation = request.operations[i];
|
|
BatchOperationResult op_result;
|
|
|
|
if (operation.operation_type == "save_model") {
|
|
op_result = ExecuteSaveModel(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "export_model") {
|
|
op_result = ExecuteExportModel(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "delete_by_path") {
|
|
op_result = ExecuteDeleteByPath(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "hierarchy_delete") {
|
|
op_result = ExecuteHierarchyDelete(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "shrinkwrap_shell") {
|
|
op_result = ExecuteShrinkwrapShell(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "close_model") {
|
|
op_result = ExecuteCloseModel(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "open_model") {
|
|
op_result = ExecuteOpenModel(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "workflow_hierarchy_delete") {
|
|
op_result = ExecuteHierarchyDeleteWorkflow(static_cast<int>(i), operation);
|
|
} else if (operation.operation_type == "workflow_shrinkwrap") {
|
|
op_result = ExecuteShrinkwrapWorkflow(static_cast<int>(i), operation);
|
|
} else {
|
|
// Unknown operation type
|
|
op_result.operation_index = static_cast<int>(i);
|
|
op_result.operation_type = operation.operation_type;
|
|
op_result.success = false;
|
|
op_result.error_message = "Unknown operation type: " + operation.operation_type;
|
|
}
|
|
|
|
response.results.push_back(op_result);
|
|
|
|
if (op_result.success) {
|
|
response.successful_operations++;
|
|
} else {
|
|
response.failed_operations++;
|
|
}
|
|
}
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
|
response.execution_time = std::to_string(duration.count()) + "ms";
|
|
|
|
// Overall success if at least one operation succeeded
|
|
response.success = (response.successful_operations > 0);
|
|
|
|
if (response.success) {
|
|
response.message = "Batch operations completed";
|
|
} else {
|
|
response.message = "All batch operations failed";
|
|
response.error_message = "All operations failed to execute";
|
|
}
|
|
|
|
} catch (const std::exception& e) {
|
|
response.success = false;
|
|
response.error_message = "Exception during batch operations: " + std::string(e.what());
|
|
} catch (...) {
|
|
response.success = false;
|
|
response.error_message = "Unknown error during batch operations";
|
|
}
|
|
|
|
return response;
|
|
}
|