From 0b2653362a477e710226c6ddfc42af8c96f5748c Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Tue, 23 Jul 2019 19:43:58 +0930 Subject: [PATCH] Support open/export from command line Usage example(on MacOS): $ ./dust3d.app/Contents/MacOS/dust3d /Users/jeremy/Desktop/test.ds3 -o /Users/jeremy/Desktop/test.glb $ echo $? --- src/documentwindow.cpp | 158 +++++++++++++++++++++-------------------- src/documentwindow.h | 9 +++ src/main.cpp | 63 ++++++++++++++-- src/scriptrunner.cpp | 2 +- 4 files changed, 150 insertions(+), 82 deletions(-) diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp index b8bd6d1f..18001011 100644 --- a/src/documentwindow.cpp +++ b/src/documentwindow.cpp @@ -1278,84 +1278,10 @@ void DocumentWindow::saveTo(const QString &saveAsFilename) QApplication::restoreOverrideCursor(); } -void DocumentWindow::openExample(const QString &modelName) +void DocumentWindow::openPathAs(const QString &path, const QString &asName) { - if (!m_documentSaved) { - QMessageBox::StandardButton answer = QMessageBox::question(this, - APP_NAME, - tr("Do you really want to open example and lose the unsaved changes?"), - QMessageBox::Yes | QMessageBox::No); - if (answer != QMessageBox::Yes) - return; - } - QApplication::setOverrideCursor(Qt::WaitCursor); - Ds3FileReader ds3Reader(":/resources/" + modelName); - - m_document->clearHistories(); - m_document->resetScript(); - m_document->reset(); - m_document->saveSnapshot(); - - for (int i = 0; i < ds3Reader.items().size(); ++i) { - Ds3ReaderItem item = ds3Reader.items().at(i); - if (item.type == "asset") { - if (item.name.startsWith("images/")) { - QString filename = item.name.split("/")[1]; - QString imageIdString = filename.split(".")[0]; - QUuid imageId = QUuid(imageIdString); - if (!imageId.isNull()) { - QByteArray data; - ds3Reader.loadItem(item.name, &data); - QImage image = QImage::fromData(data, "PNG"); - (void)ImageForever::add(&image, imageId); - } - } - } - } - - for (int i = 0; i < ds3Reader.items().size(); ++i) { - Ds3ReaderItem item = ds3Reader.items().at(i); - if (item.type == "model") { - QByteArray data; - ds3Reader.loadItem(item.name, &data); - QXmlStreamReader stream(data); - Snapshot snapshot; - loadSkeletonFromXmlStream(&snapshot, stream); - m_document->fromSnapshot(snapshot); - m_document->saveSnapshot(); - } else if (item.type == "asset") { - if (item.name == "canvas.png") { - QByteArray data; - ds3Reader.loadItem(item.name, &data); - QImage image = QImage::fromData(data, "PNG"); - m_document->updateTurnaround(image); - } - } - } - QApplication::restoreOverrideCursor(); - - setCurrentFilename(""); -} - -void DocumentWindow::open() -{ - if (!m_documentSaved) { - QMessageBox::StandardButton answer = QMessageBox::question(this, - APP_NAME, - tr("Do you really want to open another file and lose the unsaved changes?"), - QMessageBox::Yes | QMessageBox::No); - if (answer != QMessageBox::Yes) - return; - } - - QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), - tr("Dust3D Document (*.ds3)")); - if (filename.isEmpty()) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - Ds3FileReader ds3Reader(filename); + Ds3FileReader ds3Reader(path); m_document->clearHistories(); m_document->resetScript(); @@ -1416,7 +1342,40 @@ void DocumentWindow::open() } QApplication::restoreOverrideCursor(); - setCurrentFilename(filename); + setCurrentFilename(asName); +} + +void DocumentWindow::openExample(const QString &modelName) +{ + if (!m_documentSaved) { + QMessageBox::StandardButton answer = QMessageBox::question(this, + APP_NAME, + tr("Do you really want to open example and lose the unsaved changes?"), + QMessageBox::Yes | QMessageBox::No); + if (answer != QMessageBox::Yes) + return; + } + + openPathAs(":/resources/" + modelName, ""); +} + +void DocumentWindow::open() +{ + if (!m_documentSaved) { + QMessageBox::StandardButton answer = QMessageBox::question(this, + APP_NAME, + tr("Do you really want to open another file and lose the unsaved changes?"), + QMessageBox::Yes | QMessageBox::No); + if (answer != QMessageBox::Yes) + return; + } + + QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), + tr("Dust3D Document (*.ds3)")); + if (filename.isEmpty()) + return; + + openPathAs(filename, filename); } void DocumentWindow::showPreferences() @@ -1435,6 +1394,11 @@ void DocumentWindow::exportObjResult() if (filename.isEmpty()) { return; } + exportObjToFilename(filename); +} + +void DocumentWindow::exportObjToFilename(const QString &filename) +{ QApplication::setOverrideCursor(Qt::WaitCursor); MeshLoader *resultMesh = m_document->takeResultMesh(); if (nullptr != resultMesh) { @@ -1468,6 +1432,11 @@ void DocumentWindow::exportFbxResult() if (filename.isEmpty()) { return; } + exportFbxToFilename(filename); +} + +void DocumentWindow::exportFbxToFilename(const QString &filename) +{ if (!m_document->isExportReady()) { qDebug() << "Export but document is not export ready"; return; @@ -1499,6 +1468,11 @@ void DocumentWindow::exportGlbResult() if (filename.isEmpty()) { return; } + exportGlbToFilename(filename); +} + +void DocumentWindow::exportGlbToFilename(const QString &filename) +{ if (!m_document->isExportReady()) { qDebug() << "Export but document is not export ready"; return; @@ -1701,3 +1675,33 @@ void DocumentWindow::showCutFaceSettingPopup(const QPoint &globalPos, std::setisMeshGenerationSucceed(); + for (const auto &filename: list) { + if (filename.endsWith(".obj")) { + exportObjToFilename(filename); + emit waitingExportFinished(filename, isSucceed); + } else if (filename.endsWith(".fbx")) { + exportFbxToFilename(filename); + emit waitingExportFinished(filename, isSucceed); + } else if (filename.endsWith(".glb")) { + exportGlbToFilename(filename); + emit waitingExportFinished(filename, isSucceed); + } else { + emit waitingExportFinished(filename, false); + } + } +} diff --git a/src/documentwindow.h b/src/documentwindow.h index 9206debb..e1722285 100644 --- a/src/documentwindow.h +++ b/src/documentwindow.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "document.h" #include "modelwidget.h" #include "exportpreviewwidget.h" @@ -24,6 +25,7 @@ class DocumentWindow : public QMainWindow signals: void initialized(); void uninialized(); + void waitingExportFinished(const QString &filename, bool succeed); public: DocumentWindow(); ~DocumentWindow(); @@ -43,6 +45,7 @@ public slots: void saveTo(const QString &saveAsFilename); void open(); void openExample(const QString &modelName); + void openPathAs(const QString &path, const QString &asName); void exportObjResult(); void exportGlbResult(); void exportFbxResult(); @@ -68,6 +71,11 @@ public slots: void unregisterDialog(QWidget *widget); void showPreferences(); void showCutFaceSettingPopup(const QPoint &globalPos, std::set nodeIds); + void setExportWaitingList(const QStringList &filenames); + void checkExportWaitingList(); + void exportObjToFilename(const QString &filename); + void exportFbxToFilename(const QString &filename); + void exportGlbToFilename(const QString &filename); private: void initLockButton(QPushButton *button); void setCurrentFilename(const QString &filename); @@ -81,6 +89,7 @@ private: std::vector m_dialogs; bool m_isLastMeshGenerationSucceed; quint64 m_currentUpdatedMeshId; + QStringList m_waitingForExportToFilenames; private: QString m_currentFilename; diff --git a/src/main.cpp b/src/main.cpp index 5db42702..beb1f8e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,15 +57,33 @@ int main(int argc, char ** argv) Theme::initAwsomeBaseSizes(); - DocumentWindow::createDocumentWindow(); + DocumentWindow *firstWindow = DocumentWindow::createDocumentWindow(); qDebug() << "Language:" << QLocale().name(); + QStringList openFileList; + QStringList waitingExportList; bool remoteIoEnabled = false; for (int i = 1; i < argc; ++i) { - if ('-' == argv[i][0] && 0 == strcmp(argv[i], "-remoteio")) { - remoteIoEnabled = true; - break; + if ('-' == argv[i][0]) { + if (0 == strcmp(argv[i], "-remoteio")) { + remoteIoEnabled = true; + continue; + } + if (0 == strcmp(argv[i], "-output") || + 0 == strcmp(argv[i], "-o")) { + ++i; + if (i < argc) + waitingExportList.append(argv[i]); + continue; + } + qDebug() << "Unknown option:" << argv[i]; + continue; + } + QString arg = argv[i]; + if (arg.endsWith(".ds3")) { + openFileList.append(arg); + continue; } } if (remoteIoEnabled) { @@ -73,5 +91,42 @@ int main(int argc, char ** argv) new RemoteIoServer(53309); } + int finishedExportFileNum = 0; + int totalExportFileNum = 0; + int succeedExportNum = 0; + if (!openFileList.empty()) { + std::vector windowList = {firstWindow}; + for (int i = 1; i < openFileList.size(); ++i) { + windowList.push_back(DocumentWindow::createDocumentWindow()); + } + if (!waitingExportList.empty() && + openFileList.size() == 1) { + totalExportFileNum = openFileList.size() * waitingExportList.size(); + for (int i = 0; i < openFileList.size(); ++i) { + QObject::connect(windowList[i], &DocumentWindow::waitingExportFinished, &app, [&](const QString &filename, bool succeed) { + qDebug() << "Export to" << filename << (succeed ? "succeed" : "failed"); + ++finishedExportFileNum; + if (succeed) + ++succeedExportNum; + if (finishedExportFileNum == totalExportFileNum) { + if (succeedExportNum == totalExportFileNum) { + app.exit(); + return; + } + app.exit(1); + return; + } + }); + } + for (int i = 0; i < openFileList.size(); ++i) { + QObject::connect(windowList[i]->document(), &Document::exportReady, windowList[i], &DocumentWindow::checkExportWaitingList); + windowList[i]->setExportWaitingList(waitingExportList); + } + } + for (int i = 0; i < openFileList.size(); ++i) { + windowList[i]->openPathAs(openFileList[i], openFileList[i]); + } + } + return app.exec(); } diff --git a/src/scriptrunner.cpp b/src/scriptrunner.cpp index 55e3b6e5..7e3c5693 100644 --- a/src/scriptrunner.cpp +++ b/src/scriptrunner.cpp @@ -412,7 +412,7 @@ void ScriptRunner::run() JS_FreeValue(context, globalObject); - JSValue object = JS_Eval(context, buffer.constData(), buffer.size(), "", + JSValue object = JS_Eval(context, buffer.constData(), buffer.size(), "", JS_EVAL_TYPE_GLOBAL); if (JS_IsException(object)) { JSValue exceptionValue = JS_GetException(context);