122 lines
3.8 KiB
C++
122 lines
3.8 KiB
C++
#include "pch.h"
|
|
|
|
#include "Shrinkwrap90Manager.h"
|
|
|
|
#include "Creo90Manager.h"
|
|
|
|
#include "CreoOtk.h"
|
|
|
|
#include <filesystem>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
|
|
namespace {
|
|
|
|
std::string EnsurePrtExtension(std::string path) {
|
|
std::filesystem::path p(path);
|
|
if (!p.has_extension()) {
|
|
p.replace_extension(".prt");
|
|
}
|
|
return p.string();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ShrinkwrapShellResult Shrinkwrap90Manager::ExportShell(const ShrinkwrapShellRequest& req) {
|
|
if (req.output_file_path.empty()) {
|
|
throw std::runtime_error("output_file_path is required");
|
|
}
|
|
if (req.quality < 1 || req.quality > 10) {
|
|
throw std::runtime_error("quality must be in [1,10]");
|
|
}
|
|
if (req.small_surface_percentage < 0.0) {
|
|
throw std::runtime_error("small_surface_percentage must be >= 0");
|
|
}
|
|
|
|
Creo90Manager creo;
|
|
pfcSession_ptr session = creo.GetSession();
|
|
if (!session) {
|
|
throw std::runtime_error("Creo session not available");
|
|
}
|
|
|
|
pfcSolid_ptr source = creo.GetCurrentSolid();
|
|
if (!source) {
|
|
throw std::runtime_error("current model is not a solid (part/assembly) or no model is active");
|
|
}
|
|
|
|
std::string outPathS = EnsurePrtExtension(req.output_file_path);
|
|
std::filesystem::path outPath(outPathS);
|
|
std::string stem = outPath.stem().string();
|
|
std::string modelName = SanitizeCreoModelName(stem);
|
|
if (modelName.empty()) modelName = "shrinkwrap";
|
|
|
|
pfcPart_ptr outputPart = session->CreatePart(modelName.c_str());
|
|
pfcModel_ptr outputModel = pfcModel::cast(outputPart);
|
|
pfcShrinkwrapMergedSolidInstructions_ptr instr = pfcShrinkwrapMergedSolidInstructions::Create(outputModel);
|
|
|
|
instr->SetQuality(req.quality);
|
|
instr->SetAutoHoleFilling(req.fill_holes ? xtrue : xfalse);
|
|
instr->SetIgnoreSmallSurfaces(req.ignore_small_surfaces ? xtrue : xfalse);
|
|
instr->SetSmallSurfPercentage(req.small_surface_percentage);
|
|
instr->SetIgnoreQuilts(req.ignore_quilts ? xtrue : xfalse);
|
|
instr->SetIgnoreSkeleton(req.ignore_skeleton ? xtrue : xfalse);
|
|
instr->SetAssignMassProperties(req.assign_mass_properties ? xtrue : xfalse);
|
|
|
|
pfcShrinkwrapExportInstructions_ptr exportInstr = pfcShrinkwrapExportInstructions::cast(instr);
|
|
source->ExportShrinkwrap(exportInstr);
|
|
|
|
std::string dir = outPath.parent_path().string();
|
|
pfcModelDescriptor_ptr descr = pfcModelDescriptor::Create(pfcMDL_PART, modelName.c_str(), nullptr);
|
|
descr->SetPath(dir.c_str());
|
|
outputPart->Backup(descr);
|
|
|
|
std::filesystem::path actualOutPath = outPath.parent_path() / (modelName + ".prt");
|
|
ShrinkwrapShellResult res;
|
|
res.output_path = actualOutPath.string();
|
|
std::error_code ec;
|
|
uintmax_t bytes = std::filesystem::file_size(actualOutPath, ec);
|
|
if (ec) bytes = 0;
|
|
res.file_size = FormatFileSize(bytes);
|
|
res.execution_time = ""; // 由上层填充
|
|
return res;
|
|
}
|
|
|
|
std::string Shrinkwrap90Manager::SanitizeCreoModelName(const std::string& fileStem) {
|
|
std::string out;
|
|
out.reserve(fileStem.size());
|
|
for (unsigned char uc : fileStem) {
|
|
char c = static_cast<char>(uc);
|
|
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-') {
|
|
out.push_back(c);
|
|
} else if (c == ' ') {
|
|
out.push_back('_');
|
|
}
|
|
}
|
|
if (!out.empty() && (out[0] >= '0' && out[0] <= '9')) {
|
|
out.insert(out.begin(), '_');
|
|
}
|
|
if (out.size() > 31) {
|
|
out.resize(31);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::string Shrinkwrap90Manager::FormatFileSize(uintmax_t bytes) {
|
|
std::ostringstream oss;
|
|
double mb = static_cast<double>(bytes) / (1024.0 * 1024.0);
|
|
oss.setf(std::ios::fixed);
|
|
oss.precision(1);
|
|
oss << mb << " MB";
|
|
return oss.str();
|
|
}
|
|
|
|
std::string Shrinkwrap90Manager::FormatHhMmSs(long long totalSeconds) {
|
|
if (totalSeconds < 0) totalSeconds = 0;
|
|
long long h = totalSeconds / 3600;
|
|
long long m = (totalSeconds % 3600) / 60;
|
|
long long s = totalSeconds % 60;
|
|
char buf[32];
|
|
sprintf_s(buf, "%02lld:%02lld:%02lld", h, m, s);
|
|
return std::string(buf);
|
|
}
|