diff --git a/armoury/include/settingswindow.h b/armoury/include/settingswindow.h index 28cf568..13213b8 100644 --- a/armoury/include/settingswindow.h +++ b/armoury/include/settingswindow.h @@ -16,4 +16,5 @@ private: QLineEdit *m_sourcesLineEdit = nullptr; QLineEdit *m_outputLineEdit = nullptr; + QLineEdit *m_blenderPath = nullptr; }; \ No newline at end of file diff --git a/armoury/include/singlegearview.h b/armoury/include/singlegearview.h index d83fec8..320937d 100644 --- a/armoury/include/singlegearview.h +++ b/armoury/include/singlegearview.h @@ -57,7 +57,7 @@ private: GearView *gearView = nullptr; QComboBox *raceCombo, *subraceCombo, *genderCombo, *lodCombo; - QPushButton *addToFMVButton, *importButton, *exportButton; + QPushButton *addToFMVButton, *editButton, *importButton, *exportButton; bool loadingComboData = false; bool fmvAvailable = false; diff --git a/armoury/src/settingswindow.cpp b/armoury/src/settingswindow.cpp index 26f2405..fa41cde 100644 --- a/armoury/src/settingswindow.cpp +++ b/armoury/src/settingswindow.cpp @@ -74,6 +74,32 @@ SettingsWindow::SettingsWindow(QWidget *parent) penumbraLayout->addRow(QStringLiteral("Output Directory"), outputBoxLayoutContainer); + auto blenderBox = new QGroupBox(QStringLiteral("Blender")); + layout->addWidget(blenderBox); + + auto blenderLayout = new QFormLayout(); + blenderBox->setLayout(blenderLayout); + + auto blenderBoxLayoutContainer = new QWidget(this); + auto blenderBoxLayout = new QHBoxLayout(blenderBoxLayoutContainer); + blenderBoxLayout->setContentsMargins(0, 0, 0, 0); + + m_blenderPath = new QLineEdit(); + m_blenderPath->setText(game.readEntry("BlenderPath")); + m_blenderPath->setClearButtonEnabled(true); + blenderBoxLayout->addWidget(m_blenderPath); + + auto selectBlenderButton = new QPushButton(QIcon::fromTheme(QStringLiteral("folder-open")), QString()); + connect(selectBlenderButton, &QPushButton::clicked, this, [this] { + QUrl url = QFileDialog::getOpenFileUrl(this, QString()); + if (!url.isEmpty()) { + m_blenderPath->setText(url.toDisplayString(QUrl::PreferLocalFile)); + } + }); + blenderBoxLayout->addWidget(selectBlenderButton); + + blenderLayout->addRow(QStringLiteral("Blender Path"), blenderBoxLayoutContainer); + auto bottomButtonLayout = new QHBoxLayout(); layout->addLayout(bottomButtonLayout); @@ -96,4 +122,5 @@ void SettingsWindow::applySettings() KConfigGroup game = config.group(QStringLiteral("Armoury")); game.writeEntry("PenumbraOutputDirectory", m_outputLineEdit->text()); game.writeEntry("SourcesOutputDirectory", m_sourcesLineEdit->text()); + game.writeEntry("BlenderPath", m_blenderPath->text()); } diff --git a/armoury/src/singlegearview.cpp b/armoury/src/singlegearview.cpp index 5af6dbf..6bd44d8 100644 --- a/armoury/src/singlegearview.cpp +++ b/armoury/src/singlegearview.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -90,6 +91,49 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent } }); + editButton = new QPushButton(QStringLiteral("Edit...")); + editButton->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); + connect(editButton, &QPushButton::clicked, this, [this](bool) { + // Export in default location + // TODO: deduplicate + const auto sanitizeMdlPath = [](const QString &mdlPath) -> QString { + return QString(mdlPath).section(QLatin1Char('/'), -1).remove(QStringLiteral(".mdl")); + }; + + KConfig config(QStringLiteral("novusrc")); + KConfigGroup game = config.group(QStringLiteral("Armoury")); + QString sourceDirectory = game.readEntry(QStringLiteral("SourcesOutputDirectory")); + QString newFilename = QStringLiteral("%1.glb").arg(sanitizeMdlPath(gearView->getLoadedGearPath())); + + QString path = QStringLiteral("%1/%2/%3/%4") + .arg(sourceDirectory) + .arg(QString::fromStdString(magic_enum::enum_name(currentGear->slot).data())) + .arg(QString::fromStdString(currentGear->name)) + .arg(QStringLiteral("3D")); + + if (!QDir().exists(path)) + QDir().mkpath(path); + + const QString fileName = QStringLiteral("%1/%2").arg(path, newFilename); + + gearView->exportModel(fileName); + + QFileInfo info(fileName); + + QProcess *blenderProcess = new QProcess(this); + blenderProcess->setProgram(game.readEntry(QStringLiteral("BlenderPath"))); + blenderProcess->setArguments( + {QStringLiteral("--python-expr"), + QStringLiteral("import bpy\nbpy.ops.import_scene.gltf(filepath=\"%1\", files=[{\"name\":\"%2\", \"name\":\"%3\"}], bone_heuristic='TEMPERANCE')") + .arg(info.filePath(), info.fileName(), info.fileName())}); + blenderProcess->start(); + + blenderProcess->waitForFinished(); + + importButton->click(); + }); + topControlLayout->addWidget(editButton); + importButton = new QPushButton(QStringLiteral("Import...")); importButton->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); connect(importButton, &QPushButton::clicked, this, [this](bool) {