107 lines
4.5 KiB
C++
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"
|