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 $?master
parent
2c072fc083
commit
0b2653362a
|
@ -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::set<Q
|
|||
|
||||
popupMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
void DocumentWindow::setExportWaitingList(const QStringList &filenames)
|
||||
{
|
||||
m_waitingForExportToFilenames = filenames;
|
||||
}
|
||||
|
||||
void DocumentWindow::checkExportWaitingList()
|
||||
{
|
||||
if (m_waitingForExportToFilenames.empty())
|
||||
return;
|
||||
|
||||
auto list = m_waitingForExportToFilenames;
|
||||
m_waitingForExportToFilenames.clear();
|
||||
|
||||
bool isSucceed = m_document->isMeshGenerationSucceed();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QAction>
|
||||
#include <QTextBrowser>
|
||||
#include <map>
|
||||
#include <QStringList>
|
||||
#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<QUuid> 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<QWidget *> m_dialogs;
|
||||
bool m_isLastMeshGenerationSucceed;
|
||||
quint64 m_currentUpdatedMeshId;
|
||||
QStringList m_waitingForExportToFilenames;
|
||||
private:
|
||||
QString m_currentFilename;
|
||||
|
||||
|
|
61
src/main.cpp
61
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")) {
|
||||
if ('-' == argv[i][0]) {
|
||||
if (0 == strcmp(argv[i], "-remoteio")) {
|
||||
remoteIoEnabled = true;
|
||||
break;
|
||||
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<DocumentWindow *> 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();
|
||||
}
|
||||
|
|
|
@ -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(), "<input>",
|
||||
JS_EVAL_TYPE_GLOBAL);
|
||||
if (JS_IsException(object)) {
|
||||
JSValue exceptionValue = JS_GetException(context);
|
||||
|
|
Loading…
Reference in New Issue