| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <QFile>
|
| | #include <QMetaObject>
|
| | #include <QMutexLocker>
|
| | #include <QObject>
|
| | #include <QProcess>
|
| | #include <QTimer>
|
| |
|
| | #include "ThumbnailSource.h"
|
| |
|
| | #include <QThread>
|
| |
|
| | #include "FileUtilities.h"
|
| |
|
| | #include <App/Application.h>
|
| |
|
| | using namespace Start;
|
| |
|
| | ThumbnailSource::F3DInstallation ThumbnailSource::_f3d {};
|
| | QMutex ThumbnailSource::_mutex;
|
| |
|
| | ThumbnailSource::ThumbnailSource(QString file)
|
| | : _file(std::move(file))
|
| | {}
|
| |
|
| | ThumbnailSourceSignals* ThumbnailSource::signals()
|
| | {
|
| | return &_signals;
|
| | }
|
| |
|
| | void ThumbnailSource::run()
|
| | {
|
| | _thumbnailPath = getPathToCachedThumbnail(_file);
|
| | if (!useCachedThumbnail(_thumbnailPath, _file)) {
|
| |
|
| |
|
| | setupF3D();
|
| | if (_f3d.major < 2) {
|
| | return;
|
| | }
|
| | const ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
| | "User parameter:BaseApp/Preferences/Mod/Start"
|
| | );
|
| | const auto f3d = QString::fromUtf8(hGrp->GetASCII("f3d", "f3d").c_str());
|
| | QStringList args(_f3d.baseArgs);
|
| | args << QLatin1String("--output=") + _thumbnailPath << _file;
|
| |
|
| | QProcess process;
|
| | Base::Console().log("Creating thumbnail for %s...\n", _file.toStdString());
|
| | process.start(f3d, args);
|
| | if (!process.waitForFinished()) {
|
| | process.kill();
|
| | Base::Console().log("Creating thumbnail for %s timed out\n", _file.toStdString());
|
| | return;
|
| | }
|
| | if (process.exitStatus() == QProcess::CrashExit) {
|
| | Base::Console().log("Creating thumbnail for %s crashed\n", _file.toStdString());
|
| | return;
|
| | }
|
| | if (process.exitCode() != 0) {
|
| | Base::Console().log("Creating thumbnail for %s failed\n", _file.toStdString());
|
| | return;
|
| | }
|
| | Base::Console().log(
|
| | "Creating thumbnail for %s succeeded, wrote to %s\n",
|
| | _file.toStdString(),
|
| | _thumbnailPath.toStdString()
|
| | );
|
| | }
|
| | if (QFile thumbnailFile(_thumbnailPath); thumbnailFile.exists()) {
|
| | thumbnailFile.open(QIODevice::OpenModeFlag::ReadOnly);
|
| | Q_EMIT _signals.thumbnailAvailable(_file, thumbnailFile.readAll());
|
| | }
|
| | }
|
| |
|
| | std::tuple<int, int, int> extractF3DVersion(const QString& stdoutString)
|
| | {
|
| | int major {0};
|
| | int minor {0};
|
| | int patch {0};
|
| | for (auto lines = stdoutString.split(QLatin1Char('\n')); const auto& line : lines) {
|
| | if (line.startsWith(QLatin1String("Version: "))) {
|
| | const auto substring = line.mid(8);
|
| | if (auto split = substring.split(QLatin1Char('.')); split.size() >= 3) {
|
| | try {
|
| | major = split[0].toInt();
|
| | minor = split[1].toInt();
|
| | patch = split[2].toInt();
|
| | }
|
| | catch (...) {
|
| | Base::Console().log(
|
| | "Could not determine F3D version, disabling thumbnail generation\n"
|
| | );
|
| | }
|
| | }
|
| | break;
|
| | }
|
| | }
|
| | return std::make_tuple(major, minor, patch);
|
| | }
|
| |
|
| | QStringList getF3DOptions(const QString& f3d)
|
| | {
|
| |
|
| |
|
| | QStringList optionsToTest {
|
| | QStringLiteral("--load-plugins=occt"),
|
| | QStringLiteral("--config=thumbnail"),
|
| | QStringLiteral("--verbose=quiet"),
|
| | QStringLiteral("--resolution=256,256"),
|
| | QStringLiteral("--filename=0"),
|
| | QStringLiteral("--grid=0"),
|
| | QStringLiteral("--axis=0"),
|
| | QStringLiteral("--no-background"),
|
| | QStringLiteral("--max-size=100")
|
| | };
|
| | QStringList goodOptions;
|
| | for (const auto& option : optionsToTest) {
|
| | QStringList args;
|
| | args << option << QStringLiteral("--no-render");
|
| | QProcess process;
|
| | process.start(f3d, args);
|
| | if (!process.waitForFinished()) {
|
| | process.kill();
|
| | continue;
|
| | }
|
| | auto stderrAsBytes = process.readAllStandardError();
|
| | if (auto stderrAsString = QString::fromUtf8(stderrAsBytes);
|
| | !stderrAsString.contains(QLatin1String("Unknown option"))) {
|
| | goodOptions.append(option);
|
| | }
|
| | }
|
| | return goodOptions;
|
| | }
|
| |
|
| | void ThumbnailSource::setupF3D()
|
| | {
|
| | QMutexLocker locker(&_mutex);
|
| | if (_f3d.initialized) {
|
| | return;
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | _f3d.initialized = true;
|
| | const ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
| | "User parameter:BaseApp/Preferences/Mod/Start"
|
| | );
|
| | const auto f3d = QString::fromUtf8(hGrp->GetASCII("f3d", "f3d").c_str());
|
| | const QStringList args {QLatin1String("--version")};
|
| | QProcess process;
|
| | process.start(f3d, args);
|
| | if (!process.waitForFinished()) {
|
| | process.kill();
|
| | }
|
| | if (process.exitCode() != 0) {
|
| | return;
|
| | }
|
| | const QByteArray stdoutBytes = process.readAllStandardOutput();
|
| | const auto stdoutString = QString::fromUtf8(stdoutBytes);
|
| | const auto version = extractF3DVersion(stdoutString);
|
| | _f3d.major = std::get<0>(version);
|
| | _f3d.minor = std::get<1>(version);
|
| | if (_f3d.major >= 2) {
|
| | _f3d.baseArgs = getF3DOptions(f3d);
|
| | }
|
| | Base::Console().log("Running f3d version %d.%d\n", _f3d.major, _f3d.minor);
|
| | }
|
| |
|