CreoPluging9.0/ToolkitTasks.cpp
2026-01-15 16:23:23 +08:00

107 lines
4.5 KiB
C++

#include "pch.h"
#include "Shrinkwrap90Manager.h"
#include <ProArray.h>
#include <ProToolkitDll.h>
#include <ProValue.h>
#include <chrono>
#include <filesystem>
#include <sstream>
#include <stdexcept>
namespace {
bool ArgGet(ProArgument* inputs, const wchar_t* label, ProValueData* out) {
ProName name{};
wcsncpy_s(name, label, _TRUNCATE);
return ProArgumentByLabelGet(inputs, name, out) == PRO_TK_NO_ERROR;
}
std::wstring WStringFromValue(const ProValueData& v) {
if (v.type == PRO_VALUE_TYPE_WSTRING && v.v.w) return std::wstring(v.v.w);
if (v.type == PRO_VALUE_TYPE_STRING && v.v.s) {
int len = MultiByteToWideChar(CP_UTF8, 0, v.v.s, -1, nullptr, 0);
if (len <= 0) return std::wstring();
std::wstring out(len - 1, L'\0');
MultiByteToWideChar(CP_UTF8, 0, v.v.s, -1, out.data(), len);
return out;
}
return std::wstring();
}
std::string Utf8FromWide(const std::wstring& ws) {
if (ws.empty()) return std::string();
int len = WideCharToMultiByte(CP_UTF8, 0, ws.data(), static_cast<int>(ws.size()), nullptr, 0, nullptr, nullptr);
if (len <= 0) return std::string();
std::string out(len, '\0');
WideCharToMultiByte(CP_UTF8, 0, ws.data(), static_cast<int>(ws.size()), out.data(), len, nullptr, nullptr);
return out;
}
std::wstring WideFromUtf8(const std::string& s) {
if (s.empty()) return std::wstring();
int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast<int>(s.size()), nullptr, 0);
if (len <= 0) return std::wstring();
std::wstring out(len, L'\0');
MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast<int>(s.size()), out.data(), len);
return out;
}
ProError OutAddWString(ProArgument** outputs, const wchar_t* label, const std::wstring& value) {
ProArgument arg{};
wcsncpy_s(arg.label, label, _TRUNCATE);
ProValuedataWstringSet(&arg.value, const_cast<wchar_t*>(value.c_str()));
return ProArrayObjectAdd(reinterpret_cast<ProArray*>(outputs), PRO_VALUE_UNUSED, 1, &arg);
}
} // namespace
extern "C" {
__declspec(dllexport) ProError CreoShrinkwrapShell(ProArgument* inputs, ProArgument** outputs) {
*outputs = nullptr;
ProError err = ProArrayAlloc(0, sizeof(ProArgument), 1, reinterpret_cast<ProArray*>(outputs));
if (err != PRO_TK_NO_ERROR) return err;
try {
ShrinkwrapShellRequest req;
ProValueData v{};
if (ArgGet(inputs, L"software_type", &v)) req.software_type = Utf8FromWide(WStringFromValue(v));
if (ArgGet(inputs, L"quality", &v) && v.type == PRO_VALUE_TYPE_INT) req.quality = v.v.i;
if (ArgGet(inputs, L"chord_height", &v) && v.type == PRO_VALUE_TYPE_DOUBLE) req.chord_height = v.v.d;
if (ArgGet(inputs, L"fill_holes", &v) && v.type == PRO_VALUE_TYPE_BOOLEAN) req.fill_holes = (v.v.b == PRO_B_TRUE);
if (ArgGet(inputs, L"ignore_small_surfaces", &v) && v.type == PRO_VALUE_TYPE_BOOLEAN) req.ignore_small_surfaces = (v.v.b == PRO_B_TRUE);
if (ArgGet(inputs, L"small_surface_percentage", &v) && v.type == PRO_VALUE_TYPE_DOUBLE) req.small_surface_percentage = v.v.d;
if (ArgGet(inputs, L"output_file_path", &v)) req.output_file_path = Utf8FromWide(WStringFromValue(v));
if (ArgGet(inputs, L"output_type", &v)) req.output_type = Utf8FromWide(WStringFromValue(v));
if (ArgGet(inputs, L"ignore_quilts", &v) && v.type == PRO_VALUE_TYPE_BOOLEAN) req.ignore_quilts = (v.v.b == PRO_B_TRUE);
if (ArgGet(inputs, L"ignore_skeleton", &v) && v.type == PRO_VALUE_TYPE_BOOLEAN) req.ignore_skeleton = (v.v.b == PRO_B_TRUE);
if (ArgGet(inputs, L"assign_mass_properties", &v) && v.type == PRO_VALUE_TYPE_BOOLEAN) req.assign_mass_properties = (v.v.b == PRO_B_TRUE);
if (ArgGet(inputs, L"timeout_seconds", &v) && v.type == PRO_VALUE_TYPE_INT) req.timeout_seconds = v.v.i;
auto start = std::chrono::steady_clock::now();
Shrinkwrap90Manager mgr;
ShrinkwrapShellResult res = mgr.ExportShell(req);
auto end = std::chrono::steady_clock::now();
auto secs = std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
res.execution_time = Shrinkwrap90Manager::FormatHhMmSs(secs);
OutAddWString(outputs, L"output_path", WideFromUtf8(res.output_path));
OutAddWString(outputs, L"file_size", WideFromUtf8(res.file_size));
OutAddWString(outputs, L"execution_time", WideFromUtf8(res.execution_time));
return PRO_TK_NO_ERROR;
} catch (const std::exception& ex) {
OutAddWString(outputs, L"error_message", WideFromUtf8(ex.what()));
return PRO_TK_GENERAL_ERROR;
} catch (...) {
OutAddWString(outputs, L"error_message", L"unknown error");
return PRO_TK_GENERAL_ERROR;
}
}
} // extern "C"